nodebench-mcp 2.69.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +95 -39
  2. package/dist/agents/alertRouter.d.ts +38 -0
  3. package/dist/agents/alertRouter.js +151 -0
  4. package/dist/agents/alertRouter.js.map +1 -0
  5. package/dist/agents/entityMemory.d.ts +40 -0
  6. package/dist/agents/entityMemory.js +64 -0
  7. package/dist/agents/entityMemory.js.map +1 -0
  8. package/dist/agents/subAgents.d.ts +35 -0
  9. package/dist/agents/subAgents.js +62 -0
  10. package/dist/agents/subAgents.js.map +1 -0
  11. package/dist/benchmarks/benchmarkRunner.js +14 -0
  12. package/dist/benchmarks/benchmarkRunner.js.map +1 -1
  13. package/dist/benchmarks/chainEval.js +107 -0
  14. package/dist/benchmarks/chainEval.js.map +1 -1
  15. package/dist/benchmarks/llmJudgeEval.js +85 -0
  16. package/dist/benchmarks/llmJudgeEval.js.map +1 -1
  17. package/dist/benchmarks/searchQualityEval.js +118 -5
  18. package/dist/benchmarks/searchQualityEval.js.map +1 -1
  19. package/dist/cli/search.d.ts +13 -0
  20. package/dist/cli/search.js +130 -0
  21. package/dist/cli/search.js.map +1 -0
  22. package/dist/db.d.ts +6 -2
  23. package/dist/db.js +470 -3
  24. package/dist/db.js.map +1 -1
  25. package/dist/index.js +349 -64
  26. package/dist/index.js.map +1 -1
  27. package/dist/profiler/behaviorStore.d.ts +97 -0
  28. package/dist/profiler/behaviorStore.js +276 -0
  29. package/dist/profiler/behaviorStore.js.map +1 -0
  30. package/dist/profiler/eventCollector.d.ts +119 -0
  31. package/dist/profiler/eventCollector.js +267 -0
  32. package/dist/profiler/eventCollector.js.map +1 -0
  33. package/dist/profiler/index.d.ts +15 -0
  34. package/dist/profiler/index.js +16 -0
  35. package/dist/profiler/index.js.map +1 -0
  36. package/dist/profiler/mcpProxy.d.ts +49 -0
  37. package/dist/profiler/mcpProxy.js +123 -0
  38. package/dist/profiler/mcpProxy.js.map +1 -0
  39. package/dist/profiler/modelRouter.d.ts +30 -0
  40. package/dist/profiler/modelRouter.js +99 -0
  41. package/dist/profiler/modelRouter.js.map +1 -0
  42. package/dist/profiler/otelReceiver.d.ts +17 -0
  43. package/dist/profiler/otelReceiver.js +62 -0
  44. package/dist/profiler/otelReceiver.js.map +1 -0
  45. package/dist/profiler/proofEngine.d.ts +41 -0
  46. package/dist/profiler/proofEngine.js +93 -0
  47. package/dist/profiler/proofEngine.js.map +1 -0
  48. package/dist/profiler/workflowTemplates.d.ts +41 -0
  49. package/dist/profiler/workflowTemplates.js +95 -0
  50. package/dist/profiler/workflowTemplates.js.map +1 -0
  51. package/dist/providers/localMemoryProvider.js +3 -2
  52. package/dist/providers/localMemoryProvider.js.map +1 -1
  53. package/dist/runtimeConfig.d.ts +11 -0
  54. package/dist/runtimeConfig.js +27 -0
  55. package/dist/runtimeConfig.js.map +1 -0
  56. package/dist/security/auditLog.js +8 -3
  57. package/dist/security/auditLog.js.map +1 -1
  58. package/dist/subconscious/blocks.d.ts +43 -0
  59. package/dist/subconscious/blocks.js +158 -0
  60. package/dist/subconscious/blocks.js.map +1 -0
  61. package/dist/subconscious/classifier.d.ts +22 -0
  62. package/dist/subconscious/classifier.js +118 -0
  63. package/dist/subconscious/classifier.js.map +1 -0
  64. package/dist/subconscious/graphEngine.d.ts +65 -0
  65. package/dist/subconscious/graphEngine.js +234 -0
  66. package/dist/subconscious/graphEngine.js.map +1 -0
  67. package/dist/subconscious/index.d.ts +19 -0
  68. package/dist/subconscious/index.js +20 -0
  69. package/dist/subconscious/index.js.map +1 -0
  70. package/dist/subconscious/tools.d.ts +5 -0
  71. package/dist/subconscious/tools.js +255 -0
  72. package/dist/subconscious/tools.js.map +1 -0
  73. package/dist/subconscious/whisperPolicy.d.ts +20 -0
  74. package/dist/subconscious/whisperPolicy.js +171 -0
  75. package/dist/subconscious/whisperPolicy.js.map +1 -0
  76. package/dist/sweep/engine.d.ts +27 -0
  77. package/dist/sweep/engine.js +244 -0
  78. package/dist/sweep/engine.js.map +1 -0
  79. package/dist/sweep/index.d.ts +9 -0
  80. package/dist/sweep/index.js +8 -0
  81. package/dist/sweep/index.js.map +1 -0
  82. package/dist/sweep/sources/github_trending.d.ts +6 -0
  83. package/dist/sweep/sources/github_trending.js +37 -0
  84. package/dist/sweep/sources/github_trending.js.map +1 -0
  85. package/dist/sweep/sources/hackernews.d.ts +7 -0
  86. package/dist/sweep/sources/hackernews.js +57 -0
  87. package/dist/sweep/sources/hackernews.js.map +1 -0
  88. package/dist/sweep/sources/openbb_finance.d.ts +9 -0
  89. package/dist/sweep/sources/openbb_finance.js +46 -0
  90. package/dist/sweep/sources/openbb_finance.js.map +1 -0
  91. package/dist/sweep/sources/producthunt.d.ts +6 -0
  92. package/dist/sweep/sources/producthunt.js +41 -0
  93. package/dist/sweep/sources/producthunt.js.map +1 -0
  94. package/dist/sweep/sources/web_signals.d.ts +7 -0
  95. package/dist/sweep/sources/web_signals.js +63 -0
  96. package/dist/sweep/sources/web_signals.js.map +1 -0
  97. package/dist/sweep/sources/yahoo_finance.d.ts +6 -0
  98. package/dist/sweep/sources/yahoo_finance.js +47 -0
  99. package/dist/sweep/sources/yahoo_finance.js.map +1 -0
  100. package/dist/sweep/types.d.ts +50 -0
  101. package/dist/sweep/types.js +9 -0
  102. package/dist/sweep/types.js.map +1 -0
  103. package/dist/sync/founderEpisodeStore.d.ts +98 -0
  104. package/dist/sync/founderEpisodeStore.js +230 -0
  105. package/dist/sync/founderEpisodeStore.js.map +1 -0
  106. package/dist/sync/hyperloopArchive.d.ts +51 -0
  107. package/dist/sync/hyperloopArchive.js +153 -0
  108. package/dist/sync/hyperloopArchive.js.map +1 -0
  109. package/dist/sync/hyperloopEval.d.ts +123 -0
  110. package/dist/sync/hyperloopEval.js +389 -0
  111. package/dist/sync/hyperloopEval.js.map +1 -0
  112. package/dist/sync/hyperloopEval.test.d.ts +4 -0
  113. package/dist/sync/hyperloopEval.test.js +60 -0
  114. package/dist/sync/hyperloopEval.test.js.map +1 -0
  115. package/dist/sync/protocol.d.ts +172 -0
  116. package/dist/sync/protocol.js +9 -0
  117. package/dist/sync/protocol.js.map +1 -0
  118. package/dist/sync/sessionMemory.d.ts +47 -0
  119. package/dist/sync/sessionMemory.js +138 -0
  120. package/dist/sync/sessionMemory.js.map +1 -0
  121. package/dist/sync/store.d.ts +384 -0
  122. package/dist/sync/store.js +1435 -0
  123. package/dist/sync/store.js.map +1 -0
  124. package/dist/sync/store.test.d.ts +4 -0
  125. package/dist/sync/store.test.js +43 -0
  126. package/dist/sync/store.test.js.map +1 -0
  127. package/dist/sync/syncBridgeClient.d.ts +30 -0
  128. package/dist/sync/syncBridgeClient.js +172 -0
  129. package/dist/sync/syncBridgeClient.js.map +1 -0
  130. package/dist/tools/autonomousDeliveryTools.d.ts +2 -0
  131. package/dist/tools/autonomousDeliveryTools.js +1104 -0
  132. package/dist/tools/autonomousDeliveryTools.js.map +1 -0
  133. package/dist/tools/claudeCodeIngestTools.d.ts +10 -0
  134. package/dist/tools/claudeCodeIngestTools.js +347 -0
  135. package/dist/tools/claudeCodeIngestTools.js.map +1 -0
  136. package/dist/tools/coreWorkflowTools.d.ts +2 -0
  137. package/dist/tools/coreWorkflowTools.js +488 -0
  138. package/dist/tools/coreWorkflowTools.js.map +1 -0
  139. package/dist/tools/deltaTools.d.ts +15 -0
  140. package/dist/tools/deltaTools.js +1522 -0
  141. package/dist/tools/deltaTools.js.map +1 -0
  142. package/dist/tools/entityLookupTools.d.ts +14 -0
  143. package/dist/tools/entityLookupTools.js +159 -0
  144. package/dist/tools/entityLookupTools.js.map +1 -0
  145. package/dist/tools/entityTemporalTools.d.ts +12 -0
  146. package/dist/tools/entityTemporalTools.js +330 -0
  147. package/dist/tools/entityTemporalTools.js.map +1 -0
  148. package/dist/tools/founderLocalPipeline.d.ts +215 -0
  149. package/dist/tools/founderLocalPipeline.js +1516 -2
  150. package/dist/tools/founderLocalPipeline.js.map +1 -1
  151. package/dist/tools/founderOperatingModel.d.ts +120 -0
  152. package/dist/tools/founderOperatingModel.js +469 -0
  153. package/dist/tools/founderOperatingModel.js.map +1 -0
  154. package/dist/tools/founderOperatingModelTools.d.ts +2 -0
  155. package/dist/tools/founderOperatingModelTools.js +169 -0
  156. package/dist/tools/founderOperatingModelTools.js.map +1 -0
  157. package/dist/tools/founderStrategicOpsTools.d.ts +2 -0
  158. package/dist/tools/founderStrategicOpsTools.js +1310 -0
  159. package/dist/tools/founderStrategicOpsTools.js.map +1 -0
  160. package/dist/tools/graphifyTools.d.ts +19 -0
  161. package/dist/tools/graphifyTools.js +375 -0
  162. package/dist/tools/graphifyTools.js.map +1 -0
  163. package/dist/tools/index.d.ts +3 -0
  164. package/dist/tools/index.js +4 -0
  165. package/dist/tools/index.js.map +1 -1
  166. package/dist/tools/monteCarloTools.d.ts +16 -0
  167. package/dist/tools/monteCarloTools.js +225 -0
  168. package/dist/tools/monteCarloTools.js.map +1 -0
  169. package/dist/tools/packetCompilerTools.d.ts +12 -0
  170. package/dist/tools/packetCompilerTools.js +322 -0
  171. package/dist/tools/packetCompilerTools.js.map +1 -0
  172. package/dist/tools/planSynthesisTools.d.ts +15 -0
  173. package/dist/tools/planSynthesisTools.js +455 -0
  174. package/dist/tools/planSynthesisTools.js.map +1 -0
  175. package/dist/tools/profilerTools.d.ts +20 -0
  176. package/dist/tools/profilerTools.js +364 -0
  177. package/dist/tools/profilerTools.js.map +1 -0
  178. package/dist/tools/savingsTools.d.ts +11 -0
  179. package/dist/tools/savingsTools.js +155 -0
  180. package/dist/tools/savingsTools.js.map +1 -0
  181. package/dist/tools/scenarioCompilerTools.d.ts +14 -0
  182. package/dist/tools/scenarioCompilerTools.js +290 -0
  183. package/dist/tools/scenarioCompilerTools.js.map +1 -0
  184. package/dist/tools/sharedContextTools.d.ts +2 -0
  185. package/dist/tools/sharedContextTools.js +423 -0
  186. package/dist/tools/sharedContextTools.js.map +1 -0
  187. package/dist/tools/sitemapTools.d.ts +15 -0
  188. package/dist/tools/sitemapTools.js +560 -0
  189. package/dist/tools/sitemapTools.js.map +1 -0
  190. package/dist/tools/sweepTools.d.ts +9 -0
  191. package/dist/tools/sweepTools.js +112 -0
  192. package/dist/tools/sweepTools.js.map +1 -0
  193. package/dist/tools/syncBridgeTools.d.ts +2 -0
  194. package/dist/tools/syncBridgeTools.js +258 -0
  195. package/dist/tools/syncBridgeTools.js.map +1 -0
  196. package/dist/tools/toolRegistry.js +1216 -49
  197. package/dist/tools/toolRegistry.js.map +1 -1
  198. package/dist/tools/workspaceTools.d.ts +19 -0
  199. package/dist/tools/workspaceTools.js +762 -0
  200. package/dist/tools/workspaceTools.js.map +1 -0
  201. package/dist/toolsetRegistry.js +88 -2
  202. package/dist/toolsetRegistry.js.map +1 -1
  203. package/package.json +36 -36
  204. package/rules/nodebench-agentic-reliability.md +32 -0
  205. package/rules/nodebench-analyst-diagnostic.md +25 -0
  206. package/rules/nodebench-auto-qa.md +31 -0
  207. package/rules/nodebench-completion-traceability.md +22 -0
  208. package/rules/nodebench-flywheel-continuous.md +25 -0
  209. package/rules/nodebench-pre-release-review.md +24 -0
  210. package/rules/nodebench-qa-dogfood.md +26 -0
  211. package/rules/nodebench-scenario-testing.md +30 -0
  212. package/rules/nodebench-self-direction.md +23 -0
  213. package/rules/nodebench-self-judge-loop.md +24 -0
  214. package/scripts/install.sh +215 -0
