@rankcli/agent-runtime 0.0.15 → 0.0.17

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 (203) hide show
  1. package/README.md +5 -4
  2. package/dist/index.d.mts +44 -393
  3. package/dist/index.d.ts +44 -393
  4. package/dist/index.js +22098 -26131
  5. package/dist/index.mjs +11834 -15857
  6. package/package.json +10 -4
  7. package/scripts/build-deno.ts +0 -134
  8. package/src/analyzers/core-web-vitals-analyzer.test.ts +0 -236
  9. package/src/analyzers/core-web-vitals-analyzer.ts +0 -557
  10. package/src/analyzers/geo-analyzer.test.ts +0 -310
  11. package/src/analyzers/geo-analyzer.ts +0 -814
  12. package/src/analyzers/image-optimization-analyzer.test.ts +0 -145
  13. package/src/analyzers/image-optimization-analyzer.ts +0 -348
  14. package/src/analyzers/index.ts +0 -233
  15. package/src/analyzers/internal-linking-analyzer.test.ts +0 -141
  16. package/src/analyzers/internal-linking-analyzer.ts +0 -419
  17. package/src/analyzers/mobile-seo-analyzer.test.ts +0 -140
  18. package/src/analyzers/mobile-seo-analyzer.ts +0 -455
  19. package/src/analyzers/security-headers-analyzer.test.ts +0 -115
  20. package/src/analyzers/security-headers-analyzer.ts +0 -318
  21. package/src/analyzers/structured-data-analyzer.test.ts +0 -210
  22. package/src/analyzers/structured-data-analyzer.ts +0 -590
  23. package/src/audit/ai/analyzer.ts +0 -347
  24. package/src/audit/ai/index.ts +0 -29
  25. package/src/audit/ai/prompts/content-analysis.ts +0 -271
  26. package/src/audit/ai/types.ts +0 -179
  27. package/src/audit/checks/additional-checks.ts +0 -439
  28. package/src/audit/checks/agent-experience.ts +0 -108
  29. package/src/audit/checks/ai-citation-worthiness.ts +0 -399
  30. package/src/audit/checks/ai-content-structure.ts +0 -325
  31. package/src/audit/checks/ai-readiness.ts +0 -406
  32. package/src/audit/checks/anchor-text.ts +0 -179
  33. package/src/audit/checks/answer-conciseness.ts +0 -322
  34. package/src/audit/checks/asset-minification.ts +0 -270
  35. package/src/audit/checks/bing-optimization.ts +0 -206
  36. package/src/audit/checks/brand-mention-optimization.ts +0 -349
  37. package/src/audit/checks/caching-headers.ts +0 -305
  38. package/src/audit/checks/canonical-advanced.ts +0 -150
  39. package/src/audit/checks/canonical-domain.ts +0 -196
  40. package/src/audit/checks/citation-quality.ts +0 -358
  41. package/src/audit/checks/client-rendering.ts +0 -542
  42. package/src/audit/checks/color-contrast.ts +0 -342
  43. package/src/audit/checks/content-freshness.ts +0 -170
  44. package/src/audit/checks/content-science.ts +0 -589
  45. package/src/audit/checks/conversion-elements.ts +0 -526
  46. package/src/audit/checks/crawlability.ts +0 -220
  47. package/src/audit/checks/directory-listing.ts +0 -172
  48. package/src/audit/checks/dom-analysis.ts +0 -191
  49. package/src/audit/checks/dom-size.ts +0 -246
  50. package/src/audit/checks/duplicate-content.ts +0 -194
  51. package/src/audit/checks/eeat-signals.ts +0 -990
  52. package/src/audit/checks/entity-seo.ts +0 -396
  53. package/src/audit/checks/featured-snippet.ts +0 -473
  54. package/src/audit/checks/freshness-signals.ts +0 -443
  55. package/src/audit/checks/funnel-intent.ts +0 -463
  56. package/src/audit/checks/hreflang.ts +0 -174
  57. package/src/audit/checks/html-compliance.ts +0 -302
  58. package/src/audit/checks/image-dimensions.ts +0 -167
  59. package/src/audit/checks/images.ts +0 -160
  60. package/src/audit/checks/indexnow.ts +0 -275
  61. package/src/audit/checks/interactive-tools.ts +0 -475
  62. package/src/audit/checks/internal-link-graph.ts +0 -436
  63. package/src/audit/checks/keyword-analysis.ts +0 -239
  64. package/src/audit/checks/keyword-cannibalization.ts +0 -385
  65. package/src/audit/checks/keyword-placement.ts +0 -471
  66. package/src/audit/checks/links.ts +0 -273
  67. package/src/audit/checks/llms-txt.ts +0 -224
  68. package/src/audit/checks/local-seo.ts +0 -296
  69. package/src/audit/checks/mobile.ts +0 -167
  70. package/src/audit/checks/modern-images.ts +0 -226
  71. package/src/audit/checks/navboost-signals.ts +0 -395
  72. package/src/audit/checks/on-page.ts +0 -209
  73. package/src/audit/checks/page-resources.ts +0 -285
  74. package/src/audit/checks/pagination.ts +0 -180
  75. package/src/audit/checks/performance.ts +0 -153
  76. package/src/audit/checks/platform-presence.ts +0 -580
  77. package/src/audit/checks/rag-chunk-readiness.test.ts +0 -159
  78. package/src/audit/checks/rag-chunk-readiness.ts +0 -163
  79. package/src/audit/checks/redirect-analysis.ts +0 -153
  80. package/src/audit/checks/redirect-chain.ts +0 -389
  81. package/src/audit/checks/resource-hints.ts +0 -420
  82. package/src/audit/checks/responsive-css.ts +0 -247
  83. package/src/audit/checks/responsive-images.ts +0 -396
  84. package/src/audit/checks/review-ecosystem.ts +0 -415
  85. package/src/audit/checks/robots-validation.ts +0 -373
  86. package/src/audit/checks/security-headers.ts +0 -188
  87. package/src/audit/checks/security.ts +0 -144
  88. package/src/audit/checks/serp-preview.ts +0 -251
  89. package/src/audit/checks/site-maturity.ts +0 -453
  90. package/src/audit/checks/social-meta.test.ts +0 -275
  91. package/src/audit/checks/social-meta.ts +0 -134
  92. package/src/audit/checks/soft-404.ts +0 -151
  93. package/src/audit/checks/structured-data.ts +0 -238
  94. package/src/audit/checks/tech-detection.ts +0 -496
  95. package/src/audit/checks/topical-clusters.ts +0 -435
  96. package/src/audit/checks/tracker-bloat.ts +0 -462
  97. package/src/audit/checks/tracking-verification.test.ts +0 -371
  98. package/src/audit/checks/tracking-verification.ts +0 -636
  99. package/src/audit/checks/url-safety.ts +0 -682
  100. package/src/audit/deno-entry.ts +0 -66
  101. package/src/audit/discovery/index.ts +0 -15
  102. package/src/audit/discovery/link-crawler.ts +0 -233
  103. package/src/audit/discovery/repo-routes.ts +0 -347
  104. package/src/audit/engine.ts +0 -633
  105. package/src/audit/fixes/index.ts +0 -209
  106. package/src/audit/fixes/social-meta-fixes.test.ts +0 -329
  107. package/src/audit/fixes/social-meta-fixes.ts +0 -463
  108. package/src/audit/index.ts +0 -74
  109. package/src/audit/runner.test.ts +0 -299
  110. package/src/audit/runner.ts +0 -130
  111. package/src/audit/types.ts +0 -1987
  112. package/src/content/featured-snippet.ts +0 -367
  113. package/src/content/generator.test.ts +0 -534
  114. package/src/content/generator.ts +0 -501
  115. package/src/content/headline.ts +0 -317
  116. package/src/content/index.ts +0 -62
  117. package/src/content/intent.ts +0 -258
  118. package/src/content/keyword-density.ts +0 -349
  119. package/src/content/readability.ts +0 -262
  120. package/src/executor.ts +0 -336
  121. package/src/fixer/framework-fixes.test.ts +0 -489
  122. package/src/fixer/framework-fixes.ts +0 -5287
  123. package/src/fixer/index.ts +0 -6
  124. package/src/fixer/schemas.ts +0 -971
  125. package/src/fixer.ts +0 -642
  126. package/src/frameworks/detector.test.ts +0 -248
  127. package/src/frameworks/detector.ts +0 -899
  128. package/src/frameworks/index.ts +0 -68
  129. package/src/frameworks/recipes/angular.yaml +0 -171
  130. package/src/frameworks/recipes/astro.yaml +0 -206
  131. package/src/frameworks/recipes/django.yaml +0 -180
  132. package/src/frameworks/recipes/laravel.yaml +0 -137
  133. package/src/frameworks/recipes/nextjs.yaml +0 -268
  134. package/src/frameworks/recipes/nuxt.yaml +0 -175
  135. package/src/frameworks/recipes/rails.yaml +0 -188
  136. package/src/frameworks/recipes/react.yaml +0 -202
  137. package/src/frameworks/recipes/sveltekit.yaml +0 -154
  138. package/src/frameworks/recipes/vue.yaml +0 -137
  139. package/src/frameworks/recipes/wordpress.yaml +0 -209
  140. package/src/frameworks/suggestion-engine.ts +0 -357
  141. package/src/geo/geo-content.test.ts +0 -305
  142. package/src/geo/geo-content.ts +0 -266
  143. package/src/geo/geo-history.test.ts +0 -473
  144. package/src/geo/geo-history.ts +0 -433
  145. package/src/geo/geo-tracker.test.ts +0 -359
  146. package/src/geo/geo-tracker.ts +0 -411
  147. package/src/geo/index.ts +0 -11
  148. package/src/geo/llm-citation-checker.ts +0 -188
  149. package/src/git/commit-helper.test.ts +0 -261
  150. package/src/git/commit-helper.ts +0 -329
  151. package/src/git/index.ts +0 -12
  152. package/src/git/pr-helper.test.ts +0 -284
  153. package/src/git/pr-helper.ts +0 -307
  154. package/src/index.ts +0 -76
  155. package/src/keywords/ai-keyword-engine.ts +0 -1062
  156. package/src/keywords/ai-summarizer.ts +0 -387
  157. package/src/keywords/ci-mode.ts +0 -555
  158. package/src/keywords/engine.ts +0 -359
  159. package/src/keywords/index.ts +0 -151
  160. package/src/keywords/llm-judge.ts +0 -357
  161. package/src/keywords/nlp-analysis.ts +0 -706
  162. package/src/keywords/prioritizer.ts +0 -295
  163. package/src/keywords/site-crawler.ts +0 -342
  164. package/src/keywords/sources/autocomplete.ts +0 -139
  165. package/src/keywords/sources/competitive-search.ts +0 -450
  166. package/src/keywords/sources/competitor-analysis.ts +0 -374
  167. package/src/keywords/sources/dataforseo.ts +0 -206
  168. package/src/keywords/sources/free-sources.ts +0 -294
  169. package/src/keywords/sources/gsc.ts +0 -123
  170. package/src/keywords/topic-grouping.ts +0 -327
  171. package/src/keywords/types.ts +0 -144
  172. package/src/keywords/wizard.ts +0 -457
  173. package/src/loader.ts +0 -40
  174. package/src/ranking/index.ts +0 -5
  175. package/src/ranking/serp-client.ts +0 -348
  176. package/src/ranking/tracker.ts +0 -380
  177. package/src/ranking/types.ts +0 -123
  178. package/src/reports/index.ts +0 -7
  179. package/src/reports/report-generator.test.ts +0 -293
  180. package/src/reports/report-generator.ts +0 -713
  181. package/src/scheduler/alerts.test.ts +0 -458
  182. package/src/scheduler/alerts.ts +0 -328
  183. package/src/scheduler/index.ts +0 -8
  184. package/src/scheduler/scheduled-audit.test.ts +0 -377
  185. package/src/scheduler/scheduled-audit.ts +0 -149
  186. package/src/test/integration-test.ts +0 -325
  187. package/src/tools/analyzer.ts +0 -373
  188. package/src/tools/crawl.ts +0 -293
  189. package/src/tools/files.ts +0 -301
  190. package/src/tools/h1-fixer.ts +0 -249
  191. package/src/tools/index.ts +0 -67
  192. package/src/tracking/github-action.ts +0 -326
  193. package/src/tracking/google-analytics.ts +0 -265
  194. package/src/tracking/index.ts +0 -45
  195. package/src/tracking/report-generator.ts +0 -386
  196. package/src/tracking/search-console.ts +0 -335
  197. package/src/types.ts +0 -148
  198. package/src/utils/http.ts +0 -302
  199. package/src/wasm-adapter.ts +0 -297
  200. package/src/wasm-entry.ts +0 -14
  201. package/tsconfig.json +0 -17
  202. package/tsup.wasm.config.ts +0 -26
  203. package/vitest.config.ts +0 -15
