@getcoherent/cli 0.6.49 → 0.6.51

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
@@ -34,7 +34,7 @@ import {
34
34
  warnIfVolatile,
35
35
  warnInlineDuplicates,
36
36
  writeFile
37
- } from "./chunk-4I7ATX6G.js";
37
+ } from "./chunk-UZGT5APM.js";
38
38
  import {
39
39
  COHERENT_REQUIRED_PACKAGES,
40
40
  ensureUseClientIfNeeded,
@@ -52,7 +52,7 @@ import {
52
52
  sanitizeMetadataStrings,
53
53
  savePlan,
54
54
  updateArchitecturePlan
55
- } from "./chunk-VLBVBF6V.js";
55
+ } from "./chunk-IFJK5OPI.js";
56
56
  import {
57
57
  isValidTsx,
58
58
  safeWrite
@@ -74,7 +74,7 @@ import {
74
74
  getDesignQualityForType,
75
75
  inferPageTypeFromRoute,
76
76
  selectContextualRules
77
- } from "./chunk-E23FJX2I.js";
77
+ } from "./chunk-NLL3SHN3.js";
78
78
  import {
79
79
  fixGlobalsCss,
80
80
  generateV4GlobalsCss,
@@ -87,7 +87,7 @@ import {
87
87
  formatIssues,
88
88
  validatePageQuality,
89
89
  verifyIncrementalEdit
90
- } from "./chunk-NOM47EB4.js";
90
+ } from "./chunk-U5SNPHVU.js";
91
91
  import {
92
92
  __require
93
93
  } from "./chunk-3RG5ZIWI.js";
@@ -101,7 +101,7 @@ import { CLI_VERSION as CLI_VERSION6 } from "@getcoherent/core";
101
101
  import chalk3 from "chalk";
102
102
  import ora from "ora";
103
103
  import prompts2 from "prompts";
104
- import { existsSync as existsSync4, readFileSync as readFileSync2, mkdirSync as mkdirSync3, rmSync, writeFileSync as writeFileSync4 } from "fs";
104
+ import { existsSync as existsSync3, readFileSync as readFileSync2, mkdirSync as mkdirSync3, rmSync, writeFileSync as writeFileSync4 } from "fs";
105
105
  import { basename, join as join3 } from "path";
106
106
  import { execSync } from "child_process";
107
107
  import { ProjectScaffolder, ComponentGenerator } from "@getcoherent/core";
@@ -839,123 +839,14 @@ function hasApiKey() {
839
839
  return !!(process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY);
840
840
  }
841
841
 
842
- // src/utils/cursor-rules.ts
843
- import { writeFileSync as writeFileSync3, existsSync as existsSync3 } from "fs";
842
+ // src/utils/harness-context.ts
843
+ import { writeFileSync as writeFileSync3, existsSync as existsSync2 } from "fs";
844
844
  import { join as join2 } from "path";
845
- import { loadManifest as loadManifest2 } from "@getcoherent/core";
846
- import { DesignSystemManager as DesignSystemManager2 } from "@getcoherent/core";
845
+ import { loadManifest, DesignSystemManager } from "@getcoherent/core";
847
846
 
848
847
  // src/utils/claude-code.ts