@@ -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,6 @@
1
+ /**
2
+ * ProductHunt source — today's top AI/agent product launches.
3
+ * Uses the public feed (no API key needed).
4
+ */
5
+ import type { SweepSignal } from "../types.js";
6
+ export declare function collect(): Promise<SweepSignal[]>;
@@ -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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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Yahoo Finance source — live market data for key AI/tech stocks.
3
+ * No API key needed. Pattern from Crucix's yfinance.mjs.
4
+ */
5
+ import type { SweepSignal } from "../types.js";
6
+ export declare function collect(): Promise<SweepSignal[]>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Yahoo Finance source — live market data for key AI/tech stocks.
3
+ * No API key needed. Pattern from Crucix's yfinance.mjs.
4
+ */
5
+ // Key AI/tech tickers that founders track
6
+ const TICKERS = ["GOOGL", "MSFT", "META", "NVDA", "AMD", "PLTR", "SNOW", "CRM"];
7
+ export async function collect() {
8
+ const signals = [];
9
+ try {
10
+ // Use Yahoo Finance v8 API (no key needed)
11
+ const tickerStr = TICKERS.join(",");
12
+ const resp = await fetch(`https://query1.finance.yahoo.com/v8/finance/spark?symbols=${tickerStr}&range=1d&interval=1d`, { signal: AbortSignal.timeout(5000), headers: { "User-Agent": "NodeBench/1.0" } });
13
+ if (!resp.ok)
14
+ return [];
15
+ const data = (await resp.json());
16
+ for (const ticker of TICKERS) {
17
+ const spark = data?.spark?.result?.find((r) => r.symbol === ticker);
18
+ if (!spark?.response?.[0]?.indicators?.quote?.[0])
19
+ continue;
20
+ const quote = spark.response[0].indicators.quote[0];
21
+ const close = quote.close?.filter(Boolean);
22
+ if (!close?.length)
23
+ continue;
24
+ const current = close[close.length - 1];
25
+ const prev = close[0];
26
+ const changePct = prev > 0 ? ((current - prev) / prev) * 100 : 0;
27
+ const absChange = Math.abs(changePct);
28
+ if (absChange < 2)
29
+ continue; // Only signal meaningful moves
30
+ signals.push({
31
+ id: `yf_${ticker}_${new Date().toISOString().slice(0, 10)}`,
32
+ source: "yahoo_finance",
33
+ entity: ticker,
34
+ headline: `${ticker} ${changePct > 0 ? "up" : "down"} ${absChange.toFixed(1)}% today ($${current.toFixed(2)})`,
35
+ url: `https://finance.yahoo.com/quote/${ticker}`,
36
+ score: Math.min(100, Math.round(absChange * 10)),
37
+ category: "market",
38
+ severity: absChange > 5 ? "flash" : absChange > 3 ? "priority" : "routine",
39
+ metadata: { price: current, changePct: Math.round(changePct * 100) / 100 },
40
+ collectedAt: new Date().toISOString(),
41
+ });
42
+ }
43
+ }
44
+ catch { /* Yahoo unavailable */ }
45
+ return signals;
46
+ }
47
+ //# sourceMappingURL=yahoo_finance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yahoo_finance.js","sourceRoot":"","sources":["../../../src/sweep/sources/yahoo_finance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Sweep Engine Types — following Crucix's pattern of self-contained
3
+ * source modules with standardized output shapes.
4
+ *
5
+ * Each source module exports collect() → Promise<SweepSignal[]>
6
+ * The sweep engine runs all sources in parallel and feeds the delta engine.
7
+ */
8
+ export interface SweepSignal {
9
+ id: string;
10
+ source: string;
11
+ entity: string;
12
+ headline: string;
13
+ url?: string;
14
+ score?: number;
15
+ category: "company" | "product" | "market" | "funding" | "launch" | "trend" | "risk" | "regulatory";
16
+ severity: "flash" | "priority" | "routine";
17
+ metadata?: Record<string, unknown>;
18
+ collectedAt: string;
19
+ }
20
+ export interface SweepResult {
21
+ signals: SweepSignal[];
22
+ sources: Array<{
23
+ name: string;
24
+ status: "ok" | "error" | "timeout";
25
+ count: number;
26
+ durationMs: number;
27
+ }>;
28
+ totalDurationMs: number;
29
+ sweepId: string;
30
+ timestamp: string;
31
+ }
32
+ export interface DeltaResult {
33
+ newSignals: SweepSignal[];
34
+ escalations: Array<{
35
+ signal: SweepSignal;
36
+ from: string;
37
+ to: string;
38
+ }>;
39
+ deescalations: Array<{
40
+ signal: SweepSignal;
41
+ from: string;
42
+ to: string;
43
+ }>;
44
+ topEntity: string | null;
45
+ topEntityQuery: string | null;
46
+ topEntitySeverity: "flash" | "priority" | "routine" | null;
47
+ sweepId: string;
48
+ previousSweepId: string | null;
49
+ }
50
+ export type SourceCollector = () => Promise<SweepSignal[]>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Sweep Engine Types — following Crucix's pattern of self-contained
3
+ * source modules with standardized output shapes.
4
+ *
5
+ * Each source module exports collect() → Promise<SweepSignal[]>
6
+ * The sweep engine runs all sources in parallel and feeds the delta engine.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sweep/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,98 @@
1
+ export type FounderEpisodeStatus = "active" | "completed" | "error" | "aborted";
2
+ export type FounderEpisodeSurface = "web" | "api" | "browser" | "claude_code" | "openclaw" | "local_runtime";
3
+ export interface FounderEpisodeRecord {
4
+ episodeId: string;
5
+ correlationId: string;
6
+ sessionKey?: string | null;
7
+ workspaceId?: string | null;
8
+ companyKey?: string | null;
9
+ surface: FounderEpisodeSurface;
10
+ episodeType: string;
11
+ status: FounderEpisodeStatus;
12
+ query?: string | null;
13
+ lens?: string | null;
14
+ entityName?: string | null;
15
+ packetId?: string | null;
16
+ packetType?: string | null;
17
+ workflowAssetId?: string | null;
18
+ workflowEnvelopeId?: string | null;
19
+ contextId?: string | null;
20
+ taskId?: string | null;
21
+ summary?: string | null;
22
+ stateBefore?: Record<string, unknown>;
23
+ stateAfter?: Record<string, unknown>;
24
+ stateBeforeHash?: string | null;
25
+ stateAfterHash?: string | null;
26
+ spans: Array<Record<string, unknown>>;
27
+ traceStepCount?: number | null;
28
+ toolsInvoked: string[];
29
+ artifactsProduced: string[];
30
+ importantChangesDetected?: number | null;
31
+ contradictionsDetected?: number | null;
32
+ metadata?: Record<string, unknown>;
33
+ startedAt: string;
34
+ updatedAt: string;
35
+ completedAt?: string | null;
36
+ }
37
+ export declare function startFounderEpisode(input: {
38
+ episodeId?: string;
39
+ correlationId?: string;
40
+ sessionKey?: string | null;
41
+ workspaceId?: string | null;
42
+ companyKey?: string | null;
43
+ surface: FounderEpisodeSurface;
44
+ episodeType: string;
45
+ query?: string | null;
46
+ lens?: string | null;
47
+ entityName?: string | null;
48
+ stateBefore?: Record<string, unknown>;
49
+ stateBeforeHash?: string;
50
+ metadata?: Record<string, unknown>;
51
+ initialSpan?: Record<string, unknown>;
52
+ workflowAssetId?: string | null;
53
+ workflowEnvelopeId?: string | null;
54
+ }): FounderEpisodeRecord;
55
+ export declare function appendFounderEpisodeSpan(input: {
56
+ episodeId: string;
57
+ span: Record<string, unknown>;
58
+ contextId?: string | null;
59
+ taskId?: string | null;
60
+ entityName?: string | null;
61
+ packetId?: string | null;
62
+ packetType?: string | null;
63
+ workspaceId?: string | null;
64
+ companyKey?: string | null;
65
+ metadata?: Record<string, unknown>;
66
+ workflowAssetId?: string | null;
67
+ workflowEnvelopeId?: string | null;
68
+ }): FounderEpisodeRecord;
69
+ export declare function finalizeFounderEpisode(input: {
70
+ episodeId: string;
71
+ status?: FounderEpisodeStatus;
72
+ stateAfter?: Record<string, unknown>;
73
+ stateAfterHash?: string;
74
+ summary?: string | null;
75
+ toolsInvoked?: string[];
76
+ artifactsProduced?: string[];
77
+ traceStepCount?: number | null;
78
+ importantChangesDetected?: number | null;
79
+ contradictionsDetected?: number | null;
80
+ contextId?: string | null;
81
+ taskId?: string | null;
82
+ entityName?: string | null;
83
+ packetId?: string | null;
84
+ packetType?: string | null;
85
+ workspaceId?: string | null;
86
+ companyKey?: string | null;
87
+ finalSpan?: Record<string, unknown>;
88
+ metadata?: Record<string, unknown>;
89
+ workflowAssetId?: string | null;
90
+ workflowEnvelopeId?: string | null;
91
+ }): FounderEpisodeRecord;
92
+ export declare function getFounderEpisode(episodeId: string): FounderEpisodeRecord | null;
93
+ export declare function listFounderEpisodes(input?: {
94
+ sessionKey?: string | null;
95
+ workspaceId?: string | null;
96
+ status?: FounderEpisodeStatus;
97
+ limit?: number;
98
+ }): FounderEpisodeRecord[];
@@ -0,0 +1,230 @@
1
+ import { createHash } from "node:crypto";
2
+ import { genId, getDb } from "../db.js";
3
+ function json(value, fallback = {}) {
4
+ return JSON.stringify(value ?? fallback);
5
+ }
6
+ function parseJson(value, fallback) {
7
+ if (!value)
8
+ return fallback;
9
+ try {
10
+ return JSON.parse(value);
11
+ }
12
+ catch {
13
+ return fallback;
14
+ }
15
+ }
16
+ function hashPayload(payload) {
17
+ return createHash("sha256").update(JSON.stringify(payload ?? null)).digest("hex");
18
+ }
19
+ function ensureFounderEpisodeColumns() {
20
+ const db = getDb();
21
+ const columns = db.prepare("PRAGMA table_info(founder_harness_episodes)").all();
22
+ if (!columns.some((column) => column.name === "workflow_asset_id")) {
23
+ db.exec("ALTER TABLE founder_harness_episodes ADD COLUMN workflow_asset_id TEXT");
24
+ }
25
+ if (!columns.some((column) => column.name === "workflow_envelope_id")) {
26
+ db.exec("ALTER TABLE founder_harness_episodes ADD COLUMN workflow_envelope_id TEXT");
27
+ }
28
+ }
29
+ function parseRow(row) {
30
+ return {
31
+ episodeId: row.episode_id,
32
+ correlationId: row.correlation_id,
33
+ sessionKey: row.session_key ?? null,
34
+ workspaceId: row.workspace_id ?? null,
35
+ companyKey: row.company_key ?? null,
36
+ surface: row.surface,
37
+ episodeType: row.episode_type,
38
+ status: row.status,
39
+ query: row.query ?? null,
40
+ lens: row.lens ?? null,
41
+ entityName: row.entity_name ?? null,
42
+ packetId: row.packet_id ?? null,
43
+ packetType: row.packet_type ?? null,
44
+ workflowAssetId: row.workflow_asset_id ?? null,
45
+ workflowEnvelopeId: row.workflow_envelope_id ?? null,
46
+ contextId: row.context_id ?? null,
47
+ taskId: row.task_id ?? null,
48
+ summary: row.summary ?? null,
49
+ stateBefore: parseJson(row.state_before_json, {}),
50
+ stateAfter: parseJson(row.state_after_json, {}),
51
+ stateBeforeHash: row.state_before_hash ?? null,
52
+ stateAfterHash: row.state_after_hash ?? null,
53
+ spans: parseJson(row.spans_json, []),
54
+ traceStepCount: row.trace_step_count ?? null,
55
+ toolsInvoked: parseJson(row.tools_invoked_json, []),
56
+ artifactsProduced: parseJson(row.artifacts_produced_json, []),
57
+ importantChangesDetected: row.important_changes_detected ?? null,
58
+ contradictionsDetected: row.contradictions_detected ?? null,
59
+ metadata: parseJson(row.metadata_json, {}),
60
+ startedAt: row.started_at,
61
+ updatedAt: row.updated_at,
62
+ completedAt: row.completed_at ?? null,
63
+ };
64
+ }
65
+ export function startFounderEpisode(input) {
66
+ ensureFounderEpisodeColumns();
67
+ const db = getDb();
68
+ const now = new Date().toISOString();
69
+ const episodeId = input.episodeId ?? genId("episode");
70
+ const correlationId = input.correlationId ?? genId("corr");
71
+ const existing = db.prepare(`
72
+ SELECT *
73
+ FROM founder_harness_episodes
74
+ WHERE episode_id = ?
75
+ LIMIT 1
76
+ `).get(episodeId);
77
+ const stateBeforeHash = input.stateBeforeHash ?? hashPayload(input.stateBefore ?? null);
78
+ const spans = input.initialSpan ? [input.initialSpan] : [];
79
+ if (existing) {
80
+ db.prepare(`
81
+ UPDATE founder_harness_episodes
82
+ SET correlation_id = ?,
83
+ session_key = COALESCE(?, session_key),
84
+ workspace_id = COALESCE(?, workspace_id),
85
+ company_key = COALESCE(?, company_key),
86
+ surface = ?,
87
+ episode_type = ?,
88
+ query = COALESCE(?, query),
89
+ lens = COALESCE(?, lens),
90
+ entity_name = COALESCE(?, entity_name),
91
+ workflow_asset_id = COALESCE(?, workflow_asset_id),
92
+ workflow_envelope_id = COALESCE(?, workflow_envelope_id),
93
+ state_before_json = COALESCE(?, state_before_json),
94
+ state_before_hash = COALESCE(?, state_before_hash),
95
+ spans_json = CASE WHEN length(COALESCE(spans_json, '')) > 2 THEN spans_json ELSE ? END,
96
+ metadata_json = COALESCE(?, metadata_json),
97
+ updated_at = ?,
98
+ status = CASE WHEN status = 'completed' THEN status ELSE 'active' END
99
+ WHERE episode_id = ?
100
+ `).run(correlationId, input.sessionKey ?? null, input.workspaceId ?? null, input.companyKey ?? null, input.surface, input.episodeType, input.query ?? null, input.lens ?? null, input.entityName ?? null, input.workflowAssetId ?? null, input.workflowEnvelopeId ?? null, input.stateBefore ? json(input.stateBefore) : null, stateBeforeHash, json(spans, []), input.metadata ? json(input.metadata) : null, now, episodeId);
101
+ }
102
+ else {
103
+ db.prepare(`
104
+ INSERT INTO founder_harness_episodes (
105
+ episode_id, correlation_id, session_key, workspace_id, company_key,
106
+ surface, episode_type, status, query, lens, entity_name, state_before_json,
107
+ workflow_asset_id, workflow_envelope_id, state_before_hash, spans_json, tools_invoked_json, artifacts_produced_json,
108
+ metadata_json, started_at, updated_at
109
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
110
+ `).run(episodeId, correlationId, input.sessionKey ?? null, input.workspaceId ?? null, input.companyKey ?? null, input.surface, input.episodeType, "active", input.query ?? null, input.lens ?? null, input.entityName ?? null, json(input.stateBefore), input.workflowAssetId ?? null, input.workflowEnvelopeId ?? null, stateBeforeHash, json(spans, []), "[]", "[]", input.metadata ? json(input.metadata) : null, now, now);
111
+ }
112
+ return getFounderEpisode(episodeId);
113
+ }
114
+ export function appendFounderEpisodeSpan(input) {
115
+ ensureFounderEpisodeColumns();
116
+ const db = getDb();
117
+ const existing = getFounderEpisode(input.episodeId);
118
+ if (!existing) {
119
+ throw new Error(`Founder harness episode not found: ${input.episodeId}`);
120
+ }
121
+ const spans = [...existing.spans, input.span];
122
+ const metadata = input.metadata ? { ...(existing.metadata ?? {}), ...input.metadata } : existing.metadata;
123
+ const now = new Date().toISOString();
124
+ db.prepare(`
125
+ UPDATE founder_harness_episodes
126
+ SET spans_json = ?,
127
+ context_id = COALESCE(?, context_id),
128
+ task_id = COALESCE(?, task_id),
129
+ entity_name = COALESCE(?, entity_name),
130
+ packet_id = COALESCE(?, packet_id),
131
+ packet_type = COALESCE(?, packet_type),
132
+ workflow_asset_id = COALESCE(?, workflow_asset_id),
133
+ workflow_envelope_id = COALESCE(?, workflow_envelope_id),
134
+ workspace_id = COALESCE(?, workspace_id),
135
+ company_key = COALESCE(?, company_key),
136
+ metadata_json = ?,
137
+ updated_at = ?
138
+ WHERE episode_id = ?
139
+ `).run(json(spans, []), input.contextId ?? null, input.taskId ?? null, input.entityName ?? null, input.packetId ?? null, input.packetType ?? null, input.workflowAssetId ?? null, input.workflowEnvelopeId ?? null, input.workspaceId ?? null, input.companyKey ?? null, json(metadata), now, input.episodeId);
140
+ return getFounderEpisode(input.episodeId);
141
+ }
142
+ export function finalizeFounderEpisode(input) {
143
+ ensureFounderEpisodeColumns();
144
+ const db = getDb();
145
+ const existing = getFounderEpisode(input.episodeId);
146
+ if (!existing) {
147
+ throw new Error(`Founder harness episode not found: ${input.episodeId}`);
148
+ }
149
+ const spans = input.finalSpan ? [...existing.spans, input.finalSpan] : existing.spans;
150
+ const toolsInvoked = input.toolsInvoked
151
+ ? Array.from(new Set([...(existing.toolsInvoked ?? []), ...input.toolsInvoked]))
152
+ : existing.toolsInvoked;
153
+ const artifactsProduced = input.artifactsProduced
154
+ ? Array.from(new Set([...(existing.artifactsProduced ?? []), ...input.artifactsProduced]))
155
+ : existing.artifactsProduced;
156
+ const metadata = input.metadata ? { ...(existing.metadata ?? {}), ...input.metadata } : existing.metadata;
157
+ const now = new Date().toISOString();
158
+ db.prepare(`
159
+ UPDATE founder_harness_episodes
160
+ SET status = ?,
161
+ state_after_json = COALESCE(?, state_after_json),
162
+ state_after_hash = COALESCE(?, state_after_hash),
163
+ summary = COALESCE(?, summary),
164
+ tools_invoked_json = ?,
165
+ artifacts_produced_json = ?,
166
+ trace_step_count = COALESCE(?, trace_step_count),
167
+ important_changes_detected = COALESCE(?, important_changes_detected),
168
+ contradictions_detected = COALESCE(?, contradictions_detected),
169
+ context_id = COALESCE(?, context_id),
170
+ task_id = COALESCE(?, task_id),
171
+ entity_name = COALESCE(?, entity_name),
172
+ packet_id = COALESCE(?, packet_id),
173
+ packet_type = COALESCE(?, packet_type),
174
+ workflow_asset_id = COALESCE(?, workflow_asset_id),
175
+ workflow_envelope_id = COALESCE(?, workflow_envelope_id),
176
+ workspace_id = COALESCE(?, workspace_id),
177
+ company_key = COALESCE(?, company_key),
178
+ spans_json = ?,
179
+ metadata_json = ?,
180
+ updated_at = ?,
181
+ completed_at = ?
182
+ WHERE episode_id = ?
183
+ `).run(input.status ?? "completed", input.stateAfter ? json(input.stateAfter) : null, input.stateAfterHash ?? hashPayload(input.stateAfter ?? existing.stateAfter ?? null), input.summary ?? null, json(toolsInvoked, []), json(artifactsProduced, []), input.traceStepCount ?? null, input.importantChangesDetected ?? null, input.contradictionsDetected ?? null, input.contextId ?? null, input.taskId ?? null, input.entityName ?? null, input.packetId ?? null, input.packetType ?? null, input.workflowAssetId ?? null, input.workflowEnvelopeId ?? null, input.workspaceId ?? null, input.companyKey ?? null, json(spans, []), json(metadata), now, now, input.episodeId);
184
+ return getFounderEpisode(input.episodeId);
185
+ }
186
+ export function getFounderEpisode(episodeId) {
187
+ ensureFounderEpisodeColumns();
188
+ const row = getDb().prepare(`
189
+ SELECT *
190
+ FROM founder_harness_episodes
191
+ WHERE episode_id = ?
192
+ LIMIT 1
193
+ `).get(episodeId);
194
+ return row ? parseRow(row) : null;
195
+ }
196
+ export function listFounderEpisodes(input = {}) {
197
+ ensureFounderEpisodeColumns();
198
+ const limit = Math.min(Math.max(input.limit ?? 10, 1), 50);
199
+ const db = getDb();
200
+ let rows = [];
201
+ if (input.sessionKey) {
202
+ rows = db.prepare(`
203
+ SELECT *
204
+ FROM founder_harness_episodes
205
+ WHERE session_key = ?
206
+ ORDER BY started_at DESC
207
+ LIMIT ?
208
+ `).all(input.sessionKey, limit * 2);
209
+ }
210
+ else if (input.workspaceId) {
211
+ rows = db.prepare(`
212
+ SELECT *
213
+ FROM founder_harness_episodes
214
+ WHERE workspace_id = ?
215
+ ORDER BY started_at DESC
216
+ LIMIT ?
217
+ `).all(input.workspaceId, limit * 2);
218
+ }
219
+ else {
220
+ rows = db.prepare(`
221
+ SELECT *
222
+ FROM founder_harness_episodes
223
+ ORDER BY started_at DESC
224
+ LIMIT ?
225
+ `).all(limit * 2);
226
+ }
227
+ const parsed = rows.map(parseRow);
228
+ return input.status ? parsed.filter((row) => row.status === input.status).slice(0, limit) : parsed.slice(0, limit);
229
+ }
230
+ //# sourceMappingURL=founderEpisodeStore.js.map