popeye-cli 1.4.7 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +264 -63
  3. package/dist/adapters/gemini.d.ts +1 -0
  4. package/dist/adapters/gemini.d.ts.map +1 -1
  5. package/dist/adapters/gemini.js +9 -4
  6. package/dist/adapters/gemini.js.map +1 -1
  7. package/dist/adapters/grok.d.ts +1 -0
  8. package/dist/adapters/grok.d.ts.map +1 -1
  9. package/dist/adapters/grok.js +9 -4
  10. package/dist/adapters/grok.js.map +1 -1
  11. package/dist/adapters/openai.d.ts +1 -1
  12. package/dist/adapters/openai.d.ts.map +1 -1
  13. package/dist/adapters/openai.js +35 -9
  14. package/dist/adapters/openai.js.map +1 -1
  15. package/dist/cli/commands/create.d.ts.map +1 -1
  16. package/dist/cli/commands/create.js +54 -4
  17. package/dist/cli/commands/create.js.map +1 -1
  18. package/dist/cli/interactive.d.ts +29 -0
  19. package/dist/cli/interactive.d.ts.map +1 -1
  20. package/dist/cli/interactive.js +132 -7
  21. package/dist/cli/interactive.js.map +1 -1
  22. package/dist/generators/all.d.ts +8 -2
  23. package/dist/generators/all.d.ts.map +1 -1
  24. package/dist/generators/all.js +37 -316
  25. package/dist/generators/all.js.map +1 -1
  26. package/dist/generators/doc-parser.d.ts +64 -0
  27. package/dist/generators/doc-parser.d.ts.map +1 -0
  28. package/dist/generators/doc-parser.js +407 -0
  29. package/dist/generators/doc-parser.js.map +1 -0
  30. package/dist/generators/frontend-design-analyzer.d.ts +30 -0
  31. package/dist/generators/frontend-design-analyzer.d.ts.map +1 -0
  32. package/dist/generators/frontend-design-analyzer.js +208 -0
  33. package/dist/generators/frontend-design-analyzer.js.map +1 -0
  34. package/dist/generators/shared-packages.d.ts +45 -0
  35. package/dist/generators/shared-packages.d.ts.map +1 -0
  36. package/dist/generators/shared-packages.js +456 -0
  37. package/dist/generators/shared-packages.js.map +1 -0
  38. package/dist/generators/templates/index.d.ts +8 -0
  39. package/dist/generators/templates/index.d.ts.map +1 -1
  40. package/dist/generators/templates/index.js +8 -0
  41. package/dist/generators/templates/index.js.map +1 -1
  42. package/dist/generators/templates/website-components.d.ts +33 -0
  43. package/dist/generators/templates/website-components.d.ts.map +1 -0
  44. package/dist/generators/templates/website-components.js +303 -0
  45. package/dist/generators/templates/website-components.js.map +1 -0
  46. package/dist/generators/templates/website-config.d.ts +55 -0
  47. package/dist/generators/templates/website-config.d.ts.map +1 -0
  48. package/dist/generators/templates/website-config.js +425 -0
  49. package/dist/generators/templates/website-config.js.map +1 -0
  50. package/dist/generators/templates/website-conversion.d.ts +27 -0
  51. package/dist/generators/templates/website-conversion.d.ts.map +1 -0
  52. package/dist/generators/templates/website-conversion.js +326 -0
  53. package/dist/generators/templates/website-conversion.js.map +1 -0
  54. package/dist/generators/templates/website-landing.d.ts +24 -0
  55. package/dist/generators/templates/website-landing.d.ts.map +1 -0
  56. package/dist/generators/templates/website-landing.js +276 -0
  57. package/dist/generators/templates/website-landing.js.map +1 -0
  58. package/dist/generators/templates/website-layout.d.ts +42 -0
  59. package/dist/generators/templates/website-layout.d.ts.map +1 -0
  60. package/dist/generators/templates/website-layout.js +408 -0
  61. package/dist/generators/templates/website-layout.js.map +1 -0
  62. package/dist/generators/templates/website-pricing.d.ts +11 -0
  63. package/dist/generators/templates/website-pricing.d.ts.map +1 -0
  64. package/dist/generators/templates/website-pricing.js +313 -0
  65. package/dist/generators/templates/website-pricing.js.map +1 -0
  66. package/dist/generators/templates/website-sections.d.ts +102 -0
  67. package/dist/generators/templates/website-sections.d.ts.map +1 -0
  68. package/dist/generators/templates/website-sections.js +444 -0
  69. package/dist/generators/templates/website-sections.js.map +1 -0
  70. package/dist/generators/templates/website-seo.d.ts +76 -0
  71. package/dist/generators/templates/website-seo.d.ts.map +1 -0
  72. package/dist/generators/templates/website-seo.js +326 -0
  73. package/dist/generators/templates/website-seo.js.map +1 -0
  74. package/dist/generators/templates/website.d.ts +10 -83
  75. package/dist/generators/templates/website.d.ts.map +1 -1
  76. package/dist/generators/templates/website.js +12 -875
  77. package/dist/generators/templates/website.js.map +1 -1
  78. package/dist/generators/website-content-scanner.d.ts +37 -0
  79. package/dist/generators/website-content-scanner.d.ts.map +1 -0
  80. package/dist/generators/website-content-scanner.js +165 -0
  81. package/dist/generators/website-content-scanner.js.map +1 -0
  82. package/dist/generators/website-context.d.ts +119 -0
  83. package/dist/generators/website-context.d.ts.map +1 -0
  84. package/dist/generators/website-context.js +350 -0
  85. package/dist/generators/website-context.js.map +1 -0
  86. package/dist/generators/website-debug.d.ts +68 -0
  87. package/dist/generators/website-debug.d.ts.map +1 -0
  88. package/dist/generators/website-debug.js +93 -0
  89. package/dist/generators/website-debug.js.map +1 -0
  90. package/dist/generators/website.d.ts +5 -0
  91. package/dist/generators/website.d.ts.map +1 -1
  92. package/dist/generators/website.js +136 -11
  93. package/dist/generators/website.js.map +1 -1
  94. package/dist/generators/workspace-root.d.ts +27 -0
  95. package/dist/generators/workspace-root.d.ts.map +1 -0
  96. package/dist/generators/workspace-root.js +100 -0
  97. package/dist/generators/workspace-root.js.map +1 -0
  98. package/dist/state/index.d.ts +35 -0
  99. package/dist/state/index.d.ts.map +1 -1
  100. package/dist/state/index.js +40 -0
  101. package/dist/state/index.js.map +1 -1
  102. package/dist/types/consensus.d.ts +3 -0
  103. package/dist/types/consensus.d.ts.map +1 -1
  104. package/dist/types/consensus.js +1 -0
  105. package/dist/types/consensus.js.map +1 -1
  106. package/dist/types/website-strategy.d.ts +263 -0
  107. package/dist/types/website-strategy.d.ts.map +1 -0
  108. package/dist/types/website-strategy.js +105 -0
  109. package/dist/types/website-strategy.js.map +1 -0
  110. package/dist/types/workflow.d.ts +21 -0
  111. package/dist/types/workflow.d.ts.map +1 -1
  112. package/dist/types/workflow.js +8 -0
  113. package/dist/types/workflow.js.map +1 -1
  114. package/dist/upgrade/handlers.d.ts +15 -0
  115. package/dist/upgrade/handlers.d.ts.map +1 -1
  116. package/dist/upgrade/handlers.js +52 -0
  117. package/dist/upgrade/handlers.js.map +1 -1
  118. package/dist/workflow/auto-fix-bundler.d.ts +37 -0
  119. package/dist/workflow/auto-fix-bundler.d.ts.map +1 -0
  120. package/dist/workflow/auto-fix-bundler.js +320 -0
  121. package/dist/workflow/auto-fix-bundler.js.map +1 -0
  122. package/dist/workflow/auto-fix.d.ts.map +1 -1
  123. package/dist/workflow/auto-fix.js +10 -3
  124. package/dist/workflow/auto-fix.js.map +1 -1
  125. package/dist/workflow/consensus.d.ts.map +1 -1
  126. package/dist/workflow/consensus.js +2 -0
  127. package/dist/workflow/consensus.js.map +1 -1
  128. package/dist/workflow/execution-mode.d.ts.map +1 -1
  129. package/dist/workflow/execution-mode.js +18 -0
  130. package/dist/workflow/execution-mode.js.map +1 -1
  131. package/dist/workflow/index.d.ts +4 -0
  132. package/dist/workflow/index.d.ts.map +1 -1
  133. package/dist/workflow/index.js +37 -0
  134. package/dist/workflow/index.js.map +1 -1
  135. package/dist/workflow/overview.d.ts +89 -0
  136. package/dist/workflow/overview.d.ts.map +1 -0
  137. package/dist/workflow/overview.js +358 -0
  138. package/dist/workflow/overview.js.map +1 -0
  139. package/dist/workflow/plan-mode.d.ts +6 -4
  140. package/dist/workflow/plan-mode.d.ts.map +1 -1
  141. package/dist/workflow/plan-mode.js +148 -6
  142. package/dist/workflow/plan-mode.js.map +1 -1
  143. package/dist/workflow/website-strategy.d.ts +79 -0
  144. package/dist/workflow/website-strategy.d.ts.map +1 -0
  145. package/dist/workflow/website-strategy.js +310 -0
  146. package/dist/workflow/website-strategy.js.map +1 -0
  147. package/dist/workflow/website-updater.d.ts +17 -0
  148. package/dist/workflow/website-updater.d.ts.map +1 -0
  149. package/dist/workflow/website-updater.js +116 -0
  150. package/dist/workflow/website-updater.js.map +1 -0
  151. package/dist/workflow/workflow-logger.d.ts +1 -1
  152. package/dist/workflow/workflow-logger.d.ts.map +1 -1
  153. package/dist/workflow/workflow-logger.js.map +1 -1
  154. package/package.json +1 -1
  155. package/src/adapters/gemini.ts +10 -4
  156. package/src/adapters/grok.ts +10 -4
  157. package/src/adapters/openai.ts +38 -6
  158. package/src/cli/commands/create.ts +58 -4
  159. package/src/cli/interactive.ts +143 -7
  160. package/src/generators/all.ts +49 -332
  161. package/src/generators/doc-parser.ts +449 -0
  162. package/src/generators/frontend-design-analyzer.ts +261 -0
  163. package/src/generators/shared-packages.ts +500 -0
  164. package/src/generators/templates/index.ts +8 -0
  165. package/src/generators/templates/website-components.ts +330 -0
  166. package/src/generators/templates/website-config.ts +444 -0
  167. package/src/generators/templates/website-conversion.ts +341 -0
  168. package/src/generators/templates/website-landing.ts +331 -0
  169. package/src/generators/templates/website-layout.ts +443 -0
  170. package/src/generators/templates/website-pricing.ts +330 -0
  171. package/src/generators/templates/website-sections.ts +541 -0
  172. package/src/generators/templates/website-seo.ts +370 -0
  173. package/src/generators/templates/website.ts +38 -905
  174. package/src/generators/website-content-scanner.ts +208 -0
  175. package/src/generators/website-context.ts +493 -0
  176. package/src/generators/website-debug.ts +130 -0
  177. package/src/generators/website.ts +178 -20
  178. package/src/generators/workspace-root.ts +113 -0
  179. package/src/state/index.ts +56 -0
  180. package/src/types/consensus.ts +3 -0
  181. package/src/types/website-strategy.ts +243 -0
  182. package/src/types/workflow.ts +21 -0
  183. package/src/upgrade/handlers.ts +65 -0
  184. package/src/workflow/auto-fix-bundler.ts +392 -0
  185. package/src/workflow/auto-fix.ts +11 -3
  186. package/src/workflow/consensus.ts +2 -0
  187. package/src/workflow/execution-mode.ts +21 -0
  188. package/src/workflow/index.ts +37 -0
  189. package/src/workflow/overview.ts +475 -0
  190. package/src/workflow/plan-mode.ts +193 -8
  191. package/src/workflow/website-strategy.ts +379 -0
  192. package/src/workflow/website-updater.ts +142 -0
  193. package/src/workflow/workflow-logger.ts +1 -0
  194. package/tests/adapters/persona-switching.test.ts +63 -0
  195. package/tests/cli/project-naming.test.ts +136 -0
  196. package/tests/generators/doc-parser.test.ts +121 -0
  197. package/tests/generators/frontend-design-analyzer.test.ts +90 -0
  198. package/tests/generators/quality-gate.test.ts +183 -0
  199. package/tests/generators/shared-packages.test.ts +83 -0
  200. package/tests/generators/website-components.test.ts +159 -0
  201. package/tests/generators/website-config.test.ts +84 -0
  202. package/tests/generators/website-content-scanner.test.ts +181 -0
  203. package/tests/generators/website-context.test.ts +331 -0
  204. package/tests/generators/website-debug.test.ts +77 -0
  205. package/tests/generators/website-landing.test.ts +188 -0
  206. package/tests/generators/website-pricing.test.ts +98 -0
  207. package/tests/generators/website-sections.test.ts +245 -0
  208. package/tests/generators/website-seo-quality.test.ts +246 -0
  209. package/tests/generators/workspace-root.test.ts +105 -0
  210. package/tests/upgrade/handlers.test.ts +162 -0
  211. package/tests/workflow/auto-fix-bundler.test.ts +242 -0
  212. package/tests/workflow/overview.test.ts +392 -0
  213. package/tests/workflow/plan-mode.test.ts +111 -1
  214. package/tests/workflow/website-strategy.test.ts +246 -0
