nodebench-mcp 2.70.0 → 3.0.1
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/README.md +95 -41
- package/dist/agents/alertRouter.d.ts +38 -0
- package/dist/agents/alertRouter.js +151 -0
- package/dist/agents/alertRouter.js.map +1 -0
- package/dist/agents/entityMemory.d.ts +40 -0
- package/dist/agents/entityMemory.js +64 -0
- package/dist/agents/entityMemory.js.map +1 -0
- package/dist/agents/subAgents.d.ts +35 -0
- package/dist/agents/subAgents.js +62 -0
- package/dist/agents/subAgents.js.map +1 -0
- package/dist/benchmarks/benchmarkRunner.js +14 -0
- package/dist/benchmarks/benchmarkRunner.js.map +1 -1
- package/dist/benchmarks/chainEval.js +107 -0
- package/dist/benchmarks/chainEval.js.map +1 -1
- package/dist/benchmarks/llmJudgeEval.js +85 -0
- package/dist/benchmarks/llmJudgeEval.js.map +1 -1
- package/dist/benchmarks/searchQualityEval.js +118 -5
- package/dist/benchmarks/searchQualityEval.js.map +1 -1
- package/dist/cli/search.d.ts +13 -0
- package/dist/cli/search.js +130 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/dashboard/operatingDashboardHtml.js +2 -1
- package/dist/dashboard/operatingDashboardHtml.js.map +1 -1
- package/dist/dashboard/operatingServer.js +3 -2
- package/dist/dashboard/operatingServer.js.map +1 -1
- package/dist/db.d.ts +6 -2
- package/dist/db.js +521 -6
- package/dist/db.js.map +1 -1
- package/dist/index.js +349 -67
- package/dist/index.js.map +1 -1
- package/dist/packageInfo.d.ts +3 -0
- package/dist/packageInfo.js +32 -0
- package/dist/packageInfo.js.map +1 -0
- package/dist/profiler/behaviorStore.d.ts +97 -0
- package/dist/profiler/behaviorStore.js +276 -0
- package/dist/profiler/behaviorStore.js.map +1 -0
- package/dist/profiler/eventCollector.d.ts +119 -0
- package/dist/profiler/eventCollector.js +267 -0
- package/dist/profiler/eventCollector.js.map +1 -0
- package/dist/profiler/index.d.ts +15 -0
- package/dist/profiler/index.js +16 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/mcpProxy.d.ts +49 -0
- package/dist/profiler/mcpProxy.js +123 -0
- package/dist/profiler/mcpProxy.js.map +1 -0
- package/dist/profiler/modelRouter.d.ts +30 -0
- package/dist/profiler/modelRouter.js +99 -0
- package/dist/profiler/modelRouter.js.map +1 -0
- package/dist/profiler/otelReceiver.d.ts +17 -0
- package/dist/profiler/otelReceiver.js +62 -0
- package/dist/profiler/otelReceiver.js.map +1 -0
- package/dist/profiler/proofEngine.d.ts +41 -0
- package/dist/profiler/proofEngine.js +93 -0
- package/dist/profiler/proofEngine.js.map +1 -0
- package/dist/profiler/workflowTemplates.d.ts +41 -0
- package/dist/profiler/workflowTemplates.js +95 -0
- package/dist/profiler/workflowTemplates.js.map +1 -0
- package/dist/providers/localMemoryProvider.js +3 -2
- package/dist/providers/localMemoryProvider.js.map +1 -1
- package/dist/runtimeConfig.d.ts +11 -0
- package/dist/runtimeConfig.js +27 -0
- package/dist/runtimeConfig.js.map +1 -0
- package/dist/sandboxApi.js +2 -1
- package/dist/sandboxApi.js.map +1 -1
- package/dist/security/auditLog.js +8 -3
- package/dist/security/auditLog.js.map +1 -1
- package/dist/subconscious/blocks.d.ts +43 -0
- package/dist/subconscious/blocks.js +158 -0
- package/dist/subconscious/blocks.js.map +1 -0
- package/dist/subconscious/classifier.d.ts +22 -0
- package/dist/subconscious/classifier.js +118 -0
- package/dist/subconscious/classifier.js.map +1 -0
- package/dist/subconscious/graphEngine.d.ts +65 -0
- package/dist/subconscious/graphEngine.js +234 -0
- package/dist/subconscious/graphEngine.js.map +1 -0
- package/dist/subconscious/index.d.ts +19 -0
- package/dist/subconscious/index.js +20 -0
- package/dist/subconscious/index.js.map +1 -0
- package/dist/subconscious/tools.d.ts +5 -0
- package/dist/subconscious/tools.js +255 -0
- package/dist/subconscious/tools.js.map +1 -0
- package/dist/subconscious/whisperPolicy.d.ts +20 -0
- package/dist/subconscious/whisperPolicy.js +171 -0
- package/dist/subconscious/whisperPolicy.js.map +1 -0
- package/dist/sweep/engine.d.ts +27 -0
- package/dist/sweep/engine.js +244 -0
- package/dist/sweep/engine.js.map +1 -0
- package/dist/sweep/index.d.ts +9 -0
- package/dist/sweep/index.js +8 -0
- package/dist/sweep/index.js.map +1 -0
- package/dist/sweep/sources/github_trending.d.ts +6 -0
- package/dist/sweep/sources/github_trending.js +37 -0
- package/dist/sweep/sources/github_trending.js.map +1 -0
- package/dist/sweep/sources/hackernews.d.ts +7 -0
- package/dist/sweep/sources/hackernews.js +57 -0
- package/dist/sweep/sources/hackernews.js.map +1 -0
- package/dist/sweep/sources/openbb_finance.d.ts +9 -0
- package/dist/sweep/sources/openbb_finance.js +46 -0
- package/dist/sweep/sources/openbb_finance.js.map +1 -0
- package/dist/sweep/sources/producthunt.d.ts +6 -0
- package/dist/sweep/sources/producthunt.js +41 -0
- package/dist/sweep/sources/producthunt.js.map +1 -0
- package/dist/sweep/sources/web_signals.d.ts +7 -0
- package/dist/sweep/sources/web_signals.js +63 -0
- package/dist/sweep/sources/web_signals.js.map +1 -0
- package/dist/sweep/sources/yahoo_finance.d.ts +6 -0
- package/dist/sweep/sources/yahoo_finance.js +47 -0
- package/dist/sweep/sources/yahoo_finance.js.map +1 -0
- package/dist/sweep/types.d.ts +50 -0
- package/dist/sweep/types.js +9 -0
- package/dist/sweep/types.js.map +1 -0
- package/dist/sync/founderEpisodeStore.d.ts +98 -0
- package/dist/sync/founderEpisodeStore.js +230 -0
- package/dist/sync/founderEpisodeStore.js.map +1 -0
- package/dist/sync/hyperloopArchive.d.ts +51 -0
- package/dist/sync/hyperloopArchive.js +153 -0
- package/dist/sync/hyperloopArchive.js.map +1 -0
- package/dist/sync/hyperloopEval.d.ts +123 -0
- package/dist/sync/hyperloopEval.js +389 -0
- package/dist/sync/hyperloopEval.js.map +1 -0
- package/dist/sync/protocol.d.ts +172 -0
- package/dist/sync/protocol.js +9 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/sessionMemory.d.ts +47 -0
- package/dist/sync/sessionMemory.js +138 -0
- package/dist/sync/sessionMemory.js.map +1 -0
- package/dist/sync/store.d.ts +384 -0
- package/dist/sync/store.js +1435 -0
- package/dist/sync/store.js.map +1 -0
- package/dist/sync/syncBridgeClient.d.ts +30 -0
- package/dist/sync/syncBridgeClient.js +172 -0
- package/dist/sync/syncBridgeClient.js.map +1 -0
- package/dist/tools/autonomousDeliveryTools.d.ts +2 -0
- package/dist/tools/autonomousDeliveryTools.js +1104 -0
- package/dist/tools/autonomousDeliveryTools.js.map +1 -0
- package/dist/tools/boilerplateTools.js +10 -9
- package/dist/tools/boilerplateTools.js.map +1 -1
- package/dist/tools/claudeCodeIngestTools.d.ts +10 -0
- package/dist/tools/claudeCodeIngestTools.js +347 -0
- package/dist/tools/claudeCodeIngestTools.js.map +1 -0
- package/dist/tools/coreWorkflowTools.d.ts +2 -0
- package/dist/tools/coreWorkflowTools.js +488 -0
- package/dist/tools/coreWorkflowTools.js.map +1 -0
- package/dist/tools/deltaTools.d.ts +15 -0
- package/dist/tools/deltaTools.js +1522 -0
- package/dist/tools/deltaTools.js.map +1 -0
- package/dist/tools/documentationTools.js +2 -1
- package/dist/tools/documentationTools.js.map +1 -1
- package/dist/tools/entityLookupTools.d.ts +14 -0
- package/dist/tools/entityLookupTools.js +159 -0
- package/dist/tools/entityLookupTools.js.map +1 -0
- package/dist/tools/entityTemporalTools.d.ts +12 -0
- package/dist/tools/entityTemporalTools.js +330 -0
- package/dist/tools/entityTemporalTools.js.map +1 -0
- package/dist/tools/founderLocalPipeline.d.ts +215 -0
- package/dist/tools/founderLocalPipeline.js +1516 -2
- package/dist/tools/founderLocalPipeline.js.map +1 -1
- package/dist/tools/founderOperatingModel.d.ts +120 -0
- package/dist/tools/founderOperatingModel.js +469 -0
- package/dist/tools/founderOperatingModel.js.map +1 -0
- package/dist/tools/founderOperatingModelTools.d.ts +2 -0
- package/dist/tools/founderOperatingModelTools.js +169 -0
- package/dist/tools/founderOperatingModelTools.js.map +1 -0
- package/dist/tools/founderStrategicOpsTools.d.ts +2 -0
- package/dist/tools/founderStrategicOpsTools.js +1310 -0
- package/dist/tools/founderStrategicOpsTools.js.map +1 -0
- package/dist/tools/graphifyTools.d.ts +19 -0
- package/dist/tools/graphifyTools.js +375 -0
- package/dist/tools/graphifyTools.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/monteCarloTools.d.ts +16 -0
- package/dist/tools/monteCarloTools.js +225 -0
- package/dist/tools/monteCarloTools.js.map +1 -0
- package/dist/tools/packetCompilerTools.d.ts +12 -0
- package/dist/tools/packetCompilerTools.js +322 -0
- package/dist/tools/packetCompilerTools.js.map +1 -0
- package/dist/tools/planSynthesisTools.d.ts +15 -0
- package/dist/tools/planSynthesisTools.js +455 -0
- package/dist/tools/planSynthesisTools.js.map +1 -0
- package/dist/tools/profilerTools.d.ts +20 -0
- package/dist/tools/profilerTools.js +364 -0
- package/dist/tools/profilerTools.js.map +1 -0
- package/dist/tools/progressiveDiscoveryTools.js +2 -1
- package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
- package/dist/tools/savingsTools.d.ts +11 -0
- package/dist/tools/savingsTools.js +155 -0
- package/dist/tools/savingsTools.js.map +1 -0
- package/dist/tools/scenarioCompilerTools.d.ts +14 -0
- package/dist/tools/scenarioCompilerTools.js +290 -0
- package/dist/tools/scenarioCompilerTools.js.map +1 -0
- package/dist/tools/sharedContextTools.d.ts +2 -0
- package/dist/tools/sharedContextTools.js +423 -0
- package/dist/tools/sharedContextTools.js.map +1 -0
- package/dist/tools/sitemapTools.d.ts +15 -0
- package/dist/tools/sitemapTools.js +560 -0
- package/dist/tools/sitemapTools.js.map +1 -0
- package/dist/tools/sweepTools.d.ts +9 -0
- package/dist/tools/sweepTools.js +112 -0
- package/dist/tools/sweepTools.js.map +1 -0
- package/dist/tools/syncBridgeTools.d.ts +2 -0
- package/dist/tools/syncBridgeTools.js +258 -0
- package/dist/tools/syncBridgeTools.js.map +1 -0
- package/dist/tools/toolRegistry.js +1223 -45
- package/dist/tools/toolRegistry.js.map +1 -1
- package/dist/tools/workspaceTools.d.ts +19 -0
- package/dist/tools/workspaceTools.js +762 -0
- package/dist/tools/workspaceTools.js.map +1 -0
- package/dist/toolsetRegistry.js +162 -3
- package/dist/toolsetRegistry.js.map +1 -1
- package/package.json +39 -38
- package/rules/nodebench-agentic-reliability.md +32 -0
- package/rules/nodebench-analyst-diagnostic.md +25 -0
- package/rules/nodebench-auto-qa.md +31 -0
- package/rules/nodebench-completion-traceability.md +22 -0
- package/rules/nodebench-flywheel-continuous.md +25 -0
- package/rules/nodebench-pre-release-review.md +24 -0
- package/rules/nodebench-qa-dogfood.md +26 -0
- package/rules/nodebench-scenario-testing.md +30 -0
- package/rules/nodebench-self-direction.md +23 -0
- package/rules/nodebench-self-judge-loop.md +24 -0
- package/scripts/install.sh +215 -0
- package/dist/__tests__/analytics.test.d.ts +0 -11
- package/dist/__tests__/analytics.test.js +0 -546
- package/dist/__tests__/analytics.test.js.map +0 -1
- package/dist/__tests__/architectComplex.test.d.ts +0 -1
- package/dist/__tests__/architectComplex.test.js +0 -373
- package/dist/__tests__/architectComplex.test.js.map +0 -1
- package/dist/__tests__/architectSmoke.test.d.ts +0 -1
- package/dist/__tests__/architectSmoke.test.js +0 -92
- package/dist/__tests__/architectSmoke.test.js.map +0 -1
- package/dist/__tests__/audit-registry.d.ts +0 -1
- package/dist/__tests__/audit-registry.js +0 -60
- package/dist/__tests__/audit-registry.js.map +0 -1
- package/dist/__tests__/batchAutopilot.test.d.ts +0 -8
- package/dist/__tests__/batchAutopilot.test.js +0 -218
- package/dist/__tests__/batchAutopilot.test.js.map +0 -1
- package/dist/__tests__/cliSubcommands.test.d.ts +0 -1
- package/dist/__tests__/cliSubcommands.test.js +0 -138
- package/dist/__tests__/cliSubcommands.test.js.map +0 -1
- package/dist/__tests__/comparativeBench.test.d.ts +0 -1
- package/dist/__tests__/comparativeBench.test.js +0 -722
- package/dist/__tests__/comparativeBench.test.js.map +0 -1
- package/dist/__tests__/critterCalibrationEval.d.ts +0 -8
- package/dist/__tests__/critterCalibrationEval.js +0 -370
- package/dist/__tests__/critterCalibrationEval.js.map +0 -1
- package/dist/__tests__/dynamicLoading.test.d.ts +0 -1
- package/dist/__tests__/dynamicLoading.test.js +0 -280
- package/dist/__tests__/dynamicLoading.test.js.map +0 -1
- package/dist/__tests__/embeddingProvider.test.d.ts +0 -1
- package/dist/__tests__/embeddingProvider.test.js +0 -86
- package/dist/__tests__/embeddingProvider.test.js.map +0 -1
- package/dist/__tests__/evalDatasetBench.test.d.ts +0 -1
- package/dist/__tests__/evalDatasetBench.test.js +0 -738
- package/dist/__tests__/evalDatasetBench.test.js.map +0 -1
- package/dist/__tests__/evalHarness.test.d.ts +0 -1
- package/dist/__tests__/evalHarness.test.js +0 -1107
- package/dist/__tests__/evalHarness.test.js.map +0 -1
- package/dist/__tests__/fixtures/bfcl_v3_long_context.sample.json +0 -264
- package/dist/__tests__/fixtures/generateBfclLongContextFixture.d.ts +0 -10
- package/dist/__tests__/fixtures/generateBfclLongContextFixture.js +0 -135
- package/dist/__tests__/fixtures/generateBfclLongContextFixture.js.map +0 -1
- package/dist/__tests__/fixtures/generateSwebenchVerifiedFixture.d.ts +0 -14
- package/dist/__tests__/fixtures/generateSwebenchVerifiedFixture.js +0 -189
- package/dist/__tests__/fixtures/generateSwebenchVerifiedFixture.js.map +0 -1
- package/dist/__tests__/fixtures/generateToolbenchInstructionFixture.d.ts +0 -16
- package/dist/__tests__/fixtures/generateToolbenchInstructionFixture.js +0 -154
- package/dist/__tests__/fixtures/generateToolbenchInstructionFixture.js.map +0 -1
- package/dist/__tests__/fixtures/swebench_verified.sample.json +0 -162
- package/dist/__tests__/fixtures/toolbench_instruction.sample.json +0 -109
- package/dist/__tests__/forecastingDogfood.test.d.ts +0 -9
- package/dist/__tests__/forecastingDogfood.test.js +0 -284
- package/dist/__tests__/forecastingDogfood.test.js.map +0 -1
- package/dist/__tests__/forecastingScoring.test.d.ts +0 -9
- package/dist/__tests__/forecastingScoring.test.js +0 -202
- package/dist/__tests__/forecastingScoring.test.js.map +0 -1
- package/dist/__tests__/gaiaCapabilityAudioEval.test.d.ts +0 -15
- package/dist/__tests__/gaiaCapabilityAudioEval.test.js +0 -265
- package/dist/__tests__/gaiaCapabilityAudioEval.test.js.map +0 -1
- package/dist/__tests__/gaiaCapabilityEval.test.d.ts +0 -14
- package/dist/__tests__/gaiaCapabilityEval.test.js +0 -1259
- package/dist/__tests__/gaiaCapabilityEval.test.js.map +0 -1
- package/dist/__tests__/gaiaCapabilityFilesEval.test.d.ts +0 -15
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js +0 -914
- package/dist/__tests__/gaiaCapabilityFilesEval.test.js.map +0 -1
- package/dist/__tests__/gaiaCapabilityMediaEval.test.d.ts +0 -15
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js +0 -1101
- package/dist/__tests__/gaiaCapabilityMediaEval.test.js.map +0 -1
- package/dist/__tests__/helpers/answerMatch.d.ts +0 -41
- package/dist/__tests__/helpers/answerMatch.js +0 -267
- package/dist/__tests__/helpers/answerMatch.js.map +0 -1
- package/dist/__tests__/helpers/textLlm.d.ts +0 -25
- package/dist/__tests__/helpers/textLlm.js +0 -214
- package/dist/__tests__/helpers/textLlm.js.map +0 -1
- package/dist/__tests__/localDashboard.test.d.ts +0 -1
- package/dist/__tests__/localDashboard.test.js +0 -226
- package/dist/__tests__/localDashboard.test.js.map +0 -1
- package/dist/__tests__/multiHopDogfood.test.d.ts +0 -12
- package/dist/__tests__/multiHopDogfood.test.js +0 -303
- package/dist/__tests__/multiHopDogfood.test.js.map +0 -1
- package/dist/__tests__/openDatasetParallelEval.test.d.ts +0 -7
- package/dist/__tests__/openDatasetParallelEval.test.js +0 -209
- package/dist/__tests__/openDatasetParallelEval.test.js.map +0 -1
- package/dist/__tests__/openDatasetParallelEvalGaia.test.d.ts +0 -7
- package/dist/__tests__/openDatasetParallelEvalGaia.test.js +0 -279
- package/dist/__tests__/openDatasetParallelEvalGaia.test.js.map +0 -1
- package/dist/__tests__/openDatasetParallelEvalSwebench.test.d.ts +0 -7
- package/dist/__tests__/openDatasetParallelEvalSwebench.test.js +0 -220
- package/dist/__tests__/openDatasetParallelEvalSwebench.test.js.map +0 -1
- package/dist/__tests__/openDatasetParallelEvalToolbench.test.d.ts +0 -7
- package/dist/__tests__/openDatasetParallelEvalToolbench.test.js +0 -218
- package/dist/__tests__/openDatasetParallelEvalToolbench.test.js.map +0 -1
- package/dist/__tests__/openDatasetPerfComparison.test.d.ts +0 -10
- package/dist/__tests__/openDatasetPerfComparison.test.js +0 -318
- package/dist/__tests__/openDatasetPerfComparison.test.js.map +0 -1
- package/dist/__tests__/openclawDogfood.test.d.ts +0 -23
- package/dist/__tests__/openclawDogfood.test.js +0 -535
- package/dist/__tests__/openclawDogfood.test.js.map +0 -1
- package/dist/__tests__/openclawMessaging.test.d.ts +0 -14
- package/dist/__tests__/openclawMessaging.test.js +0 -232
- package/dist/__tests__/openclawMessaging.test.js.map +0 -1
- package/dist/__tests__/presetRealWorldBench.test.d.ts +0 -1
- package/dist/__tests__/presetRealWorldBench.test.js +0 -859
- package/dist/__tests__/presetRealWorldBench.test.js.map +0 -1
- package/dist/__tests__/tools.test.d.ts +0 -1
- package/dist/__tests__/tools.test.js +0 -3201
- package/dist/__tests__/tools.test.js.map +0 -1
- package/dist/__tests__/toolsetGatingEval.test.d.ts +0 -1
- package/dist/__tests__/toolsetGatingEval.test.js +0 -1099
- package/dist/__tests__/toolsetGatingEval.test.js.map +0 -1
- package/dist/__tests__/traceabilityDogfood.test.d.ts +0 -12
- package/dist/__tests__/traceabilityDogfood.test.js +0 -241
- package/dist/__tests__/traceabilityDogfood.test.js.map +0 -1
- package/dist/__tests__/webmcpTools.test.d.ts +0 -7
- package/dist/__tests__/webmcpTools.test.js +0 -195
- package/dist/__tests__/webmcpTools.test.js.map +0 -1
- package/dist/benchmarks/testProviderBus.d.ts +0 -7
- package/dist/benchmarks/testProviderBus.js +0 -272
- package/dist/benchmarks/testProviderBus.js.map +0 -1
- package/dist/hooks/postCompaction.d.ts +0 -14
- package/dist/hooks/postCompaction.js +0 -51
- package/dist/hooks/postCompaction.js.map +0 -1
- package/dist/security/__tests__/security.test.d.ts +0 -8
- package/dist/security/__tests__/security.test.js +0 -295
- package/dist/security/__tests__/security.test.js.map +0 -1
- package/dist/tools/documentTools.d.ts +0 -5
- package/dist/tools/documentTools.js +0 -524
- package/dist/tools/documentTools.js.map +0 -1
- package/dist/tools/financialTools.d.ts +0 -10
- package/dist/tools/financialTools.js +0 -403
- package/dist/tools/financialTools.js.map +0 -1
- package/dist/tools/memoryTools.d.ts +0 -5
- package/dist/tools/memoryTools.js +0 -137
- package/dist/tools/memoryTools.js.map +0 -1
- package/dist/tools/planningTools.d.ts +0 -5
- package/dist/tools/planningTools.js +0 -147
- package/dist/tools/planningTools.js.map +0 -1
- package/dist/tools/searchTools.d.ts +0 -5
- package/dist/tools/searchTools.js +0 -145
- package/dist/tools/searchTools.js.map +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sweep Engine — runs all data source collectors in parallel,
|
|
3
|
+
* computes deltas, and produces the top signal for auto-fire.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: Crucix's briefing.mjs master orchestrator
|
|
6
|
+
* Architecture: DeerFlow's sub-agent parallel dispatch
|
|
7
|
+
*
|
|
8
|
+
* Each source is a self-contained module that exports collect().
|
|
9
|
+
* The engine runs them all with timeouts, collects signals,
|
|
10
|
+
* computes what changed since last sweep, and identifies the
|
|
11
|
+
* top entity for the landing page.
|
|
12
|
+
*/
|
|
13
|
+
import { getDb, genId } from "../db.js";
|
|
14
|
+
const SOURCE_MODULES = [];
|
|
15
|
+
export function registerSource(name, collect) {
|
|
16
|
+
SOURCE_MODULES.push({ name, collect });
|
|
17
|
+
}
|
|
18
|
+
// ── Sweep execution ──────────────────────────────────────────────────
|
|
19
|
+
export async function runSweep() {
|
|
20
|
+
const sweepId = genId("sweep");
|
|
21
|
+
const startMs = Date.now();
|
|
22
|
+
const sourceResults = [];
|
|
23
|
+
const allSignals = [];
|
|
24
|
+
// Load sources dynamically (lazy import to avoid bundling issues)
|
|
25
|
+
if (SOURCE_MODULES.length === 0) {
|
|
26
|
+
try {
|
|
27
|
+
const hn = await import("./sources/hackernews.js");
|
|
28
|
+
registerSource("hackernews", hn.collect);
|
|
29
|
+
}
|
|
30
|
+
catch { /* source unavailable */ }
|
|
31
|
+
try {
|
|
32
|
+
const gh = await import("./sources/github_trending.js");
|
|
33
|
+
registerSource("github_trending", gh.collect);
|
|
34
|
+
}
|
|
35
|
+
catch { /* source unavailable */ }
|
|
36
|
+
try {
|
|
37
|
+
const yf = await import("./sources/yahoo_finance.js");
|
|
38
|
+
registerSource("yahoo_finance", yf.collect);
|
|
39
|
+
}
|
|
40
|
+
catch { /* source unavailable */ }
|
|
41
|
+
try {
|
|
42
|
+
const ph = await import("./sources/producthunt.js");
|
|
43
|
+
registerSource("producthunt", ph.collect);
|
|
44
|
+
}
|
|
45
|
+
catch { /* source unavailable */ }
|
|
46
|
+
try {
|
|
47
|
+
const ob = await import("./sources/openbb_finance.js");
|
|
48
|
+
registerSource("openbb_finance", ob.collect);
|
|
49
|
+
}
|
|
50
|
+
catch { /* source unavailable */ }
|
|
51
|
+
}
|
|
52
|
+
// Run all sources in parallel with per-source timeouts (Crucix pattern)
|
|
53
|
+
const results = await Promise.all(SOURCE_MODULES.map(async (source) => {
|
|
54
|
+
const sourceStart = Date.now();
|
|
55
|
+
try {
|
|
56
|
+
const signals = await Promise.race([
|
|
57
|
+
source.collect(),
|
|
58
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 10000)),
|
|
59
|
+
]);
|
|
60
|
+
return {
|
|
61
|
+
name: source.name,
|
|
62
|
+
status: "ok",
|
|
63
|
+
count: signals.length,
|
|
64
|
+
durationMs: Date.now() - sourceStart,
|
|
65
|
+
signals,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return {
|
|
70
|
+
name: source.name,
|
|
71
|
+
status: "error",
|
|
72
|
+
count: 0,
|
|
73
|
+
durationMs: Date.now() - sourceStart,
|
|
74
|
+
signals: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
for (const r of results) {
|
|
79
|
+
sourceResults.push({ name: r.name, status: r.status, count: r.count, durationMs: r.durationMs });
|
|
80
|
+
allSignals.push(...r.signals);
|
|
81
|
+
}
|
|
82
|
+
// Sort by score descending
|
|
83
|
+
allSignals.sort((a, b) => (b.score ?? 0) - (a.score ?? 0));
|
|
84
|
+
const result = {
|
|
85
|
+
signals: allSignals,
|
|
86
|
+
sources: sourceResults,
|
|
87
|
+
totalDurationMs: Date.now() - startMs,
|
|
88
|
+
sweepId,
|
|
89
|
+
timestamp: new Date().toISOString(),
|
|
90
|
+
};
|
|
91
|
+
// Persist sweep result
|
|
92
|
+
persistSweep(result);
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
// ── Delta engine (Crucix delta/engine.mjs pattern) ───────────────────
|
|
96
|
+
export function computeDelta(current, previous) {
|
|
97
|
+
const prevIds = new Set((previous?.signals ?? []).map(s => s.id));
|
|
98
|
+
const prevSeverities = new Map((previous?.signals ?? []).map(s => [s.id, s.severity]));
|
|
99
|
+
const newSignals = current.signals.filter(s => !prevIds.has(s.id));
|
|
100
|
+
const escalations = [];
|
|
101
|
+
const deescalations = [];
|
|
102
|
+
for (const sig of current.signals) {
|
|
103
|
+
const prevSev = prevSeverities.get(sig.id);
|
|
104
|
+
if (!prevSev)
|
|
105
|
+
continue;
|
|
106
|
+
const sevOrder = { flash: 3, priority: 2, routine: 1 };
|
|
107
|
+
if (sevOrder[sig.severity] > sevOrder[prevSev]) {
|
|
108
|
+
escalations.push({ signal: sig, from: prevSev, to: sig.severity });
|
|
109
|
+
}
|
|
110
|
+
else if (sevOrder[sig.severity] < sevOrder[prevSev]) {
|
|
111
|
+
deescalations.push({ signal: sig, from: prevSev, to: sig.severity });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Top entity = highest-scored new signal, or highest-scored escalation
|
|
115
|
+
const topCandidates = [
|
|
116
|
+
...newSignals.filter(s => s.severity === "flash"),
|
|
117
|
+
...escalations.map(e => e.signal),
|
|
118
|
+
...newSignals.filter(s => s.severity === "priority"),
|
|
119
|
+
...newSignals,
|
|
120
|
+
];
|
|
121
|
+
const topSignal = topCandidates[0] ?? current.signals[0] ?? null;
|
|
122
|
+
return {
|
|
123
|
+
newSignals,
|
|
124
|
+
escalations,
|
|
125
|
+
deescalations,
|
|
126
|
+
topEntity: topSignal?.entity ?? null,
|
|
127
|
+
topEntityQuery: topSignal
|
|
128
|
+
? `${topSignal.headline} — what does this mean for founders?`
|
|
129
|
+
: null,
|
|
130
|
+
topEntitySeverity: topSignal?.severity ?? null,
|
|
131
|
+
sweepId: current.sweepId,
|
|
132
|
+
previousSweepId: previous?.sweepId ?? null,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// ── Persistence ──────────────────────────────────────────────────────
|
|
136
|
+
export function initSweepTables() {
|
|
137
|
+
const db = getDb();
|
|
138
|
+
db.exec(`
|
|
139
|
+
CREATE TABLE IF NOT EXISTS sweep_results (
|
|
140
|
+
id TEXT PRIMARY KEY,
|
|
141
|
+
signals TEXT NOT NULL DEFAULT '[]',
|
|
142
|
+
sources TEXT NOT NULL DEFAULT '[]',
|
|
143
|
+
total_duration_ms INTEGER DEFAULT 0,
|
|
144
|
+
signal_count INTEGER DEFAULT 0,
|
|
145
|
+
top_entity TEXT,
|
|
146
|
+
top_entity_query TEXT,
|
|
147
|
+
new_signal_count INTEGER DEFAULT 0,
|
|
148
|
+
escalation_count INTEGER DEFAULT 0,
|
|
149
|
+
timestamp TEXT NOT NULL
|
|
150
|
+
);
|
|
151
|
+
CREATE INDEX IF NOT EXISTS idx_sr_ts ON sweep_results(timestamp);
|
|
152
|
+
`);
|
|
153
|
+
}
|
|
154
|
+
function persistSweep(result) {
|
|
155
|
+
try {
|
|
156
|
+
const db = getDb();
|
|
157
|
+
db.prepare(`
|
|
158
|
+
INSERT OR REPLACE INTO sweep_results (id, signals, sources, total_duration_ms, signal_count, timestamp)
|
|
159
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
160
|
+
`).run(result.sweepId, JSON.stringify(result.signals.slice(0, 50)), JSON.stringify(result.sources), result.totalDurationMs, result.signals.length, result.timestamp);
|
|
161
|
+
}
|
|
162
|
+
catch { /* persistence is non-blocking */ }
|
|
163
|
+
}
|
|
164
|
+
export function getLatestSweep() {
|
|
165
|
+
try {
|
|
166
|
+
const db = getDb();
|
|
167
|
+
const row = db.prepare(`SELECT * FROM sweep_results ORDER BY timestamp DESC LIMIT 1`).get();
|
|
168
|
+
if (!row)
|
|
169
|
+
return null;
|
|
170
|
+
return {
|
|
171
|
+
signals: JSON.parse(row.signals ?? "[]"),
|
|
172
|
+
sources: JSON.parse(row.sources ?? "[]"),
|
|
173
|
+
totalDurationMs: row.total_duration_ms,
|
|
174
|
+
sweepId: row.id,
|
|
175
|
+
timestamp: row.timestamp,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export function getPreviousSweep() {
|
|
183
|
+
try {
|
|
184
|
+
const db = getDb();
|
|
185
|
+
const row = db.prepare(`SELECT * FROM sweep_results ORDER BY timestamp DESC LIMIT 1 OFFSET 1`).get();
|
|
186
|
+
if (!row)
|
|
187
|
+
return null;
|
|
188
|
+
return {
|
|
189
|
+
signals: JSON.parse(row.signals ?? "[]"),
|
|
190
|
+
sources: JSON.parse(row.sources ?? "[]"),
|
|
191
|
+
totalDurationMs: row.total_duration_ms,
|
|
192
|
+
sweepId: row.id,
|
|
193
|
+
timestamp: row.timestamp,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
export function generateRecommendations(signals) {
|
|
201
|
+
const recs = [];
|
|
202
|
+
for (const sig of signals.slice(0, 10)) {
|
|
203
|
+
let action = "";
|
|
204
|
+
let reasoning = "";
|
|
205
|
+
let urgency = "monitor";
|
|
206
|
+
let category = "market";
|
|
207
|
+
if (sig.category === "funding") {
|
|
208
|
+
action = `Research ${sig.entity}'s funding round. Evaluate if this changes your competitive landscape.`;
|
|
209
|
+
reasoning = "Funding signals shift market dynamics. A well-funded competitor can accelerate faster.";
|
|
210
|
+
urgency = "this_week";
|
|
211
|
+
category = "competitive";
|
|
212
|
+
}
|
|
213
|
+
else if (sig.category === "launch") {
|
|
214
|
+
action = `Evaluate ${sig.entity}. Is this a competitor, partner opportunity, or irrelevant?`;
|
|
215
|
+
reasoning = "New launches in your space can validate or threaten your wedge.";
|
|
216
|
+
urgency = sig.severity === "flash" ? "act_now" : "this_week";
|
|
217
|
+
category = "opportunity";
|
|
218
|
+
}
|
|
219
|
+
else if (sig.category === "market" && sig.severity === "flash") {
|
|
220
|
+
action = `Check your exposure to ${sig.entity}. Review your portfolio and customer base.`;
|
|
221
|
+
reasoning = "Major market moves can affect your runway, fundraising, and customer behavior.";
|
|
222
|
+
urgency = "act_now";
|
|
223
|
+
category = "risk";
|
|
224
|
+
}
|
|
225
|
+
else if (sig.category === "trend") {
|
|
226
|
+
action = `Assess if the ${sig.entity} trend affects your product roadmap or positioning.`;
|
|
227
|
+
reasoning = "Trending topics signal where developer and investor attention is shifting.";
|
|
228
|
+
urgency = "this_week";
|
|
229
|
+
category = "opportunity";
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
action = `Note: ${sig.headline}`;
|
|
233
|
+
reasoning = "Signal detected but no immediate action required.";
|
|
234
|
+
urgency = "monitor";
|
|
235
|
+
category = "market";
|
|
236
|
+
}
|
|
237
|
+
recs.push({ signal: sig, action, reasoning, urgency, category });
|
|
238
|
+
}
|
|
239
|
+
// Sort: act_now first, then this_week, then monitor
|
|
240
|
+
const urgencyOrder = { act_now: 0, this_week: 1, monitor: 2 };
|
|
241
|
+
recs.sort((a, b) => urgencyOrder[a.urgency] - urgencyOrder[b.urgency]);
|
|
242
|
+
return recs;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/sweep/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeBench Sweep Engine — Live signal intelligence layer.
|
|
3
|
+
*
|
|
4
|
+
* Pattern: Crucix's 27-source parallel sweep + delta engine
|
|
5
|
+
* Architecture: Self-contained source modules, each exports collect()
|
|
6
|
+
*/
|
|
7
|
+
export type { SweepSignal, SweepResult, DeltaResult, SourceCollector } from "./types.js";
|
|
8
|
+
export { registerSource, runSweep, computeDelta, initSweepTables, getLatestSweep, getPreviousSweep, generateRecommendations } from "./engine.js";
|
|
9
|
+
export type { Recommendation } from "./engine.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeBench Sweep Engine — Live signal intelligence layer.
|
|
3
|
+
*
|
|
4
|
+
* Pattern: Crucix's 27-source parallel sweep + delta engine
|
|
5
|
+
* Architecture: Self-contained source modules, each exports collect()
|
|
6
|
+
*/
|
|
7
|
+
export { registerSource, runSweep, computeDelta, initSweepTables, getLatestSweep, getPreviousSweep, generateRecommendations } from "./engine.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sweep/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Trending source — trending repos in AI/agent space.
|
|
3
|
+
* No API key needed. Scrapes the trending page.
|
|
4
|
+
*/
|
|
5
|
+
export async function collect() {
|
|
6
|
+
const signals = [];
|
|
7
|
+
try {
|
|
8
|
+
// Use GitHub's unofficial trending API endpoint
|
|
9
|
+
const resp = await fetch("https://api.github.com/search/repositories?q=stars:>100+pushed:>2026-03-25+topic:ai-agent+topic:mcp+topic:llm&sort=stars&order=desc&per_page=10", {
|
|
10
|
+
signal: AbortSignal.timeout(5000),
|
|
11
|
+
headers: { "Accept": "application/vnd.github.v3+json" },
|
|
12
|
+
});
|
|
13
|
+
if (!resp.ok)
|
|
14
|
+
return [];
|
|
15
|
+
const data = (await resp.json());
|
|
16
|
+
for (const repo of (data.items ?? []).slice(0, 10)) {
|
|
17
|
+
const entity = repo.full_name?.split("/")?.[1] ?? repo.name ?? "unknown";
|
|
18
|
+
const stars = repo.stargazers_count ?? 0;
|
|
19
|
+
const score = Math.min(100, Math.round(stars / 100));
|
|
20
|
+
signals.push({
|
|
21
|
+
id: `gh_${repo.id}`,
|
|
22
|
+
source: "github_trending",
|
|
23
|
+
entity,
|
|
24
|
+
headline: `${repo.full_name}: ${(repo.description ?? "").slice(0, 80)}`,
|
|
25
|
+
url: repo.html_url,
|
|
26
|
+
score,
|
|
27
|
+
category: "product",
|
|
28
|
+
severity: stars > 5000 ? "flash" : stars > 1000 ? "priority" : "routine",
|
|
29
|
+
metadata: { stars, forks: repo.forks_count, language: repo.language },
|
|
30
|
+
collectedAt: new Date().toISOString(),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch { /* GitHub unavailable */ }
|
|
35
|
+
return signals;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=github_trending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github_trending.js","sourceRoot":"","sources":["../../../src/sweep/sources/github_trending.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,gDAAgD;QAChD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,iJAAiJ,EAAE;YAC1K,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;YACjC,OAAO,EAAE,EAAE,QAAQ,EAAE,gCAAgC,EAAE;SACxD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAQ,CAAC;QAExC,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;YACzE,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;YAErD,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,IAAI,CAAC,EAAE,EAAE;gBACnB,MAAM,EAAE,iBAAiB;gBACzB,MAAM;gBACN,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;gBACvE,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,KAAK;gBACL,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;gBACxE,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;gBACrE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,wBAAwB,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HackerNews source — top stories mentioning AI/agent/startup companies.
|
|
3
|
+
* No API key needed. Uses official HN Firebase API.
|
|
4
|
+
* Pattern: Crucix's self-contained source module with briefing() export.
|
|
5
|
+
*/
|
|
6
|
+
import type { SweepSignal } from "../types.js";
|
|
7
|
+
export declare function collect(): Promise<SweepSignal[]>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HackerNews source — top stories mentioning AI/agent/startup companies.
|
|
3
|
+
* No API key needed. Uses official HN Firebase API.
|
|
4
|
+
* Pattern: Crucix's self-contained source module with briefing() export.
|
|
5
|
+
*/
|
|
6
|
+
const HN_TOP_URL = "https://hacker-news.firebaseio.com/v0/topstories.json";
|
|
7
|
+
const HN_ITEM_URL = (id) => `https://hacker-news.firebaseio.com/v0/item/${id}.json`;
|
|
8
|
+
// AI/agent/startup keywords that matter to founders
|
|
9
|
+
const SIGNAL_KEYWORDS = /\b(AI|GPT|Claude|Anthropic|OpenAI|LLM|agent|MCP|startup|YC|funding|Series [A-D]|acquisition|IPO|valuation|launch|open.?source|developer tool|API|infra|vector|RAG|fine.?tun)/i;
|
|
10
|
+
export async function collect() {
|
|
11
|
+
const signals = [];
|
|
12
|
+
try {
|
|
13
|
+
const resp = await fetch(HN_TOP_URL, { signal: AbortSignal.timeout(5000) });
|
|
14
|
+
if (!resp.ok)
|
|
15
|
+
return [];
|
|
16
|
+
const ids = (await resp.json());
|
|
17
|
+
// Fetch top 30 stories in parallel
|
|
18
|
+
const items = await Promise.all(ids.slice(0, 30).map(async (id) => {
|
|
19
|
+
try {
|
|
20
|
+
const r = await fetch(HN_ITEM_URL(id), { signal: AbortSignal.timeout(3000) });
|
|
21
|
+
return r.ok ? await r.json() : null;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
for (const item of items) {
|
|
28
|
+
if (!item?.title)
|
|
29
|
+
continue;
|
|
30
|
+
if (!SIGNAL_KEYWORDS.test(item.title))
|
|
31
|
+
continue;
|
|
32
|
+
// Extract entity from title
|
|
33
|
+
const entityMatch = item.title.match(/([A-Z][a-zA-Z]+(?:\s+[A-Z][a-zA-Z]+)*)/);
|
|
34
|
+
const entity = entityMatch?.[0] ?? item.title.split(/[:\-–—]/).map((s) => s.trim())[0].slice(0, 30);
|
|
35
|
+
const score = Math.min(100, Math.round((item.score ?? 0) / 5));
|
|
36
|
+
const severity = score > 60 ? "flash" : score > 30 ? "priority" : "routine";
|
|
37
|
+
signals.push({
|
|
38
|
+
id: `hn_${item.id}`,
|
|
39
|
+
source: "hackernews",
|
|
40
|
+
entity,
|
|
41
|
+
headline: item.title.slice(0, 120),
|
|
42
|
+
url: item.url ?? `https://news.ycombinator.com/item?id=${item.id}`,
|
|
43
|
+
score,
|
|
44
|
+
category: /fund|rais|series|valuation/i.test(item.title) ? "funding"
|
|
45
|
+
: /launch|ship|release|announce/i.test(item.title) ? "launch"
|
|
46
|
+
: /acqui|merge|IPO/i.test(item.title) ? "market"
|
|
47
|
+
: "trend",
|
|
48
|
+
severity,
|
|
49
|
+
metadata: { points: item.score, comments: item.descendants },
|
|
50
|
+
collectedAt: new Date().toISOString(),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch { /* HN unavailable — non-fatal */ }
|
|
55
|
+
return signals;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=hackernews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hackernews.js","sourceRoot":"","sources":["../../../src/sweep/sources/hackernews.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenBB-style financial data source.
|
|
3
|
+
* Uses free Yahoo Finance API (same pattern as OpenBB's data providers).
|
|
4
|
+
* No API key needed.
|
|
5
|
+
*
|
|
6
|
+
* Tracks: major AI/tech company fundamentals that founders care about.
|
|
7
|
+
*/
|
|
8
|
+
import type { SweepSignal } from "../types.js";
|
|
9
|
+
export declare function collect(): Promise<SweepSignal[]>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenBB-style financial data source.
|
|
3
|
+
* Uses free Yahoo Finance API (same pattern as OpenBB's data providers).
|
|
4
|
+
* No API key needed.
|
|
5
|
+
*
|
|
6
|
+
* Tracks: major AI/tech company fundamentals that founders care about.
|
|
7
|
+
*/
|
|
8
|
+
const TRACKED_TICKERS = {
|
|
9
|
+
"GOOGL": "Alphabet/Google", "MSFT": "Microsoft", "META": "Meta",
|
|
10
|
+
"NVDA": "NVIDIA", "AMD": "AMD", "CRM": "Salesforce",
|
|
11
|
+
"PLTR": "Palantir", "SNOW": "Snowflake", "NET": "Cloudflare",
|
|
12
|
+
};
|
|
13
|
+
export async function collect() {
|
|
14
|
+
const signals = [];
|
|
15
|
+
try {
|
|
16
|
+
const tickers = Object.keys(TRACKED_TICKERS).join(",");
|
|
17
|
+
const resp = await fetch(`https://query1.finance.yahoo.com/v7/finance/quote?symbols=${tickers}&fields=regularMarketPrice,regularMarketChangePercent,marketCap,fiftyDayAverage`, { signal: AbortSignal.timeout(5000), headers: { "User-Agent": "NodeBench/1.0" } });
|
|
18
|
+
if (!resp.ok)
|
|
19
|
+
return [];
|
|
20
|
+
const data = (await resp.json());
|
|
21
|
+
const quotes = data?.quoteResponse?.result ?? [];
|
|
22
|
+
for (const q of quotes) {
|
|
23
|
+
const changePct = q.regularMarketChangePercent ?? 0;
|
|
24
|
+
const absChange = Math.abs(changePct);
|
|
25
|
+
if (absChange < 1.5)
|
|
26
|
+
continue; // Only significant moves
|
|
27
|
+
const name = TRACKED_TICKERS[q.symbol] ?? q.symbol;
|
|
28
|
+
const mcap = q.marketCap ? `$${(q.marketCap / 1e9).toFixed(0)}B` : "";
|
|
29
|
+
signals.push({
|
|
30
|
+
id: `fin_${q.symbol}_${new Date().toISOString().slice(0, 10)}`,
|
|
31
|
+
source: "openbb_finance",
|
|
32
|
+
entity: name,
|
|
33
|
+
headline: `${name} (${q.symbol}) ${changePct > 0 ? "↑" : "↓"} ${absChange.toFixed(1)}% ${mcap ? `— ${mcap} market cap` : ""}`,
|
|
34
|
+
url: `https://finance.yahoo.com/quote/${q.symbol}`,
|
|
35
|
+
score: Math.min(100, Math.round(absChange * 15)),
|
|
36
|
+
category: "market",
|
|
37
|
+
severity: absChange > 5 ? "flash" : absChange > 3 ? "priority" : "routine",
|
|
38
|
+
metadata: { ticker: q.symbol, price: q.regularMarketPrice, changePct, marketCap: q.marketCap },
|
|
39
|
+
collectedAt: new Date().toISOString(),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch { /* Yahoo unavailable */ }
|
|
44
|
+
return signals;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=openbb_finance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openbb_finance.js","sourceRoot":"","sources":["../../../src/sweep/sources/openbb_finance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProductHunt source — today's top AI/agent product launches.
|
|
3
|
+
* Uses the public feed (no API key needed).
|
|
4
|
+
*/
|
|
5
|
+
const AI_KEYWORDS = /\b(AI|agent|LLM|GPT|Claude|copilot|automation|workflow|MCP|developer|API|no.?code|low.?code)\b/i;
|
|
6
|
+
export async function collect() {
|
|
7
|
+
const signals = [];
|
|
8
|
+
try {
|
|
9
|
+
// ProductHunt doesn't have a public API without OAuth, use their RSS-like endpoint
|
|
10
|
+
const resp = await fetch("https://www.producthunt.com/feed?category=artificial-intelligence", {
|
|
11
|
+
signal: AbortSignal.timeout(5000),
|
|
12
|
+
headers: { "User-Agent": "NodeBench/1.0", "Accept": "application/json" },
|
|
13
|
+
});
|
|
14
|
+
// If JSON fails, try scraping the page title patterns
|
|
15
|
+
if (!resp.ok)
|
|
16
|
+
return [];
|
|
17
|
+
const text = await resp.text();
|
|
18
|
+
// Extract product names and taglines from the page
|
|
19
|
+
const productMatches = text.matchAll(/"name"\s*:\s*"([^"]+)".*?"tagline"\s*:\s*"([^"]+)"/g);
|
|
20
|
+
for (const match of productMatches) {
|
|
21
|
+
const name = match[1];
|
|
22
|
+
const tagline = match[2];
|
|
23
|
+
if (!AI_KEYWORDS.test(`${name} ${tagline}`))
|
|
24
|
+
continue;
|
|
25
|
+
signals.push({
|
|
26
|
+
id: `ph_${name.toLowerCase().replace(/\s+/g, "-")}`,
|
|
27
|
+
source: "producthunt",
|
|
28
|
+
entity: name,
|
|
29
|
+
headline: `${name}: ${tagline.slice(0, 80)}`,
|
|
30
|
+
url: `https://www.producthunt.com/search?q=${encodeURIComponent(name)}`,
|
|
31
|
+
score: 50,
|
|
32
|
+
category: "launch",
|
|
33
|
+
severity: "priority",
|
|
34
|
+
collectedAt: new Date().toISOString(),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { /* PH unavailable */ }
|
|
39
|
+
return signals.slice(0, 5);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=producthunt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"producthunt.js","sourceRoot":"","sources":["../../../src/sweep/sources/producthunt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,GAAG,iGAAiG,CAAC;AAEtH,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,mFAAmF;QACnF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,mEAAmE,EAAE;YAC5F,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;YACjC,OAAO,EAAE,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,kBAAkB,EAAE;SACzE,CAAC,CAAC;QACH,sDAAsD;QACtD,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC;QAExB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,mDAAmD;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,qDAAqD,CAAC,CAAC;QAE5F,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;gBAAE,SAAS;YAEtD,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;gBACnD,MAAM,EAAE,aAAa;gBACrB,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;gBAC5C,GAAG,EAAE,wCAAwC,kBAAkB,CAAC,IAAI,CAAC,EAAE;gBACvE,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,UAAU;gBACpB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAChC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web signals source — uses NodeBench's own web_search to find
|
|
3
|
+
* today's top AI/agent news. This is the bridge between Crucix-style
|
|
4
|
+
* OSINT and NodeBench's existing search infrastructure.
|
|
5
|
+
*/
|
|
6
|
+
import type { SweepSignal } from "../types.js";
|
|
7
|
+
export declare function collect(): Promise<SweepSignal[]>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web signals source — uses NodeBench's own web_search to find
|
|
3
|
+
* today's top AI/agent news. This is the bridge between Crucix-style
|
|
4
|
+
* OSINT and NodeBench's existing search infrastructure.
|
|
5
|
+
*/
|
|
6
|
+
const SIGNAL_QUERIES = [
|
|
7
|
+
"AI agent startup funding raised 2026",
|
|
8
|
+
"MCP model context protocol news today",
|
|
9
|
+
"AI coding tool launch announcement",
|
|
10
|
+
"enterprise AI competitive landscape shifts",
|
|
11
|
+
];
|
|
12
|
+
export async function collect() {
|
|
13
|
+
const signals = [];
|
|
14
|
+
try {
|
|
15
|
+
// Use NodeBench's own search API to find signals
|
|
16
|
+
const query = SIGNAL_QUERIES[new Date().getHours() % SIGNAL_QUERIES.length];
|
|
17
|
+
const resp = await fetch("https://www.nodebenchai.com/api/search", {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
|
+
body: JSON.stringify({ query, lens: "investor" }),
|
|
21
|
+
signal: AbortSignal.timeout(15000),
|
|
22
|
+
});
|
|
23
|
+
if (!resp.ok)
|
|
24
|
+
return [];
|
|
25
|
+
const data = (await resp.json());
|
|
26
|
+
const result = data.result;
|
|
27
|
+
if (!result)
|
|
28
|
+
return [];
|
|
29
|
+
// Extract signals from the search result
|
|
30
|
+
for (const sig of (result.signals ?? []).slice(0, 5)) {
|
|
31
|
+
signals.push({
|
|
32
|
+
id: `ws_${Date.now()}_${signals.length}`,
|
|
33
|
+
source: "web_signals",
|
|
34
|
+
entity: sig.name?.split(/[:\-–]/)?.map((s) => s.trim())?.[0]?.slice(0, 30) ?? "AI Market",
|
|
35
|
+
headline: sig.name?.slice(0, 120) ?? "",
|
|
36
|
+
score: sig.impact === "high" ? 80 : sig.impact === "medium" ? 50 : 30,
|
|
37
|
+
category: "trend",
|
|
38
|
+
severity: sig.impact === "high" ? "priority" : "routine",
|
|
39
|
+
metadata: { direction: sig.direction, impact: sig.impact },
|
|
40
|
+
collectedAt: new Date().toISOString(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Extract entity from the result
|
|
44
|
+
const entityName = result.canonicalEntity?.name;
|
|
45
|
+
if (entityName && entityName.length > 1) {
|
|
46
|
+
const answer = result.canonicalEntity?.canonicalMission ?? "";
|
|
47
|
+
signals.unshift({
|
|
48
|
+
id: `ws_entity_${Date.now()}`,
|
|
49
|
+
source: "web_signals",
|
|
50
|
+
entity: entityName,
|
|
51
|
+
headline: answer.slice(0, 120) || `Intelligence on ${entityName}`,
|
|
52
|
+
score: result.canonicalEntity?.identityConfidence ?? 50,
|
|
53
|
+
category: "company",
|
|
54
|
+
severity: "priority",
|
|
55
|
+
metadata: { confidence: result.canonicalEntity?.identityConfidence },
|
|
56
|
+
collectedAt: new Date().toISOString(),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch { /* search unavailable */ }
|
|
61
|
+
return signals;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=web_signals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web_signals.js","sourceRoot":"","sources":["../../../src/sweep/sources/web_signals.ts"],"names":[],"mappings":"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"}
|