popeye-cli 1.4.7 → 1.5.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 (134) hide show
  1. package/README.md +222 -63
  2. package/dist/adapters/gemini.d.ts +1 -0
  3. package/dist/adapters/gemini.d.ts.map +1 -1
  4. package/dist/adapters/gemini.js +9 -4
  5. package/dist/adapters/gemini.js.map +1 -1
  6. package/dist/adapters/grok.d.ts +1 -0
  7. package/dist/adapters/grok.d.ts.map +1 -1
  8. package/dist/adapters/grok.js +9 -4
  9. package/dist/adapters/grok.js.map +1 -1
  10. package/dist/adapters/openai.d.ts +1 -1
  11. package/dist/adapters/openai.d.ts.map +1 -1
  12. package/dist/adapters/openai.js +35 -9
  13. package/dist/adapters/openai.js.map +1 -1
  14. package/dist/cli/interactive.d.ts.map +1 -1
  15. package/dist/cli/interactive.js +42 -0
  16. package/dist/cli/interactive.js.map +1 -1
  17. package/dist/generators/all.d.ts +4 -1
  18. package/dist/generators/all.d.ts.map +1 -1
  19. package/dist/generators/all.js +2 -1
  20. package/dist/generators/all.js.map +1 -1
  21. package/dist/generators/doc-parser.d.ts +49 -0
  22. package/dist/generators/doc-parser.d.ts.map +1 -0
  23. package/dist/generators/doc-parser.js +336 -0
  24. package/dist/generators/doc-parser.js.map +1 -0
  25. package/dist/generators/templates/index.d.ts +4 -0
  26. package/dist/generators/templates/index.d.ts.map +1 -1
  27. package/dist/generators/templates/index.js +4 -0
  28. package/dist/generators/templates/index.js.map +1 -1
  29. package/dist/generators/templates/website-components.d.ts +33 -0
  30. package/dist/generators/templates/website-components.d.ts.map +1 -0
  31. package/dist/generators/templates/website-components.js +278 -0
  32. package/dist/generators/templates/website-components.js.map +1 -0
  33. package/dist/generators/templates/website-config.d.ts +41 -0
  34. package/dist/generators/templates/website-config.d.ts.map +1 -0
  35. package/dist/generators/templates/website-config.js +283 -0
  36. package/dist/generators/templates/website-config.js.map +1 -0
  37. package/dist/generators/templates/website-conversion.d.ts +27 -0
  38. package/dist/generators/templates/website-conversion.d.ts.map +1 -0
  39. package/dist/generators/templates/website-conversion.js +326 -0
  40. package/dist/generators/templates/website-conversion.js.map +1 -0
  41. package/dist/generators/templates/website-seo.d.ts +76 -0
  42. package/dist/generators/templates/website-seo.d.ts.map +1 -0
  43. package/dist/generators/templates/website-seo.js +326 -0
  44. package/dist/generators/templates/website-seo.js.map +1 -0
  45. package/dist/generators/templates/website.d.ts +14 -47
  46. package/dist/generators/templates/website.d.ts.map +1 -1
  47. package/dist/generators/templates/website.js +412 -499
  48. package/dist/generators/templates/website.js.map +1 -1
  49. package/dist/generators/website-context.d.ts +83 -0
  50. package/dist/generators/website-context.d.ts.map +1 -0
  51. package/dist/generators/website-context.js +190 -0
  52. package/dist/generators/website-context.js.map +1 -0
  53. package/dist/generators/website.d.ts +3 -0
  54. package/dist/generators/website.d.ts.map +1 -1
  55. package/dist/generators/website.js +73 -10
  56. package/dist/generators/website.js.map +1 -1
  57. package/dist/state/index.d.ts +27 -0
  58. package/dist/state/index.d.ts.map +1 -1
  59. package/dist/state/index.js +30 -0
  60. package/dist/state/index.js.map +1 -1
  61. package/dist/types/consensus.d.ts +3 -0
  62. package/dist/types/consensus.d.ts.map +1 -1
  63. package/dist/types/consensus.js +1 -0
  64. package/dist/types/consensus.js.map +1 -1
  65. package/dist/types/website-strategy.d.ts +263 -0
  66. package/dist/types/website-strategy.d.ts.map +1 -0
  67. package/dist/types/website-strategy.js +105 -0
  68. package/dist/types/website-strategy.js.map +1 -0
  69. package/dist/types/workflow.d.ts +15 -0
  70. package/dist/types/workflow.d.ts.map +1 -1
  71. package/dist/types/workflow.js +6 -0
  72. package/dist/types/workflow.js.map +1 -1
  73. package/dist/workflow/consensus.d.ts.map +1 -1
  74. package/dist/workflow/consensus.js +2 -0
  75. package/dist/workflow/consensus.js.map +1 -1
  76. package/dist/workflow/execution-mode.d.ts.map +1 -1
  77. package/dist/workflow/execution-mode.js +18 -0
  78. package/dist/workflow/execution-mode.js.map +1 -1
  79. package/dist/workflow/index.d.ts +3 -0
  80. package/dist/workflow/index.d.ts.map +1 -1
  81. package/dist/workflow/index.js +25 -0
  82. package/dist/workflow/index.js.map +1 -1
  83. package/dist/workflow/overview.d.ts +89 -0
  84. package/dist/workflow/overview.d.ts.map +1 -0
  85. package/dist/workflow/overview.js +354 -0
  86. package/dist/workflow/overview.js.map +1 -0
  87. package/dist/workflow/plan-mode.d.ts +2 -1
  88. package/dist/workflow/plan-mode.d.ts.map +1 -1
  89. package/dist/workflow/plan-mode.js +83 -5
  90. package/dist/workflow/plan-mode.js.map +1 -1
  91. package/dist/workflow/website-strategy.d.ts +70 -0
  92. package/dist/workflow/website-strategy.d.ts.map +1 -0
  93. package/dist/workflow/website-strategy.js +238 -0
  94. package/dist/workflow/website-strategy.js.map +1 -0
  95. package/dist/workflow/website-updater.d.ts +17 -0
  96. package/dist/workflow/website-updater.d.ts.map +1 -0
  97. package/dist/workflow/website-updater.js +105 -0
  98. package/dist/workflow/website-updater.js.map +1 -0
  99. package/dist/workflow/workflow-logger.d.ts +1 -1
  100. package/dist/workflow/workflow-logger.d.ts.map +1 -1
  101. package/dist/workflow/workflow-logger.js.map +1 -1
  102. package/package.json +1 -1
  103. package/src/adapters/gemini.ts +10 -4
  104. package/src/adapters/grok.ts +10 -4
  105. package/src/adapters/openai.ts +38 -6
  106. package/src/cli/interactive.ts +47 -0
  107. package/src/generators/all.ts +6 -1
  108. package/src/generators/doc-parser.ts +372 -0
  109. package/src/generators/templates/index.ts +4 -0
  110. package/src/generators/templates/website-components.ts +305 -0
  111. package/src/generators/templates/website-config.ts +291 -0
  112. package/src/generators/templates/website-conversion.ts +341 -0
  113. package/src/generators/templates/website-seo.ts +370 -0
  114. package/src/generators/templates/website.ts +451 -505
  115. package/src/generators/website-context.ts +265 -0
  116. package/src/generators/website.ts +109 -19
  117. package/src/state/index.ts +42 -0
  118. package/src/types/consensus.ts +3 -0
  119. package/src/types/website-strategy.ts +243 -0
  120. package/src/types/workflow.ts +15 -0
  121. package/src/workflow/consensus.ts +2 -0
  122. package/src/workflow/execution-mode.ts +21 -0
  123. package/src/workflow/index.ts +25 -0
  124. package/src/workflow/overview.ts +469 -0
  125. package/src/workflow/plan-mode.ts +115 -4
  126. package/src/workflow/website-strategy.ts +305 -0
  127. package/src/workflow/website-updater.ts +131 -0
  128. package/src/workflow/workflow-logger.ts +1 -0
  129. package/tests/adapters/persona-switching.test.ts +63 -0
  130. package/tests/generators/website-components.test.ts +159 -0
  131. package/tests/generators/website-context.test.ts +222 -0
  132. package/tests/generators/website-seo-quality.test.ts +246 -0
  133. package/tests/workflow/overview.test.ts +392 -0
  134. package/tests/workflow/website-strategy.test.ts +191 -0
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Shared website component templates
3
+ * Generates Header, Footer, and Navigation components with
4
+ * strategy-driven content, logo support, and mobile responsiveness
5
+ */
6
+ /**
7
+ * Escape a string for safe use inside JSX template literals
8
+ */
9
+ function escapeJsx(str) {
10
+ return str
11
+ .replace(/\\/g, '\\\\')
12
+ .replace(/'/g, "\\'")
13
+ .replace(/`/g, '\\`')
14
+ .replace(/\$/g, '\\$');
15
+ }
16
+ /**
17
+ * Generate website header component with logo, navigation, and CTA
18
+ *
19
+ * @param projectName - Project name for fallback display
20
+ * @param context - Optional content context
21
+ * @param strategy - Optional strategy for navigation and CTA
22
+ * @returns Header component source code
23
+ */
24
+ export function generateWebsiteHeader(projectName, context, strategy) {
25
+ const displayName = context?.productName || projectName
26
+ .split('-')
27
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
28
+ .join(' ');
29
+ const hasLogo = !!(context?.brandAssets?.logoOutputPath || context?.brand?.logoPath);
30
+ const logoPath = context?.brandAssets?.logoOutputPath
31
+ ? `/${context.brandAssets.logoOutputPath}`
32
+ : '/logo.svg';
33
+ // Build nav items from strategy or defaults
34
+ const navItems = strategy?.siteArchitecture.navigation || [
35
+ { label: 'Features', href: '/#features' },
36
+ { label: 'Pricing', href: '/pricing' },
37
+ { label: 'Docs', href: '/docs' },
38
+ { label: 'Blog', href: '/blog' },
39
+ ];
40
+ const navItemsStr = navItems
41
+ .map(item => ` { label: '${escapeJsx(item.label)}', href: '${escapeJsx(item.href)}' }`)
42
+ .join(',\n');
43
+ // CTA from strategy or default
44
+ const ctaText = strategy?.conversionStrategy.primaryCta.text || 'Get Started';
45
+ const ctaHref = strategy?.conversionStrategy.primaryCta.href || '/pricing';
46
+ // Logo rendering
47
+ const logoBlock = hasLogo
48
+ ? `<Image src="${logoPath}" alt="${escapeJsx(displayName)}" width={32} height={32} className="h-8 w-auto" />`
49
+ : `<span className="text-xl font-bold text-primary-600">${escapeJsx(displayName)}</span>`;
50
+ return `'use client';
51
+
52
+ import { useState } from 'react';
53
+ import Link from 'next/link';
54
+ ${hasLogo ? "import Image from 'next/image';" : ''}
55
+
56
+ const NAV_ITEMS = [
57
+ ${navItemsStr}
58
+ ];
59
+
60
+ /**
61
+ * Site header with logo, navigation links, mobile menu, and CTA
62
+ */
63
+ export default function Header() {
64
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
65
+
66
+ return (
67
+ <header className="sticky top-0 z-50 border-b border-gray-200 bg-white/80 backdrop-blur-sm">
68
+ <nav className="container flex h-16 items-center justify-between">
69
+ {/* Logo */}
70
+ <Link href="/" className="flex items-center gap-2">
71
+ ${logoBlock}
72
+ </Link>
73
+
74
+ {/* Desktop Navigation */}
75
+ <div className="hidden items-center gap-8 md:flex">
76
+ {NAV_ITEMS.map((item) => (
77
+ <Link
78
+ key={item.href}
79
+ href={item.href}
80
+ className="text-sm font-medium text-gray-700 hover:text-primary-600 transition-colors"
81
+ >
82
+ {item.label}
83
+ </Link>
84
+ ))}
85
+ <Link
86
+ href="${escapeJsx(ctaHref)}"
87
+ className="rounded-md bg-primary-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-primary-500 transition-colors"
88
+ >
89
+ ${escapeJsx(ctaText)}
90
+ </Link>
91
+ </div>
92
+
93
+ {/* Mobile Menu Button */}
94
+ <button
95
+ type="button"
96
+ className="md:hidden rounded-md p-2 text-gray-700"
97
+ onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
98
+ aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
99
+ aria-expanded={mobileMenuOpen}
100
+ >
101
+ <svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
102
+ {mobileMenuOpen ? (
103
+ <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
104
+ ) : (
105
+ <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
106
+ )}
107
+ </svg>
108
+ </button>
109
+ </nav>
110
+
111
+ {/* Mobile Menu */}
112
+ {mobileMenuOpen && (
113
+ <div className="border-t border-gray-200 bg-white px-4 py-4 md:hidden">
114
+ <div className="flex flex-col gap-4">
115
+ {NAV_ITEMS.map((item) => (
116
+ <Link
117
+ key={item.href}
118
+ href={item.href}
119
+ className="text-sm font-medium text-gray-700 hover:text-primary-600"
120
+ onClick={() => setMobileMenuOpen(false)}
121
+ >
122
+ {item.label}
123
+ </Link>
124
+ ))}
125
+ <Link
126
+ href="${escapeJsx(ctaHref)}"
127
+ className="rounded-md bg-primary-600 px-4 py-2 text-center text-sm font-semibold text-white"
128
+ onClick={() => setMobileMenuOpen(false)}
129
+ >
130
+ ${escapeJsx(ctaText)}
131
+ </Link>
132
+ </div>
133
+ </div>
134
+ )}
135
+ </header>
136
+ );
137
+ }
138
+ `;
139
+ }
140
+ /**
141
+ * Generate website footer component with multi-column sections
142
+ *
143
+ * @param projectName - Project name for copyright
144
+ * @param context - Optional content context
145
+ * @param strategy - Optional strategy for footer sections
146
+ * @returns Footer component source code
147
+ */
148
+ export function generateWebsiteFooter(projectName, context, strategy) {
149
+ const displayName = context?.productName || projectName
150
+ .split('-')
151
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
152
+ .join(' ');
153
+ // Build footer sections from strategy or defaults
154
+ const sections = strategy?.siteArchitecture.footerSections || [
155
+ {
156
+ title: 'Product',
157
+ links: [
158
+ { label: 'Features', href: '/#features' },
159
+ { label: 'Pricing', href: '/pricing' },
160
+ { label: 'Documentation', href: '/docs' },
161
+ ],
162
+ },
163
+ {
164
+ title: 'Resources',
165
+ links: [
166
+ { label: 'Blog', href: '/blog' },
167
+ { label: 'Support', href: '/contact' },
168
+ ],
169
+ },
170
+ {
171
+ title: 'Legal',
172
+ links: [
173
+ { label: 'Privacy Policy', href: '/privacy' },
174
+ { label: 'Terms of Service', href: '/terms' },
175
+ ],
176
+ },
177
+ ];
178
+ const sectionsStr = sections
179
+ .map(section => {
180
+ const linksStr = section.links
181
+ .map(link => ` { label: '${escapeJsx(link.label)}', href: '${escapeJsx(link.href)}' }`)
182
+ .join(',\n');
183
+ return ` {\n title: '${escapeJsx(section.title)}',\n links: [\n${linksStr}\n ],\n }`;
184
+ })
185
+ .join(',\n');
186
+ return `import Link from 'next/link';
187
+
188
+ const FOOTER_SECTIONS = [
189
+ ${sectionsStr}
190
+ ];
191
+
192
+ /**
193
+ * Site footer with multi-column link sections and copyright
194
+ */
195
+ export default function Footer() {
196
+ return (
197
+ <footer className="border-t border-gray-200 bg-gray-50">
198
+ <div className="container py-12">
199
+ <div className="grid grid-cols-2 gap-8 md:grid-cols-${Math.min(sections.length + 1, 4)}">
200
+ {/* Brand column */}
201
+ <div className="col-span-2 md:col-span-1">
202
+ <Link href="/" className="text-lg font-bold text-gray-900">
203
+ ${escapeJsx(displayName)}
204
+ </Link>
205
+ <p className="mt-2 text-sm text-gray-600">
206
+ ${context?.tagline ? escapeJsx(context.tagline) : 'Build something amazing.'}
207
+ </p>
208
+ </div>
209
+
210
+ {/* Link columns */}
211
+ {FOOTER_SECTIONS.map((section) => (
212
+ <div key={section.title}>
213
+ <h3 className="text-sm font-semibold text-gray-900">{section.title}</h3>
214
+ <ul className="mt-4 space-y-2">
215
+ {section.links.map((link) => (
216
+ <li key={link.href}>
217
+ <Link
218
+ href={link.href}
219
+ className="text-sm text-gray-600 hover:text-primary-600 transition-colors"
220
+ >
221
+ {link.label}
222
+ </Link>
223
+ </li>
224
+ ))}
225
+ </ul>
226
+ </div>
227
+ ))}
228
+ </div>
229
+
230
+ <div className="mt-12 border-t border-gray-200 pt-8">
231
+ <p className="text-center text-sm text-gray-500">
232
+ &copy; {new Date().getFullYear()} ${escapeJsx(displayName)}. All rights reserved.
233
+ </p>
234
+ </div>
235
+ </div>
236
+ </footer>
237
+ );
238
+ }
239
+ `;
240
+ }
241
+ /**
242
+ * Generate navigation config module
243
+ *
244
+ * @param strategy - Optional strategy for navigation items
245
+ * @returns Navigation config source code
246
+ */
247
+ export function generateWebsiteNavigation(strategy) {
248
+ const navItems = strategy?.siteArchitecture.navigation || [
249
+ { label: 'Features', href: '/#features' },
250
+ { label: 'Pricing', href: '/pricing' },
251
+ { label: 'Docs', href: '/docs' },
252
+ { label: 'Blog', href: '/blog' },
253
+ ];
254
+ const itemsStr = navItems
255
+ .map(item => {
256
+ const childrenStr = item.children && item.children.length > 0
257
+ ? `,\n children: [\n${item.children.map(c => ` { label: '${escapeJsx(c.label)}', href: '${escapeJsx(c.href)}' }`).join(',\n')}\n ]`
258
+ : '';
259
+ return ` { label: '${escapeJsx(item.label)}', href: '${escapeJsx(item.href)}'${childrenStr} }`;
260
+ })
261
+ .join(',\n');
262
+ return `/**
263
+ * Navigation configuration
264
+ * Exported for use in Header and mobile navigation components
265
+ */
266
+
267
+ export interface NavItem {
268
+ label: string;
269
+ href: string;
270
+ children?: NavItem[];
271
+ }
272
+
273
+ export const NAV_ITEMS: NavItem[] = [
274
+ ${itemsStr}
275
+ ];
276
+ `;
277
+ }
278
+ //# sourceMappingURL=website-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-components.js","sourceRoot":"","sources":["../../../src/generators/templates/website-components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG;SACP,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,OAA+B,EAC/B,QAAkC;IAElC,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,WAAW;SACpD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClD,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,IAAI,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,OAAO,EAAE,WAAW,EAAE,cAAc;QACnD,CAAC,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE;QAC1C,CAAC,CAAC,WAAW,CAAC;IAEhB,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,QAAQ,EAAE,gBAAgB,CAAC,UAAU,IAAI;QACxD,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE;QACzC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;QACtC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;QAChC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;KACjC,CAAC;IAEF,MAAM,WAAW,GAAG,QAAQ;SACzB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;SACvF,IAAI,CAAC,KAAK,CAAC,CAAC;IAEf,+BAA+B;IAC/B,MAAM,OAAO,GAAG,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,IAAI,IAAI,aAAa,CAAC;IAC9E,MAAM,OAAO,GAAG,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC;IAE3E,iBAAiB;IACjB,MAAM,SAAS,GAAG,OAAO;QACvB,CAAC,CAAC,eAAe,QAAQ,UAAU,SAAS,CAAC,WAAW,CAAC,oDAAoD;QAC7G,CAAC,CAAC,wDAAwD,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC;IAE5F,OAAO;;;;EAIP,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE;;;EAGhD,WAAW;;;;;;;;;;;;;;YAcD,SAAS;;;;;;;;;;;;;;;oBAeD,SAAS,CAAC,OAAO,CAAC;;;cAGxB,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAqCV,SAAS,CAAC,OAAO,CAAC;;;;gBAIxB,SAAS,CAAC,OAAO,CAAC;;;;;;;;CAQjC,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,OAA+B,EAC/B,QAAkC;IAElC,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,WAAW;SACpD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAClD,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,kDAAkD;IAClD,MAAM,QAAQ,GAAoB,QAAQ,EAAE,gBAAgB,CAAC,cAAc,IAAI;QAC7E;YACE,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE;gBACzC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;gBACtC,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE;aAC1C;SACF;QACD;YACE,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;gBAChC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;aACvC;SACF;QACD;YACE,KAAK,EAAE,OAAO;YACd,KAAK,EAAE;gBACL,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE;gBAC7C,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC9C;SACF;KACF,CAAC;IAEF,MAAM,WAAW,GAAG,QAAQ;SACzB,GAAG,CAAC,OAAO,CAAC,EAAE;QACb,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK;aAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAC3F,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,OAAO,oBAAoB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,QAAQ,eAAe,CAAC;IAClG,CAAC,CAAC;SACD,IAAI,CAAC,KAAK,CAAC,CAAC;IAEf,OAAO;;;EAGP,WAAW;;;;;;;;;;8DAUiD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;;;;gBAI9E,SAAS,CAAC,WAAW,CAAC;;;gBAGtB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;gDA0B1C,SAAS,CAAC,WAAW,CAAC;;;;;;;CAOrE,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAkC;IAElC,MAAM,QAAQ,GAAc,QAAQ,EAAE,gBAAgB,CAAC,UAAU,IAAI;QACnE,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE;QACzC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;QACtC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;QAChC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;KACjC,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ;SACtB,GAAG,CAAC,IAAI,CAAC,EAAE;QACV,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAC3D,CAAC,CAAC,uBAAuB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS;YAC9I,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,eAAe,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC;IAClG,CAAC,CAAC;SACD,IAAI,CAAC,KAAK,CAAC,CAAC;IAEf,OAAO;;;;;;;;;;;;EAYP,QAAQ;;CAET,CAAC;AACF,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Website configuration templates (non-content)
3
+ * Package configs, build tools, Docker, vitest, and env declarations
4
+ */
5
+ /**
6
+ * Generate Next.js package.json
7
+ */
8
+ export declare function generateWebsitePackageJson(projectName: string): string;
9
+ /**
10
+ * Generate Next.js config
11
+ */
12
+ export declare function generateNextConfig(): string;
13
+ /**
14
+ * Generate website tsconfig.json
15
+ */
16
+ export declare function generateWebsiteTsconfig(): string;
17
+ /**
18
+ * Generate Tailwind config for website
19
+ */
20
+ export declare function generateWebsiteTailwindConfig(): string;
21
+ /**
22
+ * Generate PostCSS config for website
23
+ */
24
+ export declare function generateWebsitePostcssConfig(): string;
25
+ /**
26
+ * Generate website Dockerfile
27
+ */
28
+ export declare function generateWebsiteDockerfile(): string;
29
+ /**
30
+ * Generate vitest config for website
31
+ */
32
+ export declare function generateWebsiteVitestConfig(): string;
33
+ /**
34
+ * Generate vitest setup for website
35
+ */
36
+ export declare function generateWebsiteVitestSetup(): string;
37
+ /**
38
+ * Generate Next.js environment declaration
39
+ */
40
+ export declare function generateWebsiteNextEnv(): string;
41
+ //# sourceMappingURL=website-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-config.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/website-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqCtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAwC3C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CA6BhD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAmCtD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAQrD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA4ClD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAoBpD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAsBnD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAO/C"}
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Website configuration templates (non-content)
3
+ * Package configs, build tools, Docker, vitest, and env declarations
4
+ */
5
+ /**
6
+ * Generate Next.js package.json
7
+ */
8
+ export function generateWebsitePackageJson(projectName) {
9
+ return `{
10
+ "name": "${projectName}-website",
11
+ "version": "1.0.0",
12
+ "private": true,
13
+ "scripts": {
14
+ "dev": "next dev -p 3001",
15
+ "build": "next build",
16
+ "start": "next start -p 3001",
17
+ "lint": "next lint",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "dependencies": {
23
+ "next": "^14.1.0",
24
+ "react": "^18.2.0",
25
+ "react-dom": "^18.2.0",
26
+ "lucide-react": "^0.312.0",
27
+ "clsx": "^2.1.0",
28
+ "tailwind-merge": "^2.2.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.11.0",
32
+ "@types/react": "^18.2.0",
33
+ "@types/react-dom": "^18.2.0",
34
+ "autoprefixer": "^10.4.17",
35
+ "postcss": "^8.4.33",
36
+ "tailwindcss": "^3.4.1",
37
+ "typescript": "^5.3.3",
38
+ "@testing-library/react": "^14.1.2",
39
+ "@vitejs/plugin-react": "^4.2.1",
40
+ "vitest": "^1.2.0",
41
+ "jsdom": "^24.0.0"
42
+ }
43
+ }
44
+ `;
45
+ }
46
+ /**
47
+ * Generate Next.js config
48
+ */
49
+ export function generateNextConfig() {
50
+ return `/** @type {import('next').NextConfig} */
51
+ const nextConfig = {
52
+ // Enable React Strict Mode for better development
53
+ reactStrictMode: true,
54
+
55
+ // Image optimization
56
+ images: {
57
+ domains: [],
58
+ formats: ['image/avif', 'image/webp'],
59
+ },
60
+
61
+ // Disable x-powered-by header
62
+ poweredByHeader: false,
63
+
64
+ // Trailing slash config
65
+ trailingSlash: false,
66
+
67
+ // Headers for security
68
+ async headers() {
69
+ return [
70
+ {
71
+ source: '/:path*',
72
+ headers: [
73
+ {
74
+ key: 'X-DNS-Prefetch-Control',
75
+ value: 'on',
76
+ },
77
+ {
78
+ key: 'X-Content-Type-Options',
79
+ value: 'nosniff',
80
+ },
81
+ ],
82
+ },
83
+ ];
84
+ },
85
+ };
86
+
87
+ module.exports = nextConfig;
88
+ `;
89
+ }
90
+ /**
91
+ * Generate website tsconfig.json
92
+ */
93
+ export function generateWebsiteTsconfig() {
94
+ return `{
95
+ "compilerOptions": {
96
+ "target": "ES2017",
97
+ "lib": ["dom", "dom.iterable", "esnext"],
98
+ "allowJs": true,
99
+ "skipLibCheck": true,
100
+ "strict": true,
101
+ "noEmit": true,
102
+ "esModuleInterop": true,
103
+ "module": "esnext",
104
+ "moduleResolution": "bundler",
105
+ "resolveJsonModule": true,
106
+ "isolatedModules": true,
107
+ "jsx": "preserve",
108
+ "incremental": true,
109
+ "plugins": [
110
+ {
111
+ "name": "next"
112
+ }
113
+ ],
114
+ "paths": {
115
+ "@/*": ["./src/*"]
116
+ }
117
+ },
118
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
119
+ "exclude": ["node_modules"]
120
+ }
121
+ `;
122
+ }
123
+ /**
124
+ * Generate Tailwind config for website
125
+ */
126
+ export function generateWebsiteTailwindConfig() {
127
+ return `import type { Config } from 'tailwindcss';
128
+
129
+ const config: Config = {
130
+ content: [
131
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
132
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
133
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
134
+ ],
135
+ theme: {
136
+ extend: {
137
+ colors: {
138
+ primary: {
139
+ 50: '#f0f9ff',
140
+ 100: '#e0f2fe',
141
+ 200: '#bae6fd',
142
+ 300: '#7dd3fc',
143
+ 400: '#38bdf8',
144
+ 500: '#0ea5e9',
145
+ 600: '#0284c7',
146
+ 700: '#0369a1',
147
+ 800: '#075985',
148
+ 900: '#0c4a6e',
149
+ },
150
+ },
151
+ fontFamily: {
152
+ sans: ['var(--font-inter)', 'system-ui', 'sans-serif'],
153
+ },
154
+ },
155
+ },
156
+ plugins: [],
157
+ };
158
+
159
+ export default config;
160
+ `;
161
+ }
162
+ /**
163
+ * Generate PostCSS config for website
164
+ */
165
+ export function generateWebsitePostcssConfig() {
166
+ return `module.exports = {
167
+ plugins: {
168
+ tailwindcss: {},
169
+ autoprefixer: {},
170
+ },
171
+ };
172
+ `;
173
+ }
174
+ /**
175
+ * Generate website Dockerfile
176
+ */
177
+ export function generateWebsiteDockerfile() {
178
+ return `# Build stage
179
+ FROM node:20-alpine AS builder
180
+
181
+ WORKDIR /app
182
+
183
+ # Copy package files
184
+ COPY package*.json ./
185
+
186
+ # Install dependencies
187
+ RUN npm ci
188
+
189
+ # Copy source
190
+ COPY . .
191
+
192
+ # Build
193
+ RUN npm run build
194
+
195
+ # Production stage
196
+ FROM node:20-alpine AS runner
197
+
198
+ WORKDIR /app
199
+
200
+ ENV NODE_ENV=production
201
+ ENV NEXT_TELEMETRY_DISABLED=1
202
+
203
+ # Create non-root user
204
+ RUN addgroup --system --gid 1001 nodejs
205
+ RUN adduser --system --uid 1001 nextjs
206
+
207
+ # Copy built assets
208
+ COPY --from=builder /app/public ./public
209
+ COPY --from=builder /app/.next/standalone ./
210
+ COPY --from=builder /app/.next/static ./.next/static
211
+
212
+ USER nextjs
213
+
214
+ EXPOSE 3000
215
+
216
+ ENV PORT=3000
217
+ ENV HOSTNAME="0.0.0.0"
218
+
219
+ CMD ["node", "server.js"]
220
+ `;
221
+ }
222
+ /**
223
+ * Generate vitest config for website
224
+ */
225
+ export function generateWebsiteVitestConfig() {
226
+ return `import { defineConfig } from 'vitest/config';
227
+ import react from '@vitejs/plugin-react';
228
+ import path from 'path';
229
+
230
+ export default defineConfig({
231
+ plugins: [react()],
232
+ test: {
233
+ environment: 'jsdom',
234
+ include: ['**/*.test.{ts,tsx}'],
235
+ globals: true,
236
+ setupFiles: ['./tests/setup.ts'],
237
+ },
238
+ resolve: {
239
+ alias: {
240
+ '@': path.resolve(__dirname, './src'),
241
+ },
242
+ },
243
+ });
244
+ `;
245
+ }
246
+ /**
247
+ * Generate vitest setup for website
248
+ */
249
+ export function generateWebsiteVitestSetup() {
250
+ return `import '@testing-library/jest-dom';
251
+
252
+ // Mock next/navigation
253
+ vi.mock('next/navigation', () => ({
254
+ useRouter: () => ({
255
+ push: vi.fn(),
256
+ replace: vi.fn(),
257
+ prefetch: vi.fn(),
258
+ }),
259
+ useSearchParams: () => new URLSearchParams(),
260
+ usePathname: () => '/',
261
+ }));
262
+
263
+ // Mock next/image
264
+ vi.mock('next/image', () => ({
265
+ default: (props: Record<string, unknown>) => {
266
+ // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
267
+ return <img {...props} />;
268
+ },
269
+ }));
270
+ `;
271
+ }
272
+ /**
273
+ * Generate Next.js environment declaration
274
+ */
275
+ export function generateWebsiteNextEnv() {
276
+ return `/// <reference types="next" />
277
+ /// <reference types="next/image-types/global" />
278
+
279
+ // NOTE: This file should not be edited
280
+ // see https://nextjs.org/docs/basic-features/typescript for more information.
281
+ `;
282
+ }
283
+ //# sourceMappingURL=website-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-config.js","sourceRoot":"","sources":["../../../src/generators/templates/website-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB;IAC5D,OAAO;aACI,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCvB,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B;IAC3C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;;;;;;CAMR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;;;;;;;;CAkBR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO;;;;;;;;;;;;;;;;;;;;CAoBR,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;;;;;CAKR,CAAC;AACF,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Lead capture and conversion templates
3
+ * Generates API route handlers for lead capture and contact form components
4
+ */
5
+ import type { WebsiteStrategyDocument } from '../../types/website-strategy.js';
6
+ /**
7
+ * Generate lead capture API route handler
8
+ *
9
+ * @param provider - Lead capture provider type
10
+ * @returns API route source code (src/app/api/lead/route.ts)
11
+ */
12
+ export declare function generateLeadCaptureRoute(provider?: 'none' | 'webhook' | 'resend' | 'postmark'): string;
13
+ /**
14
+ * Generate contact form component
15
+ *
16
+ * @param strategy - Optional strategy for CTA text
17
+ * @returns ContactForm component source code
18
+ */
19
+ export declare function generateContactForm(strategy?: WebsiteStrategyDocument): string;
20
+ /**
21
+ * Generate .env.example entries for lead capture provider
22
+ *
23
+ * @param provider - Lead capture provider type
24
+ * @returns Environment variable example lines
25
+ */
26
+ export declare function generateLeadCaptureEnvExample(provider: 'none' | 'webhook' | 'resend' | 'postmark'): string;
27
+ //# sourceMappingURL=website-conversion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-conversion.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/website-conversion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAa/E;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,GAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAsB,GAC/D,MAAM,CAoLR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,CAAC,EAAE,uBAAuB,GACjC,MAAM,CAuGR;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GACnD,MAAM,CAWR"}