popeye-cli 1.4.6 → 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 (140) 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/auto-fix.d.ts +7 -1
  74. package/dist/workflow/auto-fix.d.ts.map +1 -1
  75. package/dist/workflow/auto-fix.js +55 -3
  76. package/dist/workflow/auto-fix.js.map +1 -1
  77. package/dist/workflow/consensus.d.ts.map +1 -1
  78. package/dist/workflow/consensus.js +2 -0
  79. package/dist/workflow/consensus.js.map +1 -1
  80. package/dist/workflow/execution-mode.d.ts.map +1 -1
  81. package/dist/workflow/execution-mode.js +18 -0
  82. package/dist/workflow/execution-mode.js.map +1 -1
  83. package/dist/workflow/index.d.ts +3 -0
  84. package/dist/workflow/index.d.ts.map +1 -1
  85. package/dist/workflow/index.js +25 -0
  86. package/dist/workflow/index.js.map +1 -1
  87. package/dist/workflow/overview.d.ts +89 -0
  88. package/dist/workflow/overview.d.ts.map +1 -0
  89. package/dist/workflow/overview.js +354 -0
  90. package/dist/workflow/overview.js.map +1 -0
  91. package/dist/workflow/plan-mode.d.ts +2 -1
  92. package/dist/workflow/plan-mode.d.ts.map +1 -1
  93. package/dist/workflow/plan-mode.js +83 -5
  94. package/dist/workflow/plan-mode.js.map +1 -1
  95. package/dist/workflow/website-strategy.d.ts +70 -0
  96. package/dist/workflow/website-strategy.d.ts.map +1 -0
  97. package/dist/workflow/website-strategy.js +238 -0
  98. package/dist/workflow/website-strategy.js.map +1 -0
  99. package/dist/workflow/website-updater.d.ts +17 -0
  100. package/dist/workflow/website-updater.d.ts.map +1 -0
  101. package/dist/workflow/website-updater.js +105 -0
  102. package/dist/workflow/website-updater.js.map +1 -0
  103. package/dist/workflow/workflow-logger.d.ts +1 -1
  104. package/dist/workflow/workflow-logger.d.ts.map +1 -1
  105. package/dist/workflow/workflow-logger.js.map +1 -1
  106. package/package.json +1 -1
  107. package/src/adapters/gemini.ts +10 -4
  108. package/src/adapters/grok.ts +10 -4
  109. package/src/adapters/openai.ts +38 -6
  110. package/src/cli/interactive.ts +47 -0
  111. package/src/generators/all.ts +6 -1
  112. package/src/generators/doc-parser.ts +372 -0
  113. package/src/generators/templates/index.ts +4 -0
  114. package/src/generators/templates/website-components.ts +305 -0
  115. package/src/generators/templates/website-config.ts +291 -0
  116. package/src/generators/templates/website-conversion.ts +341 -0
  117. package/src/generators/templates/website-seo.ts +370 -0
  118. package/src/generators/templates/website.ts +451 -505
  119. package/src/generators/website-context.ts +265 -0
  120. package/src/generators/website.ts +109 -19
  121. package/src/state/index.ts +42 -0
  122. package/src/types/consensus.ts +3 -0
  123. package/src/types/website-strategy.ts +243 -0
  124. package/src/types/workflow.ts +15 -0
  125. package/src/workflow/auto-fix.ts +57 -3
  126. package/src/workflow/consensus.ts +2 -0
  127. package/src/workflow/execution-mode.ts +21 -0
  128. package/src/workflow/index.ts +25 -0
  129. package/src/workflow/overview.ts +469 -0
  130. package/src/workflow/plan-mode.ts +115 -4
  131. package/src/workflow/website-strategy.ts +305 -0
  132. package/src/workflow/website-updater.ts +131 -0
  133. package/src/workflow/workflow-logger.ts +1 -0
  134. package/tests/adapters/persona-switching.test.ts +63 -0
  135. package/tests/generators/website-components.test.ts +159 -0
  136. package/tests/generators/website-context.test.ts +222 -0
  137. package/tests/generators/website-seo-quality.test.ts +246 -0
  138. package/tests/workflow/auto-fix-enhanced.test.ts +61 -1
  139. package/tests/workflow/overview.test.ts +392 -0
  140. package/tests/workflow/website-strategy.test.ts +191 -0
