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,350 @@
1
+ /**
2
+ * Website content context builder
3
+ * Discovers user documentation and brand assets to populate website templates
4
+ * with project-specific content instead of generic placeholders
5
+ */
6
+ import { promises as fs } from 'node:fs';
7
+ import path from 'node:path';
8
+ import { stripCodeFences, extractProductName, extractTagline, extractDescription, extractFeatures, extractPricing, extractPrimaryColor, } from './doc-parser.js';
9
+ import { getScanDirectories } from './workspace-root.js';
10
+ /** Per-file character cap to prevent a single large doc from consuming the budget */
11
+ const PER_FILE_CAP = 8000;
12
+ /**
13
+ * Resolve brand assets into a deterministic contract
14
+ * Searches for logo/favicon in project directory and workspace root,
15
+ * sets canonical output paths
16
+ *
17
+ * @param cwd - Directory to scan for brand assets
18
+ * @param brandContext - Optional existing brand context from state
19
+ * @returns Resolved brand assets contract
20
+ */
21
+ export async function resolveBrandAssets(cwd, brandContext) {
22
+ const assets = await findBrandAssets(cwd);
23
+ const logoPath = brandContext?.logoPath || assets.logoPath;
24
+ const ext = logoPath ? path.extname(logoPath) : '.svg';
25
+ return {
26
+ logoPath,
27
+ logoOutputPath: `public/brand/logo${ext}`,
28
+ primaryColor: brandContext?.primaryColor,
29
+ };
30
+ }
31
+ /** Patterns to match documentation files */
32
+ const DOC_PATTERNS = [
33
+ /spec/i,
34
+ /pricing/i,
35
+ /color/i,
36
+ /brand/i,
37
+ /ui[\s_-]?spec/i,
38
+ /^readme\.md$/i,
39
+ /overview/i,
40
+ /features/i,
41
+ /product/i,
42
+ ];
43
+ /** Directories to exclude from scanning */
44
+ const EXCLUDED_DIRS = [
45
+ 'node_modules',
46
+ '.popeye',
47
+ '.git',
48
+ 'dist',
49
+ 'build',
50
+ '.next',
51
+ '__pycache__',
52
+ 'venv',
53
+ '.venv',
54
+ 'coverage',
55
+ ];
56
+ /**
57
+ * Discover project documentation files in a directory
58
+ *
59
+ * @param cwd - Directory to scan for documentation
60
+ * @returns Array of absolute paths to discovered doc files
61
+ */
62
+ export async function discoverProjectDocs(cwd) {
63
+ const scanDirs = await getScanDirectories(cwd);
64
+ const allDocs = [];
65
+ const seenPaths = new Set();
66
+ for (const dir of scanDirs) {
67
+ const found = await scanDirectoryForDocs(dir);
68
+ for (const docPath of found) {
69
+ const resolved = path.resolve(docPath);
70
+ if (!seenPaths.has(resolved)) {
71
+ seenPaths.add(resolved);
72
+ allDocs.push(resolved);
73
+ }
74
+ }
75
+ }
76
+ // Sort: brand/color docs first, then spec, then pricing, then others
77
+ // Reason: ensures critical brand context isn't truncated by the maxLength cap
78
+ allDocs.sort((a, b) => {
79
+ const nameA = path.basename(a).toLowerCase();
80
+ const nameB = path.basename(b).toLowerCase();
81
+ const priorityA = getDocPriority(nameA);
82
+ const priorityB = getDocPriority(nameB);
83
+ return priorityA - priorityB;
84
+ });
85
+ return allDocs;
86
+ }
87
+ /**
88
+ * Get sort priority for a doc file (lower = higher priority)
89
+ */
90
+ function getDocPriority(fileName) {
91
+ if (/color|brand/.test(fileName))
92
+ return 0;
93
+ if (/spec/.test(fileName))
94
+ return 1;
95
+ if (/pricing/.test(fileName))
96
+ return 2;
97
+ if (/feature/.test(fileName))
98
+ return 3;
99
+ return 4;
100
+ }
101
+ /**
102
+ * Scan a single directory for doc files (flat + docs/ subdirectory)
103
+ */
104
+ async function scanDirectoryForDocs(dir) {
105
+ const docs = [];
106
+ try {
107
+ const entries = await fs.readdir(dir, { withFileTypes: true });
108
+ for (const entry of entries) {
109
+ if (entry.isDirectory() && EXCLUDED_DIRS.includes(entry.name)) {
110
+ continue;
111
+ }
112
+ if (entry.isFile() && entry.name.endsWith('.md')) {
113
+ const matches = DOC_PATTERNS.some((pattern) => pattern.test(entry.name));
114
+ if (matches) {
115
+ docs.push(path.join(dir, entry.name));
116
+ }
117
+ }
118
+ // Check one level of subdirectories (e.g., docs/)
119
+ if (entry.isDirectory() && entry.name === 'docs') {
120
+ try {
121
+ const subEntries = await fs.readdir(path.join(dir, entry.name), {
122
+ withFileTypes: true,
123
+ });
124
+ for (const subEntry of subEntries) {
125
+ if (subEntry.isFile() && subEntry.name.endsWith('.md')) {
126
+ docs.push(path.join(dir, entry.name, subEntry.name));
127
+ }
128
+ }
129
+ }
130
+ catch {
131
+ // Skip unreadable directories
132
+ }
133
+ }
134
+ }
135
+ }
136
+ catch {
137
+ // Directory not accessible
138
+ }
139
+ return docs;
140
+ }
141
+ /**
142
+ * Find brand assets (logo files) in a directory
143
+ * Also searches workspace root and parent directories
144
+ *
145
+ * @param cwd - Directory to scan for brand assets
146
+ * @returns Object with optional logoPath
147
+ */
148
+ export async function findBrandAssets(cwd) {
149
+ const scanDirs = await getScanDirectories(cwd);
150
+ for (const dir of scanDirs) {
151
+ const result = await scanDirectoryForLogo(dir);
152
+ if (result.logoPath)
153
+ return result;
154
+ }
155
+ return {};
156
+ }
157
+ /**
158
+ * Scan a single directory for logo files
159
+ */
160
+ async function scanDirectoryForLogo(dir) {
161
+ const logoExtensions = ['.png', '.svg', '.jpg', '.jpeg', '.webp'];
162
+ try {
163
+ const entries = await fs.readdir(dir, { withFileTypes: true });
164
+ for (const entry of entries) {
165
+ if (!entry.isFile())
166
+ continue;
167
+ const lowerName = entry.name.toLowerCase();
168
+ const hasLogoInName = lowerName.includes('logo');
169
+ const hasValidExt = logoExtensions.some((ext) => lowerName.endsWith(ext));
170
+ if (hasLogoInName && hasValidExt) {
171
+ return { logoPath: path.join(dir, entry.name) };
172
+ }
173
+ }
174
+ }
175
+ catch {
176
+ // Directory not accessible
177
+ }
178
+ return {};
179
+ }
180
+ /**
181
+ * Read and concatenate project documentation files
182
+ *
183
+ * @param docPaths - Array of absolute paths to doc files
184
+ * @param maxLength - Maximum combined length (default 25000 chars)
185
+ * @returns Combined documentation content with file headers
186
+ */
187
+ export async function readProjectDocs(docPaths, maxLength = 25000) {
188
+ const sections = [];
189
+ let totalLength = 0;
190
+ for (const docPath of docPaths) {
191
+ if (totalLength >= maxLength)
192
+ break;
193
+ try {
194
+ let content = await fs.readFile(docPath, 'utf-8');
195
+ const fileName = path.basename(docPath);
196
+ const header = `--- ${fileName} ---`;
197
+ // Per-file cap to prevent a single large doc from consuming the budget
198
+ if (content.length > PER_FILE_CAP) {
199
+ content = content.slice(0, PER_FILE_CAP) + '...';
200
+ }
201
+ const remaining = maxLength - totalLength;
202
+ const trimmedContent = content.length > remaining ? content.slice(0, remaining) + '...' : content;
203
+ sections.push(`${header}\n${trimmedContent}`);
204
+ totalLength += header.length + 1 + trimmedContent.length;
205
+ }
206
+ catch {
207
+ // Skip unreadable files
208
+ }
209
+ }
210
+ return sections.join('\n\n');
211
+ }
212
+ /**
213
+ * Build a structured website content context from discovered docs
214
+ *
215
+ * @param cwd - Working directory to scan for docs
216
+ * @param projectName - The project name (folder name fallback)
217
+ * @param specification - Optional expanded specification text
218
+ * @returns Structured content context for website templates
219
+ */
220
+ export async function buildWebsiteContext(cwd, projectName, specification) {
221
+ const docPaths = await discoverProjectDocs(cwd);
222
+ const rawDocs = docPaths.length > 0 ? await readProjectDocs(docPaths) : '';
223
+ const brandAssets = await findBrandAssets(cwd);
224
+ // Strip markdown code fences that wrap entire doc files
225
+ const cleanDocs = stripCodeFences(rawDocs);
226
+ const context = {
227
+ productName: extractProductName(cleanDocs, specification) || projectName,
228
+ features: extractFeatures(cleanDocs, specification),
229
+ rawDocs,
230
+ };
231
+ context.tagline = extractTagline(cleanDocs, context.productName);
232
+ context.description = extractDescription(cleanDocs, specification);
233
+ context.pricing = extractPricing(cleanDocs);
234
+ // Extract brand info
235
+ if (brandAssets.logoPath) {
236
+ context.brand = { ...context.brand, logoPath: brandAssets.logoPath };
237
+ }
238
+ const primaryColor = extractPrimaryColor(cleanDocs);
239
+ if (primaryColor) {
240
+ context.brand = { ...context.brand, primaryColor };
241
+ }
242
+ return context;
243
+ }
244
+ /** Default pricing tier names that indicate placeholder content */
245
+ const DEFAULT_PRICING_NAMES = ['starter', 'free', 'pro', 'enterprise'];
246
+ /** Default pricing amounts that indicate placeholder content */
247
+ const DEFAULT_PRICING_AMOUNTS = ['$0', '$29', '$99', 'custom', 'free'];
248
+ /**
249
+ * Validate website content context without throwing
250
+ * Returns structured result with issues, warnings, and a content quality score
251
+ *
252
+ * @param context - The built website content context
253
+ * @param projectName - The project name for validation
254
+ * @returns Validation result with issues, warnings, and score
255
+ */
256
+ export function validateWebsiteContext(context, _projectName) {
257
+ const issues = [];
258
+ const warnings = [];
259
+ let contentScore = 100;
260
+ // Suspicious product name (looks like a directory name with hyphens/underscores)
261
+ const suspiciousNames = ['my-app', 'my-project', 'project', 'app', 'website', 'frontend'];
262
+ if (/^[a-z]+-[a-z]+(-[a-z]+)*$/.test(context.productName) ||
263
+ suspiciousNames.includes(context.productName.toLowerCase())) {
264
+ issues.push(`Product name "${context.productName}" looks like a directory name, not a product. ` +
265
+ `Provide .md docs with "# ProductName -- tagline" heading.`);
266
+ contentScore -= 25;
267
+ }
268
+ // No docs found at all
269
+ if (!context.rawDocs || context.rawDocs.length < 100) {
270
+ issues.push('No project documentation found. Place .md files (spec, pricing, brand) ' +
271
+ 'in the project directory or its parent.');
272
+ contentScore -= 30;
273
+ }
274
+ // No features extracted
275
+ if (context.features.length === 0) {
276
+ issues.push('No product features extracted from docs. Add a "## Features" section to your spec.');
277
+ contentScore -= 20;
278
+ }
279
+ // Strategy validation
280
+ if (!context.strategy) {
281
+ issues.push('Website strategy missing. Strategy generation may have failed or been skipped.');
282
+ contentScore -= 15;
283
+ }
284
+ // Brand color validation: brand/color docs exist but no color extracted
285
+ if (!context.brand?.primaryColor && context.rawDocs && /color|brand/i.test(context.rawDocs)) {
286
+ issues.push('Brand/color docs found but no primary color extracted. Check color doc format.');
287
+ contentScore -= 5;
288
+ }
289
+ // Logo found but output path not resolved
290
+ if (context.brand?.logoPath && !context.brandAssets?.logoOutputPath) {
291
+ issues.push('Logo found but output path not resolved. Call resolveBrandAssets().');
292
+ contentScore -= 5;
293
+ }
294
+ // --- Non-blocking warnings ---
295
+ // Default pricing tiers detection
296
+ if (context.pricing && context.pricing.length > 0) {
297
+ const tierNames = context.pricing.map((t) => t.name.toLowerCase());
298
+ const tierPrices = context.pricing.map((t) => t.price.toLowerCase().replace(/\/mo.*/, ''));
299
+ const nameMatches = tierNames.filter((n) => DEFAULT_PRICING_NAMES.includes(n));
300
+ const priceMatches = tierPrices.filter((p) => DEFAULT_PRICING_AMOUNTS.includes(p));
301
+ // Reason: if most tier names AND prices match defaults, it's likely placeholder content
302
+ if (nameMatches.length >= 2 && priceMatches.length >= 2) {
303
+ warnings.push('Pricing tiers appear to use default values (Starter/Pro/Enterprise at $0/$29/Custom). ' +
304
+ 'Add a pricing section to your docs for accurate tiers.');
305
+ contentScore -= 10;
306
+ }
307
+ }
308
+ // Missing tagline
309
+ if (!context.tagline) {
310
+ warnings.push('No tagline extracted from docs. Footer and meta tags will use generic defaults. ' +
311
+ 'Add "# ProductName -- Your tagline here" to your spec.');
312
+ contentScore -= 5;
313
+ }
314
+ // Missing description
315
+ if (!context.description) {
316
+ warnings.push('No product description extracted. Meta description will use generic text.');
317
+ contentScore -= 5;
318
+ }
319
+ // No brand color at all (not just missing from color docs)
320
+ if (!context.brand?.primaryColor && !(context.rawDocs && /color|brand/i.test(context.rawDocs))) {
321
+ warnings.push('No brand color found. Website will use default color scheme.');
322
+ contentScore -= 5;
323
+ }
324
+ // Clamp score to 0-100
325
+ contentScore = Math.max(0, Math.min(100, contentScore));
326
+ return {
327
+ passed: issues.length === 0,
328
+ issues,
329
+ warnings,
330
+ contentScore,
331
+ };
332
+ }
333
+ /**
334
+ * Validate website content context and throw if insufficient
335
+ * Prevents generation of generic websites with placeholder content
336
+ *
337
+ * @param context - The built website content context
338
+ * @param projectName - The project name for validation
339
+ * @throws Error with actionable message if context is insufficient
340
+ */
341
+ export function validateWebsiteContextOrThrow(context, projectName) {
342
+ const result = validateWebsiteContext(context, projectName);
343
+ if (!result.passed) {
344
+ throw new Error(`Website generation blocked - insufficient project context:\n` +
345
+ result.issues.map((i) => ` - ${i}`).join('\n') +
346
+ `\n\nFix these issues and re-run. Use POPEYE_DEBUG_WEBSITE=1 to see discovery details.`);
347
+ }
348
+ return { passed: true, issues: [] };
349
+ }
350
+ //# sourceMappingURL=website-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-context.js","sourceRoot":"","sources":["../../src/generators/website-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Debug tracing for website generation pipeline
3
+ * Enabled via POPEYE_DEBUG_WEBSITE=1 environment variable
4
+ * Shows exactly which value came from where during website generation
5
+ */
6
+ /**
7
+ * Structured trace of website generation pipeline decisions
8
+ */
9
+ export interface WebsiteDebugTrace {
10
+ workspaceRoot: string;
11
+ docsFound: Array<{
12
+ path: string;
13
+ size: number;
14
+ }>;
15
+ brandAssets: {
16
+ logoPath?: string;
17
+ logoOutputPath: string;
18
+ };
19
+ productName: {
20
+ value: string;
21
+ source: 'docs' | 'spec' | 'package.json' | 'directory';
22
+ };
23
+ primaryColor: {
24
+ value?: string;
25
+ source: 'brand-docs' | 'frontend' | 'defaults';
26
+ };
27
+ strategyStatus: 'success' | 'failed' | 'skipped';
28
+ strategyError?: string;
29
+ feDesignAnalysis?: {
30
+ componentLib?: string;
31
+ darkMode: boolean;
32
+ primaryColor?: string;
33
+ };
34
+ templateValues: {
35
+ headline?: string;
36
+ features: number;
37
+ pricingTiers: number;
38
+ };
39
+ /** Sections rendered with their data sources */
40
+ sectionsRendered: Array<{
41
+ name: string;
42
+ dataSource: 'strategy' | 'docs' | 'defaults' | 'skipped';
43
+ itemCount: number;
44
+ }>;
45
+ /** Validation result from quality gate */
46
+ validationPassed: boolean;
47
+ validationIssues: string[];
48
+ }
49
+ /**
50
+ * Check if debug tracing is enabled
51
+ *
52
+ * @returns True if POPEYE_DEBUG_WEBSITE=1 is set
53
+ */
54
+ export declare function isDebugEnabled(): boolean;
55
+ /**
56
+ * Format a debug trace for terminal output
57
+ *
58
+ * @param trace - The debug trace to format
59
+ * @returns Formatted string for terminal output
60
+ */
61
+ export declare function formatDebugTrace(trace: WebsiteDebugTrace): string;
62
+ /**
63
+ * Print debug trace to console if debug mode is enabled
64
+ *
65
+ * @param trace - The debug trace to print
66
+ */
67
+ export declare function printDebugTrace(trace: WebsiteDebugTrace): void;
68
+ //# sourceMappingURL=website-debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-debug.d.ts","sourceRoot":"","sources":["../../src/generators/website-debug.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,WAAW,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,WAAW,CAAA;KAAE,CAAC;IACvF,YAAY,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,GAAG,UAAU,GAAG,UAAU,CAAA;KAAE,CAAC;IACjF,cAAc,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvF,cAAc,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E,gDAAgD;IAChD,gBAAgB,EAAE,KAAK,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;QACzD,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,0CAA0C;IAC1C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAyEjE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAI9D"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Debug tracing for website generation pipeline
3
+ * Enabled via POPEYE_DEBUG_WEBSITE=1 environment variable
4
+ * Shows exactly which value came from where during website generation
5
+ */
6
+ /**
7
+ * Check if debug tracing is enabled
8
+ *
9
+ * @returns True if POPEYE_DEBUG_WEBSITE=1 is set
10
+ */
11
+ export function isDebugEnabled() {
12
+ return process.env.POPEYE_DEBUG_WEBSITE === '1';
13
+ }
14
+ /**
15
+ * Format a debug trace for terminal output
16
+ *
17
+ * @param trace - The debug trace to format
18
+ * @returns Formatted string for terminal output
19
+ */
20
+ export function formatDebugTrace(trace) {
21
+ const lines = [];
22
+ lines.push('');
23
+ lines.push('=== WEBSITE GENERATION DEBUG TRACE ===');
24
+ lines.push('');
25
+ lines.push(`Workspace Root: ${trace.workspaceRoot}`);
26
+ lines.push('');
27
+ lines.push(`Docs Found (${trace.docsFound.length}):`);
28
+ if (trace.docsFound.length === 0) {
29
+ lines.push(' (none)');
30
+ }
31
+ else {
32
+ for (const doc of trace.docsFound) {
33
+ lines.push(` - ${doc.path} (${doc.size} chars)`);
34
+ }
35
+ }
36
+ lines.push('');
37
+ lines.push(`Brand Assets:`);
38
+ lines.push(` Logo Source: ${trace.brandAssets.logoPath || '(none)'}`);
39
+ lines.push(` Logo Output: ${trace.brandAssets.logoOutputPath}`);
40
+ lines.push('');
41
+ lines.push(`Product Name: "${trace.productName.value}" (from: ${trace.productName.source})`);
42
+ lines.push('');
43
+ lines.push(`Primary Color: ${trace.primaryColor.value || '(default)'} (from: ${trace.primaryColor.source})`);
44
+ lines.push('');
45
+ lines.push(`Strategy: ${trace.strategyStatus}`);
46
+ if (trace.strategyError) {
47
+ lines.push(` Error: ${trace.strategyError}`);
48
+ }
49
+ lines.push('');
50
+ if (trace.feDesignAnalysis) {
51
+ lines.push('Frontend Design Analysis:');
52
+ lines.push(` Component Library: ${trace.feDesignAnalysis.componentLib || '(unknown)'}`);
53
+ lines.push(` Dark Mode: ${trace.feDesignAnalysis.darkMode}`);
54
+ lines.push(` Primary Color: ${trace.feDesignAnalysis.primaryColor || '(none)'}`);
55
+ lines.push('');
56
+ }
57
+ lines.push('Template Values:');
58
+ lines.push(` Headline: ${trace.templateValues.headline || '(default)'}`);
59
+ lines.push(` Features: ${trace.templateValues.features}`);
60
+ lines.push(` Pricing Tiers: ${trace.templateValues.pricingTiers}`);
61
+ lines.push('');
62
+ lines.push(`Sections Rendered (${trace.sectionsRendered.length}):`);
63
+ if (trace.sectionsRendered.length === 0) {
64
+ lines.push(' (none)');
65
+ }
66
+ else {
67
+ for (const section of trace.sectionsRendered) {
68
+ lines.push(` - ${section.name}: ${section.dataSource} (${section.itemCount} items)`);
69
+ }
70
+ }
71
+ lines.push('');
72
+ lines.push(`Validation: ${trace.validationPassed ? 'PASSED' : 'FAILED'}`);
73
+ if (trace.validationIssues.length > 0) {
74
+ for (const issue of trace.validationIssues) {
75
+ lines.push(` - ${issue}`);
76
+ }
77
+ }
78
+ lines.push('');
79
+ lines.push('=== END DEBUG TRACE ===');
80
+ lines.push('');
81
+ return lines.join('\n');
82
+ }
83
+ /**
84
+ * Print debug trace to console if debug mode is enabled
85
+ *
86
+ * @param trace - The debug trace to print
87
+ */
88
+ export function printDebugTrace(trace) {
89
+ if (isDebugEnabled()) {
90
+ console.log(formatDebugTrace(trace));
91
+ }
92
+ }
93
+ //# sourceMappingURL=website-debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"website-debug.js","sourceRoot":"","sources":["../../src/generators/website-debug.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  * Creates SEO-ready Next.js marketing website
4
4
  */
5
5
  import type { ProjectSpec } from '../types/project.js';
6
+ import type { WebsiteContentContext } from './website-context.js';
6
7
  /**
7
8
  * Project generation result
8
9
  */
@@ -26,6 +27,10 @@ export interface WebsiteGeneratorOptions {
26
27
  skipDocker?: boolean;
27
28
  /** Skip README (fullstack has root README) */
28
29
  skipReadme?: boolean;
30
+ /** Content context from user docs for populating templates */
31
+ contentContext?: WebsiteContentContext;
32
+ /** Skip content validation (scaffold-only use) */
33
+ skipValidation?: boolean;
29
34
  }
30
35
  /**
31
36
  * Generate a complete Next.js website project
@@ -1 +1 @@
1
- {"version":3,"file":"website.d.ts","sourceRoot":"","sources":["../../src/generators/website.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAwBvD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgBD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CA6L3B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCrE;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACxE,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CA0BD"}
1
+ {"version":3,"file":"website.d.ts","sourceRoot":"","sources":["../../src/generators/website.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA0CvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMlE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,kDAAkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAgBD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CA+T3B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAgCrE;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACxE,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC,CA0BD"}