opencandle 0.11.1 → 0.12.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 (653) hide show
  1. package/README.md +20 -24
  2. package/dist/analysts/contracts.js +0 -1
  3. package/dist/analysts/orchestrator.js +0 -1
  4. package/dist/cli-main.js +13 -7
  5. package/dist/cli-options.d.ts +4 -0
  6. package/dist/cli-options.js +33 -0
  7. package/dist/cli.js +8 -3
  8. package/dist/config.js +0 -1
  9. package/dist/doctor/cli-command.js +2 -1
  10. package/dist/doctor/render.js +0 -1
  11. package/dist/doctor/report.js +40 -11
  12. package/dist/gui/server/ask-user-bridge.d.ts +19 -0
  13. package/dist/gui/server/ask-user-bridge.js +55 -0
  14. package/dist/gui/server/automation-heartbeat.d.ts +25 -0
  15. package/dist/gui/server/automation-heartbeat.js +61 -0
  16. package/dist/gui/server/background-quotes.d.ts +39 -0
  17. package/dist/gui/server/background-quotes.js +71 -0
  18. package/dist/gui/server/chat-event-adapter.d.ts +16 -0
  19. package/dist/gui/server/chat-event-adapter.js +263 -0
  20. package/dist/gui/server/gui-session-manager.d.ts +2 -0
  21. package/dist/gui/server/gui-session-manager.js +4 -0
  22. package/dist/gui/server/http-routes.d.ts +69 -0
  23. package/dist/gui/server/http-routes.js +1008 -0
  24. package/dist/gui/server/invoke-tool.d.ts +47 -0
  25. package/dist/gui/server/invoke-tool.js +373 -0
  26. package/dist/gui/server/live-chat-event-adapter.d.ts +19 -0
  27. package/dist/gui/server/live-chat-event-adapter.js +206 -0
  28. package/dist/gui/server/local-session-coordinator.d.ts +26 -0
  29. package/dist/gui/server/local-session-coordinator.js +53 -0
  30. package/dist/gui/server/market-state-api.d.ts +138 -0
  31. package/dist/gui/server/market-state-api.js +355 -0
  32. package/dist/gui/server/model-setup.d.ts +64 -0
  33. package/dist/gui/server/model-setup.js +150 -0
  34. package/dist/gui/server/private-api-access.d.ts +6 -0
  35. package/dist/gui/server/private-api-access.js +53 -0
  36. package/dist/gui/server/projector.d.ts +49 -0
  37. package/dist/gui/server/projector.js +296 -0
  38. package/dist/gui/server/prompt-observation.d.ts +8 -0
  39. package/dist/gui/server/prompt-observation.js +43 -0
  40. package/dist/gui/server/quote-snapshot-store.d.ts +14 -0
  41. package/dist/gui/server/quote-snapshot-store.js +49 -0
  42. package/dist/gui/server/server.d.ts +1 -0
  43. package/dist/gui/server/server.js +259 -0
  44. package/dist/gui/server/session-actions.d.ts +60 -0
  45. package/dist/gui/server/session-actions.js +218 -0
  46. package/dist/gui/server/session-entry-wait.d.ts +27 -0
  47. package/dist/gui/server/session-entry-wait.js +129 -0
  48. package/dist/gui/server/session-list.d.ts +2 -0
  49. package/dist/gui/server/session-list.js +11 -0
  50. package/dist/gui/server/shutdown.d.ts +10 -0
  51. package/dist/gui/server/shutdown.js +29 -0
  52. package/dist/gui/server/tool-invoke-ack.d.ts +17 -0
  53. package/dist/gui/server/tool-invoke-ack.js +26 -0
  54. package/dist/gui/server/tool-metadata.d.ts +93 -0
  55. package/dist/gui/server/tool-metadata.js +148 -0
  56. package/dist/gui/server/websocket.d.ts +9 -0
  57. package/dist/gui/server/websocket.js +124 -0
  58. package/dist/gui/server/writer-lock.d.ts +1 -0
  59. package/dist/gui/server/writer-lock.js +1 -0
  60. package/dist/gui/server/ws-hub.d.ts +50 -0
  61. package/dist/gui/server/ws-hub.js +284 -0
  62. package/dist/gui/shared/chat-events.d.ts +174 -0
  63. package/dist/gui/shared/chat-events.js +13 -0
  64. package/dist/gui/shared/event-reducer.d.ts +3 -0
  65. package/dist/gui/shared/event-reducer.js +187 -0
  66. package/dist/index.js +0 -1
  67. package/dist/infra/cache.js +0 -1
  68. package/dist/infra/freshness.js +0 -1
  69. package/dist/infra/http-client.js +1 -2
  70. package/dist/infra/index.js +0 -1
  71. package/dist/infra/market-calendar.js +0 -1
  72. package/dist/infra/native-dependencies.js +0 -1
  73. package/dist/infra/node-version.js +0 -1
  74. package/dist/infra/open-url.js +0 -1
  75. package/dist/infra/opencandle-paths.js +0 -1
  76. package/dist/infra/rate-limiter.js +0 -1
  77. package/dist/market-state/alert-conditions.js +0 -1
  78. package/dist/market-state/alert-runner.d.ts +1 -0
  79. package/dist/market-state/alert-runner.js +5 -4
  80. package/dist/market-state/daily-report.js +0 -1
  81. package/dist/market-state/local-automation-service.js +0 -1
  82. package/dist/market-state/notification-delivery.js +0 -1
  83. package/dist/market-state/resolve-for-mutation.js +0 -1
  84. package/dist/market-state/resolve.js +0 -1
  85. package/dist/market-state/service.d.ts +26 -21
  86. package/dist/market-state/service.js +175 -36
  87. package/dist/market-state/summaries.js +1 -13
  88. package/dist/memory/index.js +0 -1
  89. package/dist/memory/manager.js +0 -1
  90. package/dist/memory/preference-extractor.js +0 -1
  91. package/dist/memory/retrieval.js +0 -1
  92. package/dist/memory/sqlite.js +60 -11
  93. package/dist/memory/storage.js +0 -1
  94. package/dist/memory/tool-defaults.js +0 -1
  95. package/dist/memory/types.js +0 -1
  96. package/dist/monitor.js +0 -1
  97. package/dist/onboarding/connect.js +0 -1
  98. package/dist/onboarding/credential-interceptor.js +0 -1
  99. package/dist/onboarding/degradation-accumulator.js +0 -1
  100. package/dist/onboarding/prompt-user.d.ts +1 -1
  101. package/dist/onboarding/prompt-user.js +0 -1
  102. package/dist/onboarding/provider-status.js +0 -1
  103. package/dist/onboarding/providers.js +0 -1
  104. package/dist/onboarding/state.js +0 -1
  105. package/dist/onboarding/tool-helpers.js +0 -1
  106. package/dist/onboarding/tool-tags.js +0 -1
  107. package/dist/onboarding/validate-model-key.d.ts +17 -0
  108. package/dist/onboarding/validate-model-key.js +54 -0
  109. package/dist/onboarding/validation.js +0 -1
  110. package/dist/pi/opencandle-extension.js +2 -2
  111. package/dist/pi/session-action-dedupe.js +0 -1
  112. package/dist/pi/session-storage.js +0 -1
  113. package/dist/pi/session-writer-lock.js +0 -1
  114. package/dist/pi/session.js +0 -1
  115. package/dist/pi/setup.d.ts +2 -0
  116. package/dist/pi/setup.js +10 -3
  117. package/dist/pi/tool-adapter.js +0 -1
  118. package/dist/pi/tui-session-coordinator.js +0 -1
  119. package/dist/prompts/context-builder.js +1 -2
  120. package/dist/prompts/disclaimer.js +0 -1
  121. package/dist/prompts/policy-cards.js +0 -1
  122. package/dist/prompts/sections.js +0 -1
  123. package/dist/prompts/symbol-preflight.js +0 -1
  124. package/dist/prompts/workflow-prompts.js +0 -1
  125. package/dist/providers/alpha-vantage.js +2 -3
  126. package/dist/providers/coingecko.js +0 -1
  127. package/dist/providers/errors.js +0 -1
  128. package/dist/providers/exa-search.js +11 -10
  129. package/dist/providers/external-tool-command.js +0 -1
  130. package/dist/providers/external-tool-error.js +0 -1
  131. package/dist/providers/fear-greed.js +0 -1
  132. package/dist/providers/finnhub.js +0 -1
  133. package/dist/providers/fred.js +0 -1
  134. package/dist/providers/index.js +0 -1
  135. package/dist/providers/polymarket.js +0 -1
  136. package/dist/providers/provider-credential-error.js +0 -1
  137. package/dist/providers/reddit-cli.js +0 -1
  138. package/dist/providers/reddit.js +0 -1
  139. package/dist/providers/sec-edgar.js +0 -1
  140. package/dist/providers/tradingview.js +1 -2
  141. package/dist/providers/twitter-cli.js +0 -1
  142. package/dist/providers/twitter.js +0 -1
  143. package/dist/providers/web-search.js +15 -12
  144. package/dist/providers/with-fallback.js +0 -1
  145. package/dist/providers/wrap-provider.js +0 -1
  146. package/dist/providers/yahoo-finance.js +67 -4
  147. package/dist/routing/classify-intent.js +0 -1
  148. package/dist/routing/defaults.js +0 -1
  149. package/dist/routing/entity-extractor.js +2 -3
  150. package/dist/routing/fund-symbols.js +0 -1
  151. package/dist/routing/horizon.js +0 -1
  152. package/dist/routing/index.js +0 -1
  153. package/dist/routing/legacy-rule-router.js +0 -1
  154. package/dist/routing/planning.js +0 -1
  155. package/dist/routing/route-manifest.js +0 -1
  156. package/dist/routing/router-llm-client.d.ts +2 -2
  157. package/dist/routing/router-llm-client.js +0 -1
  158. package/dist/routing/router-prompt.js +0 -1
  159. package/dist/routing/router-types.js +0 -1
  160. package/dist/routing/router.js +1 -2
  161. package/dist/routing/slot-resolver.js +0 -1
  162. package/dist/routing/symbol-disambiguator.js +0 -1
  163. package/dist/routing/turn-context.js +0 -1
  164. package/dist/routing/types.js +0 -1
  165. package/dist/runtime/answer-contracts.js +0 -1
  166. package/dist/runtime/artifact-contracts.js +0 -1
  167. package/dist/runtime/evidence.js +0 -1
  168. package/dist/runtime/numeric-claims.js +0 -1
  169. package/dist/runtime/planning-evidence.js +0 -1
  170. package/dist/runtime/prompt-step.js +0 -1
  171. package/dist/runtime/provider-tracker.js +0 -1
  172. package/dist/runtime/run-context.js +0 -1
  173. package/dist/runtime/session-coordinator.js +0 -1
  174. package/dist/runtime/session-title.js +0 -1
  175. package/dist/runtime/tool-defaults-wrapper.js +0 -1
  176. package/dist/runtime/validation.js +0 -1
  177. package/dist/runtime/workflow-events.js +0 -1
  178. package/dist/runtime/workflow-runner.d.ts +1 -0
  179. package/dist/runtime/workflow-runner.js +8 -3
  180. package/dist/runtime/workflow-types.js +0 -1
  181. package/dist/sentiment/adapters/finnhub.js +0 -1
  182. package/dist/sentiment/adapters/reddit.js +0 -1
  183. package/dist/sentiment/adapters/twitter.js +0 -1
  184. package/dist/sentiment/adapters/web.js +0 -1
  185. package/dist/sentiment/index.js +4 -2
  186. package/dist/sentiment/insights.js +0 -1
  187. package/dist/sentiment/keywords.js +0 -1
  188. package/dist/sentiment/pipeline.js +0 -1
  189. package/dist/sentiment/scorer.js +0 -1
  190. package/dist/sentiment/store.js +0 -1
  191. package/dist/sentiment/trends.js +0 -1
  192. package/dist/sentiment/types.js +0 -1
  193. package/dist/system-prompt.js +0 -1
  194. package/dist/tool-kit.js +0 -1
  195. package/dist/tools/fundamentals/company-overview.d.ts +1 -1
  196. package/dist/tools/fundamentals/company-overview.js +2 -1
  197. package/dist/tools/fundamentals/comps.js +6 -4
  198. package/dist/tools/fundamentals/dcf.js +0 -1
  199. package/dist/tools/fundamentals/earnings.d.ts +1 -1
  200. package/dist/tools/fundamentals/earnings.js +2 -1
  201. package/dist/tools/fundamentals/financials.js +2 -1
  202. package/dist/tools/fundamentals/sec-filings.js +0 -1
  203. package/dist/tools/index.d.ts +116 -2
  204. package/dist/tools/index.js +0 -1
  205. package/dist/tools/interaction/ask-user.js +11 -1
  206. package/dist/tools/macro/event-probabilities.js +0 -1
  207. package/dist/tools/macro/fear-greed.d.ts +1 -1
  208. package/dist/tools/macro/fear-greed.js +0 -1
  209. package/dist/tools/macro/fred-data.d.ts +1 -1
  210. package/dist/tools/macro/fred-data.js +2 -1
  211. package/dist/tools/market/crypto-history.js +0 -1
  212. package/dist/tools/market/crypto-price.d.ts +2 -2
  213. package/dist/tools/market/crypto-price.js +0 -1
  214. package/dist/tools/market/screen-stocks.js +0 -1
  215. package/dist/tools/market/search-ticker.js +1 -2
  216. package/dist/tools/market/stock-history.js +0 -1
  217. package/dist/tools/market/stock-quote.d.ts +2 -2
  218. package/dist/tools/market/stock-quote.js +0 -1
  219. package/dist/tools/options/greeks.js +0 -1
  220. package/dist/tools/options/option-chain.d.ts +2 -2
  221. package/dist/tools/options/option-chain.js +0 -1
  222. package/dist/tools/portfolio/alerts.d.ts +2 -1
  223. package/dist/tools/portfolio/alerts.js +228 -2
  224. package/dist/tools/portfolio/correlation.js +23 -5
  225. package/dist/tools/portfolio/daily-report.js +0 -1
  226. package/dist/tools/portfolio/holdings-overlap.js +0 -1
  227. package/dist/tools/portfolio/notifications.js +0 -1
  228. package/dist/tools/portfolio/risk-analysis.d.ts +1 -1
  229. package/dist/tools/portfolio/risk-analysis.js +0 -1
  230. package/dist/tools/portfolio/tracker.d.ts +3 -1
  231. package/dist/tools/portfolio/tracker.js +57 -10
  232. package/dist/tools/portfolio/watchlist.d.ts +3 -6
  233. package/dist/tools/portfolio/watchlist.js +101 -110
  234. package/dist/tools/sentiment/insight-format.js +0 -1
  235. package/dist/tools/sentiment/query-match.js +0 -1
  236. package/dist/tools/sentiment/reddit-sentiment.js +0 -1
  237. package/dist/tools/sentiment/sentiment-summary.js +8 -4
  238. package/dist/tools/sentiment/sentiment-trend.d.ts +5 -1
  239. package/dist/tools/sentiment/sentiment-trend.js +6 -2
  240. package/dist/tools/sentiment/twitter-sentiment.js +0 -1
  241. package/dist/tools/sentiment/untrusted-text.js +0 -1
  242. package/dist/tools/sentiment/web-search.d.ts +1 -1
  243. package/dist/tools/sentiment/web-search.js +0 -1
  244. package/dist/tools/sentiment/web-sentiment.js +0 -1
  245. package/dist/tools/technical/backtest.js +0 -1
  246. package/dist/tools/technical/indicators.js +0 -1
  247. package/dist/types/fundamentals.js +0 -1
  248. package/dist/types/index.js +0 -1
  249. package/dist/types/macro.js +0 -1
  250. package/dist/types/market.d.ts +6 -0
  251. package/dist/types/market.js +0 -1
  252. package/dist/types/options.js +0 -1
  253. package/dist/types/portfolio.js +0 -1
  254. package/dist/types/prediction-markets.js +0 -1
  255. package/dist/types/sentiment.js +0 -1
  256. package/dist/workflows/compare-assets.js +0 -1
  257. package/dist/workflows/index.js +0 -1
  258. package/dist/workflows/options-screener.js +0 -1
  259. package/dist/workflows/portfolio-builder.js +0 -1
  260. package/gui/web/dist/assets/CatalogOverlay-CAc7e3Pf.js +1 -0
  261. package/gui/web/dist/assets/index-BOEKd9wT.css +2 -0
  262. package/gui/web/dist/assets/index-C-H05cQ2.js +65 -0
  263. package/gui/web/dist/index.html +2 -2
  264. package/package.json +11 -12
  265. package/dist/analysts/contracts.js.map +0 -1
  266. package/dist/analysts/orchestrator.js.map +0 -1
  267. package/dist/cli-main.js.map +0 -1
  268. package/dist/cli.js.map +0 -1
  269. package/dist/config.js.map +0 -1
  270. package/dist/doctor/cli-command.js.map +0 -1
  271. package/dist/doctor/render.js.map +0 -1
  272. package/dist/doctor/report.js.map +0 -1
  273. package/dist/index.js.map +0 -1
  274. package/dist/infra/cache.js.map +0 -1
  275. package/dist/infra/freshness.js.map +0 -1
  276. package/dist/infra/http-client.js.map +0 -1
  277. package/dist/infra/index.js.map +0 -1
  278. package/dist/infra/market-calendar.js.map +0 -1
  279. package/dist/infra/native-dependencies.js.map +0 -1
  280. package/dist/infra/node-version.js.map +0 -1
  281. package/dist/infra/open-url.js.map +0 -1
  282. package/dist/infra/opencandle-paths.js.map +0 -1
  283. package/dist/infra/rate-limiter.js.map +0 -1
  284. package/dist/market-state/alert-conditions.js.map +0 -1
  285. package/dist/market-state/alert-runner.js.map +0 -1
  286. package/dist/market-state/daily-report.js.map +0 -1
  287. package/dist/market-state/local-automation-service.js.map +0 -1
  288. package/dist/market-state/notification-delivery.js.map +0 -1
  289. package/dist/market-state/resolve-for-mutation.js.map +0 -1
  290. package/dist/market-state/resolve.js.map +0 -1
  291. package/dist/market-state/service.js.map +0 -1
  292. package/dist/market-state/summaries.js.map +0 -1
  293. package/dist/memory/index.js.map +0 -1
  294. package/dist/memory/manager.js.map +0 -1
  295. package/dist/memory/preference-extractor.js.map +0 -1
  296. package/dist/memory/retrieval.js.map +0 -1
  297. package/dist/memory/sqlite.js.map +0 -1
  298. package/dist/memory/storage.js.map +0 -1
  299. package/dist/memory/tool-defaults.js.map +0 -1
  300. package/dist/memory/types.js.map +0 -1
  301. package/dist/monitor.js.map +0 -1
  302. package/dist/onboarding/connect.js.map +0 -1
  303. package/dist/onboarding/credential-interceptor.js.map +0 -1
  304. package/dist/onboarding/degradation-accumulator.js.map +0 -1
  305. package/dist/onboarding/prompt-user.js.map +0 -1
  306. package/dist/onboarding/provider-status.js.map +0 -1
  307. package/dist/onboarding/providers.js.map +0 -1
  308. package/dist/onboarding/state.js.map +0 -1
  309. package/dist/onboarding/tool-helpers.js.map +0 -1
  310. package/dist/onboarding/tool-tags.js.map +0 -1
  311. package/dist/onboarding/validation.js.map +0 -1
  312. package/dist/pi/opencandle-extension.js.map +0 -1
  313. package/dist/pi/session-action-dedupe.js.map +0 -1
  314. package/dist/pi/session-storage.js.map +0 -1
  315. package/dist/pi/session-writer-lock.js.map +0 -1
  316. package/dist/pi/session.js.map +0 -1
  317. package/dist/pi/setup.js.map +0 -1
  318. package/dist/pi/tool-adapter.js.map +0 -1
  319. package/dist/pi/tui-session-coordinator.js.map +0 -1
  320. package/dist/prompts/context-builder.js.map +0 -1
  321. package/dist/prompts/disclaimer.js.map +0 -1
  322. package/dist/prompts/policy-cards.js.map +0 -1
  323. package/dist/prompts/sections.js.map +0 -1
  324. package/dist/prompts/symbol-preflight.js.map +0 -1
  325. package/dist/prompts/workflow-prompts.js.map +0 -1
  326. package/dist/providers/alpha-vantage.js.map +0 -1
  327. package/dist/providers/coingecko.js.map +0 -1
  328. package/dist/providers/errors.js.map +0 -1
  329. package/dist/providers/exa-search.js.map +0 -1
  330. package/dist/providers/external-tool-command.js.map +0 -1
  331. package/dist/providers/external-tool-error.js.map +0 -1
  332. package/dist/providers/fear-greed.js.map +0 -1
  333. package/dist/providers/finnhub.js.map +0 -1
  334. package/dist/providers/fred.js.map +0 -1
  335. package/dist/providers/index.js.map +0 -1
  336. package/dist/providers/polymarket.js.map +0 -1
  337. package/dist/providers/provider-credential-error.js.map +0 -1
  338. package/dist/providers/reddit-cli.js.map +0 -1
  339. package/dist/providers/reddit.js.map +0 -1
  340. package/dist/providers/sec-edgar.js.map +0 -1
  341. package/dist/providers/tradingview.js.map +0 -1
  342. package/dist/providers/twitter-cli.js.map +0 -1
  343. package/dist/providers/twitter.js.map +0 -1
  344. package/dist/providers/web-search.js.map +0 -1
  345. package/dist/providers/with-fallback.js.map +0 -1
  346. package/dist/providers/wrap-provider.js.map +0 -1
  347. package/dist/providers/yahoo-finance.js.map +0 -1
  348. package/dist/routing/classify-intent.js.map +0 -1
  349. package/dist/routing/defaults.js.map +0 -1
  350. package/dist/routing/entity-extractor.js.map +0 -1
  351. package/dist/routing/fund-symbols.js.map +0 -1
  352. package/dist/routing/horizon.js.map +0 -1
  353. package/dist/routing/index.js.map +0 -1
  354. package/dist/routing/legacy-rule-router.js.map +0 -1
  355. package/dist/routing/planning.js.map +0 -1
  356. package/dist/routing/route-manifest.js.map +0 -1
  357. package/dist/routing/router-llm-client.js.map +0 -1
  358. package/dist/routing/router-prompt.js.map +0 -1
  359. package/dist/routing/router-types.js.map +0 -1
  360. package/dist/routing/router.js.map +0 -1
  361. package/dist/routing/slot-resolver.js.map +0 -1
  362. package/dist/routing/symbol-disambiguator.js.map +0 -1
  363. package/dist/routing/turn-context.js.map +0 -1
  364. package/dist/routing/types.js.map +0 -1
  365. package/dist/runtime/answer-contracts.js.map +0 -1
  366. package/dist/runtime/artifact-contracts.js.map +0 -1
  367. package/dist/runtime/evidence.js.map +0 -1
  368. package/dist/runtime/numeric-claims.js.map +0 -1
  369. package/dist/runtime/planning-evidence.js.map +0 -1
  370. package/dist/runtime/prompt-step.js.map +0 -1
  371. package/dist/runtime/provider-tracker.js.map +0 -1
  372. package/dist/runtime/run-context.js.map +0 -1
  373. package/dist/runtime/session-coordinator.js.map +0 -1
  374. package/dist/runtime/session-title.js.map +0 -1
  375. package/dist/runtime/tool-defaults-wrapper.js.map +0 -1
  376. package/dist/runtime/validation.js.map +0 -1
  377. package/dist/runtime/workflow-events.js.map +0 -1
  378. package/dist/runtime/workflow-runner.js.map +0 -1
  379. package/dist/runtime/workflow-types.js.map +0 -1
  380. package/dist/sentiment/adapters/finnhub.js.map +0 -1
  381. package/dist/sentiment/adapters/reddit.js.map +0 -1
  382. package/dist/sentiment/adapters/twitter.js.map +0 -1
  383. package/dist/sentiment/adapters/web.js.map +0 -1
  384. package/dist/sentiment/index.js.map +0 -1
  385. package/dist/sentiment/insights.js.map +0 -1
  386. package/dist/sentiment/keywords.js.map +0 -1
  387. package/dist/sentiment/pipeline.js.map +0 -1
  388. package/dist/sentiment/scorer.js.map +0 -1
  389. package/dist/sentiment/store.js.map +0 -1
  390. package/dist/sentiment/trends.js.map +0 -1
  391. package/dist/sentiment/types.js.map +0 -1
  392. package/dist/system-prompt.js.map +0 -1
  393. package/dist/tool-kit.js.map +0 -1
  394. package/dist/tools/fundamentals/company-overview.js.map +0 -1
  395. package/dist/tools/fundamentals/comps.js.map +0 -1
  396. package/dist/tools/fundamentals/dcf.js.map +0 -1
  397. package/dist/tools/fundamentals/earnings.js.map +0 -1
  398. package/dist/tools/fundamentals/financials.js.map +0 -1
  399. package/dist/tools/fundamentals/sec-filings.js.map +0 -1
  400. package/dist/tools/index.js.map +0 -1
  401. package/dist/tools/interaction/ask-user.js.map +0 -1
  402. package/dist/tools/macro/event-probabilities.js.map +0 -1
  403. package/dist/tools/macro/fear-greed.js.map +0 -1
  404. package/dist/tools/macro/fred-data.js.map +0 -1
  405. package/dist/tools/market/crypto-history.js.map +0 -1
  406. package/dist/tools/market/crypto-price.js.map +0 -1
  407. package/dist/tools/market/screen-stocks.js.map +0 -1
  408. package/dist/tools/market/search-ticker.js.map +0 -1
  409. package/dist/tools/market/stock-history.js.map +0 -1
  410. package/dist/tools/market/stock-quote.js.map +0 -1
  411. package/dist/tools/options/greeks.js.map +0 -1
  412. package/dist/tools/options/option-chain.js.map +0 -1
  413. package/dist/tools/portfolio/alerts.js.map +0 -1
  414. package/dist/tools/portfolio/correlation.js.map +0 -1
  415. package/dist/tools/portfolio/daily-report.js.map +0 -1
  416. package/dist/tools/portfolio/holdings-overlap.js.map +0 -1
  417. package/dist/tools/portfolio/notifications.js.map +0 -1
  418. package/dist/tools/portfolio/risk-analysis.js.map +0 -1
  419. package/dist/tools/portfolio/tracker.js.map +0 -1
  420. package/dist/tools/portfolio/watchlist.js.map +0 -1
  421. package/dist/tools/sentiment/insight-format.js.map +0 -1
  422. package/dist/tools/sentiment/query-match.js.map +0 -1
  423. package/dist/tools/sentiment/reddit-sentiment.js.map +0 -1
  424. package/dist/tools/sentiment/sentiment-summary.js.map +0 -1
  425. package/dist/tools/sentiment/sentiment-trend.js.map +0 -1
  426. package/dist/tools/sentiment/twitter-sentiment.js.map +0 -1
  427. package/dist/tools/sentiment/untrusted-text.js.map +0 -1
  428. package/dist/tools/sentiment/web-search.js.map +0 -1
  429. package/dist/tools/sentiment/web-sentiment.js.map +0 -1
  430. package/dist/tools/technical/backtest.js.map +0 -1
  431. package/dist/tools/technical/indicators.js.map +0 -1
  432. package/dist/types/fundamentals.js.map +0 -1
  433. package/dist/types/index.js.map +0 -1
  434. package/dist/types/macro.js.map +0 -1
  435. package/dist/types/market.js.map +0 -1
  436. package/dist/types/options.js.map +0 -1
  437. package/dist/types/portfolio.js.map +0 -1
  438. package/dist/types/prediction-markets.js.map +0 -1
  439. package/dist/types/sentiment.js.map +0 -1
  440. package/dist/workflows/compare-assets.js.map +0 -1
  441. package/dist/workflows/index.js.map +0 -1
  442. package/dist/workflows/options-screener.js.map +0 -1
  443. package/dist/workflows/portfolio-builder.js.map +0 -1
  444. package/gui/server/ask-user-bridge.ts +0 -89
  445. package/gui/server/automation-heartbeat.ts +0 -97
  446. package/gui/server/background-quotes.ts +0 -127
  447. package/gui/server/chat-event-adapter.ts +0 -294
  448. package/gui/server/gui-session-manager.ts +0 -5
  449. package/gui/server/http-routes.ts +0 -1201
  450. package/gui/server/invoke-tool.ts +0 -490
  451. package/gui/server/live-chat-event-adapter.ts +0 -243
  452. package/gui/server/local-session-coordinator.ts +0 -97
  453. package/gui/server/market-state-api.ts +0 -331
  454. package/gui/server/model-setup.ts +0 -254
  455. package/gui/server/package.json +0 -5
  456. package/gui/server/private-api-access.ts +0 -62
  457. package/gui/server/projector.ts +0 -392
  458. package/gui/server/prompt-observation.ts +0 -58
  459. package/gui/server/quote-snapshot-store.ts +0 -50
  460. package/gui/server/server.ts +0 -289
  461. package/gui/server/session-actions.ts +0 -323
  462. package/gui/server/session-entry-wait.ts +0 -179
  463. package/gui/server/shutdown.ts +0 -47
  464. package/gui/server/tool-invoke-ack.ts +0 -49
  465. package/gui/server/tool-metadata.ts +0 -167
  466. package/gui/server/websocket.ts +0 -138
  467. package/gui/server/writer-lock.ts +0 -1
  468. package/gui/server/ws-hub.ts +0 -403
  469. package/gui/shared/chat-events.ts +0 -165
  470. package/gui/shared/event-reducer.ts +0 -220
  471. package/gui/web/dist/assets/CatalogOverlay-DZ1niyQm.js +0 -1
  472. package/gui/web/dist/assets/index-D4F9AJnn.css +0 -2
  473. package/gui/web/dist/assets/index-DtqMMBTr.js +0 -65
  474. package/src/analysts/contracts.ts +0 -176
  475. package/src/analysts/orchestrator.ts +0 -244
  476. package/src/cli-main.ts +0 -510
  477. package/src/cli.ts +0 -17
  478. package/src/config.ts +0 -272
  479. package/src/doctor/cli-command.ts +0 -83
  480. package/src/doctor/render.ts +0 -37
  481. package/src/doctor/report.ts +0 -638
  482. package/src/index.ts +0 -5
  483. package/src/infra/cache.ts +0 -127
  484. package/src/infra/freshness.ts +0 -165
  485. package/src/infra/http-client.ts +0 -134
  486. package/src/infra/index.ts +0 -14
  487. package/src/infra/market-calendar.ts +0 -193
  488. package/src/infra/native-dependencies.ts +0 -84
  489. package/src/infra/node-version.ts +0 -23
  490. package/src/infra/open-url.ts +0 -28
  491. package/src/infra/opencandle-paths.ts +0 -53
  492. package/src/infra/rate-limiter.ts +0 -77
  493. package/src/market-state/alert-conditions.ts +0 -82
  494. package/src/market-state/alert-runner.ts +0 -863
  495. package/src/market-state/daily-report.ts +0 -237
  496. package/src/market-state/local-automation-service.ts +0 -162
  497. package/src/market-state/notification-delivery.ts +0 -158
  498. package/src/market-state/resolve-for-mutation.ts +0 -24
  499. package/src/market-state/resolve.ts +0 -112
  500. package/src/market-state/service.ts +0 -2208
  501. package/src/market-state/summaries.ts +0 -75
  502. package/src/memory/index.ts +0 -10
  503. package/src/memory/manager.ts +0 -190
  504. package/src/memory/preference-extractor.ts +0 -106
  505. package/src/memory/retrieval.ts +0 -71
  506. package/src/memory/sqlite.ts +0 -577
  507. package/src/memory/storage.ts +0 -195
  508. package/src/memory/tool-defaults.ts +0 -108
  509. package/src/memory/types.ts +0 -71
  510. package/src/monitor.ts +0 -123
  511. package/src/onboarding/connect.ts +0 -177
  512. package/src/onboarding/credential-interceptor.ts +0 -122
  513. package/src/onboarding/degradation-accumulator.ts +0 -77
  514. package/src/onboarding/prompt-user.ts +0 -85
  515. package/src/onboarding/provider-status.ts +0 -382
  516. package/src/onboarding/providers.ts +0 -442
  517. package/src/onboarding/state.ts +0 -216
  518. package/src/onboarding/tool-helpers.ts +0 -104
  519. package/src/onboarding/tool-tags.ts +0 -244
  520. package/src/onboarding/validation.ts +0 -152
  521. package/src/pi/opencandle-extension.ts +0 -1294
  522. package/src/pi/session-action-dedupe.ts +0 -155
  523. package/src/pi/session-storage.ts +0 -5
  524. package/src/pi/session-writer-lock.ts +0 -426
  525. package/src/pi/session.ts +0 -84
  526. package/src/pi/setup.ts +0 -399
  527. package/src/pi/tool-adapter.ts +0 -49
  528. package/src/pi/tui-session-coordinator.ts +0 -351
  529. package/src/prompts/context-builder.ts +0 -326
  530. package/src/prompts/disclaimer.ts +0 -9
  531. package/src/prompts/policy-cards.ts +0 -228
  532. package/src/prompts/sections.ts +0 -46
  533. package/src/prompts/symbol-preflight.ts +0 -80
  534. package/src/prompts/workflow-prompts.ts +0 -504
  535. package/src/providers/alpha-vantage.ts +0 -340
  536. package/src/providers/coingecko.ts +0 -95
  537. package/src/providers/errors.ts +0 -9
  538. package/src/providers/exa-search.ts +0 -375
  539. package/src/providers/external-tool-command.ts +0 -164
  540. package/src/providers/external-tool-error.ts +0 -20
  541. package/src/providers/fear-greed.ts +0 -45
  542. package/src/providers/finnhub.ts +0 -125
  543. package/src/providers/fred.ts +0 -83
  544. package/src/providers/index.ts +0 -17
  545. package/src/providers/polymarket.ts +0 -214
  546. package/src/providers/provider-credential-error.ts +0 -23
  547. package/src/providers/reddit-cli.ts +0 -286
  548. package/src/providers/reddit.ts +0 -106
  549. package/src/providers/sec-edgar.ts +0 -326
  550. package/src/providers/tradingview.ts +0 -399
  551. package/src/providers/twitter-cli.ts +0 -202
  552. package/src/providers/twitter.ts +0 -102
  553. package/src/providers/web-search.ts +0 -303
  554. package/src/providers/with-fallback.ts +0 -42
  555. package/src/providers/wrap-provider.ts +0 -105
  556. package/src/providers/yahoo-finance.ts +0 -984
  557. package/src/routing/classify-intent.ts +0 -380
  558. package/src/routing/defaults.ts +0 -29
  559. package/src/routing/entity-extractor.ts +0 -557
  560. package/src/routing/fund-symbols.ts +0 -58
  561. package/src/routing/horizon.ts +0 -7
  562. package/src/routing/index.ts +0 -70
  563. package/src/routing/legacy-rule-router.ts +0 -13
  564. package/src/routing/planning.ts +0 -829
  565. package/src/routing/route-manifest.ts +0 -308
  566. package/src/routing/router-llm-client.ts +0 -64
  567. package/src/routing/router-prompt.ts +0 -159
  568. package/src/routing/router-types.ts +0 -84
  569. package/src/routing/router.ts +0 -1332
  570. package/src/routing/slot-resolver.ts +0 -213
  571. package/src/routing/symbol-disambiguator.ts +0 -72
  572. package/src/routing/turn-context.ts +0 -108
  573. package/src/routing/types.ts +0 -77
  574. package/src/runtime/answer-contracts.ts +0 -693
  575. package/src/runtime/artifact-contracts.ts +0 -77
  576. package/src/runtime/evidence.ts +0 -78
  577. package/src/runtime/numeric-claims.ts +0 -108
  578. package/src/runtime/planning-evidence.ts +0 -597
  579. package/src/runtime/prompt-step.ts +0 -185
  580. package/src/runtime/provider-tracker.ts +0 -40
  581. package/src/runtime/run-context.ts +0 -32
  582. package/src/runtime/session-coordinator.ts +0 -1037
  583. package/src/runtime/session-title.ts +0 -60
  584. package/src/runtime/tool-defaults-wrapper.ts +0 -43
  585. package/src/runtime/validation.ts +0 -211
  586. package/src/runtime/workflow-events.ts +0 -77
  587. package/src/runtime/workflow-runner.ts +0 -182
  588. package/src/runtime/workflow-types.ts +0 -105
  589. package/src/sentiment/adapters/finnhub.ts +0 -49
  590. package/src/sentiment/adapters/reddit.ts +0 -65
  591. package/src/sentiment/adapters/twitter.ts +0 -36
  592. package/src/sentiment/adapters/web.ts +0 -44
  593. package/src/sentiment/index.ts +0 -49
  594. package/src/sentiment/insights.ts +0 -269
  595. package/src/sentiment/keywords.ts +0 -31
  596. package/src/sentiment/pipeline.ts +0 -91
  597. package/src/sentiment/scorer.ts +0 -89
  598. package/src/sentiment/store.ts +0 -260
  599. package/src/sentiment/trends.ts +0 -96
  600. package/src/sentiment/types.ts +0 -112
  601. package/src/system-prompt.ts +0 -115
  602. package/src/tool-kit.ts +0 -69
  603. package/src/tools/AGENTS.md +0 -36
  604. package/src/tools/fundamentals/company-overview.ts +0 -64
  605. package/src/tools/fundamentals/comps.ts +0 -180
  606. package/src/tools/fundamentals/dcf.ts +0 -447
  607. package/src/tools/fundamentals/earnings.ts +0 -57
  608. package/src/tools/fundamentals/financials.ts +0 -63
  609. package/src/tools/fundamentals/sec-filings.ts +0 -105
  610. package/src/tools/index.ts +0 -104
  611. package/src/tools/interaction/ask-user.ts +0 -93
  612. package/src/tools/macro/event-probabilities.ts +0 -141
  613. package/src/tools/macro/fear-greed.ts +0 -41
  614. package/src/tools/macro/fred-data.ts +0 -92
  615. package/src/tools/market/crypto-history.ts +0 -72
  616. package/src/tools/market/crypto-price.ts +0 -65
  617. package/src/tools/market/screen-stocks.ts +0 -290
  618. package/src/tools/market/search-ticker.ts +0 -254
  619. package/src/tools/market/stock-history.ts +0 -104
  620. package/src/tools/market/stock-quote.ts +0 -73
  621. package/src/tools/options/greeks.ts +0 -81
  622. package/src/tools/options/option-chain.ts +0 -134
  623. package/src/tools/portfolio/alerts.ts +0 -457
  624. package/src/tools/portfolio/correlation.ts +0 -189
  625. package/src/tools/portfolio/daily-report.ts +0 -107
  626. package/src/tools/portfolio/holdings-overlap.ts +0 -139
  627. package/src/tools/portfolio/notifications.ts +0 -45
  628. package/src/tools/portfolio/risk-analysis.ts +0 -173
  629. package/src/tools/portfolio/tracker.ts +0 -308
  630. package/src/tools/portfolio/watchlist.ts +0 -288
  631. package/src/tools/sentiment/insight-format.ts +0 -50
  632. package/src/tools/sentiment/query-match.ts +0 -117
  633. package/src/tools/sentiment/reddit-sentiment.ts +0 -403
  634. package/src/tools/sentiment/sentiment-summary.ts +0 -383
  635. package/src/tools/sentiment/sentiment-trend.ts +0 -75
  636. package/src/tools/sentiment/twitter-sentiment.ts +0 -287
  637. package/src/tools/sentiment/untrusted-text.ts +0 -21
  638. package/src/tools/sentiment/web-search.ts +0 -186
  639. package/src/tools/sentiment/web-sentiment.ts +0 -96
  640. package/src/tools/technical/backtest.ts +0 -336
  641. package/src/tools/technical/indicators.ts +0 -281
  642. package/src/types/fundamentals.ts +0 -47
  643. package/src/types/index.ts +0 -26
  644. package/src/types/macro.ts +0 -27
  645. package/src/types/market.ts +0 -46
  646. package/src/types/options.ts +0 -53
  647. package/src/types/portfolio.ts +0 -83
  648. package/src/types/prediction-markets.ts +0 -13
  649. package/src/types/sentiment.ts +0 -129
  650. package/src/workflows/compare-assets.ts +0 -89
  651. package/src/workflows/index.ts +0 -3
  652. package/src/workflows/options-screener.ts +0 -125
  653. package/src/workflows/portfolio-builder.ts +0 -63
