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
@@ -0,0 +1,444 @@
1
+ /**
2
+ * Reusable website section generators
3
+ * Pain Points, Value Proposition, How It Works, Stats/Proof Points, FAQ
4
+ * Each section is data-driven with graceful skip when data is missing
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
+ * Map a feature title to a lucide-react icon name by keyword matching
18
+ */
19
+ export function mapFeatureIcon(title) {
20
+ const lower = title.toLowerCase();
21
+ const iconMap = [
22
+ [/secur|auth|permission|access|lock|encrypt/, 'Shield'],
23
+ [/speed|fast|perform|optim/, 'Zap'],
24
+ [/api|integrat|connect|plugin/, 'Plug'],
25
+ [/search|find|discover|retriev/, 'Search'],
26
+ [/analyt|metric|monitor|dashboard/, 'BarChart3'],
27
+ [/data|database|storage|vector/, 'Database'],
28
+ [/team|collaborat|share|user/, 'Users'],
29
+ [/automat|workflow|pipeline/, 'GitBranch'],
30
+ [/cloud|deploy|server|host/, 'Cloud'],
31
+ [/scale|grow|expand/, 'TrendingUp'],
32
+ [/custom|config|setting/, 'Settings'],
33
+ [/document|doc|file|content/, 'FileText'],
34
+ [/test|quality|check|verify/, 'CheckCircle'],
35
+ [/ai|machine|learn|model|neural/, 'Brain'],
36
+ [/code|develop|build|engineer/, 'Code'],
37
+ [/email|message|notif|alert/, 'Bell'],
38
+ [/time|schedule|calendar|clock/, 'Clock'],
39
+ [/money|pay|bill|cost|pric/, 'CreditCard'],
40
+ [/global|world|international/, 'Globe'],
41
+ [/support|help|service/, 'Headphones'],
42
+ ];
43
+ for (const [pattern, icon] of iconMap) {
44
+ if (pattern.test(lower))
45
+ return icon;
46
+ }
47
+ return 'Star';
48
+ }
49
+ /**
50
+ * Check if a proof point string contains a numeric metric
51
+ * Numeric metrics are safe to display as stats; qualitative ones become badges
52
+ */
53
+ export function isNumericMetric(point) {
54
+ return /\d+[%+KMB]|\d{2,}/.test(point);
55
+ }
56
+ /**
57
+ * Generate Pain Points section
58
+ * Data: strategy.icp.painPoints
59
+ * Skip: if painPoints is empty
60
+ */
61
+ export function generatePainPointsSection(strategy) {
62
+ const painPoints = strategy?.icp.painPoints || [];
63
+ if (painPoints.length === 0) {
64
+ return {
65
+ jsx: '',
66
+ info: { name: 'PainPoints', dataSource: 'skipped', itemCount: 0 },
67
+ };
68
+ }
69
+ const items = painPoints.slice(0, 3);
70
+ const icons = ['AlertTriangle', 'XCircle', 'AlertOctagon'];
71
+ const itemsStr = items
72
+ .map((point, i) => ` <div key="${i}" className="rounded-2xl bg-card p-8 text-center">
73
+ <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-red-100">
74
+ <${icons[i % icons.length]} className="h-6 w-6 text-red-600" />
75
+ </div>
76
+ <p className="text-foreground font-medium">${escapeJsx(point)}</p>
77
+ </div>`)
78
+ .join('\n');
79
+ const jsx = `
80
+ {/* Pain Points */}
81
+ <section className="bg-muted/50 py-20 sm:py-28">
82
+ <div className="container">
83
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
84
+ Sound familiar?
85
+ </h2>
86
+ <p className="mx-auto mt-4 max-w-2xl text-center text-lg text-muted-foreground">
87
+ Common challenges that hold teams back
88
+ </p>
89
+ <div className="mx-auto mt-12 grid max-w-5xl grid-cols-1 gap-8 md:grid-cols-3">
90
+ ${itemsStr}
91
+ </div>
92
+ </div>
93
+ </section>
94
+ `;
95
+ return {
96
+ jsx,
97
+ info: { name: 'PainPoints', dataSource: 'strategy', itemCount: items.length },
98
+ };
99
+ }
100
+ /**
101
+ * Generate Value Proposition / Differentiators section
102
+ * Data: strategy.positioning.differentiators + valueProposition
103
+ * Skip: if no differentiators
104
+ */
105
+ export function generateDifferentiatorsSection(strategy) {
106
+ const differentiators = strategy?.positioning.differentiators || [];
107
+ const valueProp = strategy?.positioning.valueProposition;
108
+ if (differentiators.length === 0 && !valueProp) {
109
+ return {
110
+ jsx: '',
111
+ info: { name: 'Differentiators', dataSource: 'skipped', itemCount: 0 },
112
+ };
113
+ }
114
+ const heading = valueProp
115
+ ? escapeJsx(valueProp)
116
+ : 'Why choose us';
117
+ const itemsStr = differentiators
118
+ .slice(0, 6)
119
+ .map((diff) => ` <div className="flex items-start gap-3">
120
+ <CheckCircle className="mt-0.5 h-5 w-5 flex-shrink-0 text-primary-600" />
121
+ <p className="text-foreground">${escapeJsx(diff)}</p>
122
+ </div>`)
123
+ .join('\n');
124
+ const jsx = `
125
+ {/* Value Proposition */}
126
+ <section className="py-20 sm:py-28">
127
+ <div className="container">
128
+ <div className="mx-auto max-w-3xl text-center">
129
+ <h2 className="text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
130
+ ${heading}
131
+ </h2>
132
+ </div>
133
+ <div className="mx-auto mt-12 grid max-w-3xl grid-cols-1 gap-6 sm:grid-cols-2">
134
+ ${itemsStr}
135
+ </div>
136
+ </div>
137
+ </section>
138
+ `;
139
+ return {
140
+ jsx,
141
+ info: { name: 'Differentiators', dataSource: 'strategy', itemCount: differentiators.length },
142
+ };
143
+ }
144
+ /**
145
+ * Generate How It Works section
146
+ * Data: strategy siteArchitecture.pages[0].sections or defaults
147
+ * Always rendered (with defaults if no strategy)
148
+ */
149
+ export function generateHowItWorksSection(strategy) {
150
+ const defaultSteps = [
151
+ { title: 'Sign Up', description: 'Create your account in seconds' },
152
+ { title: 'Configure', description: 'Set up your workspace to match your needs' },
153
+ { title: 'Deploy', description: 'Go live and start seeing results' },
154
+ ];
155
+ const hasSections = strategy?.siteArchitecture.pages[0]?.sections;
156
+ const steps = hasSections && hasSections.length >= 3
157
+ ? hasSections.slice(0, 3).map((s, i) => ({
158
+ title: s.replace(/^(hero|features|cta|pricing|faq|testimonials)/i, '').trim() || defaultSteps[i].title,
159
+ description: defaultSteps[i].description,
160
+ }))
161
+ : defaultSteps;
162
+ const dataSource = hasSections ? 'strategy' : 'defaults';
163
+ const stepsStr = steps
164
+ .map((step, i) => ` <div className="relative text-center">
165
+ <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-primary-600 text-lg font-bold text-white">
166
+ ${i + 1}
167
+ </div>
168
+ <h3 className="mt-4 text-lg font-semibold text-foreground">${escapeJsx(step.title)}</h3>
169
+ <p className="mt-2 text-muted-foreground">${escapeJsx(step.description)}</p>
170
+ </div>`)
171
+ .join('\n');
172
+ const jsx = `
173
+ {/* How It Works */}
174
+ <section className="bg-muted/50 py-20 sm:py-28">
175
+ <div className="container">
176
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
177
+ How it works
178
+ </h2>
179
+ <div className="mx-auto mt-16 grid max-w-4xl grid-cols-1 gap-12 md:grid-cols-3">
180
+ ${stepsStr}
181
+ </div>
182
+ </div>
183
+ </section>
184
+ `;
185
+ return {
186
+ jsx,
187
+ info: { name: 'HowItWorks', dataSource: dataSource, itemCount: steps.length },
188
+ };
189
+ }
190
+ /**
191
+ * Generate Stats / Proof Points section
192
+ * CRITICAL: Only show numeric metrics if they appear literally in docs/strategy.
193
+ * Qualitative points render as badges, NOT fake numbers.
194
+ */
195
+ export function generateStatsSection(strategy) {
196
+ const proofPoints = strategy?.positioning.proofPoints || [];
197
+ if (proofPoints.length === 0) {
198
+ return {
199
+ jsx: '',
200
+ info: { name: 'Stats', dataSource: 'skipped', itemCount: 0 },
201
+ };
202
+ }
203
+ const numericPoints = proofPoints.filter(isNumericMetric);
204
+ const qualitativePoints = proofPoints.filter((p) => !isNumericMetric(p));
205
+ let statsContent = '';
206
+ if (numericPoints.length > 0) {
207
+ const statsStr = numericPoints
208
+ .slice(0, 4)
209
+ .map((point) => ` <div className="text-center">
210
+ <p className="text-4xl font-bold text-primary-600">${escapeJsx(point)}</p>
211
+ </div>`)
212
+ .join('\n');
213
+ statsContent += ` <div className="mx-auto mt-12 grid max-w-4xl grid-cols-2 gap-8 md:grid-cols-${Math.min(numericPoints.length, 4)}">
214
+ ${statsStr}
215
+ </div>\n`;
216
+ }
217
+ if (qualitativePoints.length > 0) {
218
+ const badgesStr = qualitativePoints
219
+ .slice(0, 6)
220
+ .map((point) => ` <span className="inline-flex items-center gap-1.5 rounded-full bg-primary-50 px-4 py-2 text-sm font-medium text-primary-700">
221
+ <CheckCircle className="h-4 w-4" />
222
+ ${escapeJsx(point)}
223
+ </span>`)
224
+ .join('\n');
225
+ statsContent += ` <div className="mx-auto mt-8 flex max-w-4xl flex-wrap items-center justify-center gap-3">
226
+ ${badgesStr}
227
+ </div>\n`;
228
+ }
229
+ const jsx = `
230
+ {/* Proof Points */}
231
+ <section className="py-20 sm:py-28">
232
+ <div className="container">
233
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
234
+ Built for production
235
+ </h2>
236
+ ${statsContent}
237
+ </div>
238
+ </section>
239
+ `;
240
+ return {
241
+ jsx,
242
+ info: { name: 'Stats', dataSource: 'strategy', itemCount: proofPoints.length },
243
+ };
244
+ }
245
+ /**
246
+ * Generate Social Proof section
247
+ * Data: strategy.conversionStrategy.socialProof
248
+ * Skip: if empty
249
+ */
250
+ export function generateSocialProofSection(strategy) {
251
+ const socialProof = strategy?.conversionStrategy.socialProof || [];
252
+ if (socialProof.length === 0) {
253
+ return {
254
+ jsx: '',
255
+ info: { name: 'SocialProof', dataSource: 'skipped', itemCount: 0 },
256
+ };
257
+ }
258
+ const quotesStr = socialProof
259
+ .slice(0, 4)
260
+ .map((quote, i) => ` <blockquote key={${i}} className="rounded-2xl border border-border bg-card p-6 shadow-sm">
261
+ <div className="mb-4 text-4xl text-primary-300">&ldquo;</div>
262
+ <p className="text-foreground">${escapeJsx(quote)}</p>
263
+ <div className="mt-4 flex items-center gap-3">
264
+ <div className="h-10 w-10 rounded-full bg-muted" />
265
+ <div className="text-sm text-muted-foreground">Verified User</div>
266
+ </div>
267
+ </blockquote>`)
268
+ .join('\n');
269
+ const jsx = `
270
+ {/* Social Proof */}
271
+ <section className="py-20 sm:py-28">
272
+ <div className="container">
273
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
274
+ Trusted by teams everywhere
275
+ </h2>
276
+ <div className="mx-auto mt-12 grid max-w-4xl grid-cols-1 gap-8 md:grid-cols-2">
277
+ ${quotesStr}
278
+ </div>
279
+ </div>
280
+ </section>
281
+ `;
282
+ return {
283
+ jsx,
284
+ info: { name: 'SocialProof', dataSource: 'strategy', itemCount: socialProof.length },
285
+ };
286
+ }
287
+ /**
288
+ * Generate Pricing Teaser section for landing page
289
+ * Data: context.pricing (tier names + starting prices)
290
+ * Skip: if no pricing tiers
291
+ */
292
+ export function generatePricingTeaserSection(context) {
293
+ const tiers = context?.pricing;
294
+ if (!tiers || tiers.length === 0) {
295
+ return {
296
+ jsx: '',
297
+ info: { name: 'PricingTeaser', dataSource: 'skipped', itemCount: 0 },
298
+ };
299
+ }
300
+ const tiersStr = tiers
301
+ .slice(0, 3)
302
+ .map((tier) => ` <div className="rounded-2xl border ${tier.featured ? 'border-primary-600 ring-2 ring-primary-600' : 'border-border'} bg-card p-6 text-center">
303
+ <h3 className="text-lg font-semibold text-foreground">${escapeJsx(tier.name)}</h3>
304
+ <p className="mt-2 text-3xl font-bold text-foreground">${escapeJsx(tier.price)}</p>
305
+ ${tier.period ? `<p className="text-sm text-muted-foreground">${escapeJsx(tier.period)}</p>` : ''}
306
+ <p className="mt-2 text-sm text-muted-foreground">${escapeJsx(tier.description)}</p>
307
+ </div>`)
308
+ .join('\n');
309
+ const jsx = `
310
+ {/* Pricing Teaser */}
311
+ <section className="bg-muted/50 py-20 sm:py-28">
312
+ <div className="container">
313
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
314
+ Simple, transparent pricing
315
+ </h2>
316
+ <div className="mx-auto mt-12 grid max-w-4xl grid-cols-1 gap-8 md:grid-cols-3">
317
+ ${tiersStr}
318
+ </div>
319
+ <div className="mt-8 text-center">
320
+ <Link
321
+ href="/pricing"
322
+ className="text-sm font-semibold text-primary-600 hover:text-primary-500"
323
+ >
324
+ View full pricing <span aria-hidden="true">&rarr;</span>
325
+ </Link>
326
+ </div>
327
+ </div>
328
+ </section>
329
+ `;
330
+ return {
331
+ jsx,
332
+ info: { name: 'PricingTeaser', dataSource: 'docs', itemCount: tiers.length },
333
+ };
334
+ }
335
+ /**
336
+ * Generate FAQ section from strategy objections
337
+ * Data: strategy.icp.objections rephrased as Q&A
338
+ * Skip: if no objections
339
+ * Note: Renders as client component with useState accordion
340
+ */
341
+ export function generateFaqSection(strategy) {
342
+ const objections = strategy?.icp.objections || [];
343
+ if (objections.length === 0) {
344
+ return {
345
+ jsx: '',
346
+ info: { name: 'FAQ', dataSource: 'skipped', itemCount: 0 },
347
+ needsClientDirective: false,
348
+ };
349
+ }
350
+ const faqItems = objections.slice(0, 6).map((obj) => {
351
+ // Convert objection to Q&A format
352
+ const question = obj.endsWith('?') ? obj : `${obj}?`;
353
+ return { question, answer: `We take this seriously. ${obj.replace(/\?$/, '')} is addressed through our robust platform design and industry best practices.` };
354
+ });
355
+ const jsx = `
356
+ {/* FAQ */}
357
+ <section id="faq" className="py-20 sm:py-28">
358
+ <div className="container">
359
+ <h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
360
+ Frequently asked questions
361
+ </h2>
362
+ <div className="mx-auto mt-12 max-w-3xl divide-y divide-border">
363
+ {faqItems.map((item, index) => (
364
+ <FaqItem key={index} question={item.question} answer={item.answer} />
365
+ ))}
366
+ </div>
367
+ </div>
368
+ </section>
369
+ `;
370
+ return {
371
+ jsx,
372
+ info: { name: 'FAQ', dataSource: 'strategy', itemCount: faqItems.length },
373
+ needsClientDirective: true,
374
+ };
375
+ }
376
+ /**
377
+ * Build FAQ items array declaration for the page component
378
+ */
379
+ export function buildFaqItemsDeclaration(strategy) {
380
+ const objections = strategy?.icp.objections || [];
381
+ if (objections.length === 0)
382
+ return '';
383
+ const faqItems = objections.slice(0, 6).map((obj) => {
384
+ const question = obj.endsWith('?') ? obj : `${obj}?`;
385
+ return { question, answer: `We take this seriously. ${obj.replace(/\?$/, '')} is addressed through our robust platform design and industry best practices.` };
386
+ });
387
+ const itemsStr = faqItems
388
+ .map((item) => ` { question: '${escapeJsx(item.question)}', answer: '${escapeJsx(item.answer)}' }`)
389
+ .join(',\n');
390
+ return `const faqItems = [\n${itemsStr}\n];\n`;
391
+ }
392
+ /**
393
+ * Generate the FaqItem client component code
394
+ */
395
+ export function generateFaqItemComponent() {
396
+ return `function FaqItem({ question, answer }: { question: string; answer: string }) {
397
+ const [open, setOpen] = useState(false);
398
+
399
+ return (
400
+ <div className="py-4">
401
+ <button
402
+ type="button"
403
+ className="flex w-full items-center justify-between text-left"
404
+ onClick={() => setOpen(!open)}
405
+ aria-expanded={open}
406
+ >
407
+ <span className="text-base font-medium text-foreground">{question}</span>
408
+ <ChevronDown className={\`h-5 w-5 text-muted-foreground transition-transform \${open ? 'rotate-180' : ''}\`} />
409
+ </button>
410
+ {open && (
411
+ <p className="mt-3 text-muted-foreground">{answer}</p>
412
+ )}
413
+ </div>
414
+ );
415
+ }`;
416
+ }
417
+ /**
418
+ * Build JSON-LD FAQ schema for SEO
419
+ */
420
+ export function buildFaqSchema(strategy) {
421
+ const objections = strategy?.icp.objections || [];
422
+ if (objections.length === 0)
423
+ return '';
424
+ const faqItems = objections.slice(0, 6).map((obj) => {
425
+ const question = obj.endsWith('?') ? obj : `${obj}?`;
426
+ const answer = `We take this seriously. ${obj.replace(/\?$/, '')} is addressed through our robust platform design and industry best practices.`;
427
+ return { question, answer };
428
+ });
429
+ return `const FAQ_SCHEMA = {
430
+ '@context': 'https://schema.org',
431
+ '@type': 'FAQPage',
432
+ mainEntity: [
433
+ ${faqItems.map(item => ` {
434
+ '@type': 'Question',
435
+ name: '${escapeJsx(item.question)}',
436
+ acceptedAnswer: {
437
+ '@type': 'Answer',
438
+ text: '${escapeJsx(item.answer)}',
439
+ },
440
+ }`).join(',\n')}
441
+ ],
442
+ };`;
443
+ }
444
+ //# sourceMappingURL=website-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-sections.js","sourceRoot":"","sources":["../../../src/generators/templates/website-sections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * SEO infrastructure templates for Next.js marketing websites
3
+ * Generates JSON-LD components, enhanced sitemap, robots.txt,
4
+ * error pages, web manifest, and meta helpers
5
+ */
6
+ import type { WebsiteContentContext } from '../website-context.js';
7
+ import type { WebsiteStrategyDocument } from '../../types/website-strategy.js';
8
+ /**
9
+ * Generate reusable JSON-LD component
10
+ *
11
+ * @returns JsonLd component source code
12
+ */
13
+ export declare function generateJsonLdComponent(): string;
14
+ /**
15
+ * Generate Organization JSON-LD schema data
16
+ *
17
+ * @param projectName - Product name
18
+ * @param context - Optional content context
19
+ * @returns Organization schema as string constant
20
+ */
21
+ export declare function generateOrganizationJsonLd(projectName: string, context?: WebsiteContentContext): string;
22
+ /**
23
+ * Generate SoftwareApplication JSON-LD schema data
24
+ *
25
+ * @param projectName - Product name
26
+ * @param context - Optional content context
27
+ * @returns Software application schema as string constant
28
+ */
29
+ export declare function generateProductJsonLd(projectName: string, context?: WebsiteContentContext): string;
30
+ /**
31
+ * Generate enhanced sitemap with all strategy pages
32
+ *
33
+ * @param projectName - Project name for base URL fallback
34
+ * @param strategy - Optional strategy for page list
35
+ * @returns Enhanced sitemap.ts source code
36
+ */
37
+ export declare function generateEnhancedSitemap(projectName: string, strategy?: WebsiteStrategyDocument): string;
38
+ /**
39
+ * Generate enhanced robots.txt
40
+ *
41
+ * @param projectName - Project name for base URL fallback
42
+ * @returns robots.ts source code
43
+ */
44
+ export declare function generateEnhancedRobots(projectName: string): string;
45
+ /**
46
+ * Generate branded 404 Not Found page
47
+ *
48
+ * @param projectName - Product name for branding
49
+ * @param context - Optional content context
50
+ * @returns not-found.tsx source code
51
+ */
52
+ export declare function generate404Page(projectName: string, context?: WebsiteContentContext): string;
53
+ /**
54
+ * Generate error boundary page (500)
55
+ *
56
+ * @param projectName - Product name for branding
57
+ * @returns error.tsx source code
58
+ */
59
+ export declare function generate500Page(_projectName: string): string;
60
+ /**
61
+ * Generate PWA web manifest
62
+ *
63
+ * @param projectName - Product name
64
+ * @param context - Optional content context
65
+ * @returns manifest.webmanifest JSON content
66
+ */
67
+ export declare function generateWebManifest(projectName: string, context?: WebsiteContentContext): string;
68
+ /**
69
+ * Generate shared metadata helper utility
70
+ *
71
+ * @param projectName - Product name
72
+ * @param strategy - Optional strategy for SEO data
73
+ * @returns Metadata helper source code
74
+ */
75
+ export declare function generateMetaHelper(projectName: string, strategy?: WebsiteStrategyDocument): string;
76
+ //# sourceMappingURL=website-seo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-seo.d.ts","sourceRoot":"","sources":["../../../src/generators/templates/website-seo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAa/E;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAoBhD;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CAaR;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,uBAAuB,GACjC,MAAM,CAuDR;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAkBlE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CA8BR;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CA8B5D;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,CA2BR;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,uBAAuB,GACjC,MAAM,CAoDR"}