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.
- package/CHANGELOG.md +54 -0
- package/README.md +264 -63
- package/dist/adapters/gemini.d.ts +1 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +9 -4
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.d.ts +1 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +9 -4
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +35 -9
- package/dist/adapters/openai.js.map +1 -1
- package/dist/cli/commands/create.d.ts.map +1 -1
- package/dist/cli/commands/create.js +54 -4
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/interactive.d.ts +29 -0
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +132 -7
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/all.d.ts +8 -2
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +37 -316
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/doc-parser.d.ts +64 -0
- package/dist/generators/doc-parser.d.ts.map +1 -0
- package/dist/generators/doc-parser.js +407 -0
- package/dist/generators/doc-parser.js.map +1 -0
- package/dist/generators/frontend-design-analyzer.d.ts +30 -0
- package/dist/generators/frontend-design-analyzer.d.ts.map +1 -0
- package/dist/generators/frontend-design-analyzer.js +208 -0
- package/dist/generators/frontend-design-analyzer.js.map +1 -0
- package/dist/generators/shared-packages.d.ts +45 -0
- package/dist/generators/shared-packages.d.ts.map +1 -0
- package/dist/generators/shared-packages.js +456 -0
- package/dist/generators/shared-packages.js.map +1 -0
- package/dist/generators/templates/index.d.ts +8 -0
- package/dist/generators/templates/index.d.ts.map +1 -1
- package/dist/generators/templates/index.js +8 -0
- package/dist/generators/templates/index.js.map +1 -1
- package/dist/generators/templates/website-components.d.ts +33 -0
- package/dist/generators/templates/website-components.d.ts.map +1 -0
- package/dist/generators/templates/website-components.js +303 -0
- package/dist/generators/templates/website-components.js.map +1 -0
- package/dist/generators/templates/website-config.d.ts +55 -0
- package/dist/generators/templates/website-config.d.ts.map +1 -0
- package/dist/generators/templates/website-config.js +425 -0
- package/dist/generators/templates/website-config.js.map +1 -0
- package/dist/generators/templates/website-conversion.d.ts +27 -0
- package/dist/generators/templates/website-conversion.d.ts.map +1 -0
- package/dist/generators/templates/website-conversion.js +326 -0
- package/dist/generators/templates/website-conversion.js.map +1 -0
- package/dist/generators/templates/website-landing.d.ts +24 -0
- package/dist/generators/templates/website-landing.d.ts.map +1 -0
- package/dist/generators/templates/website-landing.js +276 -0
- package/dist/generators/templates/website-landing.js.map +1 -0
- package/dist/generators/templates/website-layout.d.ts +42 -0
- package/dist/generators/templates/website-layout.d.ts.map +1 -0
- package/dist/generators/templates/website-layout.js +408 -0
- package/dist/generators/templates/website-layout.js.map +1 -0
- package/dist/generators/templates/website-pricing.d.ts +11 -0
- package/dist/generators/templates/website-pricing.d.ts.map +1 -0
- package/dist/generators/templates/website-pricing.js +313 -0
- package/dist/generators/templates/website-pricing.js.map +1 -0
- package/dist/generators/templates/website-sections.d.ts +102 -0
- package/dist/generators/templates/website-sections.d.ts.map +1 -0
- package/dist/generators/templates/website-sections.js +444 -0
- package/dist/generators/templates/website-sections.js.map +1 -0
- package/dist/generators/templates/website-seo.d.ts +76 -0
- package/dist/generators/templates/website-seo.d.ts.map +1 -0
- package/dist/generators/templates/website-seo.js +326 -0
- package/dist/generators/templates/website-seo.js.map +1 -0
- package/dist/generators/templates/website.d.ts +10 -83
- package/dist/generators/templates/website.d.ts.map +1 -1
- package/dist/generators/templates/website.js +12 -875
- package/dist/generators/templates/website.js.map +1 -1
- package/dist/generators/website-content-scanner.d.ts +37 -0
- package/dist/generators/website-content-scanner.d.ts.map +1 -0
- package/dist/generators/website-content-scanner.js +165 -0
- package/dist/generators/website-content-scanner.js.map +1 -0
- package/dist/generators/website-context.d.ts +119 -0
- package/dist/generators/website-context.d.ts.map +1 -0
- package/dist/generators/website-context.js +350 -0
- package/dist/generators/website-context.js.map +1 -0
- package/dist/generators/website-debug.d.ts +68 -0
- package/dist/generators/website-debug.d.ts.map +1 -0
- package/dist/generators/website-debug.js +93 -0
- package/dist/generators/website-debug.js.map +1 -0
- package/dist/generators/website.d.ts +5 -0
- package/dist/generators/website.d.ts.map +1 -1
- package/dist/generators/website.js +136 -11
- package/dist/generators/website.js.map +1 -1
- package/dist/generators/workspace-root.d.ts +27 -0
- package/dist/generators/workspace-root.d.ts.map +1 -0
- package/dist/generators/workspace-root.js +100 -0
- package/dist/generators/workspace-root.js.map +1 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +40 -0
- package/dist/state/index.js.map +1 -1
- package/dist/types/consensus.d.ts +3 -0
- package/dist/types/consensus.d.ts.map +1 -1
- package/dist/types/consensus.js +1 -0
- package/dist/types/consensus.js.map +1 -1
- package/dist/types/website-strategy.d.ts +263 -0
- package/dist/types/website-strategy.d.ts.map +1 -0
- package/dist/types/website-strategy.js +105 -0
- package/dist/types/website-strategy.js.map +1 -0
- package/dist/types/workflow.d.ts +21 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +8 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/upgrade/handlers.d.ts +15 -0
- package/dist/upgrade/handlers.d.ts.map +1 -1
- package/dist/upgrade/handlers.js +52 -0
- package/dist/upgrade/handlers.js.map +1 -1
- package/dist/workflow/auto-fix-bundler.d.ts +37 -0
- package/dist/workflow/auto-fix-bundler.d.ts.map +1 -0
- package/dist/workflow/auto-fix-bundler.js +320 -0
- package/dist/workflow/auto-fix-bundler.js.map +1 -0
- package/dist/workflow/auto-fix.d.ts.map +1 -1
- package/dist/workflow/auto-fix.js +10 -3
- package/dist/workflow/auto-fix.js.map +1 -1
- package/dist/workflow/consensus.d.ts.map +1 -1
- package/dist/workflow/consensus.js +2 -0
- package/dist/workflow/consensus.js.map +1 -1
- package/dist/workflow/execution-mode.d.ts.map +1 -1
- package/dist/workflow/execution-mode.js +18 -0
- package/dist/workflow/execution-mode.js.map +1 -1
- package/dist/workflow/index.d.ts +4 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +37 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/overview.d.ts +89 -0
- package/dist/workflow/overview.d.ts.map +1 -0
- package/dist/workflow/overview.js +358 -0
- package/dist/workflow/overview.js.map +1 -0
- package/dist/workflow/plan-mode.d.ts +6 -4
- package/dist/workflow/plan-mode.d.ts.map +1 -1
- package/dist/workflow/plan-mode.js +148 -6
- package/dist/workflow/plan-mode.js.map +1 -1
- package/dist/workflow/website-strategy.d.ts +79 -0
- package/dist/workflow/website-strategy.d.ts.map +1 -0
- package/dist/workflow/website-strategy.js +310 -0
- package/dist/workflow/website-strategy.js.map +1 -0
- package/dist/workflow/website-updater.d.ts +17 -0
- package/dist/workflow/website-updater.d.ts.map +1 -0
- package/dist/workflow/website-updater.js +116 -0
- package/dist/workflow/website-updater.js.map +1 -0
- package/dist/workflow/workflow-logger.d.ts +1 -1
- package/dist/workflow/workflow-logger.d.ts.map +1 -1
- package/dist/workflow/workflow-logger.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/gemini.ts +10 -4
- package/src/adapters/grok.ts +10 -4
- package/src/adapters/openai.ts +38 -6
- package/src/cli/commands/create.ts +58 -4
- package/src/cli/interactive.ts +143 -7
- package/src/generators/all.ts +49 -332
- package/src/generators/doc-parser.ts +449 -0
- package/src/generators/frontend-design-analyzer.ts +261 -0
- package/src/generators/shared-packages.ts +500 -0
- package/src/generators/templates/index.ts +8 -0
- package/src/generators/templates/website-components.ts +330 -0
- package/src/generators/templates/website-config.ts +444 -0
- package/src/generators/templates/website-conversion.ts +341 -0
- package/src/generators/templates/website-landing.ts +331 -0
- package/src/generators/templates/website-layout.ts +443 -0
- package/src/generators/templates/website-pricing.ts +330 -0
- package/src/generators/templates/website-sections.ts +541 -0
- package/src/generators/templates/website-seo.ts +370 -0
- package/src/generators/templates/website.ts +38 -905
- package/src/generators/website-content-scanner.ts +208 -0
- package/src/generators/website-context.ts +493 -0
- package/src/generators/website-debug.ts +130 -0
- package/src/generators/website.ts +178 -20
- package/src/generators/workspace-root.ts +113 -0
- package/src/state/index.ts +56 -0
- package/src/types/consensus.ts +3 -0
- package/src/types/website-strategy.ts +243 -0
- package/src/types/workflow.ts +21 -0
- package/src/upgrade/handlers.ts +65 -0
- package/src/workflow/auto-fix-bundler.ts +392 -0
- package/src/workflow/auto-fix.ts +11 -3
- package/src/workflow/consensus.ts +2 -0
- package/src/workflow/execution-mode.ts +21 -0
- package/src/workflow/index.ts +37 -0
- package/src/workflow/overview.ts +475 -0
- package/src/workflow/plan-mode.ts +193 -8
- package/src/workflow/website-strategy.ts +379 -0
- package/src/workflow/website-updater.ts +142 -0
- package/src/workflow/workflow-logger.ts +1 -0
- package/tests/adapters/persona-switching.test.ts +63 -0
- package/tests/cli/project-naming.test.ts +136 -0
- package/tests/generators/doc-parser.test.ts +121 -0
- package/tests/generators/frontend-design-analyzer.test.ts +90 -0
- package/tests/generators/quality-gate.test.ts +183 -0
- package/tests/generators/shared-packages.test.ts +83 -0
- package/tests/generators/website-components.test.ts +159 -0
- package/tests/generators/website-config.test.ts +84 -0
- package/tests/generators/website-content-scanner.test.ts +181 -0
- package/tests/generators/website-context.test.ts +331 -0
- package/tests/generators/website-debug.test.ts +77 -0
- package/tests/generators/website-landing.test.ts +188 -0
- package/tests/generators/website-pricing.test.ts +98 -0
- package/tests/generators/website-sections.test.ts +245 -0
- package/tests/generators/website-seo-quality.test.ts +246 -0
- package/tests/generators/workspace-root.test.ts +105 -0
- package/tests/upgrade/handlers.test.ts +162 -0
- package/tests/workflow/auto-fix-bundler.test.ts +242 -0
- package/tests/workflow/overview.test.ts +392 -0
- package/tests/workflow/plan-mode.test.ts +111 -1
- package/tests/workflow/website-strategy.test.ts +246 -0
package/src/generators/all.ts
CHANGED
|
@@ -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(
|
|
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
|
|
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));
|