@@ -1,127 +0,0 @@
1
- import { AsyncLocalStorage } from "node:async_hooks";
2
-
3
- interface CacheEntry<T> {
4
- value: T;
5
- expiresAt: number;
6
- cachedAt: number;
7
- }
8
-
9
- export interface StaleResult<T> {
10
- value: T;
11
- stale: true;
12
- cachedAt: number;
13
- }
14
-
15
- interface CacheMetadata {
16
- status: "none" | "cached" | "stale";
17
- cachedAt: number;
18
- }
19
-
20
- const cacheMetadataStorage = new AsyncLocalStorage<CacheMetadata>();
21
-
22
- export async function runWithStaleMetadata<T>(fn: () => Promise<T>): Promise<{
23
- value: T;
24
- cache?: { status: "cached" | "stale"; cachedAt: number };
25
- stale?: { cachedAt: number };
26
- }> {
27
- const metadata: CacheMetadata = { status: "none", cachedAt: 0 };
28
- const value = await cacheMetadataStorage.run(metadata, fn);
29
- return {
30
- value,
31
- cache:
32
- metadata.status === "cached" || metadata.status === "stale"
33
- ? { status: metadata.status, cachedAt: metadata.cachedAt }
34
- : undefined,
35
- stale: metadata.status === "stale" ? { cachedAt: metadata.cachedAt } : undefined,
36
- };
37
- }
38
-
39
- export class Cache {
40
- private store = new Map<string, CacheEntry<unknown>>();
41
-
42
- get<T>(key: string): T | undefined {
43
- const entry = this.store.get(key);
44
- if (!entry) return undefined;
45
- if (Date.now() > entry.expiresAt) return undefined;
46
- const metadata = cacheMetadataStorage.getStore();
47
- if (metadata && metadata.status === "none") {
48
- metadata.status = "cached";
49
- metadata.cachedAt = entry.cachedAt;
50
- }
51
- return entry.value as T;
52
- }
53
-
54
- /**
55
- * Return an expired entry if it exists and is within the stale limit.
56
- * Unlike get(), this does not require the entry to be within its TTL.
57
- * Entries beyond the stale limit are deleted.
58
- */
59
- getStale<T>(key: string, staleLimitMs: number): StaleResult<T> | undefined {
60
- const entry = this.store.get(key);
61
- if (!entry) return undefined;
62
-
63
- if (Date.now() > entry.cachedAt + staleLimitMs) {
64
- this.store.delete(key);
65
- return undefined;
66
- }
67
-
68
- const metadata = cacheMetadataStorage.getStore();
69
- if (metadata) {
70
- metadata.status = "stale";
71
- metadata.cachedAt = entry.cachedAt;
72
- }
73
- return { value: entry.value as T, stale: true, cachedAt: entry.cachedAt };
74
- }
75
-
76
- set<T>(key: string, value: T, ttlMs: number): void {
77
- this.store.set(key, { value, expiresAt: Date.now() + ttlMs, cachedAt: Date.now() });
78
- }
79
-
80
- invalidate(pattern: string): void {
81
- for (const key of this.store.keys()) {
82
- if (key.includes(pattern)) {
83
- this.store.delete(key);
84
- }
85
- }
86
- }
87
-
88
- clear(): void {
89
- this.store.clear();
90
- }
91
-
92
- get size(): number {
93
- return this.store.size;
94
- }
95
- }
96
-
97
- // Shared cache instance
98
- export const cache = new Cache();
99
-
100
- // Default TTLs
101
- export const TTL = {
102
- QUOTE: 60_000, // 1 minute
103
- HISTORY: 3_600_000, // 1 hour
104
- FUNDAMENTALS: 86_400_000, // 24 hours
105
- MACRO: 3_600_000, // 1 hour
106
- SENTIMENT: 300_000, // 5 minutes
107
- OPTIONS_CHAIN: 120_000, // 2 minutes
108
- SCREENER: 60_000, // 1 minute
109
- CRUMB: 900_000, // 15 minutes
110
- WEB_SEARCH: 300_000, // 5 minutes
111
- FINNHUB_NEWS: 300_000, // 5 minutes
112
- PREDICTION_MARKETS: 300_000, // 5 minutes
113
- } as const;
114
-
115
- // Stale limits — how long past TTL expiry a cached value is still useful as fallback
116
- export const STALE_LIMIT = {
117
- QUOTE: 15 * 60_000, // 15 minutes
118
- HISTORY: 24 * 3_600_000, // 24 hours
119
- FUNDAMENTALS: 7 * 86_400_000, // 7 days
120
- MACRO: 24 * 3_600_000, // 24 hours
121
- SENTIMENT: 3_600_000, // 1 hour
122
- OPTIONS_CHAIN: 30 * 60_000, // 30 minutes
123
- SCREENER: 15 * 60_000, // 15 minutes
124
- WEB_SEARCH: 3_600_000, // 1 hour
125
- FINNHUB_NEWS: 3_600_000, // 1 hour
126
- PREDICTION_MARKETS: 3_600_000, // 1 hour
127
- } as const;
@@ -1,165 +0,0 @@
1
- import {
2
- classifyMarketStatusAt,
3
- lastTradingDay,
4
- localDateTimeParts,
5
- type MarketSession,
6
- } from "./market-calendar.js";
7
-
8
- export interface FreshnessStamp {
9
- fetchedAt: string;
10
- providerDataAt?: string;
11
- providerDataDate?: string;
12
- cacheStatus: "live" | "cached" | "stale";
13
- cachedAt?: string;
14
- marketSession: MarketSession;
15
- dataDelayMs?: number;
16
- isStaleForSession: boolean;
17
- }
18
-
19
- export function buildFreshnessStamp(input: {
20
- asOf?: string | number | Date;
21
- cached?: boolean;
22
- stale?: boolean;
23
- cachedAt?: string;
24
- dataDelayMs?: number;
25
- now?: Date;
26
- assetClass?: "equity" | "crypto";
27
- }): FreshnessStamp {
28
- const now = input.now ?? new Date();
29
- const parsedAsOf = normalizeAsOf(input.asOf);
30
- const fetchedAt = now.toISOString();
31
- const cacheStatus = input.stale ? "stale" : input.cached ? "cached" : "live";
32
- const marketSession = input.assetClass === "crypto" ? "unknown" : classifyMarketStatusAt(now);
33
- const cachedAt = input.cachedAt ? normalizeDate(input.cachedAt)?.toISOString() : undefined;
34
- const providerDataAt = parsedAsOf?.date.toISOString();
35
- const providerDataDate = parsedAsOf?.dateOnly;
36
- const isStaleForSession =
37
- input.assetClass === "crypto"
38
- ? isCryptoStale(parsedAsOf?.date, cachedAt, now, cacheStatus)
39
- : isEquityStale(parsedAsOf, cacheStatus, now);
40
-
41
- return {
42
- fetchedAt,
43
- providerDataAt,
44
- providerDataDate,
45
- cacheStatus,
46
- cachedAt,
47
- marketSession,
48
- dataDelayMs: input.dataDelayMs,
49
- isStaleForSession,
50
- };
51
- }
52
-
53
- export function formatAsOfLine(stamp: FreshnessStamp): string {
54
- if (stamp.isStaleForSession && stamp.providerDataAt) {
55
- const date = stamp.providerDataDate ?? formatEtDate(new Date(stamp.providerDataAt));
56
- const parenthetical = staleSessionParenthetical(stamp.marketSession);
57
- const cached = stamp.cachedAt
58
- ? ` Cached from ${formatEtDateTime(new Date(stamp.cachedAt))} ET.`
59
- : "";
60
- return `Last available price as of ${date}${parenthetical}. This is not a live quote.${cached}`;
61
- }
62
-
63
- if (stamp.cacheStatus === "stale" && stamp.cachedAt) {
64
- const notLive = stamp.isStaleForSession ? " This is not a live quote." : "";
65
- return `Using cached data from ${formatEtDateTime(new Date(stamp.cachedAt))} ET (provider unavailable).${notLive}`;
66
- }
67
-
68
- if (stamp.providerDataAt || stamp.dataDelayMs !== undefined) {
69
- const reference = stamp.providerDataAt ?? stamp.cachedAt ?? stamp.fetchedAt;
70
- const asOf = stamp.providerDataDate ?? formatEtDateTime(new Date(reference));
71
- if (stamp.dataDelayMs !== undefined)
72
- return `As of ${asOf} ET (~${Math.round(stamp.dataDelayMs / 60_000)}m delayed).`;
73
- return `As of ${asOf} ET (${marketSessionLabel(stamp.marketSession)}).`;
74
- }
75
-
76
- return `As of ${formatEtDateTime(new Date(stamp.fetchedAt))} ET (${marketSessionLabel(stamp.marketSession)}).`;
77
- }
78
-
79
- function normalizeAsOf(
80
- asOf: string | number | Date | undefined,
81
- ): { date: Date; dateOnly?: string } | undefined {
82
- if (asOf === undefined) return undefined;
83
- if (asOf instanceof Date) return Number.isNaN(asOf.getTime()) ? undefined : { date: asOf };
84
- if (typeof asOf === "number") {
85
- const milliseconds = asOf < 10_000_000_000 ? asOf * 1000 : asOf;
86
- const date = new Date(milliseconds);
87
- return Number.isNaN(date.getTime()) ? undefined : { date };
88
- }
89
- if (/^\d{4}-\d{2}-\d{2}$/.test(asOf)) {
90
- const date = new Date(`${asOf}T00:00:00.000Z`);
91
- return Number.isNaN(date.getTime()) ? undefined : { date, dateOnly: asOf };
92
- }
93
- const date = new Date(asOf);
94
- return Number.isNaN(date.getTime()) ? undefined : { date };
95
- }
96
-
97
- function normalizeDate(value: string): Date | undefined {
98
- const date = new Date(value);
99
- return Number.isNaN(date.getTime()) ? undefined : date;
100
- }
101
-
102
- function isEquityStale(
103
- parsedAsOf: { date: Date; dateOnly?: string } | undefined,
104
- cacheStatus: FreshnessStamp["cacheStatus"],
105
- now: Date,
106
- ): boolean {
107
- if (!parsedAsOf) return cacheStatus === "stale";
108
- const localNow = localDateTimeParts(now, "America/New_York");
109
- const providerTradingDate =
110
- parsedAsOf.dateOnly ?? localDateTimeParts(parsedAsOf.date, "America/New_York").date;
111
- const marketSession = classifyMarketStatusAt(now);
112
- const requiredTradingDate =
113
- marketSession === "open" ||
114
- marketSession === "after_close" ||
115
- marketSession === "closed_after_hours"
116
- ? localNow.date
117
- : lastTradingDay(localNow.date);
118
- return providerTradingDate < requiredTradingDate;
119
- }
120
-
121
- function isCryptoStale(
122
- providerDate: Date | undefined,
123
- cachedAt: string | undefined,
124
- now: Date,
125
- cacheStatus: FreshnessStamp["cacheStatus"],
126
- ): boolean {
127
- const reference =
128
- providerDate ?? (cacheStatus === "stale" && cachedAt ? new Date(cachedAt) : undefined);
129
- if (!reference) return cacheStatus === "stale";
130
- return now.getTime() - reference.getTime() > 15 * 60_000;
131
- }
132
-
133
- function formatEtDate(date: Date): string {
134
- return localDateTimeParts(date, "America/New_York").date;
135
- }
136
-
137
- function formatEtDateTime(date: Date): string {
138
- const parts = localDateTimeParts(date, "America/New_York");
139
- return `${parts.date} ${parts.time}`;
140
- }
141
-
142
- function staleSessionParenthetical(marketSession: MarketSession): string {
143
- if (marketSession === "closed_weekend") return " (market closed — weekend)";
144
- if (marketSession === "closed_holiday") return " (market closed — holiday)";
145
- return "";
146
- }
147
-
148
- function marketSessionLabel(marketSession: MarketSession): string {
149
- switch (marketSession) {
150
- case "open":
151
- return "market open";
152
- case "pre_market":
153
- return "pre-market";
154
- case "closed_weekend":
155
- return "market closed — weekend";
156
- case "closed_holiday":
157
- return "market closed — holiday";
158
- case "after_close":
159
- return "after close";
160
- case "closed_after_hours":
161
- return "market closed";
162
- case "unknown":
163
- return "market session unknown";
164
- }
165
- }
@@ -1,134 +0,0 @@
1
- export interface HttpClientOptions {
2
- timeoutMs?: number;
3
- maxRetries?: number;
4
- retryDelayMs?: number;
5
- maxRetryAfterMs?: number;
6
- headers?: Record<string, string>;
7
- }
8
-
9
- const DEFAULT_OPTIONS: Required<HttpClientOptions> = {
10
- timeoutMs: 10_000,
11
- maxRetries: 2,
12
- retryDelayMs: 1_000,
13
- maxRetryAfterMs: 5_000,
14
- headers: {},
15
- };
16
-
17
- export class HttpError extends Error {
18
- constructor(
19
- public readonly status: number,
20
- public readonly statusText: string,
21
- public readonly body: string,
22
- public readonly retryAfterMs?: number,
23
- ) {
24
- super(`HTTP ${status} ${statusText}`);
25
- this.name = "HttpError";
26
- }
27
- }
28
-
29
- export async function httpGet<T>(url: string, options: HttpClientOptions = {}): Promise<T> {
30
- return httpRequest<T>(url, { ...options, method: "GET" });
31
- }
32
-
33
- export async function httpPost<T>(
34
- url: string,
35
- body: unknown,
36
- options: HttpClientOptions = {},
37
- ): Promise<T> {
38
- return httpRequest<T>(url, {
39
- ...options,
40
- method: "POST",
41
- body: JSON.stringify(body),
42
- headers: {
43
- "Content-Type": "application/json",
44
- ...options.headers,
45
- },
46
- });
47
- }
48
-
49
- interface HttpRequestOptions extends HttpClientOptions {
50
- method: "GET" | "POST";
51
- body?: string;
52
- }
53
-
54
- async function httpRequest<T>(url: string, options: HttpRequestOptions): Promise<T> {
55
- const opts = { ...DEFAULT_OPTIONS, ...options };
56
- let lastError: Error | undefined;
57
-
58
- for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
59
- let retryDelayMs: number | undefined;
60
-
61
- const controller = new AbortController();
62
- const timeout = setTimeout(() => controller.abort(), opts.timeoutMs);
63
-
64
- try {
65
- const response = await fetch(url, {
66
- method: opts.method,
67
- signal: controller.signal,
68
- headers: opts.headers,
69
- ...(opts.body !== undefined && { body: opts.body }),
70
- });
71
-
72
- if (!response.ok) {
73
- const body = await response.text().catch(() => "");
74
- throw new HttpError(
75
- response.status,
76
- response.statusText,
77
- body,
78
- parseRetryAfterMs(response.headers?.get?.("retry-after") ?? null),
79
- );
80
- }
81
-
82
- return (await response.json()) as T;
83
- } catch (error) {
84
- lastError = error as Error;
85
- if (!isRetryableError(error)) {
86
- throw error; // Don't retry client errors
87
- }
88
- if (attempt < opts.maxRetries) {
89
- retryDelayMs =
90
- error instanceof HttpError && error.status === 429 && error.retryAfterMs !== undefined
91
- ? capRetryAfterMs(error.retryAfterMs, opts.maxRetryAfterMs)
92
- : opts.retryDelayMs * (attempt + 1);
93
- }
94
- } finally {
95
- clearTimeout(timeout);
96
- }
97
-
98
- if (retryDelayMs !== undefined) {
99
- await sleep(retryDelayMs);
100
- }
101
- }
102
-
103
- throw lastError!;
104
- }
105
-
106
- function isRetryableError(error: unknown): boolean {
107
- if (!(error instanceof HttpError)) return true;
108
- if (error.status === 429) return true;
109
- return error.status < 400 || error.status >= 500;
110
- }
111
-
112
- function parseRetryAfterMs(value: string | null): number | undefined {
113
- if (!value) return undefined;
114
- const trimmed = value.trim();
115
- if (trimmed.length === 0) return undefined;
116
-
117
- const seconds = Number(trimmed);
118
- if (Number.isFinite(seconds) && seconds >= 0) {
119
- return seconds * 1000;
120
- }
121
-
122
- const dateMs = Date.parse(trimmed);
123
- if (Number.isNaN(dateMs)) return undefined;
124
- return Math.max(0, dateMs - Date.now());
125
- }
126
-
127
- function capRetryAfterMs(retryAfterMs: number, maxRetryAfterMs: number | undefined): number {
128
- if (maxRetryAfterMs === undefined) return retryAfterMs;
129
- return Math.min(retryAfterMs, Math.max(0, maxRetryAfterMs));
130
- }
131
-
132
- function sleep(ms: number): Promise<void> {
133
- return new Promise((resolve) => setTimeout(resolve, ms));
134
- }
@@ -1,14 +0,0 @@
1
- export { Cache, cache, TTL } from "./cache.js";
2
- export { type HttpClientOptions, HttpError, httpGet } from "./http-client.js";
3
- export {
4
- ensureOpenCandleHomeDir,
5
- ensureParentDir,
6
- getBrowserProfileDir,
7
- getConfigPath,
8
- getLogsDir,
9
- getOnboardingPath,
10
- getOpenCandleHomeDir,
11
- getStateDbPath,
12
- resolveOpenCandlePath,
13
- } from "./opencandle-paths.js";
14
- export { RateLimiter, rateLimiter } from "./rate-limiter.js";
@@ -1,193 +0,0 @@
1
- export type MarketSession =
2
- | "closed_weekend"
3
- | "closed_holiday"
4
- | "pre_market"
5
- | "open"
6
- | "after_close"
7
- | "closed_after_hours"
8
- | "unknown";
9
-
10
- export interface LocalDateTimeParts {
11
- date: string;
12
- time: string;
13
- weekday: string;
14
- minutesSinceMidnight: number;
15
- }
16
-
17
- export const KNOWN_US_MARKET_HOLIDAYS: Record<string, string> = new Proxy(
18
- {} as Record<string, string>,
19
- {
20
- get(_target, property) {
21
- return typeof property === "string" ? marketHolidayName(property) : undefined;
22
- },
23
- has(_target, property) {
24
- return typeof property === "string" && marketHolidayName(property) !== undefined;
25
- },
26
- },
27
- );
28
-
29
- export function marketHolidayName(key: string): string | undefined {
30
- const date = dateFromKey(key);
31
- const year = date.getUTCFullYear();
32
- for (const candidateYear of [year - 1, year, year + 1]) {
33
- const holiday = marketHolidaysForYear(candidateYear).find((entry) => entry.date === key);
34
- if (holiday) return holiday.name;
35
- }
36
- return undefined;
37
- }
38
-
39
- export function classifyMarketStatus(
40
- local: LocalDateTimeParts,
41
- isWeekend: boolean,
42
- isMarketHoliday: boolean,
43
- temporalReferences: string[],
44
- ): Exclude<MarketSession, "unknown"> {
45
- if (isWeekend) return "closed_weekend";
46
- if (isMarketHoliday) return "closed_holiday";
47
- if (local.minutesSinceMidnight < 9 * 60 + 30) return "pre_market";
48
- if (local.minutesSinceMidnight < 16 * 60) return "open";
49
- if (temporalReferences.includes("after_close")) return "after_close";
50
- return "closed_after_hours";
51
- }
52
-
53
- export function classifyMarketStatusAt(now: Date): MarketSession {
54
- const local = localDateTimeParts(now, "America/New_York");
55
- return classifyMarketStatus(
56
- local,
57
- local.weekday === "Sat" || local.weekday === "Sun",
58
- marketHolidayName(local.date) !== undefined,
59
- [],
60
- );
61
- }
62
-
63
- export function localDateTimeParts(date: Date, timezone: string): LocalDateTimeParts {
64
- const formatter = new Intl.DateTimeFormat("en-US", {
65
- timeZone: timezone,
66
- year: "numeric",
67
- month: "2-digit",
68
- day: "2-digit",
69
- hour: "2-digit",
70
- minute: "2-digit",
71
- hour12: false,
72
- weekday: "short",
73
- });
74
- const parts = formatter.formatToParts(date).reduce<Record<string, string>>((acc, part) => {
75
- acc[part.type] = part.value;
76
- return acc;
77
- }, {});
78
- const hour = Number(parts.hour);
79
- const minute = Number(parts.minute);
80
- return {
81
- date: `${parts.year}-${parts.month}-${parts.day}`,
82
- time: `${parts.hour}:${parts.minute}`,
83
- weekday: parts.weekday ?? "",
84
- minutesSinceMidnight: hour * 60 + minute,
85
- };
86
- }
87
-
88
- export function lastTradingDay(localDate: string): string {
89
- let cursor = dateFromKey(localDate);
90
- do {
91
- cursor = addDays(cursor, -1);
92
- } while (isWeekendOrKnownHoliday(dateKey(cursor)));
93
- return dateKey(cursor);
94
- }
95
-
96
- export function isWeekendOrKnownHoliday(key: string): boolean {
97
- const date = dateFromKey(key);
98
- const day = date.getUTCDay();
99
- return day === 0 || day === 6 || marketHolidayName(key) !== undefined;
100
- }
101
-
102
- function marketHolidaysForYear(year: number): Array<{ date: string; name: string }> {
103
- return [
104
- observedFixedHoliday(year, 1, 1, "New Year's Day"),
105
- nthWeekdayHoliday(year, 1, 1, 3, "Martin Luther King Jr. Day"),
106
- nthWeekdayHoliday(year, 2, 1, 3, "Washington's Birthday"),
107
- { date: dateKey(addDays(easterDate(year), -2)), name: "Good Friday" },
108
- lastWeekdayHoliday(year, 5, 1, "Memorial Day"),
109
- observedFixedHoliday(year, 6, 19, "Juneteenth"),
110
- observedFixedHoliday(year, 7, 4, "Independence Day"),
111
- nthWeekdayHoliday(year, 9, 1, 1, "Labor Day"),
112
- nthWeekdayHoliday(year, 11, 4, 4, "Thanksgiving Day"),
113
- observedFixedHoliday(year, 12, 25, "Christmas Day"),
114
- ];
115
- }
116
-
117
- function observedFixedHoliday(
118
- year: number,
119
- month: number,
120
- day: number,
121
- name: string,
122
- ): {
123
- date: string;
124
- name: string;
125
- } {
126
- const actual = new Date(Date.UTC(year, month - 1, day));
127
- const weekday = actual.getUTCDay();
128
- const observed =
129
- weekday === 0 ? addDays(actual, 1) : weekday === 6 ? addDays(actual, -1) : actual;
130
- return {
131
- date: dateKey(observed),
132
- name: observed.getTime() === actual.getTime() ? name : `${name} observed`,
133
- };
134
- }
135
-
136
- function nthWeekdayHoliday(
137
- year: number,
138
- month: number,
139
- weekday: number,
140
- occurrence: number,
141
- name: string,
142
- ): { date: string; name: string } {
143
- const first = new Date(Date.UTC(year, month - 1, 1));
144
- const offset = (weekday - first.getUTCDay() + 7) % 7;
145
- return { date: dateKey(addDays(first, offset + (occurrence - 1) * 7)), name };
146
- }
147
-
148
- function lastWeekdayHoliday(
149
- year: number,
150
- month: number,
151
- weekday: number,
152
- name: string,
153
- ): { date: string; name: string } {
154
- const last = new Date(Date.UTC(year, month, 0));
155
- const offset = (last.getUTCDay() - weekday + 7) % 7;
156
- return { date: dateKey(addDays(last, -offset)), name };
157
- }
158
-
159
- function easterDate(year: number): Date {
160
- const a = year % 19;
161
- const b = Math.floor(year / 100);
162
- const c = year % 100;
163
- const d = Math.floor(b / 4);
164
- const e = b % 4;
165
- const f = Math.floor((b + 8) / 25);
166
- const g = Math.floor((b - f + 1) / 3);
167
- const h = (19 * a + b - d - g + 15) % 30;
168
- const i = Math.floor(c / 4);
169
- const k = c % 4;
170
- const l = (32 + 2 * e + 2 * i - h - k) % 7;
171
- const m = Math.floor((a + 11 * h + 22 * l) / 451);
172
- const easterMonth = Math.floor((h + l - 7 * m + 114) / 31);
173
- const easterDay = ((h + l - 7 * m + 114) % 31) + 1;
174
- return new Date(Date.UTC(year, easterMonth - 1, easterDay));
175
- }
176
-
177
- function dateFromKey(key: string): Date {
178
- const [year, month, day] = key.split("-").map(Number);
179
- return new Date(Date.UTC(year, month - 1, day));
180
- }
181
-
182
- function addDays(date: Date, days: number): Date {
183
- const next = new Date(date);
184
- next.setUTCDate(next.getUTCDate() + days);
185
- return next;
186
- }
187
-
188
- function dateKey(date: Date): string {
189
- const year = date.getUTCFullYear();
190
- const month = String(date.getUTCMonth() + 1).padStart(2, "0");
191
- const day = String(date.getUTCDate()).padStart(2, "0");
192
- return `${year}-${month}-${day}`;
193
- }