@@ -9,6 +9,13 @@ import type { ProjectSpec, WorkspaceConfig } from '../types/project.js';
9
9
  import type { GenerationResult } from './python.js';
10
10
  import { generateFullstackProject } from './fullstack.js';
11
11
  import { generateWebsiteProject } from './website.js';
12
+ import type { WebsiteContentContext } from './website-context.js';
13
+ import { buildWebsiteContext, validateWebsiteContext } from './website-context.js';
14
+ import {
15
+ generateDesignTokensPackage as generateDesignTokensPackageImpl,
16
+ generateUiPackage as generateUiPackageImpl,
17
+ } from './shared-packages.js';
18
+ import type { BrandColorOptions } from './shared-packages.js';
12
19
 
13
20
  /**
14
21
  * Options for all project generation
@@ -17,6 +24,8 @@ export interface AllGeneratorOptions {
17
24
  skipWebsite?: boolean;
18
25
  skipSharedPackages?: boolean;
19
26
  includeExamples?: boolean;
27
+ /** Content context from user docs for populating website templates */
28
+ contentContext?: WebsiteContentContext;
20
29
  }
21
30
 
22
31
  /**
@@ -341,346 +350,25 @@ Generated by [Popeye CLI](https://github.com/popeye-cli/popeye)
341
350
 
342
351
  /**
343
352
  * Generate design tokens package
353
+ * Delegates to shared-packages.ts with optional brand color passthrough
344
354
  */