@@ -0,0 +1,354 @@
1
+ /**
2
+ * Project overview generator
3
+ * Provides a comprehensive view of project state, plan, and progress
4
+ * with analysis of issues and ability to fix them
5
+ */
6
+ import path from 'node:path';
7
+ import { loadProject, getProgress, storeUserDocs, storeBrandContext } from '../state/index.js';
8
+ import { discoverProjectDocs, readProjectDocs, findBrandAssets, } from '../generators/website-context.js';
9
+ import { updateWebsiteContent } from './website-updater.js';
10
+ /**
11
+ * Generate a complete project overview from state
12
+ *
13
+ * @param projectDir - The project directory
14
+ * @returns Structured project overview with analysis
15
+ */
16
+ export async function generateOverview(projectDir) {
17
+ const state = await loadProject(projectDir);
18
+ const progress = await getProgress(projectDir);
19
+ // Extract specification summary
20
+ const specSummary = extractSpecSummary(state);
21
+ const keyFeatures = extractKeyFeatures(state);
22
+ // Build milestone details
23
+ const milestones = state.milestones.map((m) => ({
24
+ name: m.name,
25
+ status: m.status,
26
+ taskCount: m.tasks.length,
27
+ completedTasks: m.tasks.filter((t) => t.status === 'complete').length,
28
+ tasks: m.tasks.map((t) => ({
29
+ name: t.name,
30
+ status: t.status,
31
+ })),
32
+ }));
33
+ // Extract user doc file names if available
34
+ const userDocs = state.userDocs
35
+ ? extractDocNames(state.userDocs)
36
+ : undefined;
37
+ // Check for available docs in CWD that haven't been discovered
38
+ const parentDir = path.dirname(projectDir);
39
+ const availableDocPaths = await discoverProjectDocs(parentDir);
40
+ const availableDocs = availableDocPaths.map((p) => path.basename(p));
41
+ // Run analysis to detect issues
42
+ const issues = analyzeProject(state, availableDocs, progress);
43
+ return {
44
+ name: state.name,
45
+ idea: state.idea,
46
+ language: state.language,
47
+ phase: state.phase,
48
+ status: state.status,
49
+ specification: {
50
+ summary: specSummary,
51
+ keyFeatures,
52
+ },
53
+ plan: {
54
+ totalMilestones: state.milestones.length,
55
+ totalTasks: state.milestones.reduce((sum, m) => sum + m.tasks.length, 0),
56
+ milestones,
57
+ },
58
+ progress: {
59
+ completedMilestones: progress.completedMilestones,
60
+ completedTasks: progress.completedTasks,
61
+ percentComplete: progress.percentComplete,
62
+ },
63
+ userDocs,
64
+ brandContext: state.brandContext,
65
+ issues,
66
+ availableDocs,
67
+ };
68
+ }
69
+ /**
70
+ * Fix detected issues by re-discovering docs and updating website content
71
+ *
72
+ * @param projectDir - The project directory
73
+ * @param onProgress - Optional progress callback
74
+ * @returns Fix result with summary of actions taken
75
+ */
76
+ export async function fixOverviewIssues(projectDir, onProgress) {
77
+ const result = {
78
+ docsDiscovered: 0,
79
+ docsStored: false,
80
+ brandFound: false,
81
+ websiteUpdated: false,
82
+ messages: [],
83
+ };
84
+ let state = await loadProject(projectDir);
85
+ const parentDir = path.dirname(projectDir);
86
+ // Step 1: Re-discover project documentation
87
+ onProgress?.('Scanning for project documentation...');
88
+ const docPaths = await discoverProjectDocs(parentDir);
89
+ if (docPaths.length > 0) {
90
+ const userDocs = await readProjectDocs(docPaths);
91
+ state = await storeUserDocs(projectDir, userDocs);
92
+ result.docsDiscovered = docPaths.length;
93
+ result.docsStored = true;
94
+ const docNames = docPaths.map((p) => path.basename(p)).join(', ');
95
+ result.messages.push(`Discovered ${docPaths.length} doc(s): ${docNames}`);
96
+ onProgress?.(`Found ${docPaths.length} doc(s): ${docNames}`);
97
+ }
98
+ else {
99
+ result.messages.push('No project documentation found in parent directory');
100
+ onProgress?.('No project documentation found in parent directory');
101
+ }
102
+ // Step 2: Find brand assets
103
+ onProgress?.('Scanning for brand assets...');
104
+ const brandAssets = await findBrandAssets(parentDir);
105
+ if (brandAssets.logoPath) {
106
+ state = await storeBrandContext(projectDir, {
107
+ ...state.brandContext,
108
+ logoPath: brandAssets.logoPath,
109
+ });
110
+ result.brandFound = true;
111
+ result.messages.push(`Found logo: ${path.basename(brandAssets.logoPath)}`);
112
+ onProgress?.(`Found logo: ${path.basename(brandAssets.logoPath)}`);
113
+ }
114
+ // Extract primary/accent color from docs if not already set
115
+ // Use smart extraction: look for accent/primary CTA color tokens first,
116
+ // then fall back to brightness-filtered colors (skip very dark/light)
117
+ if (!state.brandContext?.primaryColor && state.userDocs) {
118
+ const accentMatch = state.userDocs.match(/accent[_-]?primary[^#]{0,40}(#[0-9a-fA-F]{6})/i)
119
+ || state.userDocs.match(/(?:primary\s+(?:brand\s+)?(?:accent|color|CTA))[^#]{0,40}(#[0-9a-fA-F]{6})/i);
120
+ const color = accentMatch ? accentMatch[1] : findBrightColor(state.userDocs);
121
+ if (color) {
122
+ state = await storeBrandContext(projectDir, {
123
+ ...state.brandContext,
124
+ primaryColor: color,
125
+ });
126
+ result.messages.push(`Extracted brand color: ${color}`);
127
+ onProgress?.(`Extracted brand color: ${color}`);
128
+ }
129
+ }
130
+ // Step 3: Update website content if applicable
131
+ const language = state.language;
132
+ if (language === 'website' || language === 'all' || language === 'fullstack') {
133
+ onProgress?.('Updating website content with discovered context...');
134
+ try {
135
+ await updateWebsiteContent(projectDir, state, language, onProgress);
136
+ result.websiteUpdated = true;
137
+ result.messages.push('Website content files updated with project context');
138
+ }
139
+ catch (err) {
140
+ result.messages.push(`Website update failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
141
+ }
142
+ }
143
+ // Summary
144
+ if (result.docsDiscovered === 0 && !result.brandFound) {
145
+ result.messages.push('Tip: Place project docs (spec, pricing, color-scheme, etc.) as .md files in the parent directory, then run /overview fix again');
146
+ }
147
+ return result;
148
+ }
149
+ /** Analyze project state and detect issues */
150
+ function analyzeProject(state, availableDocs, progress) {
151
+ const issues = [];
152
+ const push = (severity, category, message, fix) => issues.push({ severity, category, message, fix });
153
+ if (!state.userDocs && availableDocs.length > 0) {
154
+ push('warning', 'docs', `Found ${availableDocs.length} doc(s) in CWD (${availableDocs.join(', ')}) but project has no user docs stored`, 'Run /overview fix to discover and apply project documentation');
155
+ }
156
+ if (!state.userDocs && availableDocs.length === 0) {
157
+ push('warning', 'docs', 'No project documentation found. Website will use generic placeholder content.', 'Add .md files (spec, pricing, brand, etc.) to the project parent directory, then run /overview fix');
158
+ }
159
+ if (progress.totalTasks > 0 && progress.totalTasks <= 3) {
160
+ push('warning', 'plan', `Project has only ${progress.totalTasks} task(s) - this may indicate an incomplete or oversimplified plan`, 'Consider resetting to plan phase with richer specification');
161
+ }
162
+ if (!state.brandContext?.primaryColor && !state.brandContext?.logoPath) {
163
+ push('warning', 'brand', 'No brand context (colors, logo) detected. Website uses default styling.', 'Add a color-scheme.md or logo file to the project parent directory, then run /overview fix');
164
+ }
165
+ if (state.specification) {
166
+ const specStart = state.specification.trim().slice(0, 200).toLowerCase();
167
+ const genericPats = ["here's a comprehensive", "here is a comprehensive",
168
+ "here's a detailed", "here is a detailed", 'based on your idea', 'based on the idea'];
169
+ if (genericPats.some((p) => specStart.includes(p))) {
170
+ push('warning', 'spec', 'Specification appears to be generic AI-generated content without project-specific documentation input', 'Add project docs to CWD and run /overview fix to re-enrich. For a full re-spec, reset to plan phase.');
171
+ }
172
+ }
173
+ const hasWebsite = state.language === 'website' || state.language === 'all' || state.language === 'fullstack';
174
+ if (hasWebsite && !state.userDocs && state.phase === 'complete') {
175
+ push('error', 'website', 'Project includes a website but was completed without any user documentation. Website likely has placeholder content.', 'Run /overview fix to discover docs and update website template files');
176
+ }
177
+ return issues;
178
+ }
179
+ /**
180
+ * Format a project overview for terminal display
181
+ *
182
+ * @param overview - The project overview to format
183
+ * @returns Formatted string for terminal output
184
+ */
185
+ export function formatOverview(overview) {
186
+ const l = [''];
187
+ l.push(` PROJECT OVERVIEW: ${overview.name}`);
188
+ l.push(` ${'='.repeat(40 + overview.name.length)}`, '');
189
+ l.push(` Language: ${overview.language}`);
190
+ l.push(` Phase: ${overview.phase}`);
191
+ l.push(` Status: ${overview.status}`, '');
192
+ if (overview.specification.summary) {
193
+ l.push(' SPECIFICATION', ` ${overview.specification.summary}`);
194
+ if (overview.specification.keyFeatures.length > 0) {
195
+ l.push('', ' Key Features:');
196
+ for (const f of overview.specification.keyFeatures.slice(0, 8))
197
+ l.push(` - ${f}`);
198
+ }
199
+ l.push('');
200
+ }
201
+ const barWidth = 30;
202
+ const filled = Math.round((overview.progress.percentComplete / 100) * barWidth);
203
+ const bar = `[${'='.repeat(filled)}${filled < barWidth ? '>' : ''}${' '.repeat(Math.max(0, barWidth - filled - 1))}]`;
204
+ l.push(` Progress: ${bar} ${overview.progress.percentComplete}% (${overview.progress.completedTasks}/${overview.plan.totalTasks} tasks)`, '');
205
+ if (overview.plan.milestones.length > 0) {
206
+ l.push(' MILESTONES', ` ${'-'.repeat(50)}`);
207
+ for (const m of overview.plan.milestones) {
208
+ l.push(` ${getStatusIcon(m.status)} ${m.name} (${m.completedTasks}/${m.taskCount} tasks)`);
209
+ for (const t of m.tasks)
210
+ l.push(` ${getStatusIcon(t.status)} ${t.name}`);
211
+ l.push('');
212
+ }
213
+ }
214
+ else {
215
+ l.push(' No milestones defined yet.', '');
216
+ }
217
+ if (overview.userDocs && overview.userDocs.length > 0) {
218
+ l.push(' DISCOVERED DOCS');
219
+ for (const doc of overview.userDocs)
220
+ l.push(` - ${doc}`);
221
+ l.push('');
222
+ }
223
+ if (overview.brandContext) {
224
+ l.push(' BRAND CONTEXT');
225
+ if (overview.brandContext.primaryColor)
226
+ l.push(` Primary Color: ${overview.brandContext.primaryColor}`);
227
+ if (overview.brandContext.logoPath)
228
+ l.push(` Logo: ${path.basename(overview.brandContext.logoPath)}`);
229
+ l.push('');
230
+ }
231
+ if (overview.issues.length > 0) {
232
+ l.push(' ANALYSIS', ` ${'-'.repeat(50)}`);
233
+ for (const issue of overview.issues) {
234
+ const icon = issue.severity === 'error' ? '[!!]' : '[!]';
235
+ l.push(` ${icon} ${issue.category.toUpperCase()}: ${issue.message}`);
236
+ if (issue.fix)
237
+ l.push(` -> ${issue.fix}`);
238
+ }
239
+ l.push('');
240
+ }
241
+ if (overview.availableDocs.length > 0 && !overview.userDocs) {
242
+ l.push(' AVAILABLE DOCS (not yet imported)');
243
+ for (const doc of overview.availableDocs)
244
+ l.push(` - ${doc}`);
245
+ l.push('');
246
+ }
247
+ if (overview.issues.length > 0) {
248
+ l.push(' Run /overview fix to auto-discover docs, detect brand assets, and update website content.', '');
249
+ }
250
+ return l.join('\n');
251
+ }
252
+ /**
253
+ * Extract a summary from the specification
254
+ */
255
+ function extractSpecSummary(state) {
256
+ if (!state.specification)
257
+ return '';
258
+ const lines = state.specification.split('\n');
259
+ // Find first non-empty, non-heading line that isn't a generic AI preamble
260
+ const genericPrefixes = [
261
+ "here's a comprehensive",
262
+ "here is a comprehensive",
263
+ "here's a detailed",
264
+ 'based on your idea',
265
+ ];
266
+ for (const line of lines) {
267
+ const trimmed = line.trim();
268
+ if (trimmed && !trimmed.startsWith('#') && trimmed.length > 20) {
269
+ const lower = trimmed.toLowerCase();
270
+ if (!genericPrefixes.some((p) => lower.startsWith(p))) {
271
+ return trimmed.slice(0, 500);
272
+ }
273
+ }
274
+ }
275
+ return state.specification.slice(0, 500);
276
+ }
277
+ /**
278
+ * Extract key features from specification
279
+ */
280
+ function extractKeyFeatures(state) {
281
+ if (!state.specification)
282
+ return [];
283
+ const features = [];
284
+ const lines = state.specification.split('\n');
285
+ let inFeatures = false;
286
+ for (const line of lines) {
287
+ const trimmed = line.trim();
288
+ // Detect feature section headers
289
+ if (/^#{1,3}\s*(core\s+)?features/i.test(trimmed)) {
290
+ inFeatures = true;
291
+ continue;
292
+ }
293
+ // Stop at next heading
294
+ if (inFeatures && /^#{1,3}\s/.test(trimmed) && !/feature/i.test(trimmed)) {
295
+ break;
296
+ }
297
+ // Collect bullet points in feature section
298
+ if (inFeatures && /^[-*+]\s+/.test(trimmed)) {
299
+ const feature = trimmed.replace(/^[-*+]\s+/, '').replace(/^\*\*(.+?)\*\*:?\s*/, '$1: ');
300
+ if (feature.length > 5) {
301
+ features.push(feature.slice(0, 100));
302
+ }
303
+ }
304
+ }
305
+ return features.slice(0, 10);
306
+ }
307
+ /**
308
+ * Extract doc file names from raw docs string
309
+ */
310
+ function extractDocNames(rawDocs) {
311
+ const names = [];
312
+ const headerPattern = /^--- (.+) ---$/gm;
313
+ let match;
314
+ while ((match = headerPattern.exec(rawDocs)) !== null) {
315
+ names.push(match[1]);
316
+ }
317
+ return names;
318
+ }
319
+ /**
320
+ * Get a status icon for terminal display
321
+ */
322
+ function getStatusIcon(status) {
323
+ switch (status) {
324
+ case 'complete':
325
+ return '[x]';
326
+ case 'in-progress':
327
+ return '[~]';
328
+ case 'failed':
329
+ return '[!]';
330
+ case 'paused':
331
+ return '[-]';
332
+ default:
333
+ return '[ ]';
334
+ }
335
+ }
336
+ /**
337
+ * Find first hex color that isn't very dark or very light
338
+ * Skips background/neutral colors to find a reasonable brand accent
339
+ */
340
+ function findBrightColor(text) {
341
+ const allColors = [...text.matchAll(/#([0-9a-fA-F]{6})/g)];
342
+ for (const match of allColors) {
343
+ const hex = match[1];
344
+ const r = parseInt(hex.substring(0, 2), 16);
345
+ const g = parseInt(hex.substring(2, 4), 16);
346
+ const b = parseInt(hex.substring(4, 6), 16);
347
+ const brightness = (r * 299 + g * 587 + b * 114) / 1000;
348
+ if (brightness > 60 && brightness < 210) {
349
+ return '#' + hex;
350
+ }
351
+ }
352
+ return undefined;
353
+ }
354
+ //# sourceMappingURL=overview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../src/workflow/overview.ts"],"names":[],"mappings":"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"}
@@ -30,9 +30,10 @@ export interface PlanModeResult {
30
30
  * @param idea - The brief project idea
31
31
  * @param language - Target programming language
32
32
  * @param onProgress - Progress callback
33
+ * @param userDocs - Optional user documentation for context
33
34
  * @returns Expanded specification
34
35
  */
35
- export declare function expandIdea(idea: string, language: OutputLanguage, onProgress?: (message: string) => void): Promise<string>;
36
+ export declare function expandIdea(idea: string, language: OutputLanguage, onProgress?: (message: string) => void, userDocs?: string): Promise<string>;
36
37
  /**
37
38
  * Create a development plan from a specification
38
39
  *
@@ -1 +1 @@
1
- {"version":3,"file":"plan-mode.d.ts","sourceRoot":"","sources":["../../src/workflow/plan-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAQ,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAW7D,OAAO,EAAyB,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAIpF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACrC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,MAAW,EACpB,QAAQ,GAAE,cAAyB,EACnC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACrC,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACrC,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAkB,GAC3B,OAAO,CAAC,MAAM,CAAC,CA2BjB;AA4CD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAMrE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAMlF;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB,CAqCxF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH,CA2DA;AAmDD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA+EvF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAsRzE;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CA0XzB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,GAC3C,OAAO,CAAC,cAAc,CAAC,CAezB"}
1
+ {"version":3,"file":"plan-mode.d.ts","sourceRoot":"","sources":["../../src/workflow/plan-mode.ts"],"names":[],"mappings":"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"}
@@ -7,21 +7,24 @@ import path from 'node:path';
7
7
  import { isWorkspace } from '../types/project.js';
8
8
  import { expandIdea as openaiExpandIdea } from '../adapters/openai.js';
9
9
  import { createPlan as claudeCreatePlan, analyzeCodebase } from '../adapters/claude.js';
10
- import { createProject, loadProject, setPhase, storePlan, storeSpecification, addMilestones, } from '../state/index.js';
10
+ import { createProject, loadProject, setPhase, storePlan, storeSpecification, storeUserDocs, storeBrandContext, storeWebsiteStrategyPath, addMilestones, } from '../state/index.js';
11
+ import { discoverProjectDocs, readProjectDocs, findBrandAssets, resolveBrandAssets, } from '../generators/website-context.js';
11
12
  import { iterateUntilConsensus } from './consensus.js';
12
13
  import { getWorkflowLogger } from './workflow-logger.js';
13
14
  import { designUI, saveUISpecification } from './ui-designer.js';
15
+ import { generateWebsiteStrategy, formatStrategyForPlanContext, storeWebsiteStrategy, loadWebsiteStrategy, } from './website-strategy.js';
14
16
  /**
15
17
  * Expand a brief idea into a detailed specification
16
18
  *
17
19
  * @param idea - The brief project idea
18
20
  * @param language - Target programming language
19
21
  * @param onProgress - Progress callback
22
+ * @param userDocs - Optional user documentation for context
20
23
  * @returns Expanded specification
21
24
  */
22
- export async function expandIdea(idea, language, onProgress) {
25
+ export async function expandIdea(idea, language, onProgress, userDocs) {
23
26
  onProgress?.('Expanding idea into specification...');
24
- const specification = await openaiExpandIdea(idea, language);
27
+ const specification = await openaiExpandIdea(idea, language, userDocs);
25
28
  onProgress?.('Specification created');
26
29
  return specification;
27
30
  }
@@ -716,11 +719,31 @@ export async function runPlanMode(spec, options) {
716
719
  language: state.language,
717
720
  });
718
721
  }
722
+ // Discover user documentation from the CWD (parent of project dir)
723
+ let userDocs = state.userDocs || '';
724
+ if (!userDocs) {
725
+ const parentDir = path.dirname(projectDir);
726
+ const docPaths = await discoverProjectDocs(parentDir);
727
+ if (docPaths.length > 0) {
728
+ userDocs = await readProjectDocs(docPaths);
729
+ onProgress?.('doc-discovery', `Found ${docPaths.length} project doc(s)`);
730
+ state = await storeUserDocs(projectDir, userDocs);
731
+ await logger.info('init', 'docs_found', `Found ${docPaths.length} project docs`, {
732
+ docCount: docPaths.length,
733
+ docPaths: docPaths.map((p) => path.basename(p)),
734
+ });
735
+ }
736
+ const brandAssets = await findBrandAssets(parentDir);
737
+ if (brandAssets.logoPath) {
738
+ state = await storeBrandContext(projectDir, { logoPath: brandAssets.logoPath });
739
+ onProgress?.('doc-discovery', `Found brand logo: ${path.basename(brandAssets.logoPath)}`);
740
+ }
741
+ }
719
742
  // Expand idea if we don't have a specification
720
743
  if (!state.specification) {
721
744
  onProgress?.('expand-idea', 'Expanding idea into specification...');
722
745
  await logger.stageStart('plan-generation', 'Expanding idea into specification');
723
- const specification = await expandIdea(spec.idea, spec.language, (msg) => onProgress?.('expand-idea', msg));
746
+ const specification = await expandIdea(spec.idea, spec.language, (msg) => onProgress?.('expand-idea', msg), userDocs || undefined);
724
747
  state = await storeSpecification(projectDir, specification);
725
748
  onProgress?.('expand-idea', 'Specification complete');
726
749
  await logger.stageComplete('plan-generation', 'Specification created', {
@@ -747,6 +770,47 @@ export async function runPlanMode(spec, options) {
747
770
  error: uiError instanceof Error ? uiError.message : 'Unknown error',
748
771
  });
749
772
  }
773
+ // Generate website strategy for website projects (after spec, before plan)
774
+ const isWebsiteProject = spec.language === 'website' || spec.language === 'all';
775
+ let websiteStrategy;
776
+ if (isWebsiteProject && state.specification) {
777
+ try {
778
+ onProgress?.('get-context', 'Generating website marketing strategy...');
779
+ await logger.stageStart('website-strategy', 'Generating website marketing strategy');
780
+ const parentDir = path.dirname(projectDir);
781
+ const brandAssets = await resolveBrandAssets(parentDir, state.brandContext);
782
+ const strategyInput = {
783
+ productContext: (userDocs || '') + '\n\n' + (state.specification || ''),
784
+ projectName: spec.name || state.name,
785
+ brandAssets,
786
+ };
787
+ // Check for cached strategy
788
+ const cached = await loadWebsiteStrategy(projectDir);
789
+ if (cached) {
790
+ websiteStrategy = cached.strategy;
791
+ onProgress?.('get-context', `Loaded cached strategy: ${cached.strategy.siteArchitecture.pages.length} pages`);
792
+ }
793
+ else {
794
+ const result = await generateWebsiteStrategy(strategyInput, (msg) => onProgress?.('get-context', msg));
795
+ websiteStrategy = result.strategy;
796
+ await storeWebsiteStrategy(projectDir, result.strategy, result.metadata);
797
+ state = await storeWebsiteStrategyPath(projectDir, '.popeye/website-strategy.json');
798
+ onProgress?.('get-context', `Strategy: ${result.strategy.siteArchitecture.pages.length} pages, ` +
799
+ `${result.strategy.seoStrategy.primaryKeywords.length} keywords`);
800
+ }
801
+ await logger.stageComplete('website-strategy', 'Website strategy generated', {
802
+ pageCount: websiteStrategy.siteArchitecture.pages.length,
803
+ keywordCount: websiteStrategy.seoStrategy.primaryKeywords.length,
804
+ });
805
+ }
806
+ catch (strategyError) {
807
+ // Non-blocking: strategy generation failure should not stop the workflow
808
+ onProgress?.('get-context', `Website strategy skipped: ${strategyError instanceof Error ? strategyError.message : 'Unknown error'}`);
809
+ await logger.warn('website-strategy', 'strategy_skipped', 'Website strategy was skipped', {
810
+ error: strategyError instanceof Error ? strategyError.message : 'Unknown error',
811
+ });
812
+ }
813
+ }
750
814
  // Get project context
751
815
  onProgress?.('get-context', 'Gathering project context...');
752
816
  let context = await getProjectContext(projectDir, (msg) => onProgress?.('get-context', msg));
@@ -755,6 +819,11 @@ export async function runPlanMode(spec, options) {
755
819
  onProgress?.('get-context', 'Incorporating additional guidance...');
756
820
  context = `${context}\n\nADDITIONAL GUIDANCE FROM USER:\n${additionalContext}`;
757
821
  }
822
+ // Inject website strategy as a separate context block (not appended to specification)
823
+ if (websiteStrategy) {
824
+ const strategyContext = formatStrategyForPlanContext(websiteStrategy);
825
+ context = `${context}\n\n## WEBSITE STRATEGY (authoritative reference)\n${strategyContext}`;
826
+ }
758
827
  // Create initial plan if we don't have one
759
828
  if (!state.plan) {
760
829
  onProgress?.('create-plan', 'Creating development plan...');
@@ -789,9 +858,18 @@ export async function runPlanMode(spec, options) {
789
858
  // Run consensus loop
790
859
  onProgress?.('consensus', 'Starting consensus review...');
791
860
  await logger.stageStart('consensus', 'Starting consensus review process');
861
+ // Set marketing persona for website project reviews
862
+ const resolvedConsensusConfig = { ...consensusConfig };
863
+ if (isWebsiteProject && !resolvedConsensusConfig.reviewerPersona) {
864
+ resolvedConsensusConfig.reviewerPersona =
865
+ 'a Senior Product Marketing Strategist, SEO expert, and Fullstack Web Architect. ' +
866
+ 'Evaluate for: conversion optimization, messaging clarity, SEO best practices ' +
867
+ '(JSON-LD, heading hierarchy, meta tags), Lighthouse 95+ performance, WCAG 2.1 AA accessibility. ' +
868
+ 'Reject generic template structures. Every section must connect to real product capabilities.';
869
+ }
792
870
  const consensusResult = await iterateUntilConsensus(state.plan, context, {
793
871
  projectDir,
794
- config: consensusConfig,
872
+ config: resolvedConsensusConfig,
795
873
  isFullstack: isWorkspace(spec.language),
796
874
  language: spec.language,
797
875
  onIteration: (iteration, result) => {