@@ -1,387 +0,0 @@
1
- /**
2
- * AI-Powered Site Summarizer
3
- *
4
- * Uses OpenAI to understand what a site does from crawled content.
5
- * Extracts: product, audience, features, industry, positioning.
6
- */
7
-
8
- import OpenAI from 'openai';
9
- import type { SiteCrawlResult } from './site-crawler.js';
10
-
11
- export interface SiteSummary {
12
- /** Primary product/service name */
13
- productName: string;
14
- /** What the product does (1-2 sentences) */
15
- productDescription: string;
16
- /** Target audience description */
17
- targetAudience: string;
18
- /** Key features/benefits (3-7 items) */
19
- keyFeatures: string[];
20
- /** Industry/category */
21
- industry: string;
22
- /** Business model */
23
- businessModel: 'saas' | 'ecommerce' | 'marketplace' | 'agency' | 'media' | 'other';
24
- /** Unique value proposition */
25
- valueProposition: string;
26
- /** Niche focus (if specific segment) */
27
- nicheFocus?: string;
28
- /** Pricing tier detected */
29
- pricingTier?: 'free' | 'freemium' | 'paid' | 'enterprise' | 'unknown';
30
- /** Geographic focus */
31
- geographicFocus?: string;
32
- /** Primary use cases */
33
- useCases: string[];
34
- /** Problems solved */
35
- problemsSolved: string[];
36
- /** Seed keyword suggestions */
37
- suggestedSeedKeywords: string[];
38
- /** Confidence score (0-1) */
39
- confidence: number;
40
- /** What we're uncertain about */
41
- uncertainties: string[];
42
- }
43
-
44
- export interface SummarizerOptions {
45
- openaiApiKey: string;
46
- model?: string;
47
- maxTokens?: number;
48
- }
49
-
50
- const SUMMARIZER_PROMPT = `You are an expert SEO analyst. Analyze the following website content and extract key information for keyword research.
51
-
52
- WEBSITE CONTENT:
53
- {content}
54
-
55
- HEADINGS FOUND:
56
- {headings}
57
-
58
- PAGE TYPES DETECTED:
59
- - Product pages: {productPages}
60
- - Pricing pages: {pricingPages}
61
- - Blog posts: {blogPages}
62
- - Feature pages: {featurePages}
63
-
64
- Analyze this content and respond with a JSON object containing:
65
-
66
- {
67
- "productName": "The name of the product/service",
68
- "productDescription": "What it does in 1-2 sentences",
69
- "targetAudience": "Who this is for (be specific)",
70
- "keyFeatures": ["feature1", "feature2", "..."],
71
- "industry": "The industry/category (e.g., 'Marketing Automation', 'Project Management')",
72
- "businessModel": "saas|ecommerce|marketplace|agency|media|other",
73
- "valueProposition": "The unique value proposition",
74
- "nicheFocus": "Specific niche if focused (e.g., 'small businesses', 'developers'), or null if broad",
75
- "pricingTier": "free|freemium|paid|enterprise|unknown",
76
- "geographicFocus": "Geographic focus if any, or null",
77
- "useCases": ["use case 1", "use case 2", "..."],
78
- "problemsSolved": ["problem 1", "problem 2", "..."],
79
- "suggestedSeedKeywords": ["keyword1", "keyword2", "..."],
80
- "confidence": 0.0 to 1.0,
81
- "uncertainties": ["What we couldn't determine from the content"]
82
- }
83
-
84
- IMPORTANT:
85
- - suggestedSeedKeywords should include: product category keywords, feature keywords, problem keywords, and audience keywords
86
- - Be specific about the niche - don't say "businesses" if you can say "small e-commerce stores"
87
- - confidence should be low if the content is thin or unclear
88
- - List specific uncertainties that would need user input to resolve
89
-
90
- Respond ONLY with the JSON object, no other text.`;
91
-
92
- /**
93
- * Summarize a site using AI
94
- */
95
- export async function summarizeSite(
96
- crawlResult: SiteCrawlResult,
97
- options: SummarizerOptions
98
- ): Promise<SiteSummary> {
99
- const openai = new OpenAI({ apiKey: options.openaiApiKey });
100
- const model = options.model || 'gpt-4o-mini';
101
-
102
- // Prepare content (limit for token constraints)
103
- let content = crawlResult.aggregatedContent;
104
- if (content.length > 15000) {
105
- content = content.substring(0, 15000) + '\n...[truncated]';
106
- }
107
-
108
- // Prepare headings
109
- const headings = crawlResult.uniqueHeadings.slice(0, 30).join('\n');
110
-
111
- // Build prompt
112
- const prompt = SUMMARIZER_PROMPT
113
- .replace('{content}', content)
114
- .replace('{headings}', headings)
115
- .replace('{productPages}', String(crawlResult.detectedPageTypes.product))
116
- .replace('{pricingPages}', String(crawlResult.detectedPageTypes.pricing))
117
- .replace('{blogPages}', String(crawlResult.detectedPageTypes.blog))
118
- .replace('{featurePages}', String(crawlResult.detectedPageTypes.feature));
119
-
120
- console.log('🤖 Analyzing site content with AI...');
121
-
122
- try {
123
- const response = await openai.chat.completions.create({
124
- model,
125
- messages: [
126
- {
127
- role: 'system',
128
- content: 'You are an expert SEO analyst. Always respond with valid JSON only.',
129
- },
130
- {
131
- role: 'user',
132
- content: prompt,
133
- },
134
- ],
135
- temperature: 0.3,
136
- max_tokens: options.maxTokens || 2000,
137
- });
138
-
139
- const responseText = response.choices[0]?.message?.content || '';
140
-
141
- // Parse JSON response
142
- const jsonMatch = responseText.match(/\{[\s\S]*\}/);
143
- if (!jsonMatch) {
144
- throw new Error('No JSON found in response');
145
- }
146
-
147
- const summary = JSON.parse(jsonMatch[0]) as SiteSummary;
148
-
149
- // Validate and set defaults
150
- return {
151
- productName: summary.productName || 'Unknown Product',
152
- productDescription: summary.productDescription || 'No description available',
153
- targetAudience: summary.targetAudience || 'General audience',
154
- keyFeatures: summary.keyFeatures || [],
155
- industry: summary.industry || 'Unknown',
156
- businessModel: summary.businessModel || 'other',
157
- valueProposition: summary.valueProposition || '',
158
- nicheFocus: summary.nicheFocus || undefined,
159
- pricingTier: summary.pricingTier || 'unknown',
160
- geographicFocus: summary.geographicFocus || undefined,
161
- useCases: summary.useCases || [],
162
- problemsSolved: summary.problemsSolved || [],
163
- suggestedSeedKeywords: summary.suggestedSeedKeywords || [],
164
- confidence: Math.min(1, Math.max(0, summary.confidence || 0.5)),
165
- uncertainties: summary.uncertainties || [],
166
- };
167
- } catch (error) {
168
- console.error('AI summarization failed:', error);
169
-
170
- // Return fallback summary
171
- return createFallbackSummary(crawlResult);
172
- }
173
- }
174
-
175
- /**
176
- * Create a basic summary without AI (fallback)
177
- */
178
- export function createFallbackSummary(crawlResult: SiteCrawlResult): SiteSummary {
179
- // Extract from page titles
180
- const titles = crawlResult.pages.map((p) => p.title).filter(Boolean);
181
- const productName = titles[0]?.split(/[|\-–—:]/)[0]?.trim() || crawlResult.domain;
182
-
183
- // Extract key phrases from headings
184
- const keyFeatures = crawlResult.uniqueHeadings
185
- .filter((h) => h.length > 5 && h.length < 60)
186
- .slice(0, 7);
187
-
188
- // Extract potential seed keywords from titles and headings
189
- const allText = [...titles, ...crawlResult.uniqueHeadings].join(' ').toLowerCase();
190
- const words = allText.split(/\s+/).filter((w) => w.length > 4);
191
- const wordFreq = new Map<string, number>();
192
- for (const word of words) {
193
- wordFreq.set(word, (wordFreq.get(word) || 0) + 1);
194
- }
195
- const suggestedSeedKeywords = Array.from(wordFreq.entries())
196
- .sort((a, b) => b[1] - a[1])
197
- .slice(0, 10)
198
- .map(([word]) => word);
199
-
200
- // Detect business model from page types
201
- let businessModel: SiteSummary['businessModel'] = 'other';
202
- if (crawlResult.detectedPageTypes.pricing > 0) {
203
- businessModel = 'saas';
204
- } else if (crawlResult.detectedPageTypes.product > 2) {
205
- businessModel = 'ecommerce';
206
- }
207
-
208
- return {
209
- productName,
210
- productDescription: `Website at ${crawlResult.domain}`,
211
- targetAudience: 'Unknown - requires AI analysis or user input',
212
- keyFeatures,
213
- industry: 'Unknown',
214
- businessModel,
215
- valueProposition: '',
216
- useCases: [],
217
- problemsSolved: [],
218
- suggestedSeedKeywords,
219
- confidence: 0.2, // Low confidence for fallback
220
- uncertainties: [
221
- 'Target audience could not be determined',
222
- 'Industry classification is uncertain',
223
- 'Value proposition is unclear',
224
- 'Use cases need user input',
225
- ],
226
- };
227
- }
228
-
229
- /**
230
- * Enhance summary with competitive context
231
- */
232
- export async function enhanceSummaryWithCompetitors(
233
- summary: SiteSummary,
234
- competitors: string[],
235
- options: SummarizerOptions
236
- ): Promise<SiteSummary & { competitivePositioning: string }> {
237
- const openai = new OpenAI({ apiKey: options.openaiApiKey });
238
-
239
- const prompt = `Given this product summary:
240
- Product: ${summary.productName}
241
- Description: ${summary.productDescription}
242
- Industry: ${summary.industry}
243
- Key Features: ${summary.keyFeatures.join(', ')}
244
-
245
- And these competitors: ${competitors.join(', ')}
246
-
247
- Analyze the competitive positioning. If this product focuses on a niche segment while competitors are broader, identify that advantage. Respond with JSON:
248
-
249
- {
250
- "competitivePositioning": "Description of how this product is positioned vs competitors",
251
- "nicheAdvantages": ["advantage1", "advantage2"],
252
- "competitorKeywordsToTarget": ["keyword1", "keyword2"],
253
- "competitorKeywordsToAvoid": ["keyword1", "keyword2"],
254
- "updatedUncertainties": ["uncertainty1", "uncertainty2"]
255
- }`;
256
-
257
- try {
258
- const response = await openai.chat.completions.create({
259
- model: options.model || 'gpt-4o-mini',
260
- messages: [
261
- { role: 'system', content: 'Respond with valid JSON only.' },
262
- { role: 'user', content: prompt },
263
- ],
264
- temperature: 0.3,
265
- max_tokens: 1000,
266
- });
267
-
268
- const responseText = response.choices[0]?.message?.content || '';
269
- const jsonMatch = responseText.match(/\{[\s\S]*\}/);
270
- if (jsonMatch) {
271
- const analysis = JSON.parse(jsonMatch[0]);
272
- return {
273
- ...summary,
274
- competitivePositioning: analysis.competitivePositioning || '',
275
- suggestedSeedKeywords: [
276
- ...summary.suggestedSeedKeywords,
277
- ...(analysis.competitorKeywordsToTarget || []),
278
- ],
279
- uncertainties: [
280
- ...summary.uncertainties.filter(
281
- (u) => !analysis.updatedUncertainties?.includes(u)
282
- ),
283
- ...(analysis.updatedUncertainties || []),
284
- ],
285
- };
286
- }
287
- } catch (error) {
288
- console.error('Competitive analysis failed:', error);
289
- }
290
-
291
- return { ...summary, competitivePositioning: '' };
292
- }
293
-
294
- /**
295
- * Generate questions to reduce uncertainty
296
- */
297
- export function generateUncertaintyQuestions(
298
- summary: SiteSummary
299
- ): Array<{
300
- id: string;
301
- question: string;
302
- category: string;
303
- impact: number;
304
- options?: string[];
305
- }> {
306
- const questions: Array<{
307
- id: string;
308
- question: string;
309
- category: string;
310
- impact: number;
311
- options?: string[];
312
- }> = [];
313
-
314
- // Always ask about target audience if uncertain
315
- if (summary.confidence < 0.7 || summary.targetAudience.includes('Unknown')) {
316
- questions.push({
317
- id: 'target_audience',
318
- question: 'Who is your primary target customer?',
319
- category: 'audience',
320
- impact: 0.3,
321
- options: [
322
- 'Small businesses (1-50 employees)',
323
- 'Mid-market companies (50-500 employees)',
324
- 'Enterprise (500+ employees)',
325
- 'Developers/Technical users',
326
- 'Marketing teams',
327
- 'Individual consumers',
328
- 'Freelancers/Agencies',
329
- ],
330
- });
331
- }
332
-
333
- // Ask about industry if uncertain
334
- if (summary.industry === 'Unknown' || summary.confidence < 0.6) {
335
- questions.push({
336
- id: 'industry',
337
- question: 'What industry or category best describes your product?',
338
- category: 'product',
339
- impact: 0.25,
340
- });
341
- }
342
-
343
- // Ask about main problem solved
344
- if (summary.problemsSolved.length === 0) {
345
- questions.push({
346
- id: 'main_problem',
347
- question: 'What is the main problem your product solves?',
348
- category: 'product',
349
- impact: 0.35,
350
- });
351
- }
352
-
353
- // Ask about competitors
354
- questions.push({
355
- id: 'competitors',
356
- question: 'Who are your main competitors? (comma-separated)',
357
- category: 'competition',
358
- impact: 0.2,
359
- });
360
-
361
- // Ask about differentiator
362
- if (!summary.nicheFocus) {
363
- questions.push({
364
- id: 'differentiator',
365
- question: 'What makes your product different from competitors?',
366
- category: 'positioning',
367
- impact: 0.25,
368
- });
369
- }
370
-
371
- // Ask about goals
372
- questions.push({
373
- id: 'seo_goals',
374
- question: 'What are your SEO goals?',
375
- category: 'goals',
376
- impact: 0.15,
377
- options: [
378
- 'Get more signups/trials',
379
- 'Generate leads',
380
- 'Build brand awareness',
381
- 'Drive organic traffic',
382
- 'Rank for specific keywords',
383
- ],
384
- });
385
-
386
- return questions.sort((a, b) => b.impact - a.impact);
387
- }