345
- export function generateDesignTokensPackage(projectName: string): {
355
+ export function generateDesignTokensPackage(
356
+ projectName: string,
357
+ brandColors?: BrandColorOptions
358
+ ): {
346
359
  files: Array<{ path: string; content: string }>;
347
360
  } {
348
- return {
349
- files: [
350
- {
351
- path: 'package.json',
352
- content: JSON.stringify(
353
- {
354
- name: `@${projectName}/design-tokens`,
355
- version: '1.0.0',
356
- type: 'module',
357
- main: './dist/index.js',
358
- types: './dist/index.d.ts',
359
- exports: {
360
- '.': './dist/index.js',
361
- './tailwind': './dist/tailwind-preset.js',
362
- },
363
- scripts: {
364
- build: 'tsc',
365
- dev: 'tsc --watch',
366
- },
367
- devDependencies: {
368
- typescript: '^5.3.3',
369
- },
370
- },
371
- null,
372
- 2
373
- ),
374
- },
375
- {
376
- path: 'tsconfig.json',
377
- content: JSON.stringify(
378
- {
379
- compilerOptions: {
380
- target: 'ES2020',
381
- module: 'ESNext',
382
- moduleResolution: 'bundler',
383
- declaration: true,
384
- outDir: './dist',
385
- strict: true,
386
- esModuleInterop: true,
387
- skipLibCheck: true,
388
- },
389
- include: ['src'],
390
- },
391
- null,
392
- 2
393
- ),
394
- },
395
- {
396
- path: 'src/index.ts',
397
- content: `/**
398
- * Design tokens for ${projectName}
399
- */
400
-
401
- export * from './colors.js';
402
- export * from './typography.js';
403
- `,
404
- },
405
- {
406
- path: 'src/colors.ts',
407
- content: `/**
408
- * Color palette
409
- */
410
-
411
- export const colors = {
412
- primary: {
413
- 50: '#f0f9ff',
414
- 100: '#e0f2fe',
415
- 200: '#bae6fd',
416
- 300: '#7dd3fc',
417
- 400: '#38bdf8',
418
- 500: '#0ea5e9',
419
- 600: '#0284c7',
420
- 700: '#0369a1',
421
- 800: '#075985',
422
- 900: '#0c4a6e',
423
- },
424
- secondary: {
425
- 50: '#f8fafc',
426
- 100: '#f1f5f9',
427
- 200: '#e2e8f0',
428
- 300: '#cbd5e1',
429
- 400: '#94a3b8',
430
- 500: '#64748b',
431
- 600: '#475569',
432
- 700: '#334155',
433
- 800: '#1e293b',
434
- 900: '#0f172a',
435
- },
436
- } as const;
437
-
438
- export type ColorScale = typeof colors.primary;
439
- export type Colors = typeof colors;
440
- `,
441
- },
442
- {
443
- path: 'src/typography.ts',
444
- content: `/**
445
- * Typography settings
446
- */
447
-
448
- export const typography = {
449
- fontFamily: {
450
- sans: ['Inter', 'system-ui', 'sans-serif'],
451
- mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
452
- },
453
- fontSize: {
454
- xs: ['0.75rem', { lineHeight: '1rem' }],
455
- sm: ['0.875rem', { lineHeight: '1.25rem' }],
456
- base: ['1rem', { lineHeight: '1.5rem' }],
457
- lg: ['1.125rem', { lineHeight: '1.75rem' }],
458
- xl: ['1.25rem', { lineHeight: '1.75rem' }],
459
- '2xl': ['1.5rem', { lineHeight: '2rem' }],
460
- '3xl': ['1.875rem', { lineHeight: '2.25rem' }],
461
- '4xl': ['2.25rem', { lineHeight: '2.5rem' }],
462
- '5xl': ['3rem', { lineHeight: '1' }],
463
- '6xl': ['3.75rem', { lineHeight: '1' }],
464
- },
465
- } as const;
466
-
467
- export type Typography = typeof typography;
468
- `,
469
- },
470
- {
471
- path: 'src/tailwind-preset.ts',
472
- content: `/**
473
- * Tailwind CSS preset with design tokens
474
- */
475
-
476
- import { colors } from './colors.js';
477
- import { typography } from './typography.js';
478
-
479
- export const preset = {
480
- theme: {
481
- extend: {
482
- colors,
483
- fontFamily: typography.fontFamily,
484
- fontSize: typography.fontSize,
485
- },
486
- },
487
- };
488
-
489
- export default preset;
490
- `,
491
- },
492
- ],
493
- };
361
+ return generateDesignTokensPackageImpl(projectName, brandColors);
494
362
  }
495
363
 
496
364
  /**
497
365
  * Generate UI components package
366
+ * Delegates to shared-packages.ts
498
367
  */
499
368
  export function generateUiPackage(projectName: string): {
500
369
  files: Array<{ path: string; content: string }>;
501
370
  } {
502
- return {
503
- files: [
504
- {
505
- path: 'package.json',
506
- content: JSON.stringify(
507
- {
508
- name: `@${projectName}/ui`,
509
- version: '1.0.0',
510
- type: 'module',
511
- main: './dist/index.js',
512
- types: './dist/index.d.ts',
513
- exports: {
514
- '.': './dist/index.js',
515
- './button': './dist/button.js',
516
- './card': './dist/card.js',
517
- },
518
- scripts: {
519
- build: 'tsc',
520
- dev: 'tsc --watch',
521
- },
522
- dependencies: {
523
- clsx: '^2.1.0',
524
- 'tailwind-merge': '^2.2.0',
525
- },
526
- peerDependencies: {
527
- react: '>=18.0.0',
528
- 'react-dom': '>=18.0.0',
529
- },
530
- devDependencies: {
531
- '@types/react': '^18.2.0',
532
- '@types/react-dom': '^18.2.0',
533
- typescript: '^5.3.3',
534
- },
535
- },
536
- null,
537
- 2
538
- ),
539
- },
540
- {
541
- path: 'tsconfig.json',
542
- content: JSON.stringify(
543
- {
544
- compilerOptions: {
545
- target: 'ES2020',
546
- module: 'ESNext',
547
- moduleResolution: 'bundler',
548
- declaration: true,
549
- outDir: './dist',
550
- strict: true,
551
- esModuleInterop: true,
552
- skipLibCheck: true,
553
- jsx: 'react-jsx',
554
- },
555
- include: ['src'],
556
- },
557
- null,
558
- 2
559
- ),
560
- },
561
- {
562
- path: 'src/index.ts',
563
- content: `/**
564
- * Shared UI components for ${projectName}
565
- */
566
-
567
- export * from './button.js';
568
- export * from './card.js';
569
- export * from './utils.js';
570
- `,
571
- },
572
- {
573
- path: 'src/utils.ts',
574
- content: `import { clsx, type ClassValue } from 'clsx';
575
- import { twMerge } from 'tailwind-merge';
576
-
577
- export function cn(...inputs: ClassValue[]) {
578
- return twMerge(clsx(inputs));
579
- }
580
- `,
581
- },
582
- {
583
- path: 'src/button.tsx',
584
- content: `import * as React from 'react';
585
- import { cn } from './utils.js';
586
-
587
- export interface ButtonProps
588
- extends React.ButtonHTMLAttributes<HTMLButtonElement> {
589
- variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
590
- size?: 'sm' | 'md' | 'lg';
591
- }
592
-
593
- export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
594
- ({ className, variant = 'primary', size = 'md', ...props }, ref) => {
595
- return (
596
- <button
597
- className={cn(
598
- 'inline-flex items-center justify-center rounded-md font-medium transition-colors',
599
- 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
600
- 'disabled:pointer-events-none disabled:opacity-50',
601
- {
602
- // Variants
603
- 'bg-primary-600 text-white hover:bg-primary-500': variant === 'primary',
604
- 'bg-secondary-100 text-secondary-900 hover:bg-secondary-200': variant === 'secondary',
605
- 'border border-secondary-300 bg-transparent hover:bg-secondary-50': variant === 'outline',
606
- 'bg-transparent hover:bg-secondary-100': variant === 'ghost',
607
- // Sizes
608
- 'h-8 px-3 text-sm': size === 'sm',
609
- 'h-10 px-4 text-sm': size === 'md',
610
- 'h-12 px-6 text-base': size === 'lg',
611
- },
612
- className
613
- )}
614
- ref={ref}
615
- {...props}
616
- />
617
- );
618
- }
619
- );
620
-
621
- Button.displayName = 'Button';
622
- `,
623
- },
624
- {
625
- path: 'src/card.tsx',
626
- content: `import * as React from 'react';
627
- import { cn } from './utils.js';
628
-
629
- export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {}
630
-
631
- export const Card = React.forwardRef<HTMLDivElement, CardProps>(
632
- ({ className, ...props }, ref) => (
633
- <div
634
- ref={ref}
635
- className={cn(
636
- 'rounded-lg border border-secondary-200 bg-white shadow-sm',
637
- className
638
- )}
639
- {...props}
640
- />
641
- )
642
- );
643
-
644
- Card.displayName = 'Card';
645
-
646
- export const CardHeader = React.forwardRef<
647
- HTMLDivElement,
648
- React.HTMLAttributes<HTMLDivElement>
649
- >(({ className, ...props }, ref) => (
650
- <div
651
- ref={ref}
652
- className={cn('flex flex-col space-y-1.5 p-6', className)}
653
- {...props}
654
- />
655
- ));
656
-
657
- CardHeader.displayName = 'CardHeader';
658
-
659
- export const CardTitle = React.forwardRef<
660
- HTMLParagraphElement,
661
- React.HTMLAttributes<HTMLHeadingElement>
662
- >(({ className, ...props }, ref) => (
663
- <h3
664
- ref={ref}
665
- className={cn('text-lg font-semibold leading-none tracking-tight', className)}
666
- {...props}
667
- />
668
- ));
669
-
670
- CardTitle.displayName = 'CardTitle';
671
-
672
- export const CardContent = React.forwardRef<
673
- HTMLDivElement,
674
- React.HTMLAttributes<HTMLDivElement>
675
- >(({ className, ...props }, ref) => (
676
- <div ref={ref} className={cn('p-6 pt-0', className)} {...props} />
677
- ));
678
-
679
- CardContent.displayName = 'CardContent';
680
- `,
681
- },
682
- ],
683
- };
371
+ return generateUiPackageImpl(projectName);
684
372
  }
685
373
 
686
374
  /**
@@ -692,7 +380,8 @@ CardContent.displayName = 'CardContent';
692
380
  */
693
381
  export async function generateAllProject(
694
382
  spec: ProjectSpec,
695
- outputDir: string
383
+ outputDir: string,
384
+ options: AllGeneratorOptions = {}
696
385
  ): Promise<GenerationResult> {
697
386
  const projectName = spec.name || 'my-project';
698
387
  const projectDir = path.join(outputDir, projectName);
@@ -707,6 +396,30 @@ export async function generateAllProject(
707
396
  await ensureDir(path.join(projectDir, 'packages', 'contracts'));
708
397
  await ensureDir(path.join(projectDir, '.popeye'));
709
398
 
399
+ // Auto-build content context if not provided
400
+ let contentContext = options.contentContext;
401
+ let contextWarning: string | undefined;
402
+ if (!contentContext) {
403
+ try {
404
+ contentContext = await buildWebsiteContext(projectDir, projectName);
405
+ } catch (e) {
406
+ contextWarning = e instanceof Error ? e.message : 'Unknown error building website context';
407
+ // Proceed with defaults, but warning is logged below
408
+ }
409
+ }
410
+ if (contextWarning) {
411
+ // Log warning so user sees it, but don't block generation
412
+ console.warn(`[website-context] Warning: ${contextWarning}`);
413
+ }
414
+
415
+ // Soft validation: log quality issues without blocking monorepo generation
416
+ if (contentContext) {
417
+ const validation = validateWebsiteContext(contentContext, projectName);
418
+ for (const issue of [...validation.issues, ...validation.warnings]) {
419
+ console.warn(`[website-context] ${issue}`);
420
+ }
421
+ }
422
+
710
423
  // Generate fullstack first (creates apps/frontend and apps/backend)
711
424
  const fullstackResult = await generateFullstackProject(spec, outputDir);
712
425
  if (!fullstackResult.success) {
@@ -720,6 +433,7 @@ export async function generateAllProject(
720
433
  workspaceMode: true,
721
434
  skipDocker: false, // Website needs its own Dockerfile
722
435
  skipReadme: false,
436
+ contentContext: contentContext,
723
437
  });
724
438
  if (!websiteResult.success) {
725
439
  return {
@@ -729,8 +443,11 @@ export async function generateAllProject(
729
443
  }
730
444
  filesCreated.push(...websiteResult.filesCreated);
731
445
 
732
- // Generate shared packages
733
- const designTokens = generateDesignTokensPackage(projectName);
446
+ // Generate shared packages (pass brand colors if available)
447
+ const brandColors: BrandColorOptions | undefined = contentContext?.brand?.primaryColor
448
+ ? { primaryColor: contentContext.brand.primaryColor }
449
+ : undefined;
450
+ const designTokens = generateDesignTokensPackage(projectName, brandColors);
734
451
  for (const file of designTokens.files) {
735
452
  const filePath = path.join(projectDir, 'packages', 'design-tokens', file.path);
736
453
  await ensureDir(path.dirname(filePath));