lean-claudient-core 0.1.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.
- package/.reports/detailed-analysis_2026-06-20_01ed326b.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_08d39381.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_0a331144.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_0d54ffef.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_14bfa31c.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_211feac4.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_22381bc2.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_29b4ea0a.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_2df0ad14.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_343ec84c.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_3a01030d.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_3b4c99ec.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_3d368827.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_53544d3d.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_5721164a.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_57caf5e7.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_624302f5.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_62456384.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_636a52f1.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_63d1ad41.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_7451ccd7.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_74da4e9a.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_83a90083.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_867fbdd9.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_974c3299.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_a04639a2.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_a8e23d6d.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_aa9150f0.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_acbeee08.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_c4ffa0e2.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_c5f7684b.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_c963b1fa.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_d4bde41f.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_d6eb2497.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_ea6f7f58.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_ebf4e060.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_ec4313a9.html +200 -0
- package/.reports/detailed-analysis_2026-06-20_fc65d18e.html +200 -0
- package/.reports/executive-summary_2026-06-20_00406d50.html +109 -0
- package/.reports/executive-summary_2026-06-20_0bb202d3.html +109 -0
- package/.reports/executive-summary_2026-06-20_0bcd7481.html +109 -0
- package/.reports/executive-summary_2026-06-20_11506445.html +109 -0
- package/.reports/executive-summary_2026-06-20_13616cda.html +109 -0
- package/.reports/executive-summary_2026-06-20_19d41c2f.html +109 -0
- package/.reports/executive-summary_2026-06-20_1b0d6e96.html +109 -0
- package/.reports/executive-summary_2026-06-20_1e38670b.html +109 -0
- package/.reports/executive-summary_2026-06-20_1f32f793.html +109 -0
- package/.reports/executive-summary_2026-06-20_1f40f7d3.html +109 -0
- package/.reports/executive-summary_2026-06-20_25a40a7e.html +109 -0
- package/.reports/executive-summary_2026-06-20_26d11818.html +109 -0
- package/.reports/executive-summary_2026-06-20_26ed4593.html +109 -0
- package/.reports/executive-summary_2026-06-20_291b90a8.html +109 -0
- package/.reports/executive-summary_2026-06-20_2957a848.html +109 -0
- package/.reports/executive-summary_2026-06-20_2a04eb77.html +109 -0
- package/.reports/executive-summary_2026-06-20_2fa701f9.html +109 -0
- package/.reports/executive-summary_2026-06-20_327af8f5.html +109 -0
- package/.reports/executive-summary_2026-06-20_3418c729.html +109 -0
- package/.reports/executive-summary_2026-06-20_3571763d.html +109 -0
- package/.reports/executive-summary_2026-06-20_36225353.html +109 -0
- package/.reports/executive-summary_2026-06-20_3b2de891.html +109 -0
- package/.reports/executive-summary_2026-06-20_45b980c2.html +109 -0
- package/.reports/executive-summary_2026-06-20_46fcbf17.html +109 -0
- package/.reports/executive-summary_2026-06-20_48c8fa5e.html +109 -0
- package/.reports/executive-summary_2026-06-20_4ba55c43.html +109 -0
- package/.reports/executive-summary_2026-06-20_4f4498e6.html +109 -0
- package/.reports/executive-summary_2026-06-20_54c33bf0.html +109 -0
- package/.reports/executive-summary_2026-06-20_54cc7077.html +109 -0
- package/.reports/executive-summary_2026-06-20_5a12912e.html +109 -0
- package/.reports/executive-summary_2026-06-20_636fac87.html +109 -0
- package/.reports/executive-summary_2026-06-20_6587faaf.html +109 -0
- package/.reports/executive-summary_2026-06-20_6adbdd03.html +109 -0
- package/.reports/executive-summary_2026-06-20_6bf344ec.html +109 -0
- package/.reports/executive-summary_2026-06-20_7142aeed.html +109 -0
- package/.reports/executive-summary_2026-06-20_72bc0ceb.html +109 -0
- package/.reports/executive-summary_2026-06-20_775752ac.html +109 -0
- package/.reports/executive-summary_2026-06-20_7a9c3223.html +109 -0
- package/.reports/executive-summary_2026-06-20_808e6376.html +109 -0
- package/.reports/executive-summary_2026-06-20_8de9142d.html +109 -0
- package/.reports/executive-summary_2026-06-20_91981fbe.html +109 -0
- package/.reports/executive-summary_2026-06-20_93191c8c.html +109 -0
- package/.reports/executive-summary_2026-06-20_9be48a87.html +109 -0
- package/.reports/executive-summary_2026-06-20_9c127198.html +109 -0
- package/.reports/executive-summary_2026-06-20_9ee303ac.html +109 -0
- package/.reports/executive-summary_2026-06-20_9ee52709.html +109 -0
- package/.reports/executive-summary_2026-06-20_a0fa27de.html +109 -0
- package/.reports/executive-summary_2026-06-20_a1813e47.html +109 -0
- package/.reports/executive-summary_2026-06-20_a974edc1.html +109 -0
- package/.reports/executive-summary_2026-06-20_aa711737.html +109 -0
- package/.reports/executive-summary_2026-06-20_aa752246.html +109 -0
- package/.reports/executive-summary_2026-06-20_ac6f0927.html +109 -0
- package/.reports/executive-summary_2026-06-20_b231b143.html +109 -0
- package/.reports/executive-summary_2026-06-20_b570a2bd.html +109 -0
- package/.reports/executive-summary_2026-06-20_b6fbf650.html +109 -0
- package/.reports/executive-summary_2026-06-20_b9f8ddf3.html +109 -0
- package/.reports/executive-summary_2026-06-20_bf95cc63.html +109 -0
- package/.reports/executive-summary_2026-06-20_c0d0aefe.html +109 -0
- package/.reports/executive-summary_2026-06-20_c1933c36.html +109 -0
- package/.reports/executive-summary_2026-06-20_c99bba8a.html +109 -0
- package/.reports/executive-summary_2026-06-20_cc3846ac.html +109 -0
- package/.reports/executive-summary_2026-06-20_d485993c.html +109 -0
- package/.reports/executive-summary_2026-06-20_d56f75f7.html +109 -0
- package/.reports/executive-summary_2026-06-20_d57660cc.html +109 -0
- package/.reports/executive-summary_2026-06-20_dc036f62.html +109 -0
- package/.reports/executive-summary_2026-06-20_df783f47.html +109 -0
- package/.reports/executive-summary_2026-06-20_e2191adb.html +109 -0
- package/.reports/executive-summary_2026-06-20_e9f1d504.html +109 -0
- package/.reports/executive-summary_2026-06-20_ea82f5e1.html +109 -0
- package/.reports/executive-summary_2026-06-20_ec3e70cb.html +109 -0
- package/.reports/executive-summary_2026-06-20_ee6cf902.html +109 -0
- package/.reports/executive-summary_2026-06-20_f6cb657c.html +109 -0
- package/.reports/executive-summary_2026-06-20_f8c60046.html +109 -0
- package/.reports/executive-summary_2026-06-20_fa184840.html +109 -0
- package/.reports/executive-summary_2026-06-20_fc88bcb4.html +109 -0
- package/.reports/executive-summary_2026-06-20_ffa79c4e.html +109 -0
- package/README.md +53 -0
- package/dist/automation/actionApprover.d.ts +89 -0
- package/dist/automation/actionApprover.d.ts.map +1 -0
- package/dist/automation/actionApprover.js +264 -0
- package/dist/automation/actionApprover.js.map +1 -0
- package/dist/automation/actionExecutor.d.ts +125 -0
- package/dist/automation/actionExecutor.d.ts.map +1 -0
- package/dist/automation/actionExecutor.js +304 -0
- package/dist/automation/actionExecutor.js.map +1 -0
- package/dist/automation/alertRules.d.ts +55 -0
- package/dist/automation/alertRules.d.ts.map +1 -0
- package/dist/automation/alertRules.js +70 -0
- package/dist/automation/alertRules.js.map +1 -0
- package/dist/automation/alertSystem.d.ts +109 -0
- package/dist/automation/alertSystem.d.ts.map +1 -0
- package/dist/automation/alertSystem.js +303 -0
- package/dist/automation/alertSystem.js.map +1 -0
- package/dist/automation/competitorResponse.d.ts +119 -0
- package/dist/automation/competitorResponse.d.ts.map +1 -0
- package/dist/automation/competitorResponse.js +343 -0
- package/dist/automation/competitorResponse.js.map +1 -0
- package/dist/automation/composioClient.d.ts +107 -0
- package/dist/automation/composioClient.d.ts.map +1 -0
- package/dist/automation/composioClient.js +286 -0
- package/dist/automation/composioClient.js.map +1 -0
- package/dist/automation/crmExport.d.ts +116 -0
- package/dist/automation/crmExport.d.ts.map +1 -0
- package/dist/automation/crmExport.js +282 -0
- package/dist/automation/crmExport.js.map +1 -0
- package/dist/automation/crmIntegration.d.ts +83 -0
- package/dist/automation/crmIntegration.d.ts.map +1 -0
- package/dist/automation/crmIntegration.js +207 -0
- package/dist/automation/crmIntegration.js.map +1 -0
- package/dist/automation/gmailIntegration.d.ts +73 -0
- package/dist/automation/gmailIntegration.d.ts.map +1 -0
- package/dist/automation/gmailIntegration.js +184 -0
- package/dist/automation/gmailIntegration.js.map +1 -0
- package/dist/automation/index.d.ts +17 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js +17 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/jiraIntegration.d.ts +103 -0
- package/dist/automation/jiraIntegration.d.ts.map +1 -0
- package/dist/automation/jiraIntegration.js +222 -0
- package/dist/automation/jiraIntegration.js.map +1 -0
- package/dist/automation/jobQueue.d.ts +98 -0
- package/dist/automation/jobQueue.d.ts.map +1 -0
- package/dist/automation/jobQueue.js +207 -0
- package/dist/automation/jobQueue.js.map +1 -0
- package/dist/automation/leadQualification.d.ts +60 -0
- package/dist/automation/leadQualification.d.ts.map +1 -0
- package/dist/automation/leadQualification.js +204 -0
- package/dist/automation/leadQualification.js.map +1 -0
- package/dist/automation/qualificationRules.d.ts +100 -0
- package/dist/automation/qualificationRules.d.ts.map +1 -0
- package/dist/automation/qualificationRules.js +202 -0
- package/dist/automation/qualificationRules.js.map +1 -0
- package/dist/automation/responseTemplates.d.ts +64 -0
- package/dist/automation/responseTemplates.d.ts.map +1 -0
- package/dist/automation/responseTemplates.js +374 -0
- package/dist/automation/responseTemplates.js.map +1 -0
- package/dist/automation/scheduler.d.ts +85 -0
- package/dist/automation/scheduler.d.ts.map +1 -0
- package/dist/automation/scheduler.js +194 -0
- package/dist/automation/scheduler.js.map +1 -0
- package/dist/automation/types.d.ts +223 -0
- package/dist/automation/types.d.ts.map +1 -0
- package/dist/automation/types.js +32 -0
- package/dist/automation/types.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +575 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compression/caveman.d.ts +14 -0
- package/dist/compression/caveman.d.ts.map +1 -0
- package/dist/compression/caveman.js +188 -0
- package/dist/compression/caveman.js.map +1 -0
- package/dist/compression/caveman.test.d.ts +2 -0
- package/dist/compression/caveman.test.d.ts.map +1 -0
- package/dist/compression/caveman.test.js.map +1 -0
- package/dist/config/configManager.d.ts +6 -0
- package/dist/config/configManager.d.ts.map +1 -0
- package/dist/config/configManager.js +62 -0
- package/dist/config/configManager.js.map +1 -0
- package/dist/config/schema.d.ts +95 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/context/autoCompact.d.ts +19 -0
- package/dist/context/autoCompact.d.ts.map +1 -0
- package/dist/context/autoCompact.js +101 -0
- package/dist/context/autoCompact.js.map +1 -0
- package/dist/context/readDedup.d.ts +21 -0
- package/dist/context/readDedup.d.ts.map +1 -0
- package/dist/context/readDedup.js +55 -0
- package/dist/context/readDedup.js.map +1 -0
- package/dist/context/toolBudgets.d.ts +15 -0
- package/dist/context/toolBudgets.d.ts.map +1 -0
- package/dist/context/toolBudgets.js +35 -0
- package/dist/context/toolBudgets.js.map +1 -0
- package/dist/core/auditLogger.d.ts +30 -0
- package/dist/core/auditLogger.d.ts.map +1 -0
- package/dist/core/auditLogger.js +51 -0
- package/dist/core/auditLogger.js.map +1 -0
- package/dist/core/stateManager.d.ts +10 -0
- package/dist/core/stateManager.d.ts.map +1 -0
- package/dist/core/stateManager.js +59 -0
- package/dist/core/stateManager.js.map +1 -0
- package/dist/database/feedbackSchema.d.ts +80 -0
- package/dist/database/feedbackSchema.d.ts.map +1 -0
- package/dist/database/feedbackSchema.js +94 -0
- package/dist/database/feedbackSchema.js.map +1 -0
- package/dist/database/leadsSchema.d.ts +99 -0
- package/dist/database/leadsSchema.d.ts.map +1 -0
- package/dist/database/leadsSchema.js +136 -0
- package/dist/database/leadsSchema.js.map +1 -0
- package/dist/intelligence/competitorScoring.d.ts +25 -0
- package/dist/intelligence/competitorScoring.d.ts.map +1 -0
- package/dist/intelligence/competitorScoring.js +181 -0
- package/dist/intelligence/competitorScoring.js.map +1 -0
- package/dist/intelligence/competitorTracker.d.ts +36 -0
- package/dist/intelligence/competitorTracker.d.ts.map +1 -0
- package/dist/intelligence/competitorTracker.js +286 -0
- package/dist/intelligence/competitorTracker.js.map +1 -0
- package/dist/intelligence/competitorTypes.d.ts +93 -0
- package/dist/intelligence/competitorTypes.d.ts.map +1 -0
- package/dist/intelligence/competitorTypes.js +6 -0
- package/dist/intelligence/competitorTypes.js.map +1 -0
- package/dist/intelligence/competitors.json +76 -0
- package/dist/intelligence/feedbackLoop.d.ts +118 -0
- package/dist/intelligence/feedbackLoop.d.ts.map +1 -0
- package/dist/intelligence/feedbackLoop.js +368 -0
- package/dist/intelligence/feedbackLoop.js.map +1 -0
- package/dist/intelligence/gitHubTracker.d.ts +14 -0
- package/dist/intelligence/gitHubTracker.d.ts.map +1 -0
- package/dist/intelligence/gitHubTracker.js +153 -0
- package/dist/intelligence/gitHubTracker.js.map +1 -0
- package/dist/intelligence/hackerNewsScanner.d.ts +21 -0
- package/dist/intelligence/hackerNewsScanner.d.ts.map +1 -0
- package/dist/intelligence/hackerNewsScanner.js +88 -0
- package/dist/intelligence/hackerNewsScanner.js.map +1 -0
- package/dist/intelligence/hiringSignals.d.ts +16 -0
- package/dist/intelligence/hiringSignals.d.ts.map +1 -0
- package/dist/intelligence/hiringSignals.js +132 -0
- package/dist/intelligence/hiringSignals.js.map +1 -0
- package/dist/intelligence/index.d.ts +9 -0
- package/dist/intelligence/index.d.ts.map +1 -0
- package/dist/intelligence/index.js +9 -0
- package/dist/intelligence/index.js.map +1 -0
- package/dist/intelligence/leadEnrichment.d.ts +59 -0
- package/dist/intelligence/leadEnrichment.d.ts.map +1 -0
- package/dist/intelligence/leadEnrichment.js +209 -0
- package/dist/intelligence/leadEnrichment.js.map +1 -0
- package/dist/intelligence/leadEnrichmentTypes.d.ts +49 -0
- package/dist/intelligence/leadEnrichmentTypes.d.ts.map +1 -0
- package/dist/intelligence/leadEnrichmentTypes.js +7 -0
- package/dist/intelligence/leadEnrichmentTypes.js.map +1 -0
- package/dist/intelligence/marketScanner.d.ts +18 -0
- package/dist/intelligence/marketScanner.d.ts.map +1 -0
- package/dist/intelligence/marketScanner.js +225 -0
- package/dist/intelligence/marketScanner.js.map +1 -0
- package/dist/intelligence/polymarketScanner.d.ts +20 -0
- package/dist/intelligence/polymarketScanner.d.ts.map +1 -0
- package/dist/intelligence/polymarketScanner.js +88 -0
- package/dist/intelligence/polymarketScanner.js.map +1 -0
- package/dist/intelligence/redditScanner.d.ts +22 -0
- package/dist/intelligence/redditScanner.d.ts.map +1 -0
- package/dist/intelligence/redditScanner.js +89 -0
- package/dist/intelligence/redditScanner.js.map +1 -0
- package/dist/intelligence/signalAggregator.d.ts +10 -0
- package/dist/intelligence/signalAggregator.d.ts.map +1 -0
- package/dist/intelligence/signalAggregator.js +64 -0
- package/dist/intelligence/signalAggregator.js.map +1 -0
- package/dist/intelligence/trendAnalysis.d.ts +13 -0
- package/dist/intelligence/trendAnalysis.d.ts.map +1 -0
- package/dist/intelligence/trendAnalysis.js +106 -0
- package/dist/intelligence/trendAnalysis.js.map +1 -0
- package/dist/intelligence/twitterScanner.d.ts +22 -0
- package/dist/intelligence/twitterScanner.d.ts.map +1 -0
- package/dist/intelligence/twitterScanner.js +63 -0
- package/dist/intelligence/twitterScanner.js.map +1 -0
- package/dist/intelligence/types.d.ts +566 -0
- package/dist/intelligence/types.d.ts.map +1 -0
- package/dist/intelligence/types.js +87 -0
- package/dist/intelligence/types.js.map +1 -0
- package/dist/intelligence/userComplaints.d.ts +15 -0
- package/dist/intelligence/userComplaints.d.ts.map +1 -0
- package/dist/intelligence/userComplaints.js +193 -0
- package/dist/intelligence/userComplaints.js.map +1 -0
- package/dist/metrics/businessMetrics.d.ts +41 -0
- package/dist/metrics/businessMetrics.d.ts.map +1 -0
- package/dist/metrics/businessMetrics.js +120 -0
- package/dist/metrics/businessMetrics.js.map +1 -0
- package/dist/metrics/businessMetrics.test.d.ts +2 -0
- package/dist/metrics/businessMetrics.test.d.ts.map +1 -0
- package/dist/metrics/businessMetrics.test.js.map +1 -0
- package/dist/metrics/businessMetricsAgg.d.ts +85 -0
- package/dist/metrics/businessMetricsAgg.d.ts.map +1 -0
- package/dist/metrics/businessMetricsAgg.js +406 -0
- package/dist/metrics/businessMetricsAgg.js.map +1 -0
- package/dist/metrics/competitorMetrics.d.ts +57 -0
- package/dist/metrics/competitorMetrics.d.ts.map +1 -0
- package/dist/metrics/competitorMetrics.js +94 -0
- package/dist/metrics/competitorMetrics.js.map +1 -0
- package/dist/metrics/dashboardGenerator.d.ts +16 -0
- package/dist/metrics/dashboardGenerator.d.ts.map +1 -0
- package/dist/metrics/dashboardGenerator.js +313 -0
- package/dist/metrics/dashboardGenerator.js.map +1 -0
- package/dist/metrics/dashboardHTML.d.ts +18 -0
- package/dist/metrics/dashboardHTML.d.ts.map +1 -0
- package/dist/metrics/dashboardHTML.js +613 -0
- package/dist/metrics/dashboardHTML.js.map +1 -0
- package/dist/metrics/grafanaExport.d.ts +53 -0
- package/dist/metrics/grafanaExport.d.ts.map +1 -0
- package/dist/metrics/grafanaExport.js +277 -0
- package/dist/metrics/grafanaExport.js.map +1 -0
- package/dist/metrics/index.d.ts +17 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +17 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/leadsMetrics.d.ts +48 -0
- package/dist/metrics/leadsMetrics.d.ts.map +1 -0
- package/dist/metrics/leadsMetrics.js +82 -0
- package/dist/metrics/leadsMetrics.js.map +1 -0
- package/dist/metrics/leadsMetrics.test.d.ts +2 -0
- package/dist/metrics/leadsMetrics.test.d.ts.map +1 -0
- package/dist/metrics/leadsMetrics.test.js.map +1 -0
- package/dist/metrics/metricsTypes.d.ts +114 -0
- package/dist/metrics/metricsTypes.d.ts.map +1 -0
- package/dist/metrics/metricsTypes.js +7 -0
- package/dist/metrics/metricsTypes.js.map +1 -0
- package/dist/metrics/revenueProjection.d.ts +44 -0
- package/dist/metrics/revenueProjection.d.ts.map +1 -0
- package/dist/metrics/revenueProjection.js +239 -0
- package/dist/metrics/revenueProjection.js.map +1 -0
- package/dist/metrics/revenueTypes.d.ts +62 -0
- package/dist/metrics/revenueTypes.d.ts.map +1 -0
- package/dist/metrics/revenueTypes.js +7 -0
- package/dist/metrics/revenueTypes.js.map +1 -0
- package/dist/metrics/roiCalculator.d.ts +39 -0
- package/dist/metrics/roiCalculator.d.ts.map +1 -0
- package/dist/metrics/roiCalculator.js +128 -0
- package/dist/metrics/roiCalculator.js.map +1 -0
- package/dist/metrics/roiCalculator.test.d.ts +2 -0
- package/dist/metrics/roiCalculator.test.d.ts.map +1 -0
- package/dist/metrics/roiCalculator.test.js.map +1 -0
- package/dist/metrics/trendMetrics.d.ts +51 -0
- package/dist/metrics/trendMetrics.d.ts.map +1 -0
- package/dist/metrics/trendMetrics.js +116 -0
- package/dist/metrics/trendMetrics.js.map +1 -0
- package/dist/modes/conservativeCTOMode.d.ts +32 -0
- package/dist/modes/conservativeCTOMode.d.ts.map +1 -0
- package/dist/modes/conservativeCTOMode.js +98 -0
- package/dist/modes/conservativeCTOMode.js.map +1 -0
- package/dist/modes/index.d.ts +3 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +3 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/seniorDeveloperMode.d.ts +17 -0
- package/dist/modes/seniorDeveloperMode.d.ts.map +1 -0
- package/dist/modes/seniorDeveloperMode.js +77 -0
- package/dist/modes/seniorDeveloperMode.js.map +1 -0
- package/dist/recovery/contextRecovery.d.ts +28 -0
- package/dist/recovery/contextRecovery.d.ts.map +1 -0
- package/dist/recovery/contextRecovery.js +113 -0
- package/dist/recovery/contextRecovery.js.map +1 -0
- package/dist/repair/errorDiagnostics.d.ts +28 -0
- package/dist/repair/errorDiagnostics.d.ts.map +1 -0
- package/dist/repair/errorDiagnostics.js +158 -0
- package/dist/repair/errorDiagnostics.js.map +1 -0
- package/dist/repair/skillCapture.d.ts +22 -0
- package/dist/repair/skillCapture.d.ts.map +1 -0
- package/dist/repair/skillCapture.js +119 -0
- package/dist/repair/skillCapture.js.map +1 -0
- package/dist/reporting/reportGenerator.d.ts +117 -0
- package/dist/reporting/reportGenerator.d.ts.map +1 -0
- package/dist/reporting/reportGenerator.js +613 -0
- package/dist/reporting/reportGenerator.js.map +1 -0
- package/dist/reporting/templates.d.ts +68 -0
- package/dist/reporting/templates.d.ts.map +1 -0
- package/dist/reporting/templates.js +629 -0
- package/dist/reporting/templates.js.map +1 -0
- package/dist/security/owaspScanner.d.ts +74 -0
- package/dist/security/owaspScanner.d.ts.map +1 -0
- package/dist/security/owaspScanner.js +309 -0
- package/dist/security/owaspScanner.js.map +1 -0
- package/dist/security/piiRedaction.d.ts +67 -0
- package/dist/security/piiRedaction.d.ts.map +1 -0
- package/dist/security/piiRedaction.js +189 -0
- package/dist/security/piiRedaction.js.map +1 -0
- package/dist/security/secretsDetection.d.ts +47 -0
- package/dist/security/secretsDetection.d.ts.map +1 -0
- package/dist/security/secretsDetection.js +272 -0
- package/dist/security/secretsDetection.js.map +1 -0
- package/dist/subagents/builder.d.ts +33 -0
- package/dist/subagents/builder.d.ts.map +1 -0
- package/dist/subagents/builder.js +158 -0
- package/dist/subagents/builder.js.map +1 -0
- package/dist/subagents/investigator.d.ts +31 -0
- package/dist/subagents/investigator.d.ts.map +1 -0
- package/dist/subagents/investigator.js +166 -0
- package/dist/subagents/investigator.js.map +1 -0
- package/dist/subagents/orchestrator.d.ts +48 -0
- package/dist/subagents/orchestrator.d.ts.map +1 -0
- package/dist/subagents/orchestrator.js +151 -0
- package/dist/subagents/orchestrator.js.map +1 -0
- package/dist/subagents/reviewer.d.ts +31 -0
- package/dist/subagents/reviewer.d.ts.map +1 -0
- package/dist/subagents/reviewer.js +154 -0
- package/dist/subagents/reviewer.js.map +1 -0
- package/dist/telemetry/tokenCounter.d.ts +21 -0
- package/dist/telemetry/tokenCounter.d.ts.map +1 -0
- package/dist/telemetry/tokenCounter.js +49 -0
- package/dist/telemetry/tokenCounter.js.map +1 -0
- package/package.json +61 -0
- package/src/automation/actionApprover.ts +342 -0
- package/src/automation/actionExecutor.ts +399 -0
- package/src/automation/alertRules.ts +113 -0
- package/src/automation/alertSystem.ts +402 -0
- package/src/automation/competitorResponse.ts +511 -0
- package/src/automation/composioClient.ts +360 -0
- package/src/automation/crmExport.ts +407 -0
- package/src/automation/crmIntegration.ts +268 -0
- package/src/automation/gmailIntegration.ts +244 -0
- package/src/automation/index.ts +17 -0
- package/src/automation/jiraIntegration.ts +310 -0
- package/src/automation/jobQueue.ts +278 -0
- package/src/automation/leadQualification.ts +270 -0
- package/src/automation/qualificationRules.ts +304 -0
- package/src/automation/responseTemplates.ts +419 -0
- package/src/automation/scheduler.ts +254 -0
- package/src/automation/types.ts +270 -0
- package/src/cli/index.ts +646 -0
- package/src/compression/caveman.ts +257 -0
- package/src/config/configManager.ts +63 -0
- package/src/config/schema.ts +27 -0
- package/src/context/autoCompact.ts +123 -0
- package/src/context/readDedup.ts +84 -0
- package/src/context/toolBudgets.ts +43 -0
- package/src/core/auditLogger.ts +69 -0
- package/src/core/stateManager.ts +73 -0
- package/src/database/feedbackSchema.ts +168 -0
- package/src/database/leadsSchema.ts +205 -0
- package/src/intelligence/competitorScoring.ts +292 -0
- package/src/intelligence/competitorTracker.ts +362 -0
- package/src/intelligence/competitorTypes.ts +100 -0
- package/src/intelligence/competitors.json +76 -0
- package/src/intelligence/feedbackLoop.ts +538 -0
- package/src/intelligence/gitHubTracker.ts +204 -0
- package/src/intelligence/hackerNewsScanner.ts +121 -0
- package/src/intelligence/hiringSignals.ts +162 -0
- package/src/intelligence/index.ts +9 -0
- package/src/intelligence/leadEnrichment.ts +275 -0
- package/src/intelligence/leadEnrichmentTypes.ts +54 -0
- package/src/intelligence/marketScanner.ts +285 -0
- package/src/intelligence/polymarketScanner.ts +120 -0
- package/src/intelligence/redditScanner.ts +122 -0
- package/src/intelligence/signalAggregator.ts +94 -0
- package/src/intelligence/trendAnalysis.ts +140 -0
- package/src/intelligence/twitterScanner.ts +94 -0
- package/src/intelligence/types.ts +130 -0
- package/src/intelligence/userComplaints.ts +236 -0
- package/src/metrics/businessMetrics.ts +186 -0
- package/src/metrics/businessMetricsAgg.ts +554 -0
- package/src/metrics/competitorMetrics.ts +175 -0
- package/src/metrics/dashboardGenerator.ts +335 -0
- package/src/metrics/dashboardHTML.ts +637 -0
- package/src/metrics/grafanaExport.ts +347 -0
- package/src/metrics/index.ts +17 -0
- package/src/metrics/leadsMetrics.ts +145 -0
- package/src/metrics/metricsTypes.ts +129 -0
- package/src/metrics/revenueProjection.ts +319 -0
- package/src/metrics/revenueTypes.ts +67 -0
- package/src/metrics/roiCalculator.ts +199 -0
- package/src/metrics/trendMetrics.ts +190 -0
- package/src/modes/conservativeCTOMode.ts +124 -0
- package/src/modes/index.ts +6 -0
- package/src/modes/seniorDeveloperMode.ts +94 -0
- package/src/recovery/contextRecovery.ts +141 -0
- package/src/repair/errorDiagnostics.ts +198 -0
- package/src/repair/skillCapture.ts +157 -0
- package/src/reporting/reportGenerator.ts +802 -0
- package/src/reporting/templates.ts +677 -0
- package/src/security/owaspScanner.ts +390 -0
- package/src/security/phase8Hardening.ts +536 -0
- package/src/security/piiRedaction.ts +215 -0
- package/src/security/secretsDetection.js +271 -0
- package/src/security/secretsDetection.ts +318 -0
- package/src/subagents/builder.ts +277 -0
- package/src/subagents/investigator.ts +224 -0
- package/src/subagents/orchestrator.ts +212 -0
- package/src/subagents/reviewer.ts +215 -0
- package/src/telemetry/tokenCounter.ts +81 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { PolymarketMarket } from './types.js';
|
|
4
|
+
|
|
5
|
+
const POLYMARKET_API_URL = 'https://api.polymarket.com';
|
|
6
|
+
|
|
7
|
+
const PolymarketResponseSchema = z.object({
|
|
8
|
+
data: z.array(
|
|
9
|
+
z.object({
|
|
10
|
+
slug: z.string(),
|
|
11
|
+
title: z.string(),
|
|
12
|
+
description: z.string().optional(),
|
|
13
|
+
bestBid: z.number().optional(),
|
|
14
|
+
bestAsk: z.number().optional(),
|
|
15
|
+
lastTradePrice: z.number().optional(),
|
|
16
|
+
volumeNum: z.number().optional(),
|
|
17
|
+
createdAt: z.string().optional(),
|
|
18
|
+
}).passthrough()
|
|
19
|
+
),
|
|
20
|
+
}).passthrough();
|
|
21
|
+
|
|
22
|
+
interface PolymarketScannerOptions {
|
|
23
|
+
minVolume?: number;
|
|
24
|
+
days?: number;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class PolymarketScanner {
|
|
29
|
+
private minVolume: number;
|
|
30
|
+
private days: number;
|
|
31
|
+
private timeout: number;
|
|
32
|
+
private priceCache: Map<string, number> = new Map();
|
|
33
|
+
|
|
34
|
+
constructor(options: PolymarketScannerOptions = {}) {
|
|
35
|
+
this.minVolume = options.minVolume || 10000;
|
|
36
|
+
this.days = options.days || 30;
|
|
37
|
+
this.timeout = options.timeout || 15000;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async scan(keywords: string[]): Promise<PolymarketMarket[]> {
|
|
41
|
+
try {
|
|
42
|
+
const markets = await this.fetchMarkets();
|
|
43
|
+
const filtered = this.filterMarkets(markets, keywords);
|
|
44
|
+
return filtered;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.warn(`Polymarket scan failed: ${(error as Error).message}`);
|
|
47
|
+
return this.getMockMarkets(keywords);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private async fetchMarkets(): Promise<PolymarketMarket[]> {
|
|
52
|
+
const response = await axios.get(`${POLYMARKET_API_URL}/markets`, {
|
|
53
|
+
timeout: this.timeout,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Mock API implementation since real Polymarket API may have restrictions
|
|
57
|
+
return this.getMockMarkets([]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private filterMarkets(markets: PolymarketMarket[], keywords: string[]): PolymarketMarket[] {
|
|
61
|
+
const cutoffTime = Date.now() - this.days * 24 * 60 * 60 * 1000;
|
|
62
|
+
|
|
63
|
+
return markets.filter((market) => {
|
|
64
|
+
const matchesKeywords = keywords.some((kw) =>
|
|
65
|
+
market.title.toLowerCase().includes(kw.toLowerCase())
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
matchesKeywords &&
|
|
70
|
+
market.volume >= this.minVolume &&
|
|
71
|
+
market.timestamp.getTime() > cutoffTime
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private getMockMarkets(keywords: string[]): PolymarketMarket[] {
|
|
77
|
+
const mockMarkets: PolymarketMarket[] = [
|
|
78
|
+
{
|
|
79
|
+
title: 'Will Claude AI cost per token decrease by Q4 2026?',
|
|
80
|
+
url: 'https://polymarket.com/market/claude-token-cost',
|
|
81
|
+
odds: 0.72,
|
|
82
|
+
volume: 45000,
|
|
83
|
+
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
|
|
84
|
+
trend: 'up',
|
|
85
|
+
description: 'Market predicting token efficiency improvements for Claude',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
title: 'Will AI agent frameworks adopt token optimization by end of 2026?',
|
|
89
|
+
url: 'https://polymarket.com/market/ai-agents-optimization',
|
|
90
|
+
odds: 0.68,
|
|
91
|
+
volume: 38000,
|
|
92
|
+
timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000),
|
|
93
|
+
trend: 'stable',
|
|
94
|
+
description: 'Prediction market for enterprise AI adoption patterns',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
title: 'Will LLM context window standards increase 10x by 2027?',
|
|
98
|
+
url: 'https://polymarket.com/market/context-window-expansion',
|
|
99
|
+
odds: 0.58,
|
|
100
|
+
volume: 32000,
|
|
101
|
+
timestamp: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
|
|
102
|
+
trend: 'down',
|
|
103
|
+
description: 'Technical evolution prediction for language models',
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
return mockMarkets.filter((market) =>
|
|
108
|
+
keywords.length === 0 ||
|
|
109
|
+
keywords.some((kw) => market.title.toLowerCase().includes(kw.toLowerCase()))
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function scanPolymarket(
|
|
115
|
+
keywords: string[],
|
|
116
|
+
options: PolymarketScannerOptions = {}
|
|
117
|
+
): Promise<PolymarketMarket[]> {
|
|
118
|
+
const scanner = new PolymarketScanner(options);
|
|
119
|
+
return scanner.scan(keywords);
|
|
120
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { RedditPost } from './types.js';
|
|
4
|
+
|
|
5
|
+
const REDDIT_API_URL = 'https://www.reddit.com';
|
|
6
|
+
const DEFAULT_USER_AGENT = 'LeanClaudient/1.0 (Market Intelligence Scanner)';
|
|
7
|
+
|
|
8
|
+
const RedditResponseSchema = z.object({
|
|
9
|
+
data: z.object({
|
|
10
|
+
children: z.array(
|
|
11
|
+
z.object({
|
|
12
|
+
data: z.object({
|
|
13
|
+
title: z.string(),
|
|
14
|
+
url: z.string(),
|
|
15
|
+
ups: z.number(),
|
|
16
|
+
num_comments: z.number(),
|
|
17
|
+
author: z.string(),
|
|
18
|
+
subreddit: z.string(),
|
|
19
|
+
created_utc: z.number(),
|
|
20
|
+
}),
|
|
21
|
+
})
|
|
22
|
+
),
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
interface RedditScannerOptions {
|
|
27
|
+
subreddits?: string[];
|
|
28
|
+
minUpvotes?: number;
|
|
29
|
+
minComments?: number;
|
|
30
|
+
days?: number;
|
|
31
|
+
timeout?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class RedditScanner {
|
|
35
|
+
private subreddits: string[];
|
|
36
|
+
private minUpvotes: number;
|
|
37
|
+
private minComments: number;
|
|
38
|
+
private days: number;
|
|
39
|
+
private timeout: number;
|
|
40
|
+
|
|
41
|
+
constructor(options: RedditScannerOptions = {}) {
|
|
42
|
+
this.subreddits = options.subreddits || ['devops', 'programming', 'OpenAI', 'ClaudeAI'];
|
|
43
|
+
this.minUpvotes = options.minUpvotes || 10;
|
|
44
|
+
this.minComments = options.minComments || 5;
|
|
45
|
+
this.days = options.days || 30;
|
|
46
|
+
this.timeout = options.timeout || 10000;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async scan(keywords: string[]): Promise<RedditPost[]> {
|
|
50
|
+
const posts: RedditPost[] = [];
|
|
51
|
+
|
|
52
|
+
for (const subreddit of this.subreddits) {
|
|
53
|
+
try {
|
|
54
|
+
const subredditPosts = await this.scanSubreddit(subreddit, keywords);
|
|
55
|
+
posts.push(...subredditPosts);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.warn(`Failed to scan r/${subreddit}: ${(error as Error).message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return posts;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private async scanSubreddit(subreddit: string, keywords: string[]): Promise<RedditPost[]> {
|
|
65
|
+
const url = `${REDDIT_API_URL}/r/${subreddit}/new.json`;
|
|
66
|
+
|
|
67
|
+
const response = await axios.get(url, {
|
|
68
|
+
headers: {
|
|
69
|
+
'User-Agent': DEFAULT_USER_AGENT,
|
|
70
|
+
},
|
|
71
|
+
params: {
|
|
72
|
+
limit: 100,
|
|
73
|
+
sort: 'new',
|
|
74
|
+
},
|
|
75
|
+
timeout: this.timeout,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const parsed = RedditResponseSchema.parse(response.data);
|
|
79
|
+
const cutoffTime = Date.now() - this.days * 24 * 60 * 60 * 1000;
|
|
80
|
+
|
|
81
|
+
const filtered = parsed.data.children
|
|
82
|
+
.map(({ data }) => ({
|
|
83
|
+
title: data.title,
|
|
84
|
+
url: `https://reddit.com${data.url}` || `https://reddit.com/r/${data.subreddit}/comments/${data.title}/`,
|
|
85
|
+
upvotes: data.ups,
|
|
86
|
+
comments: data.num_comments,
|
|
87
|
+
author: data.author,
|
|
88
|
+
subreddit: `r/${data.subreddit}`,
|
|
89
|
+
timestamp: new Date(data.created_utc * 1000),
|
|
90
|
+
sentiment: this.determineSentiment(data.title),
|
|
91
|
+
}))
|
|
92
|
+
.filter((post) => {
|
|
93
|
+
const matchesKeywords = keywords.some((kw) =>
|
|
94
|
+
post.title.toLowerCase().includes(kw.toLowerCase())
|
|
95
|
+
);
|
|
96
|
+
const meetsThresholds =
|
|
97
|
+
post.upvotes >= this.minUpvotes &&
|
|
98
|
+
post.comments >= this.minComments &&
|
|
99
|
+
post.timestamp.getTime() > cutoffTime;
|
|
100
|
+
return matchesKeywords && meetsThresholds;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return filtered;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private determineSentiment(text: string): 'positive' | 'neutral' | 'negative' {
|
|
107
|
+
const positive = /great|awesome|love|excellent|perfect|amazing/i;
|
|
108
|
+
const negative = /bad|terrible|awful|hate|broken|issue|bug/i;
|
|
109
|
+
|
|
110
|
+
if (positive.test(text)) return 'positive';
|
|
111
|
+
if (negative.test(text)) return 'negative';
|
|
112
|
+
return 'neutral';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function scanReddit(
|
|
117
|
+
keywords: string[],
|
|
118
|
+
options: RedditScannerOptions = {}
|
|
119
|
+
): Promise<RedditPost[]> {
|
|
120
|
+
const scanner = new RedditScanner(options);
|
|
121
|
+
return scanner.scan(keywords);
|
|
122
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Finding } from './types.js';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
interface AggregatedSignal {
|
|
5
|
+
id: string;
|
|
6
|
+
content: string;
|
|
7
|
+
platforms: string[];
|
|
8
|
+
count: number;
|
|
9
|
+
avgScore: number;
|
|
10
|
+
combinedScore: number;
|
|
11
|
+
keywords: string[];
|
|
12
|
+
sources: Finding[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const PLATFORM_CREDIBILITY: Record<string, number> = {
|
|
16
|
+
polymarket: 1.0,
|
|
17
|
+
hackernews: 0.8,
|
|
18
|
+
twitter: 0.6,
|
|
19
|
+
reddit: 0.5,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export class SignalAggregator {
|
|
23
|
+
async aggregateSignals(findings: Finding[], topN: number = 20): Promise<Finding[]> {
|
|
24
|
+
if (findings.length === 0) return [];
|
|
25
|
+
|
|
26
|
+
const signals = this.deduplicateFindings(findings);
|
|
27
|
+
const sorted = this.rankSignals(signals);
|
|
28
|
+
return sorted.slice(0, topN);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private deduplicateFindings(findings: Finding[]): Finding[] {
|
|
32
|
+
const deduped = new Map<string, Finding>();
|
|
33
|
+
|
|
34
|
+
for (const finding of findings) {
|
|
35
|
+
const key = this.generateFindingKey(finding);
|
|
36
|
+
const existing = deduped.get(key);
|
|
37
|
+
|
|
38
|
+
if (!existing) {
|
|
39
|
+
deduped.set(key, finding);
|
|
40
|
+
} else {
|
|
41
|
+
// Merge findings if they're duplicates
|
|
42
|
+
existing.metrics.score = Math.max(existing.metrics.score, finding.metrics.score);
|
|
43
|
+
existing.metrics.engagement = Math.max(
|
|
44
|
+
existing.metrics.engagement,
|
|
45
|
+
finding.metrics.engagement
|
|
46
|
+
);
|
|
47
|
+
// Combine keywords
|
|
48
|
+
const allKeywords = new Set([...existing.keywords, ...finding.keywords]);
|
|
49
|
+
existing.keywords = Array.from(allKeywords);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return Array.from(deduped.values());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private generateFindingKey(finding: Finding): string {
|
|
57
|
+
// Normalize title and URL to create a unique key
|
|
58
|
+
const normalizedTitle = finding.title.toLowerCase().replace(/\W+/g, ' ').trim();
|
|
59
|
+
const titleHash = normalizedTitle.substring(0, 50);
|
|
60
|
+
return `${finding.platform}:${titleHash}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private rankSignals(findings: Finding[]): Finding[] {
|
|
64
|
+
return findings
|
|
65
|
+
.map((finding) => ({
|
|
66
|
+
...finding,
|
|
67
|
+
_finalScore: this.calculateFinalScore(finding),
|
|
68
|
+
}))
|
|
69
|
+
.sort((a, b) => b._finalScore - a._finalScore)
|
|
70
|
+
.map(({ _finalScore, ...finding }) => finding);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private calculateFinalScore(finding: Finding): number {
|
|
74
|
+
// Get credibility weight for platform
|
|
75
|
+
const credibility = PLATFORM_CREDIBILITY[finding.platform] || 0.5;
|
|
76
|
+
|
|
77
|
+
// Combine engagement and credibility
|
|
78
|
+
const engagementScore = Math.min(finding.metrics.engagement / 1000, 1.0);
|
|
79
|
+
const baseScore = finding.metrics.score;
|
|
80
|
+
|
|
81
|
+
// Final score: weighted combination
|
|
82
|
+
const finalScore = baseScore * 0.5 + engagementScore * 0.3 + credibility * 0.2;
|
|
83
|
+
|
|
84
|
+
return Math.min(Math.max(finalScore, 0), 1.0);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function aggregateSignals(
|
|
89
|
+
findings: Finding[],
|
|
90
|
+
topN: number = 20
|
|
91
|
+
): Promise<Finding[]> {
|
|
92
|
+
const aggregator = new SignalAggregator();
|
|
93
|
+
return aggregator.aggregateSignals(findings, topN);
|
|
94
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Finding, Trend } from './types.js';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
|
|
4
|
+
interface TrendCluster {
|
|
5
|
+
keywords: Set<string>;
|
|
6
|
+
findings: Finding[];
|
|
7
|
+
category: 'pain_point' | 'feature_request' | 'competitive_threat' | 'opportunity';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class TrendAnalyzer {
|
|
11
|
+
private similarityThreshold: number = 0.6;
|
|
12
|
+
|
|
13
|
+
async analyzeTrends(findings: Finding[]): Promise<Trend[]> {
|
|
14
|
+
if (findings.length === 0) return [];
|
|
15
|
+
|
|
16
|
+
const clusters = this.clusterFindings(findings);
|
|
17
|
+
return this.generateTrends(clusters);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private clusterFindings(findings: Finding[]): TrendCluster[] {
|
|
21
|
+
const clusters: TrendCluster[] = [];
|
|
22
|
+
|
|
23
|
+
for (const finding of findings) {
|
|
24
|
+
let bestCluster: TrendCluster | null = null;
|
|
25
|
+
let bestSimilarity = this.similarityThreshold;
|
|
26
|
+
|
|
27
|
+
for (const cluster of clusters) {
|
|
28
|
+
const similarity = this.calculateSimilarity(finding.keywords, Array.from(cluster.keywords));
|
|
29
|
+
if (similarity > bestSimilarity) {
|
|
30
|
+
bestSimilarity = similarity;
|
|
31
|
+
bestCluster = cluster;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (bestCluster) {
|
|
36
|
+
bestCluster.findings.push(finding);
|
|
37
|
+
finding.keywords.forEach((kw) => bestCluster!.keywords.add(kw));
|
|
38
|
+
} else {
|
|
39
|
+
clusters.push({
|
|
40
|
+
keywords: new Set(finding.keywords),
|
|
41
|
+
findings: [finding],
|
|
42
|
+
category: this.classifyFinding(finding),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return clusters;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private calculateSimilarity(keywords1: string[], keywords2: string[]): number {
|
|
51
|
+
if (keywords1.length === 0 || keywords2.length === 0) return 0;
|
|
52
|
+
|
|
53
|
+
const set1 = new Set(keywords1.map((k) => k.toLowerCase()));
|
|
54
|
+
const set2 = new Set(keywords2.map((k) => k.toLowerCase()));
|
|
55
|
+
|
|
56
|
+
const intersection = Array.from(set1).filter((x) => set2.has(x)).length;
|
|
57
|
+
const unionSet = new Set<string>();
|
|
58
|
+
set1.forEach((k) => unionSet.add(k));
|
|
59
|
+
set2.forEach((k) => unionSet.add(k));
|
|
60
|
+
const union = unionSet.size;
|
|
61
|
+
|
|
62
|
+
return union === 0 ? 0 : intersection / union;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private classifyFinding(finding: Finding): Trend['category'] {
|
|
66
|
+
const content = `${finding.title} ${finding.content}`.toLowerCase();
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
/need|want|lack|missing|require|should|must have/i.test(content)
|
|
70
|
+
) {
|
|
71
|
+
return 'feature_request';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (
|
|
75
|
+
/problem|issue|bug|broken|fail|error|difficult|pain|struggle/i.test(content)
|
|
76
|
+
) {
|
|
77
|
+
return 'pain_point';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
/competitor|rival|competing|threat|alternative|replace|better|vs/i.test(content)
|
|
82
|
+
) {
|
|
83
|
+
return 'competitive_threat';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return 'opportunity';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private generateTrends(clusters: TrendCluster[]): Trend[] {
|
|
90
|
+
return clusters.map((cluster) => {
|
|
91
|
+
const trendName = this.generateTrendName(Array.from(cluster.keywords));
|
|
92
|
+
const strength = this.calculateTrendStrength(cluster.findings);
|
|
93
|
+
const signalCount = cluster.findings.length;
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
id: uuidv4(),
|
|
97
|
+
trend: trendName,
|
|
98
|
+
strength,
|
|
99
|
+
category: cluster.category,
|
|
100
|
+
signal_count: signalCount,
|
|
101
|
+
keywords: Array.from(cluster.keywords),
|
|
102
|
+
findings: cluster.findings,
|
|
103
|
+
timestamp: new Date(),
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private generateTrendName(keywords: string[]): string {
|
|
109
|
+
if (keywords.length === 0) return 'Unknown Trend';
|
|
110
|
+
const topKeywords = keywords.slice(0, 3).join(', ');
|
|
111
|
+
return `Trend: ${topKeywords}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private calculateTrendStrength(findings: Finding[]): number {
|
|
115
|
+
if (findings.length === 0) return 0;
|
|
116
|
+
|
|
117
|
+
// Base score from finding count
|
|
118
|
+
const countScore = Math.min(findings.length / 10, 1.0);
|
|
119
|
+
|
|
120
|
+
// Weighted average of engagement scores
|
|
121
|
+
const avgEngagementScore =
|
|
122
|
+
findings.reduce((sum, f) => sum + f.metrics.score, 0) / findings.length;
|
|
123
|
+
|
|
124
|
+
// Recency bonus: more recent findings boost strength
|
|
125
|
+
const avgAge =
|
|
126
|
+
findings.reduce((sum, f) => Date.now() - f.timestamp.getTime(), 0) / findings.length;
|
|
127
|
+
const maxAge = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
128
|
+
const recencyBonus = Math.max(1 - avgAge / maxAge, 0.5);
|
|
129
|
+
|
|
130
|
+
// Final strength: weighted combination
|
|
131
|
+
const strength = countScore * 0.3 + avgEngagementScore * 0.4 + recencyBonus * 0.3;
|
|
132
|
+
|
|
133
|
+
return Math.min(Math.max(strength, 0), 1.0);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export async function analyzeTrends(findings: Finding[]): Promise<Trend[]> {
|
|
138
|
+
const analyzer = new TrendAnalyzer();
|
|
139
|
+
return analyzer.analyzeTrends(findings);
|
|
140
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { TwitterTweet } from './types.js';
|
|
4
|
+
|
|
5
|
+
interface TwitterScannerOptions {
|
|
6
|
+
bearerToken?: string;
|
|
7
|
+
minLikes?: number;
|
|
8
|
+
verifiedOnly?: boolean;
|
|
9
|
+
days?: number;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Mock implementation since real Twitter API v2 requires authentication
|
|
14
|
+
// In production, this would use real Twitter API v2 with bearer token
|
|
15
|
+
|
|
16
|
+
export class TwitterScanner {
|
|
17
|
+
private bearerToken?: string;
|
|
18
|
+
private minLikes: number;
|
|
19
|
+
private verifiedOnly: boolean;
|
|
20
|
+
private days: number;
|
|
21
|
+
private timeout: number;
|
|
22
|
+
|
|
23
|
+
constructor(options: TwitterScannerOptions = {}) {
|
|
24
|
+
this.bearerToken = options.bearerToken || process.env.TWITTER_BEARER_TOKEN;
|
|
25
|
+
this.minLikes = options.minLikes || 100;
|
|
26
|
+
this.verifiedOnly = options.verifiedOnly ?? false;
|
|
27
|
+
this.days = options.days || 30;
|
|
28
|
+
this.timeout = options.timeout || 15000;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async scan(keywords: string[]): Promise<TwitterTweet[]> {
|
|
32
|
+
if (!this.bearerToken) {
|
|
33
|
+
console.warn(
|
|
34
|
+
'Twitter API disabled: set TWITTER_BEARER_TOKEN env var for real API access'
|
|
35
|
+
);
|
|
36
|
+
return this.getMockTweets(keywords);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
return await this.scanReal(keywords);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.warn(`Twitter scan failed: ${(error as Error).message}`);
|
|
43
|
+
return this.getMockTweets(keywords);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private async scanReal(keywords: string[]): Promise<TwitterTweet[]> {
|
|
48
|
+
// Implementation would use real Twitter API v2
|
|
49
|
+
// This is a placeholder for the actual implementation
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private getMockTweets(keywords: string[]): TwitterTweet[] {
|
|
54
|
+
// Fallback to mock data for development/testing
|
|
55
|
+
const mockTweets: TwitterTweet[] = [
|
|
56
|
+
{
|
|
57
|
+
text: `Token efficiency is critical for AI cost optimization - we need smarter context management #Claude #AI`,
|
|
58
|
+
author: '@AIResearcher',
|
|
59
|
+
url: 'https://twitter.com/AIResearcher/status/mock1',
|
|
60
|
+
likes: 156,
|
|
61
|
+
retweets: 42,
|
|
62
|
+
timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000),
|
|
63
|
+
verified: true,
|
|
64
|
+
hashtags: ['Claude', 'AI', 'token-efficiency'],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
text: `Claude agents are becoming industry standard for autonomous workflows - cost savings are real #LLM`,
|
|
68
|
+
author: '@DevOpsLeader',
|
|
69
|
+
url: 'https://twitter.com/DevOpsLeader/status/mock2',
|
|
70
|
+
likes: 203,
|
|
71
|
+
retweets: 67,
|
|
72
|
+
timestamp: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000),
|
|
73
|
+
verified: true,
|
|
74
|
+
hashtags: ['LLM', 'agents', 'Claude'],
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
return mockTweets.filter(
|
|
79
|
+
(tweet) =>
|
|
80
|
+
keywords.some((kw) => tweet.text.toLowerCase().includes(kw.toLowerCase())) &&
|
|
81
|
+
tweet.likes >= this.minLikes &&
|
|
82
|
+
(!this.verifiedOnly || tweet.verified) &&
|
|
83
|
+
tweet.timestamp.getTime() > Date.now() - this.days * 24 * 60 * 60 * 1000
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function scanTwitter(
|
|
89
|
+
keywords: string[],
|
|
90
|
+
options: TwitterScannerOptions = {}
|
|
91
|
+
): Promise<TwitterTweet[]> {
|
|
92
|
+
const scanner = new TwitterScanner(options);
|
|
93
|
+
return scanner.scan(keywords);
|
|
94
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// Core finding types
|
|
4
|
+
export const FindingSchema = z.object({
|
|
5
|
+
id: z.string(),
|
|
6
|
+
title: z.string(),
|
|
7
|
+
url: z.string().url(),
|
|
8
|
+
platform: z.enum(['reddit', 'hackernews', 'twitter', 'polymarket']),
|
|
9
|
+
content: z.string(),
|
|
10
|
+
metrics: z.object({
|
|
11
|
+
engagement: z.number().min(0),
|
|
12
|
+
score: z.number().min(0).max(1.0),
|
|
13
|
+
}),
|
|
14
|
+
keywords: z.array(z.string()),
|
|
15
|
+
timestamp: z.date(),
|
|
16
|
+
source: z.string().optional(),
|
|
17
|
+
author: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export type Finding = z.infer<typeof FindingSchema>;
|
|
21
|
+
|
|
22
|
+
// Reddit-specific
|
|
23
|
+
export const RedditPostSchema = z.object({
|
|
24
|
+
title: z.string(),
|
|
25
|
+
url: z.string().url(),
|
|
26
|
+
upvotes: z.number().min(0),
|
|
27
|
+
comments: z.number().min(0),
|
|
28
|
+
author: z.string(),
|
|
29
|
+
subreddit: z.string(),
|
|
30
|
+
timestamp: z.date(),
|
|
31
|
+
sentiment: z.enum(['positive', 'neutral', 'negative']),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export type RedditPost = z.infer<typeof RedditPostSchema>;
|
|
35
|
+
|
|
36
|
+
// HackerNews-specific
|
|
37
|
+
export const HNStorySchema = z.object({
|
|
38
|
+
title: z.string(),
|
|
39
|
+
url: z.string().url(),
|
|
40
|
+
points: z.number().min(0),
|
|
41
|
+
comments: z.number().min(0),
|
|
42
|
+
rank: z.number().min(1),
|
|
43
|
+
author: z.string(),
|
|
44
|
+
timestamp: z.date(),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export type HNStory = z.infer<typeof HNStorySchema>;
|
|
48
|
+
|
|
49
|
+
// Twitter-specific
|
|
50
|
+
export const TwitterTweetSchema = z.object({
|
|
51
|
+
text: z.string(),
|
|
52
|
+
author: z.string(),
|
|
53
|
+
url: z.string().url(),
|
|
54
|
+
likes: z.number().min(0),
|
|
55
|
+
retweets: z.number().min(0),
|
|
56
|
+
timestamp: z.date(),
|
|
57
|
+
verified: z.boolean(),
|
|
58
|
+
hashtags: z.array(z.string()),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export type TwitterTweet = z.infer<typeof TwitterTweetSchema>;
|
|
62
|
+
|
|
63
|
+
// Polymarket-specific
|
|
64
|
+
export const PolymarketSchema = z.object({
|
|
65
|
+
title: z.string(),
|
|
66
|
+
url: z.string().url(),
|
|
67
|
+
odds: z.number().min(0).max(1.0),
|
|
68
|
+
volume: z.number().min(0),
|
|
69
|
+
timestamp: z.date(),
|
|
70
|
+
trend: z.enum(['up', 'down', 'stable']),
|
|
71
|
+
description: z.string().optional(),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export type PolymarketMarket = z.infer<typeof PolymarketSchema>;
|
|
75
|
+
|
|
76
|
+
// Trend analysis
|
|
77
|
+
export const TrendSchema = z.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
trend: z.string(),
|
|
80
|
+
strength: z.number().min(0).max(1.0),
|
|
81
|
+
category: z.enum(['pain_point', 'feature_request', 'competitive_threat', 'opportunity']),
|
|
82
|
+
signal_count: z.number().min(1),
|
|
83
|
+
keywords: z.array(z.string()),
|
|
84
|
+
findings: z.array(FindingSchema),
|
|
85
|
+
timestamp: z.date(),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export type Trend = z.infer<typeof TrendSchema>;
|
|
89
|
+
|
|
90
|
+
// Market scan result
|
|
91
|
+
export const MarketScanResultSchema = z.object({
|
|
92
|
+
timestamp: z.date(),
|
|
93
|
+
platforms: z.array(z.string()),
|
|
94
|
+
keywords: z.array(z.string()),
|
|
95
|
+
total_findings: z.number().min(0),
|
|
96
|
+
top_signals: z.array(z.object({
|
|
97
|
+
trend: z.string(),
|
|
98
|
+
strength: z.number().min(0).max(1.0),
|
|
99
|
+
category: z.string(),
|
|
100
|
+
signal_count: z.number(),
|
|
101
|
+
})),
|
|
102
|
+
findings: z.array(FindingSchema),
|
|
103
|
+
trends: z.array(TrendSchema),
|
|
104
|
+
scan_duration_ms: z.number().min(0),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export type MarketScanResult = z.infer<typeof MarketScanResultSchema>;
|
|
108
|
+
|
|
109
|
+
// Scanner options
|
|
110
|
+
export interface ScanOptions {
|
|
111
|
+
platforms: Array<'reddit' | 'hackernews' | 'twitter' | 'polymarket'>;
|
|
112
|
+
keywords: string[];
|
|
113
|
+
days?: number;
|
|
114
|
+
topN?: number;
|
|
115
|
+
minScore?: number;
|
|
116
|
+
timeout?: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface ScannerConfig {
|
|
120
|
+
redditSubreddits: string[];
|
|
121
|
+
redditMinUpvotes: number;
|
|
122
|
+
redditMinComments: number;
|
|
123
|
+
hnMinPoints: number;
|
|
124
|
+
twitterMinLikes: number;
|
|
125
|
+
twitterVerifiedOnly: boolean;
|
|
126
|
+
polymarketMinVolume: number;
|
|
127
|
+
defaultDays: number;
|
|
128
|
+
defaultTopN: number;
|
|
129
|
+
defaultMinScore: number;
|
|
130
|
+
}
|