849
- import { writeFileSync as writeFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
848
+ import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
850
849
  import { join } from "path";
851
- import { loadManifest } from "@getcoherent/core";
852
- import { DesignSystemManager } from "@getcoherent/core";
853
- function buildSharedComponentsListForClaude(manifest) {
854
- if (!manifest.shared || manifest.shared.length === 0) {
855
- return "No shared components yet. Register with: coherent components shared add <name> --type layout|navigation|data-display|form|feedback|section|widget";
856
- }
857
- const order = {
858
- layout: 0,
859
- navigation: 1,
860
- "data-display": 2,
861
- form: 3,
862
- feedback: 4,
863
- section: 5,
864
- widget: 6
865
- };
866
- const sorted = [...manifest.shared].sort(
867
- (a, b) => (order[a.type] ?? 9) - (order[b.type] ?? 9) || a.name.localeCompare(b.name)
868
- );
869
- return sorted.map((e) => {
870
- const used = e.usedIn.length === 0 ? "\u2014" : e.usedIn.length === 1 && e.usedIn[0] === "app/layout.tsx" ? "layout" : e.usedIn.length + " files";
871
- return `- ${e.id} ${e.name} (${e.type}) \u2014 ${e.file} \u2014 ${used}`;
872
- }).join("\n");
873
- }
874
- function buildClaudeMdContent(manifest, _config) {
875
- const sharedList = buildSharedComponentsListForClaude(manifest);
876
- return `# Coherent Design Method Project
877
-
878
- This is a Coherent Design Method project \u2014 AI-powered multi-page UI prototype with shared component system.
879
-
880
- ## Architecture
881
-
882
- - app/ \u2014 Next.js App Router pages
883
- - components/ui/ \u2014 base shadcn/ui components (Button, Card, Input, etc.)
884
- - components/shared/ \u2014 shared reusable blocks with unique IDs (CID-XXX)
885
- - app/design-system/ \u2014 platform overlay (DO NOT MODIFY)
886
- - coherent.components.json \u2014 shared component manifest
887
- - design-system.config.ts \u2014 design tokens and page definitions
888
-
889
- ## Shared Components (MUST REUSE)
890
-
891
- ${sharedList}
892
-
893
- Before creating ANY UI block, check if a shared component exists above. If yes \u2014 IMPORT it. NEVER recreate inline.
894
-
895
- ## Rules
896
-
897
- - ONLY use @/components/ui/* \u2014 never native <button>, <select>, <input type="checkbox">, <table>
898
- - Icons: lucide-react only
899
- - Forms: Label above Input, Switch for toggles, Select for 3+ options
900
- - Colors: semantic tokens only (bg-background, text-foreground, bg-primary) \u2014 never hardcoded
901
- - Links: text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground transition-colors (ALL links same style per page)
902
- - ALL interactive elements MUST have hover: and focus-visible: states \u2014 no exceptions
903
- - Identical components must look identical everywhere
904
- - Badge: default=success, secondary=neutral, outline=warning, destructive=error (same status = same variant everywhere)
905
- - Avatar: size-8 in lists, size-10 in profiles, always rounded-full
906
- - Dialog: max-w-sm for confirms, max-w-md for forms. Footer: cancel left, action right
907
- - Tabs: shadcn Tabs. TabsContent space-y-4. TabsList w-full md:w-auto
908
- - Alert: <Alert> for info, variant="destructive" for errors. Never for success (use toast)
909
- - Sections: h2 text-lg font-semibold. Separator between sections, border-b between list items
910
- - Nav active: sidebar=bg-accent font-medium, top nav=text-foreground font-medium
911
- - Toast: use shadcn toast, not browser alert(). Success=description only 3-5s, error=variant="destructive" persistent
912
- - Table rows: hover:bg-muted/50, actions via DropdownMenu (MoreHorizontal), wrap in overflow-x-auto
913
- - Button order: secondary first, primary LAST. Icon+text: icon mr-2 size-4 before text
914
- - Skeleton: h-4 animate-pulse rounded-md bg-muted (match content shape). Button loading: Loader2 animate-spin
915
- - Sheet for filters/mobile nav/previews. Dialog for confirmations/blocking. Sheet default side: right
916
- - Breadcrumb on pages 2+ levels deep. Current page=text-foreground, parents=muted-foreground
917
- - Code blocks: inline=rounded bg-muted px-1.5 py-0.5 font-mono text-sm. Block=rounded-md bg-muted px-4 py-3
918
- - Pagination: shadcn Pagination, centered below list. Feeds: "Load more" button instead
919
- - Card actions: DropdownMenu in CardHeader top-right OR actions in CardFooter, never both
920
- - Search: relative + Search icon absolute left-3, Input pl-9, debounce 300ms
921
- - Accordion: shadcn, type="single" for FAQ, "multiple" for settings
922
- - Popover=small forms, DropdownMenu=action lists, Dialog=complex/blocking
923
- - ScrollArea=fixed containers, native overflow-y-auto=dynamic content
924
- - Empty states: centered icon (size-12) + title + description + CTA. Search/filter variants
925
- - Stat cards: CardTitle text-sm font-medium, metric text-2xl font-bold, trend text-emerald-600/text-destructive
926
- - Error pages: centered 404/500 + "Go home" CTA. Never dead-end the user
927
- - Confirmation: title=action-specific, description=consequences, Cancel(outline)+Destructive
928
- - Multi-step: numbered circles (bg-primary active, bg-muted upcoming), Back/Next buttons
929
- - Form validation: text-sm text-destructive below input, border-destructive on input. NEVER toast
930
- - File upload: border-2 border-dashed + Upload icon + "Drag and drop or browse"
931
- - RadioGroup: 2-3 options=Radio, 4+=Select. Vertical default
932
- - Notification dot: absolute -top-1 -right-1 size-2 bg-destructive. Count: max "9+"
933
- - Progress: shadcn Progress h-2. For uploads/quotas. NEVER for page loads
934
- - Data format: dates=relative recent, absolute older. Numbers=toLocaleString. Currency=$1,234.56
935
- - Status dots: size-2 rounded-full (emerald=active, destructive=error, yellow=warning)
936
- - Timeline: vertical dot+line+event. Avatar group: flex -space-x-2 ring-2 ring-background
937
- - Sidebar: w-64 desktop, Sheet from left mobile. Settings: two-col nav+cards
938
- - Pricing: grid md:grid-cols-3, highlighted=ring-2 ring-primary, Popular badge
939
- - Hero: centered py-16 md:py-24, h1 text-3xl md:text-5xl, CTA size="lg"
940
- - Command palette: shadcn Command, \u2318K trigger. Toggle/ToggleGroup for view switchers
941
- - Copy: ghost sm button, swap Copy\u2192Check icon 2s. Z-index: content=0, dropdown=50, toast=100
942
- - Animation: transition-colors for hovers, 150ms. NEVER page load animations
943
- - Accessibility: WCAG 2.2 AA, contrast \u2265 4.5:1, touch targets \u2265 44px, focus-visible on all interactive
944
- - Auth pages (login, signup, etc.) go in app/(auth)/ route group \u2014 no Header/Footer
945
-
946
- ## After Making Changes
947
-
948
- Run after changes:
949
- - coherent check \u2014 show all quality and consistency issues (read-only)
950
- - coherent fix \u2014 auto-fix cache, deps, syntax, and style issues
951
-
952
- ## Do NOT modify
953
-
954
- - app/design-system/* \u2014 platform overlay
955
- - app/api/design-system/* \u2014 platform API routes
956
- - coherent.components.json \u2014 managed by platform
957
- `;
958
- }
959
850
  function ensureDir(dir) {
960
851
  try {
961
852
  mkdirSync2(dir, { recursive: true });
@@ -1290,11 +1181,6 @@ var SETTINGS_JSON = `{
1290
1181
  }
1291
1182
  }
1292
1183
  `;
1293
- function writeClaudeMd(projectRoot, manifest, config2) {
1294
- const content = buildClaudeMdContent(manifest, config2);
1295
- const outPath = join(projectRoot, "CLAUDE.md");
1296
- writeFileSync2(outPath, content, "utf-8");
1297
- }
1298
1184
  function writeClaudeCommands(projectRoot) {
1299
1185
  const dir = join(projectRoot, ".claude", "commands");
1300
1186
  ensureDir(dir);
@@ -1315,34 +1201,8 @@ function writeClaudeSettings(projectRoot) {
1315
1201
  ensureDir(dir);
1316
1202
  writeFileSync2(join(dir, "settings.json"), SETTINGS_JSON.trim(), "utf-8");
1317
1203
  }
1318
- async function loadManifestAndConfig(projectRoot) {
1319
- let manifest;
1320
- try {
1321
- manifest = await loadManifest(projectRoot);
1322
- } catch {
1323
- manifest = { shared: [], nextId: 1 };
1324
- }
1325
- let config2 = null;
1326
- const configPath = join(projectRoot, "design-system.config.ts");
1327
- if (existsSync2(configPath)) {
1328
- try {
1329
- const dsm = new DesignSystemManager(configPath);
1330
- await dsm.load();
1331
- config2 = dsm.getConfig();
1332
- } catch {
1333
- }
1334
- }
1335
- return { manifest, config: config2 };
1336
- }
1337
- async function generateClaudeCodeFiles(projectRoot) {
1338
- const { manifest, config: config2 } = await loadManifestAndConfig(projectRoot);
1339
- writeClaudeMd(projectRoot, manifest, config2);
1340
- writeClaudeCommands(projectRoot);
1341
- writeClaudeSkills(projectRoot);
1342
- writeClaudeSettings(projectRoot);
1343
- }
1344
1204
 
1345
- // src/utils/cursor-rules.ts
1205
+ // src/utils/harness-context.ts
1346
1206
  function buildSharedComponentsList(manifest) {
1347
1207
  if (!manifest.shared || manifest.shared.length === 0) {
1348
1208
  return `No shared components registered yet.
@@ -1377,6 +1237,27 @@ register them: coherent components shared add <Name> --type layout|navigation|da
1377
1237
 
1378
1238
  ${lines.join("\n\n")}`;
1379
1239
  }
1240
+ function buildSharedComponentsListCompact(manifest) {
1241
+ if (!manifest.shared || manifest.shared.length === 0) {
1242
+ return "No shared components yet. Register with: coherent components shared add <name> --type layout|navigation|data-display|form|feedback|section|widget";
1243
+ }
1244
+ const order = {
1245
+ layout: 0,
1246
+ navigation: 1,
1247
+ "data-display": 2,
1248
+ form: 3,
1249
+ feedback: 4,
1250
+ section: 5,
1251
+ widget: 6
1252
+ };
1253
+ const sorted = [...manifest.shared].sort(
1254
+ (a, b) => (order[a.type] ?? 9) - (order[b.type] ?? 9) || a.name.localeCompare(b.name)
1255
+ );
1256
+ return sorted.map((e) => {
1257
+ const used = e.usedIn.length === 0 ? "\u2014" : e.usedIn.length === 1 && e.usedIn[0] === "app/layout.tsx" ? "layout" : e.usedIn.length + " files";
1258
+ return `- ${e.id} ${e.name} (${e.type}) \u2014 ${e.file} \u2014 ${used}`;
1259
+ }).join("\n");
1260
+ }
1380
1261
  function buildDesignTokensSummary(config2) {
1381
1262
  if (!config2?.tokens) {
1382
1263
  return `Design tokens are defined in design-system.config.ts and globals.css.
@@ -1403,14 +1284,7 @@ Use semantic classes: bg-background, text-foreground, bg-primary, text-muted-for
1403
1284
  return `Current design tokens:
1404
1285
  ${lines.join("\n")}`;
1405
1286
  }
1406
- function buildCursorRules(manifest, config2) {
1407
- const sharedList = buildSharedComponentsList(manifest);
1408
- const tokensSummary = buildDesignTokensSummary(config2);
1409
- return `# Coherent Design Method \u2014 Project Rules
1410
- # Auto-generated. Updated when shared components or config change.
1411
- # Do NOT edit manually \u2014 run \`coherent rules\` to regenerate.
1412
-
1413
- ## Project Architecture
1287
+ var ARCHITECTURE_DETAILED = `## Project Architecture
1414
1288
 
1415
1289
  This is a Coherent Design Method project. It uses Next.js + Tailwind + a built-in component library.
1416
1290
 
@@ -1424,21 +1298,16 @@ This is a Coherent Design Method project. It uses Next.js + Tailwind + a built-i
1424
1298
  ### Config files
1425
1299
  - design-system.config.ts \u2014 design tokens, pages, navigation
1426
1300
  - coherent.components.json \u2014 shared component manifest
1427
- - globals.css \u2014 CSS variables (colors, typography, spacing)
1428
-
1429
- ## Shared Components (MUST REUSE)
1430
-
1431
- Before creating ANY UI block, check if a matching shared component exists below.
1432
- If it does \u2014 IMPORT and USE it. NEVER recreate inline.
1433
-
1434
- ${sharedList}
1435
-
1436
- When using a shared component:
1437
- - Import from @/components/shared/{filename}
1438
- - If you need it with different props, use its props interface
1439
- - If the component doesn't accept the prop you need, add the prop to the shared component and update all existing usages
1301
+ - globals.css \u2014 CSS variables (colors, typography, spacing)`;
1302
+ var ARCHITECTURE_COMPACT = `## Architecture
1440
1303
 
1441
- ## Component Rules (MANDATORY)
1304
+ - app/ \u2014 Next.js App Router pages
1305
+ - components/ui/ \u2014 base shadcn/ui components (Button, Card, Input, etc.)
1306
+ - components/shared/ \u2014 shared reusable blocks with unique IDs (CID-XXX)
1307
+ - app/design-system/ \u2014 platform overlay (DO NOT MODIFY)
1308
+ - coherent.components.json \u2014 shared component manifest
1309
+ - design-system.config.ts \u2014 design tokens and page definitions`;
1310
+ var RULES_DETAILED = `## Component Rules (MANDATORY)
1442
1311
 
1443
1312
  - ONLY use components from @/components/ui/* \u2014 never native HTML elements
1444
1313
  - NEVER use native <button> \u2014 use: import { Button } from "@/components/ui/button"
@@ -1634,9 +1503,58 @@ When using a shared component:
1634
1503
  - Content: z-0. Sticky: z-10. Dropdowns: z-50. Toast: z-[100]. Never arbitrary above z-50.
1635
1504
 
1636
1505
  ### Animation
1637
- - transition-colors for hovers. 150ms default. NEVER animate on page load or decorative.
1506
+ - transition-colors for hovers. 150ms default. NEVER animate on page load or decorative.`;
1507
+ var RULES_COMPACT = `## Rules
1638
1508
 
1639
- ## Design Quality Standards
1509
+ - ONLY use @/components/ui/* \u2014 never native <button>, <select>, <input type="checkbox">, <table>
1510
+ - Icons: lucide-react only
1511
+ - Forms: Label above Input, Switch for toggles, Select for 3+ options
1512
+ - Colors: semantic tokens only (bg-background, text-foreground, bg-primary) \u2014 never hardcoded
1513
+ - Links: text-sm text-muted-foreground underline underline-offset-4 hover:text-foreground transition-colors (ALL links same style per page)
1514
+ - ALL interactive elements MUST have hover: and focus-visible: states \u2014 no exceptions
1515
+ - Identical components must look identical everywhere
1516
+ - Badge: default=success, secondary=neutral, outline=warning, destructive=error (same status = same variant everywhere)
1517
+ - Avatar: size-8 in lists, size-10 in profiles, always rounded-full
1518
+ - Dialog: max-w-sm for confirms, max-w-md for forms. Footer: cancel left, action right
1519
+ - Tabs: shadcn Tabs. TabsContent space-y-4. TabsList w-full md:w-auto
1520
+ - Alert: <Alert> for info, variant="destructive" for errors. Never for success (use toast)
1521
+ - Sections: h2 text-lg font-semibold. Separator between sections, border-b between list items
1522
+ - Nav active: sidebar=bg-accent font-medium, top nav=text-foreground font-medium
1523
+ - Toast: use shadcn toast, not browser alert(). Success=description only 3-5s, error=variant="destructive" persistent
1524
+ - Table rows: hover:bg-muted/50, actions via DropdownMenu (MoreHorizontal), wrap in overflow-x-auto
1525
+ - Button order: secondary first, primary LAST. Icon+text: icon mr-2 size-4 before text
1526
+ - Skeleton: h-4 animate-pulse rounded-md bg-muted (match content shape). Button loading: Loader2 animate-spin
1527
+ - Sheet for filters/mobile nav/previews. Dialog for confirmations/blocking. Sheet default side: right
1528
+ - Breadcrumb on pages 2+ levels deep. Current page=text-foreground, parents=muted-foreground
1529
+ - Code blocks: inline=rounded bg-muted px-1.5 py-0.5 font-mono text-sm. Block=rounded-md bg-muted px-4 py-3
1530
+ - Pagination: shadcn Pagination, centered below list. Feeds: "Load more" button instead
1531
+ - Card actions: DropdownMenu in CardHeader top-right OR actions in CardFooter, never both
1532
+ - Search: relative + Search icon absolute left-3, Input pl-9, debounce 300ms
1533
+ - Accordion: shadcn, type="single" for FAQ, "multiple" for settings
1534
+ - Popover=small forms, DropdownMenu=action lists, Dialog=complex/blocking
1535
+ - ScrollArea=fixed containers, native overflow-y-auto=dynamic content
1536
+ - Empty states: centered icon (size-12) + title + description + CTA. Search/filter variants
1537
+ - Stat cards: CardTitle text-sm font-medium, metric text-2xl font-bold, trend text-emerald-600/text-destructive
1538
+ - Error pages: centered 404/500 + "Go home" CTA. Never dead-end the user
1539
+ - Confirmation: title=action-specific, description=consequences, Cancel(outline)+Destructive
1540
+ - Multi-step: numbered circles (bg-primary active, bg-muted upcoming), Back/Next buttons
1541
+ - Form validation: text-sm text-destructive below input, border-destructive on input. NEVER toast
1542
+ - File upload: border-2 border-dashed + Upload icon + "Drag and drop or browse"
1543
+ - RadioGroup: 2-3 options=Radio, 4+=Select. Vertical default
1544
+ - Notification dot: absolute -top-1 -right-1 size-2 bg-destructive. Count: max "9+"
1545
+ - Progress: shadcn Progress h-2. For uploads/quotas. NEVER for page loads
1546
+ - Data format: dates=relative recent, absolute older. Numbers=toLocaleString. Currency=$1,234.56
1547
+ - Status dots: size-2 rounded-full (emerald=active, destructive=error, yellow=warning)
1548
+ - Timeline: vertical dot+line+event. Avatar group: flex -space-x-2 ring-2 ring-background
1549
+ - Sidebar: w-64 desktop, Sheet from left mobile. Settings: two-col nav+cards
1550
+ - Pricing: grid md:grid-cols-3, highlighted=ring-2 ring-primary, Popular badge
1551
+ - Hero: centered py-16 md:py-24, h1 text-3xl md:text-5xl, CTA size="lg"
1552
+ - Command palette: shadcn Command, \u2318K trigger. Toggle/ToggleGroup for view switchers
1553
+ - Copy: ghost sm button, swap Copy\u2192Check icon 2s. Z-index: content=0, dropdown=50, toast=100
1554
+ - Animation: transition-colors for hovers, 150ms. NEVER page load animations
1555
+ - Accessibility: WCAG 2.2 AA, contrast \u2265 4.5:1, touch targets \u2265 44px, focus-visible on all interactive
1556
+ - Auth pages (login, signup, etc.) go in app/(auth)/ route group \u2014 no Header/Footer`;
1557
+ var DESIGN_QUALITY2 = `## Design Quality Standards
1640
1558
 
1641
1559
  - Headlines: text-4xl+ font-bold tracking-tight for page titles, text-5xl+ for heroes, text-2xl+ for sections
1642
1560
  - Cards: rounded-xl with border-border/15, ALWAYS hover state: hover:border-border/30 transition-colors
@@ -1646,45 +1564,33 @@ When using a shared component:
1646
1564
  - One accent color per page \u2014 never mix blue + purple + emerald
1647
1565
  - Hero: min-h-[80vh] centered, gradient text on key phrase (from-white to-zinc-500 bg-clip-text text-transparent)
1648
1566
  - Comparison sections: red-400 X for negative, emerald-400 Check for positive
1649
- - Footer: minimal, border-t border-border/10, py-10, text-sm text-muted-foreground
1650
-
1651
- ## Design Tokens
1652
-
1653
- ${tokensSummary}
1654
-
1655
- Use semantic token classes (bg-background, text-foreground, bg-primary, etc.).
1656
- NEVER hardcode colors. NEVER use arbitrary Tailwind values like bg-[#123456].
1657
-
1658
- ## Form Layout Rules
1567
+ - Footer: minimal, border-t border-border/10, py-10, text-sm text-muted-foreground`;
1568
+ var FORMS = `## Form Layout Rules
1659
1569
 
1660
1570
  - Label above Input (never beside on mobile)
1661
1571
  - space-y-2 within field group (label + input + description)
1662
1572
  - space-y-6 between field groups
1663
1573
  - Switch for boolean toggles, not Checkbox
1664
1574
  - Select for 3+ options, Radio for 2-3 options
1665
- - CardFooter for form actions (Save, Cancel)
1666
-
1667
- ## Accessibility (WCAG 2.2 AA)
1575
+ - CardFooter for form actions (Save, Cancel)`;
1576
+ var ACCESSIBILITY = `## Accessibility (WCAG 2.2 AA)
1668
1577
 
1669
1578
  - Text contrast \u2265 4.5:1, UI component contrast \u2265 3:1
1670
1579
  - Touch targets \u2265 44\xD744px (min-h-11 min-w-11)
1671
1580
  - Focus visible on ALL interactive elements (focus-visible:ring-2)
1672
1581
  - Color never the only indicator
1673
1582
  - Every form input must have a Label with htmlFor
1674
- - Heading hierarchy: one h1 per page, no skipped levels
1675
-
1676
- ## Auth Pages
1583
+ - Heading hierarchy: one h1 per page, no skipped levels`;
1584
+ var AUTH = `## Auth Pages
1677
1585
 
1678
1586
  Login, signup, register, forgot-password \u2192 placed in app/(auth)/ route group.
1679
- These pages do NOT show Header/Footer.
1680
-
1681
- ## After Making Changes
1587
+ These pages do NOT show Header/Footer.`;
1588
+ var COMMANDS_SECTION = `## After Making Changes
1682
1589
 
1683
1590
  Run in terminal:
1684
1591
  - coherent check \u2014 show all quality and consistency issues (read-only)
1685
- - coherent fix \u2014 auto-fix cache, deps, syntax, and style issues
1686
-
1687
- ## Platform Overlay (DO NOT TOUCH)
1592
+ - coherent fix \u2014 auto-fix cache, deps, syntax, and style issues`;
1593
+ var PLATFORM = `## Platform Overlay (DO NOT TOUCH)
1688
1594
 
1689
1595
  The following are dev-only platform features, excluded from production export:
1690
1596
  - Floating Design System button (in shared Header component)
@@ -1692,30 +1598,166 @@ The following are dev-only platform features, excluded from production export:
1692
1598
  - /api/design-system/* routes
1693
1599
  - coherent.components.json
1694
1600
 
1695
- DO NOT modify or delete these. They are managed by the platform.
1601
+ DO NOT modify or delete these. They are managed by the platform.`;
1602
+ var COMMANDS_COMPACT = `## After Making Changes
1603
+
1604
+ Run after changes:
1605
+ - coherent check \u2014 show all quality and consistency issues (read-only)
1606
+ - coherent fix \u2014 auto-fix cache, deps, syntax, and style issues`;
1607
+ var PLATFORM_COMPACT = `## Do NOT modify
1608
+
1609
+ - app/design-system/* \u2014 platform overlay
1610
+ - app/api/design-system/* \u2014 platform API routes
1611
+ - coherent.components.json \u2014 managed by platform`;
1612
+ function buildProjectContext(manifest, config2) {
1613
+ return {
1614
+ sharedComponents: buildSharedComponentsList(manifest),
1615
+ sharedComponentsCompact: buildSharedComponentsListCompact(manifest),
1616
+ designTokens: buildDesignTokensSummary(config2),
1617
+ architectureDetailed: ARCHITECTURE_DETAILED,
1618
+ architectureCompact: ARCHITECTURE_COMPACT,
1619
+ rulesDetailed: RULES_DETAILED,
1620
+ rulesCompact: RULES_COMPACT,
1621
+ designQuality: DESIGN_QUALITY2,
1622
+ forms: FORMS,
1623
+ accessibility: ACCESSIBILITY,
1624
+ auth: AUTH,
1625
+ commands: COMMANDS_SECTION,
1626
+ platform: PLATFORM
1627
+ };
1628
+ }
1629
+ function formatForCursor(ctx) {
1630
+ return `# Coherent Design Method \u2014 Project Rules
1631
+ # Auto-generated. Updated when shared components or config change.
1632
+ # Do NOT edit manually \u2014 run \`coherent rules\` to regenerate.
1633
+
1634
+ ${ctx.architectureDetailed}
1635
+
1636
+ ## Shared Components (MUST REUSE)
1637
+
1638
+ Before creating ANY UI block, check if a matching shared component exists below.
1639
+ If it does \u2014 IMPORT and USE it. NEVER recreate inline.
1640
+
1641
+ ${ctx.sharedComponents}
1642
+
1643
+ When using a shared component:
1644
+ - Import from @/components/shared/{filename}
1645
+ - If you need it with different props, use its props interface
1646
+ - If the component doesn't accept the prop you need, add the prop to the shared component and update all existing usages
1647
+
1648
+ ${ctx.rulesDetailed}
1649
+
1650
+ ${ctx.designQuality}
1651
+
1652
+ ## Design Tokens
1653
+
1654
+ ${ctx.designTokens}
1655
+
1656
+ Use semantic token classes (bg-background, text-foreground, bg-primary, etc.).
1657
+ NEVER hardcode colors. NEVER use arbitrary Tailwind values like bg-[#123456].
1658
+
1659
+ ${ctx.forms}
1660
+
1661
+ ${ctx.accessibility}
1662
+
1663
+ ${ctx.auth}
1664
+
1665
+ ${ctx.commands}
1666
+
1667
+ ${ctx.platform}
1668
+ `;
1669
+ }
1670
+ function formatForClaude(ctx) {
1671
+ return `# Coherent Design Method Project
1672
+
1673
+ This is a Coherent Design Method project \u2014 AI-powered multi-page UI prototype with shared component system.
1674
+
1675
+ ${ctx.architectureCompact}
1676
+
1677
+ ## Shared Components (MUST REUSE)
1678
+
1679
+ ${ctx.sharedComponentsCompact}
1680
+
1681
+ Before creating ANY UI block, check if a shared component exists above. If yes \u2014 IMPORT it. NEVER recreate inline.
1682
+
1683
+ ${ctx.rulesCompact}
1684
+
1685
+ ## Design Tokens
1686
+
1687
+ ${ctx.designTokens}
1688
+
1689
+ Use semantic token classes (bg-background, text-foreground, bg-primary, etc.).
1690
+ NEVER hardcode colors. NEVER use arbitrary Tailwind values like bg-[#123456].
1691
+
1692
+ ${COMMANDS_COMPACT}
1693
+
1694
+ ${PLATFORM_COMPACT}
1695
+ `;
1696
+ }
1697
+ function formatForAgents(ctx) {
1698
+ return `# Project Conventions
1699
+ # Auto-generated by Coherent. Run \`coherent rules\` to regenerate.
1700
+
1701
+ ${ctx.architectureDetailed}
1702
+
1703
+ ## Shared Components (MUST REUSE)
1704
+
1705
+ Before creating ANY UI block, check if a matching shared component exists below.
1706
+ If it does \u2014 IMPORT and USE it. NEVER recreate inline.
1707
+
1708
+ ${ctx.sharedComponents}
1709
+
1710
+ When using a shared component:
1711
+ - Import from @/components/shared/{filename}
1712
+ - If you need it with different props, use its props interface
1713
+ - If the component doesn't accept the prop you need, add the prop to the shared component and update all existing usages
1714
+
1715
+ ${ctx.rulesDetailed}
1716
+
1717
+ ${ctx.designQuality}
1718
+
1719
+ ## Design Tokens
1720
+
1721
+ ${ctx.designTokens}
1722
+
1723
+ Use semantic token classes (bg-background, text-foreground, bg-primary, etc.).
1724
+ NEVER hardcode colors. NEVER use arbitrary Tailwind values like bg-[#123456].
1725
+
1726
+ ${ctx.forms}
1727
+
1728
+ ${ctx.accessibility}
1729
+
1730
+ ${ctx.auth}
1731
+
1732
+ ${ctx.commands}
1733
+
1734
+ ${ctx.platform}
1696
1735
  `;
1697
1736
  }
1698
- async function writeCursorRules(projectRoot) {
1737
+ async function writeAllHarnessFiles(projectRoot) {
1699
1738
  let manifest;
1700
1739
  try {
1701
- manifest = await loadManifest2(projectRoot);
1740
+ manifest = await loadManifest(projectRoot);
1702
1741
  } catch {
1703
1742
  manifest = { shared: [], nextId: 1 };
1704
1743
  }
1705
1744
  let config2 = null;
1706
1745
  const configPath = join2(projectRoot, "design-system.config.ts");
1707
- if (existsSync3(configPath)) {
1746
+ if (existsSync2(configPath)) {
1708
1747
  try {
1709
- const dsm = new DesignSystemManager2(configPath);
1748
+ const dsm = new DesignSystemManager(configPath);
1710
1749
  await dsm.load();
1711
1750
  config2 = dsm.getConfig();
1712
1751
  } catch {
1713
1752
  }
1714
1753
  }
1715
- const content = buildCursorRules(manifest, config2);
1716
- const outPath = join2(projectRoot, ".cursorrules");
1717
- writeFileSync3(outPath, content, "utf-8");
1718
- writeClaudeMd(projectRoot, manifest, config2);
1754
+ const ctx = buildProjectContext(manifest, config2);
1755
+ writeFileSync3(join2(projectRoot, ".cursorrules"), formatForCursor(ctx), "utf-8");
1756
+ writeFileSync3(join2(projectRoot, "CLAUDE.md"), formatForClaude(ctx), "utf-8");
1757
+ writeFileSync3(join2(projectRoot, "AGENTS.md"), formatForAgents(ctx), "utf-8");
1758
+ writeClaudeCommands(projectRoot);
1759
+ writeClaudeSkills(projectRoot);
1760
+ writeClaudeSettings(projectRoot);
1719
1761
  const tokenKeys = config2?.tokens ? [
1720
1762
  ...Object.keys(config2.tokens.colors?.light ?? {}),
1721
1763
  ...Object.keys(config2.tokens.colors?.dark ?? {}),
@@ -1728,19 +1770,19 @@ async function writeCursorRules(projectRoot) {
1728
1770
  tokenKeys: tokenKeys || void 0
1729
1771
  };
1730
1772
  }
1731
- async function regenerateCursorRules() {
1773
+ async function regenerateAllHarnessFiles() {
1732
1774
  const project = findConfig();
1733
1775
  if (!project) {
1734
1776
  return { written: false };
1735
1777
  }
1736
- return writeCursorRules(project.root);
1778
+ return writeAllHarnessFiles(project.root);
1737
1779
  }
1738
1780
 
1739
1781
  // src/commands/init.ts
1740
1782
  import { cwd } from "process";
1741
1783
  function hasNextInPackageJson(projectPath) {
1742
1784
  const pkgPath = join3(projectPath, "package.json");
1743
- if (!existsSync4(pkgPath)) return false;
1785
+ if (!existsSync3(pkgPath)) return false;
1744
1786
  try {
1745
1787
  const json = JSON.parse(readFileSync2(pkgPath, "utf-8"));
1746
1788
  const deps = { ...json.dependencies, ...json.devDependencies };
@@ -1753,7 +1795,7 @@ function cleanConflictingFiles(projectPath) {
1753
1795
  const conflicts = [".next", ".coherent", ".cursorrules", ".eslintrc.json", "CLAUDE.md", ".claude", ".vscode"];
1754
1796
  for (const name of conflicts) {
1755
1797
  const fullPath = join3(projectPath, name);
1756
- if (existsSync4(fullPath)) {
1798
+ if (existsSync3(fullPath)) {
1757
1799
  rmSync(fullPath, { recursive: true, force: true });
1758
1800
  }
1759
1801
  }
@@ -1761,12 +1803,12 @@ function cleanConflictingFiles(projectPath) {
1761
1803
  function runCreateNextApp(projectPath) {
1762
1804
  cleanConflictingFiles(projectPath);
1763
1805
  const envPath = join3(projectPath, ".env");
1764
- const envBackup = existsSync4(envPath) ? readFileSync2(envPath, "utf-8") : null;
1806
+ const envBackup = existsSync3(envPath) ? readFileSync2(envPath, "utf-8") : null;
1765
1807
  if (envBackup !== null) rmSync(envPath, { force: true });
1766
1808
  const cmd = "npx --yes create-next-app@15.2.4 . --typescript --tailwind --eslint --app --no-src-dir --no-turbopack --yes";
1767
1809
  execSync(cmd, { cwd: projectPath, stdio: "inherit" });
1768
1810
  if (envBackup !== null) {
1769
- const existing = existsSync4(envPath) ? readFileSync2(envPath, "utf-8") : "";
1811
+ const existing = existsSync3(envPath) ? readFileSync2(envPath, "utf-8") : "";
1770
1812
  writeFileSync4(envPath, existing ? existing + "\n" + envBackup : envBackup, "utf-8");
1771
1813
  }
1772
1814
  }
@@ -1774,8 +1816,8 @@ async function ensureCoherentPrerequisites(projectPath) {
1774
1816
  const libPath = join3(projectPath, "lib");
1775
1817
  const utilsPath = join3(projectPath, "lib", "utils.ts");
1776
1818
  const componentsUiPath = join3(projectPath, "components", "ui");
1777
- if (!existsSync4(utilsPath)) {
1778
- if (!existsSync4(libPath)) mkdirSync3(libPath, { recursive: true });
1819
+ if (!existsSync3(utilsPath)) {
1820
+ if (!existsSync3(libPath)) mkdirSync3(libPath, { recursive: true });
1779
1821
  const cnContent = `import { type ClassValue, clsx } from 'clsx'
1780
1822
  import { twMerge } from 'tailwind-merge'
1781
1823
 
@@ -1785,7 +1827,7 @@ export function cn(...inputs: ClassValue[]) {
1785
1827
  `;
1786
1828
  await writeFile(utilsPath, cnContent);
1787
1829
  }
1788
- if (!existsSync4(componentsUiPath)) mkdirSync3(componentsUiPath, { recursive: true });
1830
+ if (!existsSync3(componentsUiPath)) mkdirSync3(componentsUiPath, { recursive: true });
1789
1831
  }
1790
1832
  async function ensureRegistryComponents(config2, projectPath) {
1791
1833
  const provider = getComponentProvider();
@@ -1793,12 +1835,12 @@ async function ensureRegistryComponents(config2, projectPath) {
1793
1835
  await provider.installBatch(baseComponents, projectPath);
1794
1836
  const generator = new ComponentGenerator(config2);
1795
1837
  const uiDir = join3(projectPath, "components", "ui");
1796
- if (!existsSync4(uiDir)) mkdirSync3(uiDir, { recursive: true });
1838
+ if (!existsSync3(uiDir)) mkdirSync3(uiDir, { recursive: true });
1797
1839
  for (const comp of config2.components) {
1798
1840
  if (comp.source === "shadcn") continue;
1799
1841
  const fileName = toKebabCase(comp.name) + ".tsx";
1800
1842
  const filePath = join3(uiDir, fileName);
1801
- if (existsSync4(filePath)) continue;
1843
+ if (existsSync3(filePath)) continue;
1802
1844
  const code = await generator.generate(comp);
1803
1845
  await writeFile(filePath, code);
1804
1846
  }
@@ -1827,7 +1869,7 @@ async function initCommand(name) {
1827
1869
  process.exit(1);
1828
1870
  }
1829
1871
  const targetDir = join3(cwd(), name);
1830
- if (!existsSync4(targetDir)) {
1872
+ if (!existsSync3(targetDir)) {
1831
1873
  mkdirSync3(targetDir, { recursive: true });
1832
1874
  }
1833
1875
  process.chdir(targetDir);
@@ -1835,7 +1877,7 @@ async function initCommand(name) {
1835
1877
  let projectPath;
1836
1878
  try {
1837
1879
  projectPath = cwd();
1838
- if (!existsSync4(projectPath)) {
1880
+ if (!existsSync3(projectPath)) {
1839
1881
  throw new Error("ENOENT");
1840
1882
  }
1841
1883
  } catch (err) {
@@ -1901,7 +1943,7 @@ async function initCommand(name) {
1901
1943
  } else {
1902
1944
  try {
1903
1945
  const pkgPath = join3(projectPath, "package.json");
1904
- if (existsSync4(pkgPath)) {
1946
+ if (existsSync3(pkgPath)) {
1905
1947
  const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
1906
1948
  if (typeof pkg.name === "string" && pkg.name) {
1907
1949
  appName = toTitleCase(pkg.name);
@@ -1996,8 +2038,7 @@ export default config
1996
2038
  { type: "init", description: "Project initialized", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
1997
2039
  ]);
1998
2040
  try {
1999
- await writeCursorRules(projectPath);
2000
- await generateClaudeCodeFiles(projectPath);
2041
+ await writeAllHarnessFiles(projectPath);
2001
2042
  } catch (e) {
2002
2043
  if (process.env.COHERENT_DEBUG === "1") console.error(chalk3.dim("Could not write .cursorrules / CLAUDE.md:"), e);
2003
2044
  }
@@ -2013,9 +2054,9 @@ async function configureNextImages(projectPath) {
2013
2054
  const jsPath = join3(projectPath, "next.config.js");
2014
2055
  const mjsPath = join3(projectPath, "next.config.mjs");
2015
2056
  let configPath = "";
2016
- if (existsSync4(tsPath)) configPath = tsPath;
2017
- else if (existsSync4(mjsPath)) configPath = mjsPath;
2018
- else if (existsSync4(jsPath)) configPath = jsPath;
2057
+ if (existsSync3(tsPath)) configPath = tsPath;
2058
+ else if (existsSync3(mjsPath)) configPath = mjsPath;
2059
+ else if (existsSync3(jsPath)) configPath = jsPath;
2019
2060
  else return;
2020
2061
  const content = `import type { NextConfig } from "next";
2021
2062
 
@@ -2055,14 +2096,14 @@ async function createAppRouteGroupLayout(projectPath) {
2055
2096
  import chalk10 from "chalk";
2056
2097
  import ora2 from "ora";
2057
2098
  import { resolve as resolve5, relative as relative2, join as join6 } from "path";
2058
- import { existsSync as existsSync9, readFileSync as readFileSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
2099
+ import { existsSync as existsSync8, readFileSync as readFileSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
2059
2100
  import {
2060
- DesignSystemManager as DesignSystemManager5,
2101
+ DesignSystemManager as DesignSystemManager4,
2061
2102
  ComponentManager as ComponentManager4,
2062
2103
  PageManager as PageManager2,
2063
2104
  CLI_VERSION as CLI_VERSION2,
2064
2105
  getTemplateForPageType as getTemplateForPageType2,
2065
- loadManifest as loadManifest7,
2106
+ loadManifest as loadManifest6,
2066
2107
  saveManifest as saveManifest3,
2067
2108
  updateEntry
2068
2109
  } from "@getcoherent/core";
@@ -2555,8 +2596,8 @@ function extractComponentSpec(changes) {
2555
2596
  // src/utils/dark-mode.ts
2556
2597
  import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
2557
2598
  import { join as join4 } from "path";
2558
- import { existsSync as existsSync5 } from "fs";
2559
- import { generateSharedComponent, loadManifest as loadManifest3, integrateSharedLayoutIntoRootLayout } from "@getcoherent/core";
2599
+ import { existsSync as existsSync4 } from "fs";
2600
+ import { generateSharedComponent, loadManifest as loadManifest2, integrateSharedLayoutIntoRootLayout } from "@getcoherent/core";
2560
2601
  var THEME_TOGGLE_CODE = `'use client'
2561
2602
 
2562
2603
  import { Moon, Sun } from 'lucide-react'
@@ -2582,7 +2623,7 @@ export function ThemeToggle() {
2582
2623
  `;
2583
2624
  async function setDefaultDarkTheme(projectRoot) {
2584
2625
  const layoutPath = join4(projectRoot, "app", "layout.tsx");
2585
- if (!existsSync5(layoutPath)) return false;
2626
+ if (!existsSync4(layoutPath)) return false;
2586
2627
  let content = await readFile2(layoutPath, "utf-8");
2587
2628
  if (content.includes('<html className="dark"') || content.includes("<html className='dark'")) return true;
2588
2629
  content = content.replace(/<html(\s|>)/, '<html className="dark"$1');
@@ -2590,7 +2631,7 @@ async function setDefaultDarkTheme(projectRoot) {
2590
2631
  return true;
2591
2632
  }
2592
2633
  async function ensureThemeToggle(projectRoot) {
2593
- const manifest = await loadManifest3(projectRoot);
2634
+ const manifest = await loadManifest2(projectRoot);
2594
2635
  const existing = manifest.shared.find((e) => e.name === "ThemeToggle" || e.name.toLowerCase().includes("themetoggle"));
2595
2636
  if (existing) {
2596
2637
  await integrateSharedLayoutIntoRootLayout(projectRoot);
@@ -2610,7 +2651,7 @@ async function ensureThemeToggle(projectRoot) {
2610
2651
  import { appendFile } from "fs/promises";
2611
2652
 
2612
2653
  // src/utils/backup.ts
2613
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync5, readdirSync, rmSync as rmSync2, statSync } from "fs";
2654
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync5, readdirSync, rmSync as rmSync2, statSync } from "fs";
2614
2655
  import { join as join5, relative, dirname as dirname2 } from "path";
2615
2656
  import chalk5 from "chalk";
2616
2657
  var DEBUG = process.env.COHERENT_DEBUG === "1";
@@ -2633,7 +2674,7 @@ function createBackup(projectRoot) {
2633
2674
  let fileCount = 0;
2634
2675
  for (const file of CRITICAL_FILES) {
2635
2676
  const src = join5(projectRoot, file);
2636
- if (existsSync6(src)) {
2677
+ if (existsSync5(src)) {
2637
2678
  const dest = join5(backupPath, file);
2638
2679
  mkdirSync4(dirname2(dest), { recursive: true });
2639
2680
  writeFileSync5(dest, readFileSync3(src));
@@ -2642,7 +2683,7 @@ function createBackup(projectRoot) {
2642
2683
  }
2643
2684
  for (const dir of CRITICAL_DIRS) {
2644
2685
  const srcDir = join5(projectRoot, dir);
2645
- if (!existsSync6(srcDir)) continue;
2686
+ if (!existsSync5(srcDir)) continue;
2646
2687
  backupDirectory(srcDir, projectRoot, backupPath);
2647
2688
  fileCount += countFiles(srcDir);
2648
2689
  }
@@ -2710,12 +2751,12 @@ function pruneOldBackups(backupBase) {
2710
2751
  }
2711
2752
  function listBackups(projectRoot) {
2712
2753
  const backupBase = join5(projectRoot, BACKUP_DIR);
2713
- if (!existsSync6(backupBase)) return [];
2754
+ if (!existsSync5(backupBase)) return [];
2714
2755
  try {
2715
2756
  return readdirSync(backupBase).filter((e) => !e.startsWith(".")).map((name) => {
2716
2757
  const metaPath = join5(backupBase, name, ".backup-meta.json");
2717
2758
  let meta = { timestamp: name, files: 0 };
2718
- if (existsSync6(metaPath)) {
2759
+ if (existsSync5(metaPath)) {
2719
2760
  try {
2720
2761
  meta = JSON.parse(readFileSync3(metaPath, "utf-8"));
2721
2762
  } catch (e) {
@@ -2731,7 +2772,7 @@ function listBackups(projectRoot) {
2731
2772
  }
2732
2773
  function restoreBackup(projectRoot, backupName) {
2733
2774
  const backupPath = join5(projectRoot, BACKUP_DIR, backupName);
2734
- if (!existsSync6(backupPath)) return false;
2775
+ if (!existsSync5(backupPath)) return false;
2735
2776
  try {
2736
2777
  restoreDirectory(backupPath, backupPath, projectRoot);
2737
2778
  return true;
@@ -3209,12 +3250,12 @@ function applyDefaults(request) {
3209
3250
  }
3210
3251
 
3211
3252
  // src/commands/chat/split-generator.ts
3212
- import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
3253
+ import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
3213
3254
  import { resolve as resolve2 } from "path";
3214
3255
  import { z } from "zod";
3215
3256
  import {
3216
3257
  SharedComponentTypeSchema,
3217
- loadManifest as loadManifest4,
3258
+ loadManifest as loadManifest3,
3218
3259
  saveManifest,
3219
3260
  generateSharedComponent as generateSharedComponent2
3220
3261
  } from "@getcoherent/core";
@@ -3660,7 +3701,7 @@ function readExistingAppPageForReference(projectRoot, plan) {
3660
3701
  for (const group of ["(app)", "(admin)", "(dashboard)"]) {
3661
3702
  const filePath = resolve2(projectRoot, "app", group, key, "page.tsx");
3662
3703
  try {
3663
- if (existsSync7(filePath)) {
3704
+ if (existsSync6(filePath)) {
3664
3705
  const code = readFileSync4(filePath, "utf-8");
3665
3706
  const lines = code.split("\n");
3666
3707
  return lines.slice(0, 60).join("\n");
@@ -3672,7 +3713,7 @@ function readExistingAppPageForReference(projectRoot, plan) {
3672
3713
  }
3673
3714
  }
3674
3715
  const appDir = resolve2(projectRoot, "app");
3675
- if (!existsSync7(appDir)) return null;
3716
+ if (!existsSync6(appDir)) return null;
3676
3717
  try {
3677
3718
  const entries = readdirSync2(appDir);
3678
3719
  for (const entry of entries) {
@@ -3682,7 +3723,7 @@ function readExistingAppPageForReference(projectRoot, plan) {
3682
3723
  const subDirs = readdirSync2(groupDir);
3683
3724
  for (const sub of subDirs) {
3684
3725
  const pagePath = resolve2(groupDir, sub, "page.tsx");
3685
- if (existsSync7(pagePath)) {
3726
+ if (existsSync6(pagePath)) {
3686
3727
  const code = readFileSync4(pagePath, "utf-8");
3687
3728
  const lines = code.split("\n");
3688
3729
  return lines.slice(0, 60).join("\n");
@@ -3728,7 +3769,7 @@ var manifestLock = Promise.resolve();
3728
3769
  async function updateManifestSafe(projectRoot, fn) {
3729
3770
  const timeoutMs = 5e3;
3730
3771
  const update = manifestLock.then(async () => {
3731
- const m = await loadManifest4(projectRoot);
3772
+ const m = await loadManifest3(projectRoot);
3732
3773
  const updated = fn(m);
3733
3774
  await saveManifest(projectRoot, updated);
3734
3775
  });
@@ -3900,7 +3941,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
3900
3941
  if (plan && plan.sharedComponents.length > 0) {
3901
3942
  spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
3902
3943
  try {
3903
- const { generateSharedComponentsFromPlan } = await import("./plan-generator-PIDLFRWZ.js");
3944
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-D2UBTVCN.js");
3904
3945
  const generated = await generateSharedComponentsFromPlan(
3905
3946
  plan,
3906
3947
  styleContext,
@@ -3908,7 +3949,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
3908
3949
  await createAIProvider(provider ?? "auto")
3909
3950
  );
3910
3951
  if (generated.length > 0) {
3911
- const updatedManifest = await loadManifest4(projectRoot);
3952
+ const updatedManifest = await loadManifest3(projectRoot);
3912
3953
  parseOpts.sharedComponentsSummary = buildSharedComponentsSummary(updatedManifest);
3913
3954
  const names = generated.map((c) => c.name).join(", ");
3914
3955
  spinner.succeed(`Phase 4.5/6 \u2014 Generated ${generated.length} shared components (${names})`);
@@ -3919,7 +3960,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
3919
3960
  spinner.warn("Phase 4.5/6 \u2014 Could not generate shared components (continuing without)");
3920
3961
  }
3921
3962
  } else if (homePageCode) {
3922
- const manifest = await loadManifest4(projectRoot);
3963
+ const manifest = await loadManifest3(projectRoot);
3923
3964
  const shouldSkip = reusedExistingAnchor && manifest.shared.some((e) => e.type !== "layout");
3924
3965
  if (!shouldSkip) {
3925
3966
  spinner.start("Phase 4.5/6 \u2014 Extracting shared components (legacy)...");
@@ -3943,7 +3984,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
3943
3984
  }
3944
3985
  spinner.start(`Phase 5/6 \u2014 Generating ${remainingPages.length} pages in parallel...`);
3945
3986
  const sharedComponentsNote = buildSharedComponentsNote(parseOpts.sharedComponentsSummary);
3946
- const currentManifest = projectRoot ? await loadManifest4(projectRoot) : null;
3987
+ const currentManifest = projectRoot ? await loadManifest3(projectRoot) : null;
3947
3988
  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="#".`;
3948
3989
  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.';
3949
3990
  const existingAppPageCode = readExistingAppPageForReference(parseOpts?.projectRoot ?? null, plan);
@@ -3957,7 +3998,7 @@ ${existingAppPageCode}
3957
3998
  const existingPageCode = {};
3958
3999
  if (projectRoot) {
3959
4000
  const appDir = resolve2(projectRoot, "app");
3960
- if (existsSync7(appDir)) {
4001
+ if (existsSync6(appDir)) {
3961
4002
  const pageFiles = readdirSync2(appDir, { recursive: true }).filter(
3962
4003
  (f) => typeof f === "string" && f.endsWith("page.tsx")
3963
4004
  );
@@ -4144,7 +4185,7 @@ var SharedExtractionResponseSchema = z.object({
4144
4185
  components: z.array(SharedExtractionItemSchema).max(5).default([])
4145
4186
  });
4146
4187
  async function extractSharedComponents(homePageCode, projectRoot, aiProvider) {
4147
- const manifest = await loadManifest4(projectRoot);
4188
+ const manifest = await loadManifest3(projectRoot);
4148
4189
  let ai;
4149
4190
  try {
4150
4191
  ai = await createAIProvider(aiProvider);
@@ -4199,7 +4240,7 @@ async function extractSharedComponents(homePageCode, projectRoot, aiProvider) {
4199
4240
  } catch {
4200
4241
  }
4201
4242
  }
4202
- const updatedManifest = await loadManifest4(projectRoot);
4243
+ const updatedManifest = await loadManifest3(projectRoot);
4203
4244
  return { components: results, summary: buildSharedComponentsSummary(updatedManifest) };
4204
4245
  }
4205
4246
  function extractAppNameFromPrompt(prompt) {
@@ -4249,7 +4290,7 @@ import { dirname as dirname3 } from "path";
4249
4290
  import chalk8 from "chalk";
4250
4291
  import {
4251
4292
  getTemplateForPageType,
4252
- loadManifest as loadManifest5,
4293
+ loadManifest as loadManifest4,
4253
4294
  saveManifest as saveManifest2,
4254
4295
  updateUsedIn,
4255
4296
  findSharedComponentByIdOrName,
@@ -4655,6 +4696,16 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4655
4696
  console.log(chalk8.dim(" \u{1F527} Post-generation fixes:"));
4656
4697
  fixes.forEach((f) => console.log(chalk8.dim(` ${f}`)));
4657
4698
  }
4699
+ const colorIssueTypes = ["raw-color", "inline-style-color", "arbitrary-color", "svg-raw-color", "color-prop"];
4700
+ const colorIssues = validatePageQuality(fixedCode).filter(
4701
+ (i) => i.severity === "error" && colorIssueTypes.includes(i.type)
4702
+ );
4703
+ if (colorIssues.length > 0) {
4704
+ console.warn(
4705
+ `\u26A0 Component has ${colorIssues.length} color issue(s) after auto-fix:
4706
+ ` + colorIssues.map((i) => ` L${i.line}: ${i.message}`).join("\n")
4707
+ );
4708
+ }
4658
4709
  await writeFile(fullPath, fixedCode);
4659
4710
  printSharedComponentReport({
4660
4711
  id: resolved.id,
@@ -4664,7 +4715,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4664
4715
  postFixes: fixes
4665
4716
  });
4666
4717
  try {
4667
- await writeCursorRules(projectRoot);
4718
+ await writeAllHarnessFiles(projectRoot);
4668
4719
  } catch {
4669
4720
  }
4670
4721
  return {
@@ -4731,7 +4782,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4731
4782
  fixes.forEach((f) => console.log(chalk8.dim(` ${f}`)));
4732
4783
  }
4733
4784
  await writeFile(pageFilePath, fixedCode);
4734
- const manifest = await loadManifest5(projectRoot);
4785
+ const manifest = await loadManifest4(projectRoot);
4735
4786
  const usedIn = manifest.shared.find((e) => e.id === resolved.id)?.usedIn ?? [];
4736
4787
  const filePathRel = routeToRelPath(route, readPlan || isAuthRoute(route));
4737
4788
  if (!usedIn.includes(filePathRel)) {
@@ -4746,7 +4797,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4746
4797
  postFixes: fixes
4747
4798
  });
4748
4799
  try {
4749
- await writeCursorRules(projectRoot);
4800
+ await writeAllHarnessFiles(projectRoot);
4750
4801
  } catch {
4751
4802
  }
4752
4803
  return {
@@ -4833,7 +4884,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4833
4884
  await writeFile(fullPath, fixedCode);
4834
4885
  usedInFiles.push(relPath);
4835
4886
  }
4836
- const manifest = await loadManifest5(projectRoot);
4887
+ const manifest = await loadManifest4(projectRoot);
4837
4888
  const nextManifest = updateUsedIn(manifest, created.id, usedInFiles);
4838
4889
  await saveManifest2(projectRoot, nextManifest);
4839
4890
  printPromoteAndLinkReport({
@@ -4843,7 +4894,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
4843
4894
  usedInFiles
4844
4895
  });
4845
4896
  try {
4846
- await writeCursorRules(projectRoot);
4897
+ await writeAllHarnessFiles(projectRoot);
4847
4898
  } catch {
4848
4899
  }
4849
4900
  return {
@@ -5089,7 +5140,7 @@ Keep all existing functionality intact.`,
5089
5140
  cm.updateConfig(cfg);
5090
5141
  pm.updateConfig(cfg);
5091
5142
  }
5092
- const manifestForAudit = await loadManifest5(projectRoot);
5143
+ const manifestForAudit = await loadManifest4(projectRoot);
5093
5144
  const planForAudit = loadPlan(projectRoot);
5094
5145
  await warnInlineDuplicates(
5095
5146
  projectRoot,
@@ -5320,7 +5371,7 @@ ${pagesCtx}`
5320
5371
  cm.updateConfig(cfg);
5321
5372
  pm.updateConfig(cfg);
5322
5373
  }
5323
- const manifestForAudit = await loadManifest5(projectRoot);
5374
+ const manifestForAudit = await loadManifest4(projectRoot);
5324
5375
  const planForAudit2 = loadPlan(projectRoot);
5325
5376
  await warnInlineDuplicates(
5326
5377
  projectRoot,
@@ -5419,7 +5470,7 @@ Rules:
5419
5470
  fixes.forEach((f) => console.log(chalk8.dim(` ${f}`)));
5420
5471
  }
5421
5472
  const relFilePath = routeToRelPath(route, isAuth);
5422
- const manifest = await loadManifest5(projectRoot);
5473
+ const manifest = await loadManifest4(projectRoot);
5423
5474
  printPostGenerationReport({
5424
5475
  action: "updated",
5425
5476
  pageTitle: pageDef.name || pageDef.id || "Page",
@@ -5563,8 +5614,8 @@ function hasNavChanged(before, after) {
5563
5614
  // src/commands/chat/interactive.ts
5564
5615
  import chalk9 from "chalk";
5565
5616
  import { resolve as resolve4 } from "path";
5566
- import { existsSync as existsSync8, readFileSync as readFileSync5, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5 } from "fs";
5567
- import { DesignSystemManager as DesignSystemManager4, ComponentManager as ComponentManager3, loadManifest as loadManifest6 } from "@getcoherent/core";
5617
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5 } from "fs";
5618
+ import { DesignSystemManager as DesignSystemManager3, ComponentManager as ComponentManager3, loadManifest as loadManifest5 } from "@getcoherent/core";
5568
5619
  var DEBUG3 = process.env.COHERENT_DEBUG === "1";
5569
5620
  async function interactiveChat(options, chatCommandFn) {
5570
5621
  const { createInterface } = await import("readline");
@@ -5573,7 +5624,7 @@ async function interactiveChat(options, chatCommandFn) {
5573
5624
  const projectRoot = project.root;
5574
5625
  const configPath = project.configPath;
5575
5626
  const config2 = await loadConfig(configPath);
5576
- const dsm = new DesignSystemManager4(configPath);
5627
+ const dsm = new DesignSystemManager3(configPath);
5577
5628
  await dsm.load();
5578
5629
  const cm = new ComponentManager3(config2);
5579
5630
  const validProviders = ["claude", "openai", "auto"];
@@ -5588,7 +5639,7 @@ async function interactiveChat(options, chatCommandFn) {
5588
5639
  let history = [];
5589
5640
  try {
5590
5641
  mkdirSync5(historyDir, { recursive: true });
5591
- if (existsSync8(historyFile)) {
5642
+ if (existsSync7(historyFile)) {
5592
5643
  history = readFileSync5(historyFile, "utf-8").split("\n").filter(Boolean).slice(-200);
5593
5644
  }
5594
5645
  } catch (e) {
@@ -5634,7 +5685,7 @@ async function interactiveChat(options, chatCommandFn) {
5634
5685
  return;
5635
5686
  }
5636
5687
  if (lower === "components" || lower === "list components" || lower.includes("what components")) {
5637
- const manifest = await loadManifest6(projectRoot);
5688
+ const manifest = await loadManifest5(projectRoot);
5638
5689
  if (manifest.shared.length === 0) {
5639
5690
  console.log(chalk9.gray("\n No shared components yet.\n"));
5640
5691
  } else {
@@ -5676,7 +5727,7 @@ async function interactiveChat(options, chatCommandFn) {
5676
5727
  }
5677
5728
  if (lower === "status") {
5678
5729
  const currentConfig = dsm.getConfig();
5679
- const manifest = await loadManifest6(projectRoot);
5730
+ const manifest = await loadManifest5(projectRoot);
5680
5731
  console.log(chalk9.bold(`
5681
5732
  ${currentConfig.name || "Coherent Project"}`));
5682
5733
  console.log(
@@ -5768,7 +5819,7 @@ async function chatCommand(message, options) {
5768
5819
  const projectRoot = project.root;
5769
5820
  const configPath = project.configPath;
5770
5821
  const migrationGuard = join6(projectRoot, ".coherent", "migration-in-progress");
5771
- if (existsSync9(migrationGuard)) {
5822
+ if (existsSync8(migrationGuard)) {
5772
5823
  spinner.fail("Migration in progress");
5773
5824
  console.error(chalk10.red("\n\u274C A migration is in progress. Run `coherent migrate --rollback` to undo first."));
5774
5825
  bail("Migration in progress");
@@ -5807,7 +5858,7 @@ async function chatCommand(message, options) {
5807
5858
  spinner.text = "Loading design system configuration...";
5808
5859
  }
5809
5860
  const storedHashes = await loadHashes(projectRoot);
5810
- const dsm = new DesignSystemManager5(configPath);
5861
+ const dsm = new DesignSystemManager4(configPath);
5811
5862
  await dsm.load();
5812
5863
  const cm = new ComponentManager4(config2);
5813
5864
  const pm = new PageManager2(config2, cm);
@@ -5818,7 +5869,7 @@ async function chatCommand(message, options) {
5818
5869
  spinner.start(`Creating shared component: ${componentName}...`);
5819
5870
  const { createAIProvider: createAIProvider2 } = await import("./ai-provider-CGSIYFZT.js");
5820
5871
  const { generateSharedComponent: generateSharedComponent6 } = await import("@getcoherent/core");
5821
- const { autoFixCode: autoFixCode2 } = await import("./quality-validator-2KIT6QKA.js");
5872
+ const { autoFixCode: autoFixCode2 } = await import("./quality-validator-IM6YFKLI.js");
5822
5873
  const { extractPropsInterface, extractDependencies } = await import("./component-extractor-VYJLT5NR.js");
5823
5874
  const aiProvider = await createAIProvider2(provider ?? "auto");
5824
5875
  const prompt = `Generate a React component called "${componentName}". Description: ${message}.
@@ -5857,7 +5908,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
5857
5908
  async (p) => JSON.stringify(await aiProvider.generateJSON("You are a component classifier.", p))
5858
5909
  );
5859
5910
  if (classifications.length > 0) {
5860
- let manifest2 = await loadManifest7(projectRoot);
5911
+ let manifest2 = await loadManifest6(projectRoot);
5861
5912
  manifest2 = updateEntry(manifest2, genResult.id, {
5862
5913
  type: classifications[0].type,
5863
5914
  description: classifications[0].description || message
@@ -5923,10 +5974,10 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
5923
5974
  }
5924
5975
  }
5925
5976
  spinner.start("Parsing your request...");
5926
- let manifest = await loadManifest7(project.root);
5977
+ let manifest = await loadManifest6(project.root);
5927
5978
  const validShared = manifest.shared.filter((s) => {
5928
5979
  const fp = resolve5(project.root, s.file);
5929
- return existsSync9(fp);
5980
+ return existsSync8(fp);
5930
5981
  });
5931
5982
  if (validShared.length !== manifest.shared.length) {
5932
5983
  const cleaned = manifest.shared.length - validShared.length;
@@ -5995,7 +6046,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
5995
6046
  } else {
5996
6047
  let reusePlanDirective;
5997
6048
  try {
5998
- const singlePageManifest = await loadManifest7(projectRoot);
6049
+ const singlePageManifest = await loadManifest6(projectRoot);
5999
6050
  if (singlePageManifest.shared.length > 0) {
6000
6051
  const reusePlan = buildReusePlan({
6001
6052
  pageName: "page",
@@ -6147,7 +6198,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6147
6198
  for (const entry of manifest.shared) {
6148
6199
  try {
6149
6200
  const sharedPath = resolve5(projectRoot, entry.file);
6150
- if (existsSync9(sharedPath)) {
6201
+ if (existsSync8(sharedPath)) {
6151
6202
  const sharedCode = readFileSync6(sharedPath, "utf-8");
6152
6203
  const sharedImports = sharedCode.matchAll(/@\/components\/ui\/([a-z0-9-]+)/g);
6153
6204
  for (const m of sharedImports) {
@@ -6169,7 +6220,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6169
6220
  for (const componentId of allNeededComponentIds) {
6170
6221
  const isRegistered = !!cm.read(componentId);
6171
6222
  const filePath = join6(projectRoot, "components", "ui", `${componentId}.tsx`);
6172
- const fileExists = existsSync9(filePath);
6223
+ const fileExists = existsSync8(filePath);
6173
6224
  if (DEBUG4) console.log(chalk10.gray(` Checking ${componentId}: registered=${isRegistered} file=${fileExists}`));
6174
6225
  if (!isRegistered || !fileExists) {
6175
6226
  missingComponents.push(componentId);
@@ -6287,8 +6338,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6287
6338
  }
6288
6339
  try {
6289
6340
  const { validateReuse } = await import("./reuse-validator-XR2ZEYC4.js");
6290
- const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-HGNEY3W3.js");
6291
- const manifest2 = await loadManifest7(projectRoot);
6341
+ const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFZDW2XW.js");
6342
+ const manifest2 = await loadManifest6(projectRoot);
6292
6343
  const reuseplan = projectRoot ? loadPlan(projectRoot) : null;
6293
6344
  if (manifest2.shared.length > 0) {
6294
6345
  for (const request of normalizedRequests) {
@@ -6318,7 +6369,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6318
6369
  const route = page.route || `/${page.id || "page"}`;
6319
6370
  const pageFilePath = routeToFsPath(projectRoot, route, false);
6320
6371
  let pageCode = "";
6321
- if (existsSync9(pageFilePath)) {
6372
+ if (existsSync8(pageFilePath)) {
6322
6373
  try {
6323
6374
  pageCode = readFileSync6(pageFilePath, "utf-8");
6324
6375
  } catch {
@@ -6340,8 +6391,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6340
6391
  }
6341
6392
  const missingRoutes = [...allLinkedRoutes].filter((route) => {
6342
6393
  if (expandedExisting.has(route)) return false;
6343
- if (existsSync9(routeToFsPath(projectRoot, route, false))) return false;
6344
- if (existsSync9(routeToFsPath(projectRoot, route, true))) return false;
6394
+ if (existsSync8(routeToFsPath(projectRoot, route, false))) return false;
6395
+ if (existsSync8(routeToFsPath(projectRoot, route, true))) return false;
6345
6396
  return true;
6346
6397
  });
6347
6398
  const SCAFFOLD_AI_LIMIT = 10;
@@ -6406,7 +6457,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6406
6457
  const filePath = routeToFsPath(projectRoot, linkedRoute, isAuth);
6407
6458
  if (isAuth) await ensureAuthRouteGroup(projectRoot);
6408
6459
  const dir = resolve5(filePath, "..");
6409
- if (!existsSync9(dir)) {
6460
+ if (!existsSync8(dir)) {
6410
6461
  mkdirSync6(dir, { recursive: true });
6411
6462
  }
6412
6463
  const placeholderCode = `export default function ${pageName.replace(/\s/g, "")}Page() {
@@ -6523,13 +6574,13 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6523
6574
  const sharedDir = resolve5(projectRoot, "components", "shared");
6524
6575
  const layoutFile = resolve5(projectRoot, "app", "layout.tsx");
6525
6576
  const filesToHash = [layoutFile];
6526
- if (existsSync9(sharedDir)) {
6577
+ if (existsSync8(sharedDir)) {
6527
6578
  for (const f of readdirSync3(sharedDir)) {
6528
6579
  if (f.endsWith(".tsx")) filesToHash.push(resolve5(sharedDir, f));
6529
6580
  }
6530
6581
  }
6531
6582
  for (const filePath of filesToHash) {
6532
- if (existsSync9(filePath)) {
6583
+ if (existsSync8(filePath)) {
6533
6584
  const rel = relative2(projectRoot, filePath);
6534
6585
  updatedHashes[rel] = await computeFileHash(filePath);
6535
6586
  }
@@ -6540,11 +6591,11 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6540
6591
  }
6541
6592
  try {
6542
6593
  const { extractPropsInterface, extractDependencies, extractUsageExample } = await import("./component-extractor-VYJLT5NR.js");
6543
- let currentManifest = await loadManifest7(projectRoot);
6594
+ let currentManifest = await loadManifest6(projectRoot);
6544
6595
  let manifestChanged = false;
6545
6596
  for (const entry of currentManifest.shared) {
6546
6597
  const fullPath = resolve5(projectRoot, entry.file);
6547
- if (!existsSync9(fullPath)) continue;
6598
+ if (!existsSync8(fullPath)) continue;
6548
6599
  const code = readFileSync6(fullPath, "utf-8");
6549
6600
  const props = extractPropsInterface(code);
6550
6601
  const deps = extractDependencies(code);
@@ -6559,7 +6610,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6559
6610
  const pageFiles = Array.from(allModified).filter((f) => f.startsWith("app/") && f.endsWith("page.tsx"));
6560
6611
  for (const pageFile of pageFiles) {
6561
6612
  const fullPath = resolve5(projectRoot, pageFile);
6562
- if (!existsSync9(fullPath)) continue;
6613
+ if (!existsSync8(fullPath)) continue;
6563
6614
  const pageCode = readFileSync6(fullPath, "utf-8");
6564
6615
  for (const entry of currentManifest.shared) {
6565
6616
  const isUsed = pageCode.includes(`from '@/components/shared/`) && (pageCode.includes(`{ ${entry.name} }`) || pageCode.includes(`{ ${entry.name},`));
@@ -6617,7 +6668,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
6617
6668
  ${uxRecommendations}
6618
6669
  `;
6619
6670
  try {
6620
- if (!existsSync9(recPath)) {
6671
+ if (!existsSync8(recPath)) {
6621
6672
  await writeFile(
6622
6673
  recPath,
6623
6674
  "# UX/UI Recommendations\n\nRecommendations are added here when you use `coherent chat` and the AI suggests improvements.\n"
@@ -6691,7 +6742,7 @@ ${uxRecommendations}
6691
6742
  import chalk11 from "chalk";
6692
6743
  import ora3 from "ora";
6693
6744
  import { spawn } from "child_process";
6694
- import { existsSync as existsSync12, rmSync as rmSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync8, readdirSync as readdirSync5 } from "fs";
6745
+ import { existsSync as existsSync11, rmSync as rmSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync8, readdirSync as readdirSync5 } from "fs";
6695
6746
  import { resolve as resolve6, join as join9 } from "path";
6696
6747
  import { readdir } from "fs/promises";
6697
6748
 
@@ -6744,15 +6795,15 @@ function validateV4GlobalsCss(css) {
6744
6795
  }
6745
6796
 
6746
6797
  // src/commands/preview.ts
6747
- import { DesignSystemManager as DesignSystemManager6, ComponentGenerator as ComponentGenerator2 } from "@getcoherent/core";
6798
+ import { DesignSystemManager as DesignSystemManager5, ComponentGenerator as ComponentGenerator2 } from "@getcoherent/core";
6748
6799
 
6749
6800
  // src/utils/file-watcher.ts
6750
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync11 } from "fs";
6801
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "fs";
6751
6802
  import { relative as relative4, join as join8 } from "path";
6752
- import { loadManifest as loadManifest8, saveManifest as saveManifest4 } from "@getcoherent/core";
6803
+ import { loadManifest as loadManifest7, saveManifest as saveManifest4 } from "@getcoherent/core";
6753
6804
 
6754
6805
  // src/utils/component-integrity.ts
6755
- import { existsSync as existsSync10, readFileSync as readFileSync7, readdirSync as readdirSync4 } from "fs";
6806
+ import { existsSync as existsSync9, readFileSync as readFileSync7, readdirSync as readdirSync4 } from "fs";
6756
6807
  import { join as join7, relative as relative3 } from "path";
6757
6808
  function extractExportedComponentNames(code) {
6758
6809
  const names = [];
@@ -6786,7 +6837,7 @@ function arraysEqual(a, b) {
6786
6837
  function findPagesImporting(projectRoot, componentName, componentFile) {
6787
6838
  const results = [];
6788
6839
  const appDir = join7(projectRoot, "app");
6789
- if (!existsSync10(appDir)) return results;
6840
+ if (!existsSync9(appDir)) return results;
6790
6841
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
6791
6842
  const componentImportPath = componentFile.replace(/\.tsx$/, "").replace(/\.jsx$/, "");
6792
6843
  for (const absPath of pageFiles) {
@@ -6807,7 +6858,7 @@ function findPagesImporting(projectRoot, componentName, componentFile) {
6807
6858
  function isUsedInLayout(projectRoot, componentName) {
6808
6859
  const appDir = join7(projectRoot, "app");
6809
6860
  const layoutPaths = [join7(appDir, "layout.tsx")];
6810
- if (existsSync10(appDir)) {
6861
+ if (existsSync9(appDir)) {
6811
6862
  try {
6812
6863
  for (const entry of readdirSync4(appDir, { withFileTypes: true })) {
6813
6864
  if (entry.isDirectory() && entry.name.startsWith("(") && entry.name.endsWith(")")) {
@@ -6831,7 +6882,7 @@ function isUsedInLayout(projectRoot, componentName) {
6831
6882
  function findUnregisteredComponents(projectRoot, manifest) {
6832
6883
  const results = [];
6833
6884
  const componentsDir = join7(projectRoot, "components");
6834
- if (!existsSync10(componentsDir)) return results;
6885
+ if (!existsSync9(componentsDir)) return results;
6835
6886
  const registeredFiles = new Set(manifest.shared.map((s) => s.file));
6836
6887
  const registeredNames = new Set(manifest.shared.map((s) => s.name));
6837
6888
  const files = collectFiles(
@@ -6859,7 +6910,7 @@ function findUnregisteredComponents(projectRoot, manifest) {
6859
6910
  function findInlineDuplicates(projectRoot, manifest) {
6860
6911
  const results = [];
6861
6912
  const appDir = join7(projectRoot, "app");
6862
- if (!existsSync10(appDir)) return results;
6913
+ if (!existsSync9(appDir)) return results;
6863
6914
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
6864
6915
  for (const absPath of pageFiles) {
6865
6916
  if (absPath.includes("design-system")) continue;
@@ -6889,7 +6940,7 @@ function findInlineDuplicates(projectRoot, manifest) {
6889
6940
  }
6890
6941
  function findComponentFileByExportName(projectRoot, componentName) {
6891
6942
  const componentsDir = join7(projectRoot, "components");
6892
- if (!existsSync10(componentsDir)) return null;
6943
+ if (!existsSync9(componentsDir)) return null;
6893
6944
  const files = collectFiles(
6894
6945
  componentsDir,
6895
6946
  (name) => (name.endsWith(".tsx") || name.endsWith(".jsx")) && !name.startsWith("."),
@@ -6911,7 +6962,7 @@ function removeOrphanedEntries(projectRoot, manifest) {
6911
6962
  const removed = [];
6912
6963
  const valid = manifest.shared.filter((entry) => {
6913
6964
  const filePath = join7(projectRoot, entry.file);
6914
- if (existsSync10(filePath)) return true;
6965
+ if (existsSync9(filePath)) return true;
6915
6966
  removed.push({ id: entry.id, name: entry.name });
6916
6967
  return false;
6917
6968
  });
@@ -6930,7 +6981,7 @@ function reconcileComponents(projectRoot, manifest) {
6930
6981
  const m = { ...manifest, shared: [...manifest.shared], nextId: manifest.nextId };
6931
6982
  m.shared = m.shared.filter((entry) => {
6932
6983
  const filePath = join7(projectRoot, entry.file);
6933
- if (!existsSync10(filePath)) {
6984
+ if (!existsSync9(filePath)) {
6934
6985
  const newPath = findComponentFileByExportName(projectRoot, entry.name);
6935
6986
  if (newPath) {
6936
6987
  result.updated.push({ id: entry.id, field: "file", from: entry.file, to: newPath });
@@ -7066,7 +7117,7 @@ function findInlineDuplicatesOfShared(content, manifest) {
7066
7117
  function getWatcherConfig(projectRoot) {
7067
7118
  try {
7068
7119
  const pkgPath = join8(projectRoot, "package.json");
7069
- if (!existsSync11(pkgPath)) return defaultWatcherConfig();
7120
+ if (!existsSync10(pkgPath)) return defaultWatcherConfig();
7070
7121
  const pkg = JSON.parse(readFileSync8(pkgPath, "utf-8"));
7071
7122
  const c = pkg?.coherent?.watcher ?? {};
7072
7123
  return {
@@ -7125,7 +7176,7 @@ async function handleFileChange(projectRoot, filePath) {
7125
7176
  if (config2.warnSharedReuse) {
7126
7177
  let manifest;
7127
7178
  try {
7128
- manifest = await loadManifest8(projectRoot);
7179
+ manifest = await loadManifest7(projectRoot);
7129
7180
  } catch {
7130
7181
  manifest = { shared: [], nextId: 1 };
7131
7182
  }
@@ -7144,7 +7195,7 @@ async function handleFileDelete(projectRoot, filePath) {
7144
7195
  if (!relativePath.startsWith("components/") || relativePath.startsWith("components/ui/")) return;
7145
7196
  try {
7146
7197
  const chalk30 = (await import("chalk")).default;
7147
- const manifest = await loadManifest8(projectRoot);
7198
+ const manifest = await loadManifest7(projectRoot);
7148
7199
  const orphaned = manifest.shared.find((s) => s.file === relativePath);
7149
7200
  if (orphaned) {
7150
7201
  const cleaned = {
@@ -7154,7 +7205,7 @@ async function handleFileDelete(projectRoot, filePath) {
7154
7205
  await saveManifest4(projectRoot, cleaned);
7155
7206
  console.log(chalk30.cyan(`
7156
7207
  \u{1F5D1} Auto-removed ${orphaned.id} (${orphaned.name}) \u2014 file deleted`));
7157
- await writeCursorRules(projectRoot);
7208
+ await writeAllHarnessFiles(projectRoot);
7158
7209
  }
7159
7210
  } catch {
7160
7211
  }
@@ -7165,7 +7216,7 @@ async function detectNewComponent(projectRoot, filePath) {
7165
7216
  if (!relativePath.endsWith(".tsx") && !relativePath.endsWith(".jsx")) return;
7166
7217
  try {
7167
7218
  const chalk30 = (await import("chalk")).default;
7168
- const manifest = await loadManifest8(projectRoot);
7219
+ const manifest = await loadManifest7(projectRoot);
7169
7220
  const alreadyRegistered = manifest.shared.some((s) => s.file === relativePath);
7170
7221
  if (alreadyRegistered) return;
7171
7222
  const code = readFileSync8(filePath, "utf-8");
@@ -7183,7 +7234,7 @@ async function detectNewComponent(projectRoot, filePath) {
7183
7234
  }
7184
7235
  async function handleManifestChange(projectRoot) {
7185
7236
  try {
7186
- await writeCursorRules(projectRoot);
7237
+ await writeAllHarnessFiles(projectRoot);
7187
7238
  } catch {
7188
7239
  }
7189
7240
  }
@@ -7208,7 +7259,7 @@ function startFileWatcher(projectRoot) {
7208
7259
  watcher.on("unlink", (fp) => handleFileDelete(projectRoot, fp));
7209
7260
  });
7210
7261
  const manifestPath = join8(projectRoot, "coherent.components.json");
7211
- if (existsSync11(manifestPath)) {
7262
+ if (existsSync10(manifestPath)) {
7212
7263
  import("chokidar").then((chokidar) => {
7213
7264
  manifestWatcher = chokidar.default.watch(manifestPath, { ignoreInitial: true });
7214
7265
  manifestWatcher.on("change", () => handleManifestChange(projectRoot));
@@ -7222,7 +7273,7 @@ function startFileWatcher(projectRoot) {
7222
7273
 
7223
7274
  // src/commands/preview.ts
7224
7275
  function getPackageManager(projectRoot) {
7225
- const hasPnpm = existsSync12(resolve6(projectRoot, "pnpm-lock.yaml"));
7276
+ const hasPnpm = existsSync11(resolve6(projectRoot, "pnpm-lock.yaml"));
7226
7277
  return hasPnpm ? "pnpm" : "npm";
7227
7278
  }
7228
7279
  function runInstall(projectRoot) {
@@ -7246,21 +7297,21 @@ function runInstall(projectRoot) {
7246
7297
  function checkProjectInitialized(projectRoot) {
7247
7298
  const configPath = resolve6(projectRoot, "design-system.config.ts");
7248
7299
  const packageJsonPath = resolve6(projectRoot, "package.json");
7249
- if (!existsSync12(configPath)) {
7300
+ if (!existsSync11(configPath)) {
7250
7301
  return false;
7251
7302
  }
7252
- if (!existsSync12(packageJsonPath)) {
7303
+ if (!existsSync11(packageJsonPath)) {
7253
7304
  return false;
7254
7305
  }
7255
7306
  return true;
7256
7307
  }
7257
7308
  function checkDependenciesInstalled(projectRoot) {
7258
7309
  const nodeModulesPath = resolve6(projectRoot, "node_modules");
7259
- return existsSync12(nodeModulesPath);
7310
+ return existsSync11(nodeModulesPath);
7260
7311
  }
7261
7312
  function clearStaleCache(projectRoot) {
7262
7313
  const nextDir = join9(projectRoot, ".next");
7263
- if (existsSync12(nextDir)) {
7314
+ if (existsSync11(nextDir)) {
7264
7315
  rmSync3(nextDir, { recursive: true, force: true });
7265
7316
  console.log(chalk11.dim(" \u2714 Cleared stale build cache"));
7266
7317
  }
@@ -7276,7 +7327,7 @@ async function preflightDependencyCheck(projectRoot) {
7276
7327
  }
7277
7328
  async function listPageFiles(appDir) {
7278
7329
  const out = [];
7279
- if (!existsSync12(appDir)) return out;
7330
+ if (!existsSync11(appDir)) return out;
7280
7331
  async function walk(dir) {
7281
7332
  const entries = await readdir(dir, { withFileTypes: true });
7282
7333
  for (const e of entries) {
@@ -7303,10 +7354,10 @@ async function validateSyntax(projectRoot) {
7303
7354
  async function fixMissingComponentExports(projectRoot) {
7304
7355
  const appDir = join9(projectRoot, "app");
7305
7356
  const uiDir = join9(projectRoot, "components", "ui");
7306
- if (!existsSync12(appDir) || !existsSync12(uiDir)) return;
7357
+ if (!existsSync11(appDir) || !existsSync11(uiDir)) return;
7307
7358
  const pages = await listPageFiles(appDir);
7308
7359
  const sharedDir = join9(projectRoot, "components", "shared");
7309
- if (existsSync12(sharedDir)) {
7360
+ if (existsSync11(sharedDir)) {
7310
7361
  const sharedFiles = readdirSync5(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => join9(sharedDir, f));
7311
7362
  pages.push(...sharedFiles);
7312
7363
  }
@@ -7325,7 +7376,7 @@ async function fixMissingComponentExports(projectRoot) {
7325
7376
  const configPath = join9(projectRoot, "design-system.config.ts");
7326
7377
  let config2 = null;
7327
7378
  try {
7328
- const mgr = new DesignSystemManager6(configPath);
7379
+ const mgr = new DesignSystemManager5(configPath);
7329
7380
  config2 = mgr.getConfig();
7330
7381
  } catch {
7331
7382
  }
@@ -7333,7 +7384,7 @@ async function fixMissingComponentExports(projectRoot) {
7333
7384
  const provider = getComponentProvider();
7334
7385
  for (const [componentId, needed] of neededExports) {
7335
7386
  const componentFile = join9(uiDir, `${componentId}.tsx`);
7336
- if (!existsSync12(componentFile)) {
7387
+ if (!existsSync11(componentFile)) {
7337
7388
  if (provider.has(componentId)) {
7338
7389
  try {
7339
7390
  const result = await provider.installComponent(componentId, projectRoot);
@@ -7402,7 +7453,7 @@ async function fixMissingComponentExports(projectRoot) {
7402
7453
  }
7403
7454
  for (const [componentId, needed] of neededSharedExports) {
7404
7455
  const componentFile = join9(sharedDir, `${componentId}.tsx`);
7405
- if (!existsSync12(componentFile)) continue;
7456
+ if (!existsSync11(componentFile)) continue;
7406
7457
  let content = readFileSync9(componentFile, "utf-8");
7407
7458
  const exportRe = /export\s+(?:const|function|class)\s+(\w+)|export\s*\{([^}]+)\}/g;
7408
7459
  const existingExports = /* @__PURE__ */ new Set();
@@ -7426,9 +7477,9 @@ async function fixMissingComponentExports(projectRoot) {
7426
7477
  }
7427
7478
  async function backfillPageAnalysis(projectRoot) {
7428
7479
  const configPath = join9(projectRoot, "design-system.config.ts");
7429
- if (!existsSync12(configPath)) return;
7480
+ if (!existsSync11(configPath)) return;
7430
7481
  try {
7431
- const mgr = new DesignSystemManager6(configPath);
7482
+ const mgr = new DesignSystemManager5(configPath);
7432
7483
  const config2 = mgr.getConfig();
7433
7484
  let changed = false;
7434
7485
  for (const page of config2.pages) {
@@ -7443,7 +7494,7 @@ async function backfillPageAnalysis(projectRoot) {
7443
7494
  } else {
7444
7495
  filePath = join9(projectRoot, "app", route.slice(1), "page.tsx");
7445
7496
  }
7446
- if (!existsSync12(filePath)) continue;
7497
+ if (!existsSync11(filePath)) continue;
7447
7498
  const code = readFileSync9(filePath, "utf-8");
7448
7499
  if (code.length < 50) continue;
7449
7500
  page.pageAnalysis = analyzePageCode(code);
@@ -7595,11 +7646,11 @@ async function openBrowser(url) {
7595
7646
  }
7596
7647
  function startDevServer(projectRoot) {
7597
7648
  const packageJsonPath = resolve6(projectRoot, "package.json");
7598
- if (!existsSync12(packageJsonPath)) {
7649
+ if (!existsSync11(packageJsonPath)) {
7599
7650
  throw new Error('package.json not found. Run "coherent init" first.');
7600
7651
  }
7601
- const hasPnpm = existsSync12(resolve6(projectRoot, "pnpm-lock.yaml"));
7602
- const hasNpm = existsSync12(resolve6(projectRoot, "package-lock.json"));
7652
+ const hasPnpm = existsSync11(resolve6(projectRoot, "pnpm-lock.yaml"));
7653
+ const hasNpm = existsSync11(resolve6(projectRoot, "package-lock.json"));
7603
7654
  const command = hasPnpm ? "pnpm" : hasNpm ? "npm" : "npx";
7604
7655
  const args = hasPnpm ? ["dev", "--turbo"] : hasNpm ? ["run", "dev", "--", "--turbo"] : ["next", "dev", "--turbo"];
7605
7656
  const child = spawn(command, args, {
@@ -7646,7 +7697,7 @@ async function previewCommand() {
7646
7697
  if (needsGlobalsFix(projectRoot)) {
7647
7698
  spinner.text = "Fixing globals.css...";
7648
7699
  try {
7649
- const dsm = new DesignSystemManager6(resolve6(projectRoot, "design-system.config.ts"));
7700
+ const dsm = new DesignSystemManager5(resolve6(projectRoot, "design-system.config.ts"));
7650
7701
  await dsm.load();
7651
7702
  const config2 = dsm.getConfig();
7652
7703
  fixGlobalsCss(projectRoot, config2);
@@ -7657,7 +7708,7 @@ async function previewCommand() {
7657
7708
  }
7658
7709
  if (isTailwindV4(projectRoot)) {
7659
7710
  const globalsPath = resolve6(projectRoot, "app", "globals.css");
7660
- if (existsSync12(globalsPath)) {
7711
+ if (existsSync11(globalsPath)) {
7661
7712
  const globalsContent = readFileSync9(globalsPath, "utf-8");
7662
7713
  const cssIssues = validateV4GlobalsCss(globalsContent);
7663
7714
  if (cssIssues.length > 0) {
@@ -7699,7 +7750,7 @@ async function previewCommand() {
7699
7750
  import chalk12 from "chalk";
7700
7751
  import ora4 from "ora";
7701
7752
  import { spawn as spawn2 } from "child_process";
7702
- import { existsSync as existsSync13, rmSync as rmSync4, readdirSync as readdirSync6 } from "fs";
7753
+ import { existsSync as existsSync12, rmSync as rmSync4, readdirSync as readdirSync6 } from "fs";
7703
7754
  import { resolve as resolve7, join as join10, dirname as dirname4 } from "path";
7704
7755
  import { readdir as readdir2, readFile as readFile3, writeFile as writeFile3, mkdir as mkdir2, copyFile } from "fs/promises";
7705
7756
  var COPY_EXCLUDE = /* @__PURE__ */ new Set([
@@ -7710,6 +7761,7 @@ var COPY_EXCLUDE = /* @__PURE__ */ new Set([
7710
7761
  ".tmp-e2e",
7711
7762
  ".cursorrules",
7712
7763
  "CLAUDE.md",
7764
+ "AGENTS.md",
7713
7765
  ".claude",
7714
7766
  ".coherent",
7715
7767
  "design-system.config.ts",
@@ -7734,17 +7786,17 @@ async function copyDir(src, dest) {
7734
7786
  }
7735
7787
  }
7736
7788
  function checkProjectInitialized2(projectRoot) {
7737
- return existsSync13(resolve7(projectRoot, "design-system.config.ts")) && existsSync13(resolve7(projectRoot, "package.json"));
7789
+ return existsSync12(resolve7(projectRoot, "design-system.config.ts")) && existsSync12(resolve7(projectRoot, "package.json"));
7738
7790
  }
7739
7791
  function getPackageManager2(projectRoot) {
7740
- if (existsSync13(resolve7(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
7741
- if (existsSync13(resolve7(projectRoot, "package-lock.json"))) return "npm";
7792
+ if (existsSync12(resolve7(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
7793
+ if (existsSync12(resolve7(projectRoot, "package-lock.json"))) return "npm";
7742
7794
  return "npx";
7743
7795
  }
7744
7796
  async function patchNextConfigForExport(outRoot) {
7745
7797
  for (const name of ["next.config.ts", "next.config.mjs", "next.config.js"]) {
7746
7798
  const p = join10(outRoot, name);
7747
- if (!existsSync13(p)) continue;
7799
+ if (!existsSync12(p)) continue;
7748
7800
  let content = await readFile3(p, "utf-8");
7749
7801
  if (content.includes("ignoreDuringBuilds")) return;
7750
7802
  content = content.replace(
@@ -7786,7 +7838,7 @@ EXPOSE 3000
7786
7838
  `;
7787
7839
  async function ensureReadmeDeploySection(outRoot) {
7788
7840
  const readmePath = join10(outRoot, "README.md");
7789
- if (!existsSync13(readmePath)) return;
7841
+ if (!existsSync12(readmePath)) return;
7790
7842
  try {
7791
7843
  let content = await readFile3(readmePath, "utf-8");
7792
7844
  if (/##\s+Deploy\b/m.test(content)) return;
@@ -7811,14 +7863,14 @@ async function countPages(outRoot) {
7811
7863
  }
7812
7864
  }
7813
7865
  const appDir = join10(outRoot, "app");
7814
- if (existsSync13(appDir)) await walk(appDir);
7866
+ if (existsSync12(appDir)) await walk(appDir);
7815
7867
  return n;
7816
7868
  }
7817
7869
  function countComponents(outRoot) {
7818
7870
  let n = 0;
7819
7871
  for (const sub of ["ui", "shared"]) {
7820
7872
  const dir = join10(outRoot, "components", sub);
7821
- if (!existsSync13(dir)) continue;
7873
+ if (!existsSync12(dir)) continue;
7822
7874
  try {
7823
7875
  n += readdirSync6(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
7824
7876
  } catch {
@@ -7829,7 +7881,7 @@ function countComponents(outRoot) {
7829
7881
  var IMPORT_FROM_REGEX = /from\s+['"]([^'"]+)['"]/g;
7830
7882
  async function collectImportedPackages(dir, extensions) {
7831
7883
  const packages = /* @__PURE__ */ new Set();
7832
- if (!existsSync13(dir)) return packages;
7884
+ if (!existsSync12(dir)) return packages;
7833
7885
  async function walk(d) {
7834
7886
  const entries = await readdir2(d, { withFileTypes: true });
7835
7887
  for (const e of entries) {
@@ -7857,7 +7909,7 @@ async function collectImportedPackages(dir, extensions) {
7857
7909
  }
7858
7910
  async function findMissingDepsInExport(outRoot) {
7859
7911
  const pkgPath = join10(outRoot, "package.json");
7860
- if (!existsSync13(pkgPath)) return [];
7912
+ if (!existsSync12(pkgPath)) return [];
7861
7913
  let pkg;
7862
7914
  try {
7863
7915
  pkg = JSON.parse(await readFile3(pkgPath, "utf-8"));
@@ -7878,32 +7930,32 @@ async function stripCoherentArtifacts(outputDir) {
7878
7930
  const removed = [];
7879
7931
  for (const p of ["app/design-system", "app/api/design-system"]) {
7880
7932
  const full = join10(outputDir, p);
7881
- if (existsSync13(full)) {
7933
+ if (existsSync12(full)) {
7882
7934
  rmSync4(full, { recursive: true, force: true });
7883
7935
  removed.push(p);
7884
7936
  }
7885
7937
  }
7886
7938
  const appNavPath = join10(outputDir, "app", "AppNav.tsx");
7887
- if (existsSync13(appNavPath)) {
7939
+ if (existsSync12(appNavPath)) {
7888
7940
  rmSync4(appNavPath, { force: true });
7889
7941
  removed.push("app/AppNav.tsx");
7890
7942
  }
7891
7943
  const layoutPath = join10(outputDir, "app", "layout.tsx");
7892
- if (existsSync13(layoutPath)) {
7944
+ if (existsSync12(layoutPath)) {
7893
7945
  let layout = await readFile3(layoutPath, "utf-8");
7894
7946
  layout = layout.replace(/import\s*\{?\s*AppNav\s*\}?\s*from\s*['"][^'"]+['"]\s*\n?/g, "");
7895
7947
  layout = layout.replace(/\s*<AppNav\s*\/?\s*>\s*/g, "\n");
7896
7948
  await writeFile3(layoutPath, layout, "utf-8");
7897
7949
  }
7898
7950
  const sharedHeaderPath = join10(outputDir, "components", "shared", "header.tsx");
7899
- if (existsSync13(sharedHeaderPath)) {
7951
+ if (existsSync12(sharedHeaderPath)) {
7900
7952
  let header = await readFile3(sharedHeaderPath, "utf-8");
7901
7953
  header = header.replace(/<Link\s[^>]*href="\/design-system"[^>]*>[\s\S]*?<\/Link>/g, "");
7902
7954
  header = header.replace(/\n\s*<>\s*\n/, "\n");
7903
7955
  header = header.replace(/\n\s*<\/>\s*\n/, "\n");
7904
7956
  await writeFile3(sharedHeaderPath, header, "utf-8");
7905
7957
  }
7906
- if (existsSync13(layoutPath)) {
7958
+ if (existsSync12(layoutPath)) {
7907
7959
  let rootLayout = await readFile3(layoutPath, "utf-8");
7908
7960
  const before = rootLayout;
7909
7961
  rootLayout = rootLayout.replace(/<Link\s[^>]*href="\/design-system"[^>]*>[\s\S]*?<\/Link>/g, "");
@@ -7912,7 +7964,7 @@ async function stripCoherentArtifacts(outputDir) {
7912
7964
  }
7913
7965
  }
7914
7966
  const guardPath2 = join10(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
7915
- if (existsSync13(guardPath2)) {
7967
+ if (existsSync12(guardPath2)) {
7916
7968
  let guard = await readFile3(guardPath2, "utf-8");
7917
7969
  guard = guard.replace(/['"],?\s*'\/design-system['"],?\s*/g, "");
7918
7970
  const pathsMatch = guard.match(/HIDDEN_PATHS\s*=\s*\[([^\]]*)\]/);
@@ -7920,7 +7972,7 @@ async function stripCoherentArtifacts(outputDir) {
7920
7972
  if (remaining.length === 0) {
7921
7973
  rmSync4(guardPath2, { force: true });
7922
7974
  removed.push("app/ShowWhenNotAuthRoute.tsx");
7923
- if (existsSync13(layoutPath)) {
7975
+ if (existsSync12(layoutPath)) {
7924
7976
  let layout = await readFile3(layoutPath, "utf-8");
7925
7977
  layout = layout.replace(/import\s+\w+\s+from\s*['"]\.\/ShowWhenNotAuthRoute['"]\s*\n?/g, "");
7926
7978
  layout = layout.replace(/\s*<ShowWhenNotAuthRoute>\s*\n?/g, "\n");
@@ -7936,19 +7988,20 @@ async function stripCoherentArtifacts(outputDir) {
7936
7988
  "design-system.config.ts",
7937
7989
  ".cursorrules",
7938
7990
  "CLAUDE.md",
7991
+ "AGENTS.md",
7939
7992
  ".env",
7940
7993
  ".env.local",
7941
7994
  "recommendations.md"
7942
7995
  ]) {
7943
7996
  const full = join10(outputDir, name);
7944
- if (existsSync13(full)) {
7997
+ if (existsSync12(full)) {
7945
7998
  rmSync4(full, { force: true });
7946
7999
  removed.push(name);
7947
8000
  }
7948
8001
  }
7949
8002
  for (const dir of [".claude", ".coherent"]) {
7950
8003
  const full = join10(outputDir, dir);
7951
- if (existsSync13(full)) {
8004
+ if (existsSync12(full)) {
7952
8005
  rmSync4(full, { recursive: true, force: true });
7953
8006
  removed.push(dir + "/");
7954
8007
  }
@@ -7972,7 +8025,7 @@ async function exportCommand(options = {}) {
7972
8025
  process.exit(1);
7973
8026
  }
7974
8027
  spinner.text = "Copying project...";
7975
- if (existsSync13(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
8028
+ if (existsSync12(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
7976
8029
  await copyDir(projectRoot, outputDir);
7977
8030
  spinner.succeed("Project copied");
7978
8031
  if (!keepDs) {
@@ -8035,7 +8088,7 @@ async function exportCommand(options = {}) {
8035
8088
  // src/commands/status.ts
8036
8089
  import chalk13 from "chalk";
8037
8090
  import { basename as basename2 } from "path";
8038
- import { DesignSystemManager as DesignSystemManager7 } from "@getcoherent/core";
8091
+ import { DesignSystemManager as DesignSystemManager6 } from "@getcoherent/core";
8039
8092
  function countTokens(tokens) {
8040
8093
  let count = 0;
8041
8094
  function countObj(obj) {
@@ -8067,7 +8120,7 @@ async function statusCommand() {
8067
8120
  console.log(chalk13.gray("\u{1F4C4} Config: ") + chalk13.white(basename2(project.configPath)));
8068
8121
  console.log("");
8069
8122
  try {
8070
- const manager = new DesignSystemManager7(project.configPath);
8123
+ const manager = new DesignSystemManager6(project.configPath);
8071
8124
  await manager.load();
8072
8125
  const config2 = manager.getConfig();
8073
8126
  console.log(chalk13.cyan("\u{1F4CA} Statistics:\n"));
@@ -8110,7 +8163,7 @@ async function statusCommand() {
8110
8163
  // src/commands/regenerate-docs.ts
8111
8164
  import chalk14 from "chalk";
8112
8165
  import ora5 from "ora";
8113
- import { DesignSystemManager as DesignSystemManager8 } from "@getcoherent/core";
8166
+ import { DesignSystemManager as DesignSystemManager7 } from "@getcoherent/core";
8114
8167
  import { ProjectScaffolder as ProjectScaffolder2 } from "@getcoherent/core";
8115
8168
  async function regenerateDocsCommand() {
8116
8169
  try {
@@ -8123,7 +8176,7 @@ async function regenerateDocsCommand() {
8123
8176
  }
8124
8177
  const spinner = ora5("Regenerating documentation pages...").start();
8125
8178
  try {
8126
- const manager = new DesignSystemManager8(project.configPath);
8179
+ const manager = new DesignSystemManager7(project.configPath);
8127
8180
  await manager.load();
8128
8181
  const config2 = manager.getConfig();
8129
8182
  const scaffolder = new ProjectScaffolder2(config2, project.root);
@@ -8147,14 +8200,14 @@ async function regenerateDocsCommand() {
8147
8200
 
8148
8201
  // src/commands/fix.ts
8149
8202
  import chalk15 from "chalk";
8150
- import { readdirSync as readdirSync7, readFileSync as readFileSync10, existsSync as existsSync14, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
8203
+ import { readdirSync as readdirSync7, readFileSync as readFileSync10, existsSync as existsSync13, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
8151
8204
  import { resolve as resolve8, join as join11, relative as relative5, basename as basename3 } from "path";
8152
8205
  import {
8153
- DesignSystemManager as DesignSystemManager9,
8206
+ DesignSystemManager as DesignSystemManager8,
8154
8207
  ComponentManager as ComponentManager5,
8155
8208
  PageManager as PageManager3,
8156
8209
  ComponentGenerator as ComponentGenerator3,
8157
- loadManifest as loadManifest9,
8210
+ loadManifest as loadManifest8,
8158
8211
  saveManifest as saveManifest5
8159
8212
  } from "@getcoherent/core";
8160
8213
  function extractComponentIdsFromCode2(code) {
@@ -8206,7 +8259,7 @@ async function fixCommand(opts = {}) {
8206
8259
  }
8207
8260
  if (!skipCache) {
8208
8261
  const nextDir = join11(projectRoot, ".next");
8209
- if (existsSync14(nextDir)) {
8262
+ if (existsSync13(nextDir)) {
8210
8263
  if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
8211
8264
  fixes.push("Cleared build cache");
8212
8265
  console.log(chalk15.green(" \u2714 Cleared build cache"));
@@ -8240,7 +8293,7 @@ async function fixCommand(opts = {}) {
8240
8293
  let cm = null;
8241
8294
  let pm = null;
8242
8295
  if (allComponentIds.size > 0) {
8243
- dsm = new DesignSystemManager9(project.configPath);
8296
+ dsm = new DesignSystemManager8(project.configPath);
8244
8297
  await dsm.load();
8245
8298
  const config2 = dsm.getConfig();
8246
8299
  cm = new ComponentManager5(config2);
@@ -8253,7 +8306,7 @@ async function fixCommand(opts = {}) {
8253
8306
  } else {
8254
8307
  const fileName = toKebabCase(id) + ".tsx";
8255
8308
  const filePath = resolve8(projectRoot, "components", "ui", fileName);
8256
- if (!existsSync14(filePath)) missingFiles.push(id);
8309
+ if (!existsSync13(filePath)) missingFiles.push(id);
8257
8310
  }
8258
8311
  }
8259
8312
  const provider = getComponentProvider();
@@ -8302,8 +8355,8 @@ async function fixCommand(opts = {}) {
8302
8355
  }
8303
8356
  }
8304
8357
  }
8305
- if (!dsm && existsSync14(project.configPath)) {
8306
- dsm = new DesignSystemManager9(project.configPath);
8358
+ if (!dsm && existsSync13(project.configPath)) {
8359
+ dsm = new DesignSystemManager8(project.configPath);
8307
8360
  await dsm.load();
8308
8361
  }
8309
8362
  if (dsm && dsm.getConfig().name === "My App") {
@@ -8311,7 +8364,7 @@ async function fixCommand(opts = {}) {
8311
8364
  let derivedName = null;
8312
8365
  try {
8313
8366
  const pkgPath = resolve8(projectRoot, "package.json");
8314
- if (existsSync14(pkgPath)) {
8367
+ if (existsSync13(pkgPath)) {
8315
8368
  const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
8316
8369
  if (typeof pkg.name === "string" && pkg.name) {
8317
8370
  derivedName = toTitleCase2(pkg.name);
@@ -8349,7 +8402,7 @@ async function fixCommand(opts = {}) {
8349
8402
  const configName = dsm.getConfig().name;
8350
8403
  if (configName && configName !== "My App") {
8351
8404
  const appLayoutPath = resolve8(projectRoot, "app", "(app)", "layout.tsx");
8352
- if (existsSync14(appLayoutPath)) {
8405
+ if (existsSync13(appLayoutPath)) {
8353
8406
  let appLayoutCode = readFileSync10(appLayoutPath, "utf-8");
8354
8407
  if (appLayoutCode.includes("My App")) {
8355
8408
  appLayoutCode = appLayoutCode.replace(/My App/g, configName);
@@ -8368,7 +8421,7 @@ async function fixCommand(opts = {}) {
8368
8421
  }
8369
8422
  }
8370
8423
  const sharedDir = resolve8(projectRoot, "components", "shared");
8371
- if (existsSync14(sharedDir)) {
8424
+ if (existsSync13(sharedDir)) {
8372
8425
  try {
8373
8426
  for (const f of readdirSync7(sharedDir).filter((n) => n.endsWith(".tsx"))) {
8374
8427
  const sharedPath = join11(sharedDir, f);
@@ -8425,12 +8478,12 @@ async function fixCommand(opts = {}) {
8425
8478
  console.log(chalk15.green(` \u2714 ${verb} syntax: ${syntaxFixed} file(s) (use client, metadata, quotes)`));
8426
8479
  }
8427
8480
  try {
8428
- const { loadPlan: loadPlan2 } = await import("./plan-generator-PIDLFRWZ.js");
8429
- const { ensurePlanGroupLayouts: ensurePlanGroupLayouts2 } = await import("./code-generator-YSGVHVNN.js");
8481
+ const { loadPlan: loadPlan2 } = await import("./plan-generator-D2UBTVCN.js");
8482
+ const { ensurePlanGroupLayouts: ensurePlanGroupLayouts2 } = await import("./code-generator-IZ6XM6WG.js");
8430
8483
  const plan = loadPlan2(projectRoot);
8431
8484
  if (plan) {
8432
8485
  if (!dsm) {
8433
- dsm = new DesignSystemManager9(project.configPath);
8486
+ dsm = new DesignSystemManager8(project.configPath);
8434
8487
  await dsm.load();
8435
8488
  }
8436
8489
  await ensurePlanGroupLayouts2(projectRoot, plan, {}, dsm.getConfig());
@@ -8439,9 +8492,9 @@ async function fixCommand(opts = {}) {
8439
8492
  console.log(chalk15.green(` \u2714 Verified group layouts: ${layoutTypes}`));
8440
8493
  const hasSidebar = plan.groups.some((g) => g.layout === "sidebar" || g.layout === "both");
8441
8494
  const sidebarPath = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
8442
- if (hasSidebar && !existsSync14(sidebarPath) && !dryRun) {
8495
+ if (hasSidebar && !existsSync13(sidebarPath) && !dryRun) {
8443
8496
  if (!dsm) {
8444
- dsm = new DesignSystemManager9(project.configPath);
8497
+ dsm = new DesignSystemManager8(project.configPath);
8445
8498
  await dsm.load();
8446
8499
  }
8447
8500
  const { PageGenerator } = await import("@getcoherent/core");
@@ -8458,7 +8511,7 @@ async function fixCommand(opts = {}) {
8458
8511
  }
8459
8512
  if (hasSidebar && !dryRun) {
8460
8513
  const rootLayoutPath = resolve8(projectRoot, "app", "layout.tsx");
8461
- if (existsSync14(rootLayoutPath)) {
8514
+ if (existsSync13(rootLayoutPath)) {
8462
8515
  let rootCode = readFileSync10(rootLayoutPath, "utf-8");
8463
8516
  if (rootCode.includes("<Header")) {
8464
8517
  rootCode = rootCode.replace(/import\s*\{[^}]*Header[^}]*\}[^;\n]*[;\n]?\s*/g, "").replace(/import\s*\{[^}]*Footer[^}]*\}[^;\n]*[;\n]?\s*/g, "").replace(/import\s+ShowWhenNotAuthRoute[^;\n]*[;\n]?\s*/g, "").replace(/<ShowWhenNotAuthRoute>[\s\S]*?<\/ShowWhenNotAuthRoute>/g, (match) => {
@@ -8477,10 +8530,10 @@ async function fixCommand(opts = {}) {
8477
8530
  }
8478
8531
  }
8479
8532
  const publicLayoutPath = resolve8(projectRoot, "app", "(public)", "layout.tsx");
8480
- const publicExists = existsSync14(publicLayoutPath);
8533
+ const publicExists = existsSync13(publicLayoutPath);
8481
8534
  const needsPublicLayout = !publicExists || !readFileSync10(publicLayoutPath, "utf-8").includes("<Header");
8482
8535
  if (needsPublicLayout) {
8483
- const { buildPublicLayoutCodeForSidebar } = await import("./code-generator-YSGVHVNN.js");
8536
+ const { buildPublicLayoutCodeForSidebar } = await import("./code-generator-IZ6XM6WG.js");
8484
8537
  mkdirSync7(resolve8(projectRoot, "app", "(public)"), { recursive: true });
8485
8538
  const publicResult = safeWrite(publicLayoutPath, buildPublicLayoutCodeForSidebar(), projectRoot, backups);
8486
8539
  if (publicResult.ok) {
@@ -8491,7 +8544,7 @@ async function fixCommand(opts = {}) {
8491
8544
  }
8492
8545
  }
8493
8546
  const sidebarComponentPath2 = resolve8(projectRoot, "components", "shared", "sidebar.tsx");
8494
- if (existsSync14(sidebarComponentPath2)) {
8547
+ if (existsSync13(sidebarComponentPath2)) {
8495
8548
  const existingSidebarCode = readFileSync10(sidebarComponentPath2, "utf-8");
8496
8549
  const sidebarConfigName = dsm?.getConfig().name ?? "";
8497
8550
  const hasWrongName = existingSidebarCode.includes("My App") && sidebarConfigName !== "My App";
@@ -8499,7 +8552,7 @@ async function fixCommand(opts = {}) {
8499
8552
  const isBroken = !isValidTsx(existingSidebarCode, projectRoot);
8500
8553
  if (hasWrongName || hasTrigger || isBroken) {
8501
8554
  if (!dsm) {
8502
- dsm = new DesignSystemManager9(project.configPath);
8555
+ dsm = new DesignSystemManager8(project.configPath);
8503
8556
  await dsm.load();
8504
8557
  }
8505
8558
  const { PageGenerator } = await import("@getcoherent/core");
@@ -8520,7 +8573,7 @@ async function fixCommand(opts = {}) {
8520
8573
  }
8521
8574
  const rootPagePath = resolve8(projectRoot, "app", "page.tsx");
8522
8575
  const publicPagePath = resolve8(projectRoot, "app", "(public)", "page.tsx");
8523
- if (existsSync14(rootPagePath) && !existsSync14(publicPagePath)) {
8576
+ if (existsSync13(rootPagePath) && !existsSync13(publicPagePath)) {
8524
8577
  const { renameSync } = await import("fs");
8525
8578
  mkdirSync7(resolve8(projectRoot, "app", "(public)"), { recursive: true });
8526
8579
  renameSync(rootPagePath, publicPagePath);
@@ -8528,8 +8581,8 @@ async function fixCommand(opts = {}) {
8528
8581
  console.log(chalk15.green(" \u2714 Moved app/page.tsx \u2192 app/(public)/page.tsx (gets Header/Footer)"));
8529
8582
  }
8530
8583
  const themeTogglePath = resolve8(projectRoot, "components", "shared", "theme-toggle.tsx");
8531
- if (!existsSync14(themeTogglePath)) {
8532
- const { generateThemeToggleCode } = await import("./code-generator-YSGVHVNN.js");
8584
+ if (!existsSync13(themeTogglePath)) {
8585
+ const { generateThemeToggleCode } = await import("./code-generator-IZ6XM6WG.js");
8533
8586
  mkdirSync7(resolve8(projectRoot, "components", "shared"), { recursive: true });
8534
8587
  const themeResult = safeWrite(themeTogglePath, generateThemeToggleCode(), projectRoot, backups);
8535
8588
  if (themeResult.ok) {
@@ -8545,12 +8598,12 @@ async function fixCommand(opts = {}) {
8545
8598
  console.log(chalk15.yellow(` \u26A0 Layout repair skipped: ${err instanceof Error ? err.message : "unknown error"}`));
8546
8599
  }
8547
8600
  const appLayoutRepairPath = resolve8(projectRoot, "app", "(app)", "layout.tsx");
8548
- if (existsSync14(appLayoutRepairPath) && dsm) {
8601
+ if (existsSync13(appLayoutRepairPath) && dsm) {
8549
8602
  const appLayoutCode = readFileSync10(appLayoutRepairPath, "utf-8");
8550
8603
  const isMinimal = appLayoutCode.length < 500 && !appLayoutCode.includes("Header") && !appLayoutCode.includes("Footer") && !appLayoutCode.includes("Sidebar") && !appLayoutCode.includes("SidebarProvider") && !appLayoutCode.includes("SidebarTrigger") && !appLayoutCode.includes("Sheet");
8551
8604
  const navType = dsm.getConfig().navigation?.type || "header";
8552
8605
  if (isMinimal && navType !== "none") {
8553
- const { buildAppLayoutCode, buildGroupLayoutCode } = await import("./code-generator-YSGVHVNN.js");
8606
+ const { buildAppLayoutCode, buildGroupLayoutCode } = await import("./code-generator-IZ6XM6WG.js");
8554
8607
  const isSidebar = navType === "sidebar" || navType === "both";
8555
8608
  const newLayout = isSidebar ? buildAppLayoutCode(navType, dsm.getConfig().name) : buildGroupLayoutCode("header", dsm.getConfig().pages?.map((p) => p.name) || [], dsm.getConfig().name);
8556
8609
  if (!dryRun) {
@@ -8683,7 +8736,7 @@ async function fixCommand(opts = {}) {
8683
8736
  }
8684
8737
  }
8685
8738
  try {
8686
- let manifest = await loadManifest9(project.root);
8739
+ let manifest = await loadManifest8(project.root);
8687
8740
  let manifestModified = false;
8688
8741
  const { manifest: cleaned, removed: orphaned } = removeOrphanedEntries(project.root, manifest);
8689
8742
  if (orphaned.length > 0) {
@@ -8763,7 +8816,7 @@ async function fixCommand(opts = {}) {
8763
8816
  }
8764
8817
  try {
8765
8818
  const tsconfigPath = resolve8(projectRoot, "tsconfig.json");
8766
- if (existsSync14(tsconfigPath)) {
8819
+ if (existsSync13(tsconfigPath)) {
8767
8820
  const { runTscCheck, applyDeterministicFixes } = await import("./tsc-autofix-S5PKMFSC.js");
8768
8821
  const { applyAiFixes } = await import("./tsc-ai-fix-O3EMRWV2.js");
8769
8822
  const tscErrors = runTscCheck(projectRoot);
@@ -8851,8 +8904,8 @@ async function fixCommand(opts = {}) {
8851
8904
  // src/commands/check.ts
8852
8905
  import chalk16 from "chalk";
8853
8906
  import { resolve as resolve9 } from "path";
8854
- import { readdirSync as readdirSync8, readFileSync as readFileSync11, statSync as statSync3, existsSync as existsSync15 } from "fs";
8855
- import { loadManifest as loadManifest10 } from "@getcoherent/core";
8907
+ import { readdirSync as readdirSync8, readFileSync as readFileSync11, statSync as statSync3, existsSync as existsSync14 } from "fs";
8908
+ import { loadManifest as loadManifest9 } from "@getcoherent/core";
8856
8909
  var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "design-system"]);
8857
8910
  function findTsxFiles(dir) {
8858
8911
  const results = [];
@@ -8887,8 +8940,8 @@ async function checkCommand(opts = {}) {
8887
8940
  };
8888
8941
  let validRoutes = [];
8889
8942
  try {
8890
- const { DesignSystemManager: DesignSystemManager15 } = await import("@getcoherent/core");
8891
- const dsm = new DesignSystemManager15(project.configPath);
8943
+ const { DesignSystemManager: DesignSystemManager14 } = await import("@getcoherent/core");
8944
+ const dsm = new DesignSystemManager14(project.configPath);
8892
8945
  await dsm.load();
8893
8946
  validRoutes = dsm.getConfig().pages.map((p) => p.route).filter(Boolean);
8894
8947
  } catch {
@@ -8979,11 +9032,11 @@ async function checkCommand(opts = {}) {
8979
9032
  \u{1F517} Internal Links`) + chalk16.dim(` \u2014 all ${result.links.total} links resolve \u2713`));
8980
9033
  }
8981
9034
  try {
8982
- const manifest = await loadManifest10(project.root);
9035
+ const manifest = await loadManifest9(project.root);
8983
9036
  if (manifest.shared.length > 0) {
8984
9037
  for (const entry of manifest.shared) {
8985
9038
  const fullPath = resolve9(project.root, entry.file);
8986
- if (!existsSync15(fullPath)) {
9039
+ if (!existsSync14(fullPath)) {
8987
9040
  result.pages.withErrors++;
8988
9041
  if (!opts.json) console.log(chalk16.red(`
8989
9042
  \u2717 Missing shared component file: ${entry.id} (${entry.file})`));
@@ -8995,7 +9048,7 @@ async function checkCommand(opts = {}) {
8995
9048
  }
8996
9049
  if (!skipShared) {
8997
9050
  try {
8998
- const manifest = await loadManifest10(projectRoot);
9051
+ const manifest = await loadManifest9(projectRoot);
8999
9052
  if (!opts.json && manifest.shared.length > 0) {
9000
9053
  console.log(chalk16.cyan(`
9001
9054
  \u{1F9E9} Shared Components`) + chalk16.dim(` (${manifest.shared.length} registered)
@@ -9008,7 +9061,7 @@ async function checkCommand(opts = {}) {
9008
9061
  let _nameMismatch = 0;
9009
9062
  for (const entry of manifest.shared) {
9010
9063
  const filePath = resolve9(projectRoot, entry.file);
9011
- const fileExists = existsSync15(filePath);
9064
+ const fileExists = existsSync14(filePath);
9012
9065
  if (!fileExists) {
9013
9066
  _orphaned++;
9014
9067
  if (!opts.json) {
@@ -9086,7 +9139,7 @@ async function checkCommand(opts = {}) {
9086
9139
  id: e.id,
9087
9140
  name: e.name,
9088
9141
  type: e.type,
9089
- status: existsSync15(resolve9(projectRoot, e.file)) ? "ok" : "unused",
9142
+ status: existsSync14(resolve9(projectRoot, e.file)) ? "ok" : "unused",
9090
9143
  message: "",
9091
9144
  suggestions: void 0
9092
9145
  }))
@@ -9097,10 +9150,10 @@ async function checkCommand(opts = {}) {
9097
9150
  if (!skipShared) {
9098
9151
  try {
9099
9152
  const { validateReuse } = await import("./reuse-validator-XR2ZEYC4.js");
9100
- const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-HGNEY3W3.js");
9101
- const manifest = await loadManifest10(projectRoot);
9153
+ const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-PFZDW2XW.js");
9154
+ const manifest = await loadManifest9(projectRoot);
9102
9155
  const appDir = resolve9(projectRoot, "app");
9103
- const pageFiles = existsSync15(appDir) ? findTsxFiles(appDir) : [];
9156
+ const pageFiles = existsSync14(appDir) ? findTsxFiles(appDir) : [];
9104
9157
  if (manifest.shared.length > 0 && pageFiles.length > 0) {
9105
9158
  const reuseWarnings = [];
9106
9159
  for (const file of pageFiles) {
@@ -9175,7 +9228,7 @@ async function doctorCommand() {
9175
9228
  import chalk19 from "chalk";
9176
9229
  async function rulesCommand() {
9177
9230
  try {
9178
- const result = await regenerateCursorRules();
9231
+ const result = await regenerateAllHarnessFiles();
9179
9232
  if (!result.written) {
9180
9233
  exitNotCoherent();
9181
9234
  }
@@ -9183,7 +9236,7 @@ async function rulesCommand() {
9183
9236
  if (result.sharedCount !== void 0) parts.push(`${result.sharedCount} shared components`);
9184
9237
  if (result.tokenKeys !== void 0) parts.push(`${result.tokenKeys} design token keys`);
9185
9238
  const summary = parts.length > 0 ? ` (${parts.join(", ")})` : "";
9186
- console.log(chalk19.green(`\u2714 Updated .cursorrules and CLAUDE.md${summary}
9239
+ console.log(chalk19.green(`\u2714 Updated .cursorrules, CLAUDE.md, and AGENTS.md${summary}
9187
9240
  `));
9188
9241
  } catch (error) {
9189
9242
  console.error(chalk19.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
@@ -9209,13 +9262,13 @@ async function auditCommand(options) {
9209
9262
  import { Command } from "commander";
9210
9263
  import chalk22 from "chalk";
9211
9264
  import {
9212
- DesignSystemManager as DesignSystemManager10,
9265
+ DesignSystemManager as DesignSystemManager9,
9213
9266
  ComponentManager as ComponentManager6,
9214
- loadManifest as loadManifest11,
9267
+ loadManifest as loadManifest10,
9215
9268
  generateSharedComponent as generateSharedComponent4,
9216
9269
  integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout2
9217
9270
  } from "@getcoherent/core";
9218
- import { existsSync as existsSync16 } from "fs";
9271
+ import { existsSync as existsSync15 } from "fs";
9219
9272
  import { resolve as resolve10 } from "path";
9220
9273
 
9221
9274
  // src/utils/ds-files.ts
@@ -9248,11 +9301,11 @@ function createComponentsCommand() {
9248
9301
  cmd.command("list").description("List all components (shared + UI)").option("--json", "Machine-readable JSON output").action(async (opts) => {
9249
9302
  const project = findConfig();
9250
9303
  if (!project) exitNotCoherent();
9251
- const dsm = new DesignSystemManager10(project.configPath);
9304
+ const dsm = new DesignSystemManager9(project.configPath);
9252
9305
  await dsm.load();
9253
9306
  const config2 = dsm.getConfig();
9254
9307
  const cm = new ComponentManager6(config2);
9255
- const manifest = await loadManifest11(project.root);
9308
+ const manifest = await loadManifest10(project.root);
9256
9309
  if (opts.json) {
9257
9310
  const installed2 = cm.getAllComponents();
9258
9311
  console.log(JSON.stringify({ shared: manifest.shared, ui: installed2 }, null, 2));
@@ -9312,7 +9365,7 @@ function createComponentsCommand() {
9312
9365
  sharedCmd.option("--json", "Machine-readable JSON output").option("--verbose", "Show file paths and usage details").action(async (opts) => {
9313
9366
  const project = findConfig();
9314
9367
  if (!project) exitNotCoherent();
9315
- const manifest = await loadManifest11(project.root);
9368
+ const manifest = await loadManifest10(project.root);
9316
9369
  if (opts.json) {
9317
9370
  console.log(JSON.stringify(manifest, null, 2));
9318
9371
  return;
@@ -9370,9 +9423,9 @@ function createComponentsCommand() {
9370
9423
  if (updated) console.log(chalk22.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
9371
9424
  }
9372
9425
  const sharedPagePath = resolve10(project.root, "app/design-system/shared/page.tsx");
9373
- if (!existsSync16(sharedPagePath)) {
9426
+ if (!existsSync15(sharedPagePath)) {
9374
9427
  try {
9375
- const dsm = new DesignSystemManager10(project.configPath);
9428
+ const dsm = new DesignSystemManager9(project.configPath);
9376
9429
  await dsm.load();
9377
9430
  const config2 = dsm.getConfig();
9378
9431
  const written = await writeDesignSystemFiles(project.root, config2, { sharedOnly: true });
@@ -9384,7 +9437,7 @@ function createComponentsCommand() {
9384
9437
  }
9385
9438
  }
9386
9439
  try {
9387
- await writeCursorRules(project.root);
9440
+ await writeAllHarnessFiles(project.root);
9388
9441
  } catch (e) {
9389
9442
  if (process.env.COHERENT_DEBUG === "1") console.error(chalk22.dim("Could not update .cursorrules:"), e);
9390
9443
  }
@@ -9397,7 +9450,7 @@ import chalk23 from "chalk";
9397
9450
  import ora6 from "ora";
9398
9451
  import { writeFile as writeFile5, mkdir as mkdir4 } from "fs/promises";
9399
9452
  import { resolve as resolve11, join as join13, dirname as dirname6 } from "path";
9400
- import { existsSync as existsSync17 } from "fs";
9453
+ import { existsSync as existsSync16 } from "fs";
9401
9454
  import {
9402
9455
  FigmaClient,
9403
9456
  parseFigmaFileResponse,
@@ -9410,7 +9463,7 @@ import {
9410
9463
  generateSharedComponent as generateSharedComponent5,
9411
9464
  generatePagesFromFigma,
9412
9465
  integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout3,
9413
- DesignSystemManager as DesignSystemManager11,
9466
+ DesignSystemManager as DesignSystemManager10,
9414
9467
  validateConfig,
9415
9468
  FRAMEWORK_VERSIONS as FRAMEWORK_VERSIONS2,
9416
9469
  CLI_VERSION as CLI_VERSION3
@@ -9645,8 +9698,8 @@ async function importFigmaAction(urlOrKey, opts) {
9645
9698
  if (!dryRun) {
9646
9699
  spinner.start("Updating design-system.config.ts...");
9647
9700
  const configPath = resolve11(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
9648
- const dsm = new DesignSystemManager11(configPath);
9649
- if (existsSync17(configPath)) {
9701
+ const dsm = new DesignSystemManager10(configPath);
9702
+ if (existsSync16(configPath)) {
9650
9703
  await dsm.load();
9651
9704
  const existing = dsm.getConfig();
9652
9705
  dsm.updateConfig({
@@ -9676,7 +9729,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
9676
9729
  spinner.succeed("design-system.config.ts updated");
9677
9730
  spinner.start("Ensuring root layout...");
9678
9731
  const layoutPath = join13(projectRoot, "app/layout.tsx");
9679
- if (!existsSync17(layoutPath)) {
9732
+ if (!existsSync16(layoutPath)) {
9680
9733
  await mkdir4(dirname6(layoutPath), { recursive: true });
9681
9734
  await writeFile5(layoutPath, MINIMAL_ROOT_LAYOUT, "utf-8");
9682
9735
  stats.filesWritten.push("app/layout.tsx");
@@ -9691,7 +9744,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
9691
9744
  stats.dsFilesWritten = dsFiles.length;
9692
9745
  spinner.succeed(`DS viewer: ${dsFiles.length} files`);
9693
9746
  try {
9694
- await writeCursorRules(projectRoot);
9747
+ await writeAllHarnessFiles(projectRoot);
9695
9748
  } catch (e) {
9696
9749
  if (process.env.COHERENT_DEBUG === "1") console.error(chalk23.dim("Could not update .cursorrules:"), e);
9697
9750
  }
@@ -9742,7 +9795,7 @@ function printReport(stats, opts) {
9742
9795
  // src/commands/ds.ts
9743
9796
  import chalk24 from "chalk";
9744
9797
  import ora7 from "ora";
9745
- import { DesignSystemManager as DesignSystemManager12 } from "@getcoherent/core";
9798
+ import { DesignSystemManager as DesignSystemManager11 } from "@getcoherent/core";
9746
9799
  async function dsRegenerateCommand() {
9747
9800
  try {
9748
9801
  const project = findConfig();
@@ -9750,7 +9803,7 @@ async function dsRegenerateCommand() {
9750
9803
  exitNotCoherent();
9751
9804
  }
9752
9805
  const spinner = ora7("Loading config and regenerating Design System pages...").start();
9753
- const dsm = new DesignSystemManager12(project.configPath);
9806
+ const dsm = new DesignSystemManager11(project.configPath);
9754
9807
  await dsm.load();
9755
9808
  const config2 = dsm.getConfig();
9756
9809
  const written = await writeDesignSystemFiles(project.root, config2);
@@ -9766,9 +9819,9 @@ async function dsRegenerateCommand() {
9766
9819
  // src/commands/update.ts
9767
9820
  import chalk25 from "chalk";
9768
9821
  import ora8 from "ora";
9769
- import { readFileSync as readFileSync12, existsSync as existsSync18 } from "fs";
9822
+ import { readFileSync as readFileSync12, existsSync as existsSync17 } from "fs";
9770
9823
  import { join as join14 } from "path";
9771
- import { DesignSystemManager as DesignSystemManager13, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
9824
+ import { DesignSystemManager as DesignSystemManager12, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
9772
9825
 
9773
9826
  // src/utils/migrations.ts
9774
9827
  var MIGRATIONS = [
@@ -9810,7 +9863,7 @@ async function updateCommand(opts) {
9810
9863
  }
9811
9864
  const spinner = ora8("Loading project configuration...").start();
9812
9865
  try {
9813
- const dsm = new DesignSystemManager13(project.configPath);
9866
+ const dsm = new DesignSystemManager12(project.configPath);
9814
9867
  await dsm.load();
9815
9868
  const config2 = dsm.getConfig();
9816
9869
  const projectVersion = config2.coherentVersion || "0.0.0";
@@ -9850,7 +9903,7 @@ async function updateCommand(opts) {
9850
9903
  const overlayFiles = await writeDesignSystemFiles(project.root, config2);
9851
9904
  report.overlayFiles = overlayFiles.length;
9852
9905
  spinner.text = "Updating .cursorrules and CLAUDE.md...";
9853
- const rulesResult = await writeCursorRules(project.root);
9906
+ const rulesResult = await writeAllHarnessFiles(project.root);
9854
9907
  report.rulesUpdated = rulesResult.written;
9855
9908
  spinner.text = "Checking globals.css...";
9856
9909
  report.missingCssVars = checkMissingCssVars(project.root);
@@ -9937,7 +9990,7 @@ var EXPECTED_CSS_VARS = [
9937
9990
  ];
9938
9991
  function checkMissingCssVars(projectRoot) {
9939
9992
  const globalsPath = join14(projectRoot, "app", "globals.css");
9940
- if (!existsSync18(globalsPath)) return [];
9993
+ if (!existsSync17(globalsPath)) return [];
9941
9994
  try {
9942
9995
  const content = readFileSync12(globalsPath, "utf-8");
9943
9996
  return EXPECTED_CSS_VARS.filter((v) => !content.includes(v));
@@ -9947,7 +10000,7 @@ function checkMissingCssVars(projectRoot) {
9947
10000
  }
9948
10001
  function patchGlobalsCss(projectRoot, missingVars) {
9949
10002
  const globalsPath = join14(projectRoot, "app", "globals.css");
9950
- if (!existsSync18(globalsPath) || missingVars.length === 0) return;
10003
+ if (!existsSync17(globalsPath) || missingVars.length === 0) return;
9951
10004
  const { writeFileSync: writeFileSync11 } = __require("fs");
9952
10005
  let content = readFileSync12(globalsPath, "utf-8");
9953
10006
  const defaultValues = {
@@ -10027,16 +10080,16 @@ async function undoCommand(options) {
10027
10080
  // src/commands/sync.ts
10028
10081
  import chalk27 from "chalk";
10029
10082
  import ora9 from "ora";
10030
- import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
10083
+ import { existsSync as existsSync18, readFileSync as readFileSync13 } from "fs";
10031
10084
  import { join as join15, relative as relative6, dirname as dirname7 } from "path";
10032
10085
  import { readdir as readdir3, readFile as readFile4 } from "fs/promises";
10033
- import { DesignSystemManager as DesignSystemManager14 } from "@getcoherent/core";
10034
- import { loadManifest as loadManifest12, saveManifest as saveManifest6, findSharedComponent } from "@getcoherent/core";
10086
+ import { DesignSystemManager as DesignSystemManager13 } from "@getcoherent/core";
10087
+ import { loadManifest as loadManifest11, saveManifest as saveManifest6, findSharedComponent } from "@getcoherent/core";
10035
10088
  function extractTokensFromProject(projectRoot) {
10036
10089
  const lightColors = {};
10037
10090
  const darkColors = {};
10038
10091
  const globalsPath = join15(projectRoot, "app", "globals.css");
10039
- if (existsSync19(globalsPath)) {
10092
+ if (existsSync18(globalsPath)) {
10040
10093
  const css = readFileSync13(globalsPath, "utf-8");
10041
10094
  const rootMatch = css.match(/:root\s*\{([^}]+)\}/s);
10042
10095
  if (rootMatch) parseVarsInto(rootMatch[1], lightColors);
@@ -10045,7 +10098,7 @@ function extractTokensFromProject(projectRoot) {
10045
10098
  }
10046
10099
  const layoutPath = join15(projectRoot, "app", "layout.tsx");
10047
10100
  let layoutCode = "";
10048
- if (existsSync19(layoutPath)) {
10101
+ if (existsSync18(layoutPath)) {
10049
10102
  layoutCode = readFileSync13(layoutPath, "utf-8");
10050
10103
  const rootInline = layoutCode.match(/:root\s*\{([^}]+)\}/s);
10051
10104
  if (rootInline && Object.keys(lightColors).length === 0) {
@@ -10064,7 +10117,7 @@ function extractTokensFromProject(projectRoot) {
10064
10117
  defaultMode = "dark";
10065
10118
  }
10066
10119
  let radius;
10067
- const allCss = [existsSync19(globalsPath) ? readFileSync13(globalsPath, "utf-8") : "", layoutCode].join("\n");
10120
+ const allCss = [existsSync18(globalsPath) ? readFileSync13(globalsPath, "utf-8") : "", layoutCode].join("\n");
10068
10121
  const radiusMatch = allCss.match(/--radius:\s*([^;]+);/);
10069
10122
  if (radiusMatch) radius = radiusMatch[1].trim();
10070
10123
  return {
@@ -10088,7 +10141,7 @@ function parseVarsInto(block, target) {
10088
10141
  async function detectCustomComponents(projectRoot, allPageCode) {
10089
10142
  const results = [];
10090
10143
  const componentsDir = join15(projectRoot, "components");
10091
- if (!existsSync19(componentsDir)) return results;
10144
+ if (!existsSync18(componentsDir)) return results;
10092
10145
  const files = [];
10093
10146
  await walkForTsx(componentsDir, files, ["ui"]);
10094
10147
  const fileResults = await Promise.all(
@@ -10279,11 +10332,11 @@ async function syncCommand(options = {}) {
10279
10332
  const spinner = ora9("Scanning project files...").start();
10280
10333
  try {
10281
10334
  const appDir = join15(project.root, "app");
10282
- if (!existsSync19(appDir)) {
10335
+ if (!existsSync18(appDir)) {
10283
10336
  spinner.fail("No app/ directory found");
10284
10337
  process.exit(1);
10285
10338
  }
10286
- const dsm = new DesignSystemManager14(project.configPath);
10339
+ const dsm = new DesignSystemManager13(project.configPath);
10287
10340
  await dsm.load();
10288
10341
  const config2 = dsm.getConfig();
10289
10342
  const discoveredPages = await discoverPages(appDir);
@@ -10323,7 +10376,7 @@ async function syncCommand(options = {}) {
10323
10376
  let reconcileResult = null;
10324
10377
  if (doComponents) {
10325
10378
  spinner.start("Reconciling shared components...");
10326
- const manifest = await loadManifest12(project.root);
10379
+ const manifest = await loadManifest11(project.root);
10327
10380
  const { manifest: reconciledManifest, result: rr } = reconcileComponents(project.root, manifest);
10328
10381
  reconcileResult = rr;
10329
10382
  if (!dryRun) {
@@ -10411,9 +10464,8 @@ async function syncCommand(options = {}) {
10411
10464
  const written = await writeDesignSystemFiles(project.root, config2);
10412
10465
  spinner.succeed(`Regenerated ${written.length} Design System file(s)`);
10413
10466
  spinner.start("Updating AI context files...");
10414
- await writeCursorRules(project.root);
10415
- await generateClaudeCodeFiles(project.root);
10416
- spinner.succeed("Updated .cursorrules and CLAUDE.md");
10467
+ await writeAllHarnessFiles(project.root);
10468
+ spinner.succeed("Updated .cursorrules, CLAUDE.md, and AGENTS.md");
10417
10469
  }
10418
10470
  console.log("");
10419
10471
  console.log(chalk27.green(`\u2705 Design System ${dryRun ? "analyzed" : "synced"} with actual code
@@ -10509,7 +10561,7 @@ async function syncCommand(options = {}) {
10509
10561
  // src/commands/migrate.ts
10510
10562
  import chalk28 from "chalk";
10511
10563
  import ora10 from "ora";
10512
- import { existsSync as existsSync20, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync9, readFileSync as readFileSync14, readdirSync as readdirSync9 } from "fs";
10564
+ import { existsSync as existsSync19, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync9, readFileSync as readFileSync14, readdirSync as readdirSync9 } from "fs";
10513
10565
  import { join as join16 } from "path";
10514
10566
  function backupDir(projectRoot) {
10515
10567
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -10522,11 +10574,11 @@ function createBackup2(projectRoot) {
10522
10574
  const uiDir = join16(projectRoot, "components", "ui");
10523
10575
  const dest = backupDir(projectRoot);
10524
10576
  mkdirSync8(dest, { recursive: true });
10525
- if (existsSync20(uiDir)) {
10577
+ if (existsSync19(uiDir)) {
10526
10578
  cpSync(uiDir, join16(dest, "components-ui"), { recursive: true });
10527
10579
  }
10528
10580
  const configPath = join16(projectRoot, "design-system.config.ts");
10529
- if (existsSync20(configPath)) {
10581
+ if (existsSync19(configPath)) {
10530
10582
  cpSync(configPath, join16(dest, "design-system.config.ts"));
10531
10583
  }
10532
10584
  return dest;
@@ -10538,24 +10590,24 @@ function setGuard(projectRoot, backupPath) {
10538
10590
  }
10539
10591
  function clearGuard(projectRoot) {
10540
10592
  const guard = guardPath(projectRoot);
10541
- if (existsSync20(guard)) rmSync6(guard);
10593
+ if (existsSync19(guard)) rmSync6(guard);
10542
10594
  }
10543
10595
  function rollback(projectRoot) {
10544
10596
  const guard = guardPath(projectRoot);
10545
- if (!existsSync20(guard)) return false;
10597
+ if (!existsSync19(guard)) return false;
10546
10598
  try {
10547
10599
  const data = JSON.parse(readFileSync14(guard, "utf-8"));
10548
10600
  const backup = data.backup;
10549
- if (!existsSync20(backup)) return false;
10601
+ if (!existsSync19(backup)) return false;
10550
10602
  const uiBackup = join16(backup, "components-ui");
10551
10603
  const uiDir = join16(projectRoot, "components", "ui");
10552
- if (existsSync20(uiBackup)) {
10553
- if (existsSync20(uiDir)) rmSync6(uiDir, { recursive: true });
10604
+ if (existsSync19(uiBackup)) {
10605
+ if (existsSync19(uiDir)) rmSync6(uiDir, { recursive: true });
10554
10606
  cpSync(uiBackup, uiDir, { recursive: true });
10555
10607
  }
10556
10608
  const configBackup = join16(backup, "design-system.config.ts");
10557
10609
  const configDest = join16(projectRoot, "design-system.config.ts");
10558
- if (existsSync20(configBackup)) {
10610
+ if (existsSync19(configBackup)) {
10559
10611
  cpSync(configBackup, configDest);
10560
10612
  }
10561
10613
  clearGuard(projectRoot);
@@ -10583,13 +10635,13 @@ async function migrateAction(options) {
10583
10635
  return;
10584
10636
  }
10585
10637
  const guard = guardPath(projectRoot);
10586
- if (existsSync20(guard)) {
10638
+ if (existsSync19(guard)) {
10587
10639
  console.log(chalk28.yellow("A migration is already in progress."));
10588
10640
  console.log(chalk28.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
10589
10641
  return;
10590
10642
  }
10591
10643
  const uiDir = join16(projectRoot, "components", "ui");
10592
- if (!existsSync20(uiDir)) {
10644
+ if (!existsSync19(uiDir)) {
10593
10645
  console.log(chalk28.yellow("No components/ui directory found. Nothing to migrate."));
10594
10646
  return;
10595
10647
  }
@@ -10616,7 +10668,7 @@ Found ${migratable.length} component(s) to migrate:`));
10616
10668
  try {
10617
10669
  for (const id of migratable) {
10618
10670
  const filePath = join16(uiDir, `${id}.tsx`);
10619
- if (existsSync20(filePath)) rmSync6(filePath);
10671
+ if (existsSync19(filePath)) rmSync6(filePath);
10620
10672
  }
10621
10673
  const results = await provider.installBatch(migratable, projectRoot, { force: true });
10622
10674
  let migrated = 0;
@@ -10638,7 +10690,7 @@ Found ${migratable.length} component(s) to migrate:`));
10638
10690
  }
10639
10691
 
10640
10692
  // src/utils/update-notifier.ts
10641
- import { existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
10693
+ import { existsSync as existsSync20, mkdirSync as mkdirSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
10642
10694
  import { join as join17 } from "path";
10643
10695
  import { homedir } from "os";
10644
10696
  import chalk29 from "chalk";
@@ -10650,7 +10702,7 @@ var CACHE_FILE = join17(CACHE_DIR, "update-check.json");
10650
10702
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
10651
10703
  function readCache() {
10652
10704
  try {
10653
- if (!existsSync21(CACHE_FILE)) return null;
10705
+ if (!existsSync20(CACHE_FILE)) return null;
10654
10706
  const raw = readFileSync15(CACHE_FILE, "utf-8");
10655
10707
  return JSON.parse(raw);
10656
10708
  } catch (e) {
@@ -10660,7 +10712,7 @@ function readCache() {
10660
10712
  }
10661
10713
  function writeCache(data) {
10662
10714
  try {
10663
- if (!existsSync21(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
10715
+ if (!existsSync20(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
10664
10716
  writeFileSync10(CACHE_FILE, JSON.stringify(data), "utf-8");
10665
10717
  } catch (e) {
10666
10718
  if (DEBUG5) console.error("Failed to write update cache:", e);