@reefclaw/connect 0.1.10 → 0.1.12

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 (396) hide show
  1. package/assets/bridge/gateway/event-parser.d.ts +6 -1
  2. package/assets/bridge/gateway/event-parser.js +19 -2
  3. package/assets/bridge/gateway/heartbeat-cron.d.ts +27 -0
  4. package/assets/bridge/gateway/heartbeat-cron.js +85 -0
  5. package/assets/bridge/gateway/poller.d.ts +1 -0
  6. package/assets/bridge/gateway/poller.js +14 -2
  7. package/assets/bridge/providers/gateway.d.ts +24 -2
  8. package/assets/bridge/providers/gateway.js +124 -25
  9. package/assets/bridge/setup.js +6 -51
  10. package/assets/shared/signals/conditions/registry.js +11 -2
  11. package/assets/shared/signals/strategy-adapter.js +17 -7
  12. package/assets/skill/SKILL.md +2 -0
  13. package/dist/deps.js +2 -2
  14. package/dist/plugin.js +35 -7
  15. package/package.json +1 -1
  16. package/assets/plugin/audit/mode-transition-audit.d.ts +0 -11
  17. package/assets/plugin/audit/mode-transition-audit.js +0 -29
  18. package/assets/plugin/balance-utils.d.ts +0 -36
  19. package/assets/plugin/balance-utils.js +0 -98
  20. package/assets/plugin/ccxt/binance-ban-gate.d.ts +0 -47
  21. package/assets/plugin/ccxt/binance-ban-gate.js +0 -420
  22. package/assets/plugin/ccxt/binance-private.d.ts +0 -346
  23. package/assets/plugin/ccxt/binance-private.js +0 -1525
  24. package/assets/plugin/ccxt/binance-public.d.ts +0 -34
  25. package/assets/plugin/ccxt/binance-public.js +0 -180
  26. package/assets/plugin/ccxt/intel-public.d.ts +0 -25
  27. package/assets/plugin/ccxt/intel-public.js +0 -80
  28. package/assets/plugin/ccxt/public-market-data-api.d.ts +0 -12
  29. package/assets/plugin/ccxt/public-market-data-api.js +0 -9
  30. package/assets/plugin/config/agent-config-client.d.ts +0 -77
  31. package/assets/plugin/config/agent-config-client.js +0 -188
  32. package/assets/plugin/config/agent-config-poller.d.ts +0 -32
  33. package/assets/plugin/config/agent-config-poller.js +0 -101
  34. package/assets/plugin/config/brackets-config.d.ts +0 -22
  35. package/assets/plugin/config/brackets-config.js +0 -58
  36. package/assets/plugin/config/entitlement-gate.d.ts +0 -51
  37. package/assets/plugin/config/entitlement-gate.js +0 -137
  38. package/assets/plugin/config/gate-store.d.ts +0 -18
  39. package/assets/plugin/config/gate-store.js +0 -61
  40. package/assets/plugin/config/plugin-config-io.d.ts +0 -215
  41. package/assets/plugin/config/plugin-config-io.js +0 -111
  42. package/assets/plugin/config/position-review-config.d.ts +0 -35
  43. package/assets/plugin/config/position-review-config.js +0 -105
  44. package/assets/plugin/config/tool-gate.d.ts +0 -53
  45. package/assets/plugin/config/tool-gate.js +0 -128
  46. package/assets/plugin/config/user-data-stream-config.d.ts +0 -89
  47. package/assets/plugin/config/user-data-stream-config.js +0 -239
  48. package/assets/plugin/connector-supervisor.d.ts +0 -36
  49. package/assets/plugin/connector-supervisor.js +0 -149
  50. package/assets/plugin/exchange-adapter.d.ts +0 -65
  51. package/assets/plugin/exchange-adapter.js +0 -4
  52. package/assets/plugin/index.d.ts +0 -30
  53. package/assets/plugin/index.js +0 -2678
  54. package/assets/plugin/ingest/pending-entry-metadata.d.ts +0 -74
  55. package/assets/plugin/ingest/pending-entry-metadata.js +0 -236
  56. package/assets/plugin/ingest/position-auto-capture.d.ts +0 -103
  57. package/assets/plugin/ingest/position-auto-capture.js +0 -411
  58. package/assets/plugin/ingest/position-decisions-client.d.ts +0 -322
  59. package/assets/plugin/ingest/position-decisions-client.js +0 -296
  60. package/assets/plugin/ingest/readiness-reporter.d.ts +0 -42
  61. package/assets/plugin/ingest/readiness-reporter.js +0 -163
  62. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +0 -13
  63. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +0 -114
  64. package/assets/plugin/ingest/reconciler-cleanup.d.ts +0 -37
  65. package/assets/plugin/ingest/reconciler-cleanup.js +0 -147
  66. package/assets/plugin/ingest/rest-gap-filler.d.ts +0 -191
  67. package/assets/plugin/ingest/rest-gap-filler.js +0 -565
  68. package/assets/plugin/ingest/touched-symbols-store.d.ts +0 -25
  69. package/assets/plugin/ingest/touched-symbols-store.js +0 -96
  70. package/assets/plugin/ingest/trade-store-client.d.ts +0 -40
  71. package/assets/plugin/ingest/trade-store-client.js +0 -125
  72. package/assets/plugin/ingest/ws-ingest.d.ts +0 -43
  73. package/assets/plugin/ingest/ws-ingest.js +0 -126
  74. package/assets/plugin/learning/setup-family.d.ts +0 -21
  75. package/assets/plugin/learning/setup-family.js +0 -103
  76. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +0 -33
  77. package/assets/plugin/lifecycle/install-signal-handlers.js +0 -112
  78. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +0 -43
  79. package/assets/plugin/lifecycle/shutdown-coordinator.js +0 -131
  80. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +0 -17
  81. package/assets/plugin/lifecycle/trading-operation-lock.js +0 -14
  82. package/assets/plugin/live/bracket-id.d.ts +0 -26
  83. package/assets/plugin/live/bracket-id.js +0 -112
  84. package/assets/plugin/live/bracket-ledger.d.ts +0 -54
  85. package/assets/plugin/live/bracket-ledger.js +0 -267
  86. package/assets/plugin/live/bracket-manager.d.ts +0 -82
  87. package/assets/plugin/live/bracket-manager.js +0 -478
  88. package/assets/plugin/live/bracket-params.d.ts +0 -22
  89. package/assets/plugin/live/bracket-params.js +0 -124
  90. package/assets/plugin/live/bracket-reconciler.d.ts +0 -95
  91. package/assets/plugin/live/bracket-reconciler.js +0 -573
  92. package/assets/plugin/live/bracket-types.d.ts +0 -102
  93. package/assets/plugin/live/bracket-types.js +0 -8
  94. package/assets/plugin/live/deposit-tracker.d.ts +0 -62
  95. package/assets/plugin/live/deposit-tracker.js +0 -97
  96. package/assets/plugin/live/emergency-controls.d.ts +0 -32
  97. package/assets/plugin/live/emergency-controls.js +0 -226
  98. package/assets/plugin/live/exchange-errors.d.ts +0 -12
  99. package/assets/plugin/live/exchange-errors.js +0 -130
  100. package/assets/plugin/live/exchange-info-cache.d.ts +0 -37
  101. package/assets/plugin/live/exchange-info-cache.js +0 -134
  102. package/assets/plugin/live/fact-subscriber.d.ts +0 -78
  103. package/assets/plugin/live/fact-subscriber.js +0 -182
  104. package/assets/plugin/live/intent-journal.d.ts +0 -42
  105. package/assets/plugin/live/intent-journal.js +0 -122
  106. package/assets/plugin/live/listen-key-manager.d.ts +0 -70
  107. package/assets/plugin/live/listen-key-manager.js +0 -169
  108. package/assets/plugin/live/live-adapter.d.ts +0 -287
  109. package/assets/plugin/live/live-adapter.js +0 -1777
  110. package/assets/plugin/live/live-balance-enricher.d.ts +0 -32
  111. package/assets/plugin/live/live-balance-enricher.js +0 -104
  112. package/assets/plugin/live/live-bracket-api.d.ts +0 -13
  113. package/assets/plugin/live/live-bracket-api.js +0 -20
  114. package/assets/plugin/live/live-state-store.d.ts +0 -194
  115. package/assets/plugin/live/live-state-store.js +0 -450
  116. package/assets/plugin/live/local-signal-service.d.ts +0 -57
  117. package/assets/plugin/live/local-signal-service.js +0 -151
  118. package/assets/plugin/live/local-strategy-evaluator.d.ts +0 -62
  119. package/assets/plugin/live/local-strategy-evaluator.js +0 -131
  120. package/assets/plugin/live/microstructure-assembler.d.ts +0 -54
  121. package/assets/plugin/live/microstructure-assembler.js +0 -148
  122. package/assets/plugin/live/order-poller.d.ts +0 -29
  123. package/assets/plugin/live/order-poller.js +0 -125
  124. package/assets/plugin/live/position-state-store.d.ts +0 -83
  125. package/assets/plugin/live/position-state-store.js +0 -237
  126. package/assets/plugin/live/proposal-decision-listener.d.ts +0 -70
  127. package/assets/plugin/live/proposal-decision-listener.js +0 -292
  128. package/assets/plugin/live/proposal-manager.d.ts +0 -76
  129. package/assets/plugin/live/proposal-manager.js +0 -140
  130. package/assets/plugin/live/rate-limiter.d.ts +0 -47
  131. package/assets/plugin/live/rate-limiter.js +0 -159
  132. package/assets/plugin/live/reconciler.d.ts +0 -39
  133. package/assets/plugin/live/reconciler.js +0 -175
  134. package/assets/plugin/live/setup-buckets.d.ts +0 -7
  135. package/assets/plugin/live/setup-buckets.js +0 -33
  136. package/assets/plugin/live/slippage-tracker.d.ts +0 -45
  137. package/assets/plugin/live/slippage-tracker.js +0 -78
  138. package/assets/plugin/live/stop-watcher.d.ts +0 -60
  139. package/assets/plugin/live/stop-watcher.js +0 -215
  140. package/assets/plugin/live/user-data-active-probe.d.ts +0 -54
  141. package/assets/plugin/live/user-data-active-probe.js +0 -180
  142. package/assets/plugin/live/user-data-stream-controller.d.ts +0 -200
  143. package/assets/plugin/live/user-data-stream-controller.js +0 -579
  144. package/assets/plugin/live/user-data-stream-ws.d.ts +0 -22
  145. package/assets/plugin/live/user-data-stream-ws.js +0 -63
  146. package/assets/plugin/live/user-data-stream.d.ts +0 -243
  147. package/assets/plugin/live/user-data-stream.js +0 -704
  148. package/assets/plugin/logger.d.ts +0 -2
  149. package/assets/plugin/logger.js +0 -2
  150. package/assets/plugin/mfe.d.ts +0 -21
  151. package/assets/plugin/mfe.js +0 -68
  152. package/assets/plugin/onboarding/mode-ladder.d.ts +0 -1
  153. package/assets/plugin/onboarding/mode-ladder.js +0 -3
  154. package/assets/plugin/onboarding/runtime.d.ts +0 -84
  155. package/assets/plugin/onboarding/runtime.js +0 -173
  156. package/assets/plugin/openclaw.plugin.json +0 -92
  157. package/assets/plugin/paper-adapter.d.ts +0 -24
  158. package/assets/plugin/paper-adapter.js +0 -91
  159. package/assets/plugin/persistence/state-manager.d.ts +0 -66
  160. package/assets/plugin/persistence/state-manager.js +0 -222
  161. package/assets/plugin/pinned-plan.d.ts +0 -9
  162. package/assets/plugin/pinned-plan.js +0 -23
  163. package/assets/plugin/portfolio/wave9-admission.d.ts +0 -67
  164. package/assets/plugin/portfolio/wave9-admission.js +0 -262
  165. package/assets/plugin/portfolio/wave9-policy.d.ts +0 -36
  166. package/assets/plugin/portfolio/wave9-policy.js +0 -183
  167. package/assets/plugin/risk/pre-trade-check.d.ts +0 -38
  168. package/assets/plugin/risk/pre-trade-check.js +0 -345
  169. package/assets/plugin/risk/pre-trade-types.d.ts +0 -60
  170. package/assets/plugin/risk/pre-trade-types.js +0 -3
  171. package/assets/plugin/shadow/shadow-tracker.d.ts +0 -36
  172. package/assets/plugin/shadow/shadow-tracker.js +0 -151
  173. package/assets/plugin/shadow/types.d.ts +0 -42
  174. package/assets/plugin/shadow/types.js +0 -20
  175. package/assets/plugin/shared/indicators-extended.d.ts +0 -52
  176. package/assets/plugin/shared/indicators-extended.js +0 -291
  177. package/assets/plugin/shared/indicators.d.ts +0 -15
  178. package/assets/plugin/shared/indicators.js +0 -114
  179. package/assets/plugin/signals/conditions/registry.d.ts +0 -16
  180. package/assets/plugin/signals/conditions/registry.js +0 -1324
  181. package/assets/plugin/signals/conditions/types.d.ts +0 -1
  182. package/assets/plugin/signals/conditions/types.js +0 -4
  183. package/assets/plugin/signals/direction-rules.d.ts +0 -3
  184. package/assets/plugin/signals/direction-rules.js +0 -24
  185. package/assets/plugin/signals/entry-rules.d.ts +0 -6
  186. package/assets/plugin/signals/entry-rules.js +0 -33
  187. package/assets/plugin/signals/serialize-context.d.ts +0 -4
  188. package/assets/plugin/signals/serialize-context.js +0 -39
  189. package/assets/plugin/signals/stop-rules.d.ts +0 -3
  190. package/assets/plugin/signals/stop-rules.js +0 -48
  191. package/assets/plugin/signals/strategy-adapter.d.ts +0 -47
  192. package/assets/plugin/signals/strategy-adapter.js +0 -199
  193. package/assets/plugin/signals/types.d.ts +0 -1
  194. package/assets/plugin/signals/types.js +0 -8
  195. package/assets/plugin/simulator/exchange-simulator.d.ts +0 -93
  196. package/assets/plugin/simulator/exchange-simulator.js +0 -689
  197. package/assets/plugin/simulator/fill-engine.d.ts +0 -53
  198. package/assets/plugin/simulator/fill-engine.js +0 -280
  199. package/assets/plugin/simulator/paper-market-feed.d.ts +0 -26
  200. package/assets/plugin/simulator/paper-market-feed.js +0 -104
  201. package/assets/plugin/simulator/realistic-fills.d.ts +0 -59
  202. package/assets/plugin/simulator/realistic-fills.js +0 -175
  203. package/assets/plugin/simulator/types.d.ts +0 -224
  204. package/assets/plugin/simulator/types.js +0 -43
  205. package/assets/plugin/strategy/builtin-strategies.d.ts +0 -2
  206. package/assets/plugin/strategy/builtin-strategies.js +0 -113
  207. package/assets/plugin/strategy/condition-registry.d.ts +0 -3
  208. package/assets/plugin/strategy/condition-registry.js +0 -153
  209. package/assets/plugin/strategy/evaluator.d.ts +0 -70
  210. package/assets/plugin/strategy/evaluator.js +0 -98
  211. package/assets/plugin/tools/assessment-validation.d.ts +0 -120
  212. package/assets/plugin/tools/assessment-validation.js +0 -415
  213. package/assets/plugin/tools/attach-brackets.d.ts +0 -39
  214. package/assets/plugin/tools/attach-brackets.js +0 -399
  215. package/assets/plugin/tools/audit-bracket-protection.d.ts +0 -49
  216. package/assets/plugin/tools/audit-bracket-protection.js +0 -527
  217. package/assets/plugin/tools/cancel-all-orders.d.ts +0 -9
  218. package/assets/plugin/tools/cancel-all-orders.js +0 -8
  219. package/assets/plugin/tools/cancel-order.d.ts +0 -14
  220. package/assets/plugin/tools/cancel-order.js +0 -60
  221. package/assets/plugin/tools/check-position-health.d.ts +0 -46
  222. package/assets/plugin/tools/check-position-health.js +0 -194
  223. package/assets/plugin/tools/clear-exchange-credentials.d.ts +0 -24
  224. package/assets/plugin/tools/clear-exchange-credentials.js +0 -70
  225. package/assets/plugin/tools/close-position.d.ts +0 -45
  226. package/assets/plugin/tools/close-position.js +0 -722
  227. package/assets/plugin/tools/create-order.d.ts +0 -82
  228. package/assets/plugin/tools/create-order.js +0 -1516
  229. package/assets/plugin/tools/exit-gate.d.ts +0 -58
  230. package/assets/plugin/tools/exit-gate.js +0 -162
  231. package/assets/plugin/tools/fetch-balance.d.ts +0 -5
  232. package/assets/plugin/tools/fetch-balance.js +0 -4
  233. package/assets/plugin/tools/fetch-ohlcv.d.ts +0 -11
  234. package/assets/plugin/tools/fetch-ohlcv.js +0 -8
  235. package/assets/plugin/tools/fetch-open-orders.d.ts +0 -7
  236. package/assets/plugin/tools/fetch-open-orders.js +0 -4
  237. package/assets/plugin/tools/fetch-positions.d.ts +0 -7
  238. package/assets/plugin/tools/fetch-positions.js +0 -4
  239. package/assets/plugin/tools/fetch-ticker.d.ts +0 -11
  240. package/assets/plugin/tools/fetch-ticker.js +0 -5
  241. package/assets/plugin/tools/get-agent-profile.d.ts +0 -4
  242. package/assets/plugin/tools/get-agent-profile.js +0 -6
  243. package/assets/plugin/tools/get-analytics.d.ts +0 -6
  244. package/assets/plugin/tools/get-analytics.js +0 -7
  245. package/assets/plugin/tools/get-backtest.d.ts +0 -12
  246. package/assets/plugin/tools/get-backtest.js +0 -91
  247. package/assets/plugin/tools/get-basis.d.ts +0 -7
  248. package/assets/plugin/tools/get-basis.js +0 -7
  249. package/assets/plugin/tools/get-bracket-config.d.ts +0 -11
  250. package/assets/plugin/tools/get-bracket-config.js +0 -24
  251. package/assets/plugin/tools/get-cascade-risk.d.ts +0 -7
  252. package/assets/plugin/tools/get-cascade-risk.js +0 -8
  253. package/assets/plugin/tools/get-crypto-metrics.d.ts +0 -18
  254. package/assets/plugin/tools/get-crypto-metrics.js +0 -62
  255. package/assets/plugin/tools/get-cvd.d.ts +0 -6
  256. package/assets/plugin/tools/get-cvd.js +0 -6
  257. package/assets/plugin/tools/get-divergences.d.ts +0 -6
  258. package/assets/plugin/tools/get-divergences.js +0 -6
  259. package/assets/plugin/tools/get-funding-context.d.ts +0 -6
  260. package/assets/plugin/tools/get-funding-context.js +0 -16
  261. package/assets/plugin/tools/get-liquidation-levels.d.ts +0 -7
  262. package/assets/plugin/tools/get-liquidation-levels.js +0 -7
  263. package/assets/plugin/tools/get-liquidation-pulse.d.ts +0 -9
  264. package/assets/plugin/tools/get-liquidation-pulse.js +0 -22
  265. package/assets/plugin/tools/get-market-breadth.d.ts +0 -6
  266. package/assets/plugin/tools/get-market-breadth.js +0 -8
  267. package/assets/plugin/tools/get-market-intel.d.ts +0 -19
  268. package/assets/plugin/tools/get-market-intel.js +0 -116
  269. package/assets/plugin/tools/get-market-structure.d.ts +0 -47
  270. package/assets/plugin/tools/get-market-structure.js +0 -198
  271. package/assets/plugin/tools/get-my-mined-patterns.d.ts +0 -20
  272. package/assets/plugin/tools/get-my-mined-patterns.js +0 -61
  273. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +0 -20
  274. package/assets/plugin/tools/get-my-proposed-learnings.js +0 -55
  275. package/assets/plugin/tools/get-my-recent-reviews.d.ts +0 -22
  276. package/assets/plugin/tools/get-my-recent-reviews.js +0 -66
  277. package/assets/plugin/tools/get-orderbook.d.ts +0 -21
  278. package/assets/plugin/tools/get-orderbook.js +0 -32
  279. package/assets/plugin/tools/get-pattern-scan.d.ts +0 -7
  280. package/assets/plugin/tools/get-pattern-scan.js +0 -8
  281. package/assets/plugin/tools/get-regime.d.ts +0 -6
  282. package/assets/plugin/tools/get-regime.js +0 -7
  283. package/assets/plugin/tools/get-relevant-learnings.d.ts +0 -21
  284. package/assets/plugin/tools/get-relevant-learnings.js +0 -65
  285. package/assets/plugin/tools/get-resting-liquidity.d.ts +0 -6
  286. package/assets/plugin/tools/get-resting-liquidity.js +0 -11
  287. package/assets/plugin/tools/get-risk-scenario.d.ts +0 -29
  288. package/assets/plugin/tools/get-risk-scenario.js +0 -47
  289. package/assets/plugin/tools/get-risk-summary.d.ts +0 -51
  290. package/assets/plugin/tools/get-risk-summary.js +0 -118
  291. package/assets/plugin/tools/get-sentiment.d.ts +0 -4
  292. package/assets/plugin/tools/get-sentiment.js +0 -6
  293. package/assets/plugin/tools/get-session-review.d.ts +0 -7
  294. package/assets/plugin/tools/get-session-review.js +0 -8
  295. package/assets/plugin/tools/get-setup-detail.d.ts +0 -7
  296. package/assets/plugin/tools/get-setup-detail.js +0 -311
  297. package/assets/plugin/tools/get-signals.d.ts +0 -15
  298. package/assets/plugin/tools/get-signals.js +0 -54
  299. package/assets/plugin/tools/get-sizing.d.ts +0 -6
  300. package/assets/plugin/tools/get-sizing.js +0 -6
  301. package/assets/plugin/tools/get-trade-feedback.d.ts +0 -7
  302. package/assets/plugin/tools/get-trade-feedback.js +0 -8
  303. package/assets/plugin/tools/get-trade-flow.d.ts +0 -7
  304. package/assets/plugin/tools/get-trade-flow.js +0 -7
  305. package/assets/plugin/tools/get-volume-analysis.d.ts +0 -21
  306. package/assets/plugin/tools/get-volume-analysis.js +0 -74
  307. package/assets/plugin/tools/get-volume-profile.d.ts +0 -7
  308. package/assets/plugin/tools/get-volume-profile.js +0 -7
  309. package/assets/plugin/tools/get-wave9-status.d.ts +0 -127
  310. package/assets/plugin/tools/get-wave9-status.js +0 -796
  311. package/assets/plugin/tools/helpers.d.ts +0 -26
  312. package/assets/plugin/tools/helpers.js +0 -39
  313. package/assets/plugin/tools/intel-api.d.ts +0 -34
  314. package/assets/plugin/tools/intel-api.js +0 -119
  315. package/assets/plugin/tools/intel-cache.d.ts +0 -25
  316. package/assets/plugin/tools/intel-cache.js +0 -148
  317. package/assets/plugin/tools/list-strategies.d.ts +0 -17
  318. package/assets/plugin/tools/list-strategies.js +0 -23
  319. package/assets/plugin/tools/modify-stop.d.ts +0 -21
  320. package/assets/plugin/tools/modify-stop.js +0 -120
  321. package/assets/plugin/tools/modify-target.d.ts +0 -21
  322. package/assets/plugin/tools/modify-target.js +0 -110
  323. package/assets/plugin/tools/propose-learning.d.ts +0 -22
  324. package/assets/plugin/tools/propose-learning.js +0 -65
  325. package/assets/plugin/tools/query-review-outcomes.d.ts +0 -30
  326. package/assets/plugin/tools/query-review-outcomes.js +0 -64
  327. package/assets/plugin/tools/query-trades.d.ts +0 -21
  328. package/assets/plugin/tools/query-trades.js +0 -37
  329. package/assets/plugin/tools/record-position-reviews.d.ts +0 -38
  330. package/assets/plugin/tools/record-position-reviews.js +0 -147
  331. package/assets/plugin/tools/save-strategy.d.ts +0 -16
  332. package/assets/plugin/tools/save-strategy.js +0 -46
  333. package/assets/plugin/tools/scan-pairs.d.ts +0 -18
  334. package/assets/plugin/tools/scan-pairs.js +0 -231
  335. package/assets/plugin/tools/score-setup.d.ts +0 -31
  336. package/assets/plugin/tools/score-setup.js +0 -268
  337. package/assets/plugin/tools/set-bracket-requirement.d.ts +0 -18
  338. package/assets/plugin/tools/set-bracket-requirement.js +0 -81
  339. package/assets/plugin/tools/set-exchange-credentials.d.ts +0 -25
  340. package/assets/plugin/tools/set-exchange-credentials.js +0 -80
  341. package/assets/plugin/tools/set-trading-mode.d.ts +0 -26
  342. package/assets/plugin/tools/set-trading-mode.js +0 -135
  343. package/assets/plugin/tools/test-exchange-credentials.d.ts +0 -16
  344. package/assets/plugin/tools/test-exchange-credentials.js +0 -100
  345. package/assets/plugin/tools/toggle-strategy.d.ts +0 -8
  346. package/assets/plugin/tools/toggle-strategy.js +0 -15
  347. package/assets/plugin/trading-params-cache.d.ts +0 -26
  348. package/assets/plugin/trading-params-cache.js +0 -52
  349. package/assets/plugin/types.d.ts +0 -134
  350. package/assets/plugin/types.js +0 -7
  351. package/assets/plugin/util/plugin-paths.d.ts +0 -3
  352. package/assets/plugin/util/plugin-paths.js +0 -15
  353. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +0 -116
  354. package/assets/plugin/venues/hyperliquid/hl-balance.js +0 -145
  355. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +0 -102
  356. package/assets/plugin/venues/hyperliquid/hl-brackets.js +0 -172
  357. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +0 -22
  358. package/assets/plugin/venues/hyperliquid/hl-cloid.js +0 -82
  359. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +0 -46
  360. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +0 -125
  361. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +0 -88
  362. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +0 -353
  363. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +0 -61
  364. package/assets/plugin/venues/hyperliquid/hl-precision.js +0 -176
  365. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +0 -88
  366. package/assets/plugin/venues/hyperliquid/hl-private.js +0 -357
  367. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +0 -79
  368. package/assets/plugin/venues/hyperliquid/hl-public.js +0 -429
  369. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +0 -57
  370. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +0 -220
  371. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +0 -90
  372. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +0 -220
  373. package/assets/plugin/venues/registry.d.ts +0 -38
  374. package/assets/plugin/venues/registry.js +0 -46
  375. package/assets/plugin/venues/symbols.d.ts +0 -43
  376. package/assets/plugin/venues/symbols.js +0 -107
  377. package/assets/plugin/wave9/live-account-capture.d.ts +0 -67
  378. package/assets/plugin/wave9/live-account-capture.js +0 -435
  379. package/assets/plugin/wave9/live-autonomous-protection.d.ts +0 -39
  380. package/assets/plugin/wave9/live-autonomous-protection.js +0 -112
  381. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +0 -33
  382. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +0 -115
  383. package/assets/plugin/wave9/live-execution-ledger.d.ts +0 -107
  384. package/assets/plugin/wave9/live-execution-ledger.js +0 -498
  385. package/assets/plugin/wave9/live-position-confirmation.d.ts +0 -18
  386. package/assets/plugin/wave9/live-position-confirmation.js +0 -111
  387. package/assets/plugin/wave9/live-residual-protection.d.ts +0 -18
  388. package/assets/plugin/wave9/live-residual-protection.js +0 -250
  389. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +0 -38
  390. package/assets/plugin/wave9/live-startup-reconciliation.js +0 -454
  391. package/assets/plugin/wave9/live-symbol-ownership.d.ts +0 -20
  392. package/assets/plugin/wave9/live-symbol-ownership.js +0 -132
  393. package/assets/plugin/wave9/paper-admission-guard.d.ts +0 -199
  394. package/assets/plugin/wave9/paper-admission-guard.js +0 -650
  395. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +0 -42
  396. package/assets/plugin/wave9/usdm-evidence-provider.js +0 -133
@@ -1,237 +0,0 @@
1
- // Position state store — restart-survival for the Position Decision Journal.
2
- //
3
- // Tracks the minimal per-open-position state the auto-capture pipeline needs
4
- // to keep the (symbol, positionOpenAt) join key stable across plugin restarts:
5
- //
6
- // - openedAt: authoritative timestamp of the first opening fill, used as the
7
- // webapp's natural-key column. Without persistence, restart would
8
- // reset every position's openedAt to "now" and break the join.
9
- // - webappPositionId: the UUID returned by POST /api/internal/positions; needed
10
- // so subsequent /position-{entries,reviews,closes} POSTs can
11
- // reference the correct parent row.
12
- // - lastReviewAt + lastVerdict: drives the stale-review gate (per
13
- // POSITION_REVIEW_PLAN.md §7.4). Cheap to recompute from the
14
- // webapp on boot, but persisting locally avoids a round-trip
15
- // during the gate-check hot path.
16
- //
17
- // Storage: full JSON rewrite + atomic rename, same pattern as bracket-ledger.
18
- // Path: ~/.openclaw/plugins/<pluginId>/position-state.json
19
- // Symbols stored in canonical (un-suffixed) form via normalizeBracketSymbol.
20
- //
21
- // Recovery on boot:
22
- // - If the file exists and is valid, load it.
23
- // - If not, start empty. On the next position observation (live: getPositions
24
- // tick; paper: state.json load) the auto-capture pipeline seeds new entries.
25
- //
26
- // See docs/POSITION_DECISION_JOURNAL_PLAN.md §4.5.
27
- import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
28
- import { join } from 'node:path';
29
- import { logger, formatError } from '../logger.js';
30
- import { normalizeBracketSymbol } from './bracket-ledger.js';
31
- import { resolvePluginsBaseDir } from '../util/plugin-paths.js';
32
- const TAG = 'position-state-store';
33
- const DEFAULT_PLUGIN_ID = 'reefclaw-paper-trading';
34
- const STATE_FILENAME = 'position-state.json';
35
- const SCHEMA_VERSION = 1;
36
- const defaultNow = () => Date.now();
37
- export class PositionStateStore {
38
- filePath;
39
- dir;
40
- now;
41
- entries = new Map(); // key = canonical symbol
42
- constructor(pluginId, opts) {
43
- const base = resolvePluginsBaseDir(opts?.basePath);
44
- this.dir = join(base, pluginId ?? DEFAULT_PLUGIN_ID);
45
- this.filePath = join(this.dir, STATE_FILENAME);
46
- this.now = opts?.now ?? defaultNow;
47
- if (!existsSync(this.dir))
48
- mkdirSync(this.dir, { recursive: true });
49
- this.loadOrInit();
50
- }
51
- /** Insert or update a position. Caller is responsible for deciding when
52
- * to call this — typically on first observation of a new position. */
53
- upsert(entry) {
54
- const ts = this.now();
55
- const symbol = normalizeBracketSymbol(entry.symbol);
56
- const existing = this.entries.get(symbol);
57
- const full = {
58
- ...entry,
59
- symbol,
60
- createdAt: existing?.createdAt ?? entry.createdAt ?? ts,
61
- updatedAt: ts,
62
- };
63
- this.entries.set(symbol, full);
64
- this.persist();
65
- return full;
66
- }
67
- /** Set the webapp positionId after the upsert returns. Idempotent. */
68
- setWebappId(symbol, webappPositionId) {
69
- const key = normalizeBracketSymbol(symbol);
70
- const current = this.entries.get(key);
71
- if (!current) {
72
- logger.warn(TAG, `setWebappId: no entry for ${key} — dropping ${webappPositionId}`);
73
- return;
74
- }
75
- if (current.webappPositionId === webappPositionId)
76
- return;
77
- this.entries.set(key, { ...current, webappPositionId, updatedAt: this.now() });
78
- this.persist();
79
- }
80
- /** Update review tracking after a successful record_position_reviews call.
81
- * thesisStatus is optional for backwards compatibility — older callers that
82
- * predate the exit-gate work pass only verdict; the gate falls back to
83
- * PASS('inputs_unavailable_thesis_status') when the field isn't cached. */
84
- recordReview(symbol, verdict, reviewAt, thesisStatus) {
85
- const key = normalizeBracketSymbol(symbol);
86
- const current = this.entries.get(key);
87
- if (!current)
88
- return;
89
- this.entries.set(key, {
90
- ...current,
91
- lastReviewAt: reviewAt ?? this.now(),
92
- lastVerdict: verdict,
93
- lastThesisStatus: thesisStatus ?? current.lastThesisStatus,
94
- updatedAt: this.now(),
95
- });
96
- this.persist();
97
- }
98
- /** Add opening contracts to the running size (first opening fill or a
99
- * scale-in). Initialises the realised-PnL accumulator on first open. No-op
100
- * if the entry doesn't exist yet (caller upserts the entry first). */
101
- addOpenContracts(symbol, qty) {
102
- const key = normalizeBracketSymbol(symbol);
103
- const current = this.entries.get(key);
104
- if (!current || !(qty > 0))
105
- return;
106
- this.entries.set(key, {
107
- ...current,
108
- remainingContracts: (current.remainingContracts ?? 0) + qty,
109
- realizedPnlAccum: current.realizedPnlAccum ?? 0,
110
- updatedAt: this.now(),
111
- });
112
- this.persist();
113
- }
114
- /** Seed remaining contracts from exchange truth at startup. Only sets when
115
- * the size is currently unknown — never clobbers live fill-tracked state. */
116
- seedRemainingContracts(symbol, qty) {
117
- const key = normalizeBracketSymbol(symbol);
118
- const current = this.entries.get(key);
119
- if (!current || current.remainingContracts !== undefined || !(qty > 0))
120
- return;
121
- this.entries.set(key, {
122
- ...current,
123
- remainingContracts: qty,
124
- realizedPnlAccum: current.realizedPnlAccum ?? 0,
125
- updatedAt: this.now(),
126
- });
127
- this.persist();
128
- }
129
- /** Apply a reduce-only exit fill: decrement remaining contracts and sum the
130
- * fill's realised PnL. Returns the updated entry so the caller can journal a
131
- * close when the position is flat, or null when there's no tracked entry or
132
- * the size is unknown (can't decide flatness — defer to the backstop). */
133
- applyExitContracts(symbol, qty, realizedPnl) {
134
- const key = normalizeBracketSymbol(symbol);
135
- const current = this.entries.get(key);
136
- if (!current || current.remainingContracts === undefined || !(qty > 0))
137
- return null;
138
- const updated = {
139
- ...current,
140
- remainingContracts: current.remainingContracts - qty,
141
- realizedPnlAccum: (current.realizedPnlAccum ?? 0) + (Number.isFinite(realizedPnl) ? realizedPnl : 0),
142
- updatedAt: this.now(),
143
- };
144
- this.entries.set(key, updated);
145
- this.persist();
146
- return updated;
147
- }
148
- get(symbol) {
149
- return this.entries.get(normalizeBracketSymbol(symbol));
150
- }
151
- /** Returns all entries — used by the stale-gate to enumerate open positions. */
152
- getAll() {
153
- return Array.from(this.entries.values());
154
- }
155
- /** Drop an entry — called when the auto-capture pipeline observes the
156
- * position has closed (size dropped to zero on the exchange). */
157
- remove(symbol) {
158
- const existed = this.entries.delete(normalizeBracketSymbol(symbol));
159
- if (existed)
160
- this.persist();
161
- return existed;
162
- }
163
- size() {
164
- return this.entries.size;
165
- }
166
- getFilePath() {
167
- return this.filePath;
168
- }
169
- // ---- Internals ----
170
- loadOrInit() {
171
- if (!existsSync(this.filePath)) {
172
- logger.info(TAG, `No state file at ${this.filePath}; starting empty`);
173
- return;
174
- }
175
- let raw;
176
- try {
177
- raw = readFileSync(this.filePath, 'utf8');
178
- }
179
- catch (err) {
180
- throw new Error(`position-state-store: failed to read ${this.filePath}: ${formatError(err)}`);
181
- }
182
- let parsed;
183
- try {
184
- parsed = JSON.parse(raw);
185
- }
186
- catch (err) {
187
- throw new Error(`position-state-store: ${this.filePath} is not valid JSON: ${formatError(err)}`);
188
- }
189
- const file = this.validateFile(parsed);
190
- for (const entry of file.entries) {
191
- this.entries.set(entry.symbol, entry);
192
- }
193
- logger.info(TAG, `Loaded ${this.entries.size} entries from ${this.filePath}`);
194
- }
195
- persist() {
196
- const file = {
197
- schemaVersion: SCHEMA_VERSION,
198
- entries: Array.from(this.entries.values()),
199
- };
200
- const tempPath = `${this.filePath}.tmp`;
201
- writeFileSync(tempPath, JSON.stringify(file, null, 2));
202
- renameSync(tempPath, this.filePath);
203
- }
204
- validateFile(raw) {
205
- if (!isRecord(raw))
206
- throw new Error('position-state-store: file root is not an object');
207
- if (raw.schemaVersion !== SCHEMA_VERSION) {
208
- throw new Error(`position-state-store: unsupported schemaVersion ${String(raw.schemaVersion)} (expected ${SCHEMA_VERSION})`);
209
- }
210
- if (!Array.isArray(raw.entries))
211
- throw new Error('position-state-store: entries is not an array');
212
- const entries = [];
213
- for (const e of raw.entries)
214
- entries.push(this.validateEntry(e));
215
- return { schemaVersion: SCHEMA_VERSION, entries };
216
- }
217
- validateEntry(raw) {
218
- if (!isRecord(raw))
219
- throw new Error('position-state-store: entry is not an object');
220
- if (typeof raw.symbol !== 'string' || raw.symbol.length === 0) {
221
- throw new Error('position-state-store: entry missing symbol');
222
- }
223
- if (typeof raw.openedAt !== 'number' || !Number.isFinite(raw.openedAt)) {
224
- throw new Error('position-state-store: entry missing/invalid openedAt');
225
- }
226
- if (raw.side !== 'long' && raw.side !== 'short') {
227
- throw new Error(`position-state-store: bad side ${String(raw.side)}`);
228
- }
229
- if (typeof raw.createdAt !== 'number' || typeof raw.updatedAt !== 'number') {
230
- throw new Error('position-state-store: missing createdAt/updatedAt');
231
- }
232
- return raw;
233
- }
234
- }
235
- function isRecord(v) {
236
- return typeof v === 'object' && v !== null && !Array.isArray(v);
237
- }
@@ -1,70 +0,0 @@
1
- import type { BinancePublicApi } from '../ccxt/binance-public.js';
2
- import type { IExchangeAdapter } from '../exchange-adapter.js';
3
- import type { AutoCaptureContext } from '../ingest/position-auto-capture.js';
4
- import type { TradingOperationLock } from '../lifecycle/trading-operation-lock.js';
5
- import type { Wave9LiveSymbolOwnershipCheck } from '../wave9/live-symbol-ownership.js';
6
- export interface ProposalDecisionListenerOptions {
7
- baseUrl: string;
8
- ingestToken: string;
9
- userId: string;
10
- adapter: IExchangeAdapter;
11
- binanceApi: BinancePublicApi;
12
- autoCapture?: AutoCaptureContext;
13
- /** Shared mutation serialization and durable Wave 9 ownership check for
14
- * listener-side approved-order execution. */
15
- operationLock?: TradingOperationLock;
16
- checkWave9LiveSymbolOwnership?: Wave9LiveSymbolOwnershipCheck;
17
- /** Active poll interval — used while there are pending proposals (or the
18
- * previous tick fetched any). Default 3 s. Keeps approval-to-fire latency
19
- * low when the operator is actively working through proposals. */
20
- pollIntervalMs?: number;
21
- /** Idle poll interval — used after a tick returns zero pending proposals.
22
- * Default 15 s. Cuts the constant-warm pressure on the webapp DB by ~5x
23
- * during idle stretches (no approvals queued). Reset to active on the
24
- * next non-empty tick. 15 s is well within the shortest hard-expiry
25
- * bucket (90 s momentum) even allowing for operator decision time. */
26
- pollIntervalIdleMs?: number;
27
- /** Maximum |markPrice − proposedEntry| / |proposedEntry − stopPrice|.
28
- * Default 0.3 per Locked Decision #6. */
29
- driftAbandonR?: number;
30
- /** Per-attempt request timeout for HTTP calls to the webapp. */
31
- requestTimeoutMs?: number;
32
- fetchImpl?: typeof fetch;
33
- }
34
- export interface ProposalDecisionListenerHealth {
35
- running: boolean;
36
- ticksTotal: number;
37
- ticksWithFires: number;
38
- firesAttempted: number;
39
- firesSucceeded: number;
40
- firesAbandonedDrift: number;
41
- firesFailedTrading: number;
42
- patchFailures: number;
43
- pollFailures: number;
44
- lastTickAt: string | null;
45
- }
46
- export declare class ProposalDecisionListener {
47
- private readonly opts;
48
- private timer;
49
- private inFlight;
50
- /** Current scheduling interval. Starts at active (so the first tick after
51
- * start() fires promptly even if the queue is empty); switches to idle
52
- * after any tick that finds zero pending; resets to active on any tick
53
- * that finds ≥1 pending. */
54
- private currentIntervalMs;
55
- private health;
56
- constructor(options: ProposalDecisionListenerOptions);
57
- /** Begin the poll loop. Idempotent — subsequent calls are no-ops while
58
- * the listener is already running. */
59
- start(): void;
60
- /** Stop the poll loop. If a tick is in flight, awaits its completion so
61
- * the PATCH back to the webapp lands before the process exits. */
62
- stop(): Promise<void>;
63
- getHealth(): ProposalDecisionListenerHealth;
64
- private scheduleNextTick;
65
- private runTick;
66
- private tick;
67
- private fetchPending;
68
- private firePending;
69
- private patchResult;
70
- }
@@ -1,292 +0,0 @@
1
- // ProposalDecisionListener — background poller that fires operator-approved
2
- // proposals via the existing create_order backend path.
3
- //
4
- // Phase B implementation: polls GET /api/internal/proposed_orders/pending-decisions
5
- // at config.pollIntervalMs (default 3 sec). For each approved-but-unfired row:
6
- // 1. Drift abandon — if mark price has moved more than ±0.3 R from the
7
- // proposed entry since the proposal was created, fail with a transparent
8
- // `fireError` rather than firing into a different setup.
9
- // 2. Fire via createOrderTool — same backend function the toggle-off path
10
- // calls directly. Reuses the pre-trade risk gate, bracket attach, and
11
- // auto-capture entry-row write.
12
- // 3. PATCH /fire-result with either firedOrderId or fireError. Fired-once
13
- // idempotency lives in the DB constraint (status='approved' AND
14
- // fired_order_id IS NULL filter).
15
- //
16
- // Started by index.ts only when config.approval.mode === 'per_trade' AND
17
- // ingest credentials are present. Drained at shutdown so an in-flight fire
18
- // completes its PATCH before the process exits.
19
- //
20
- // Why polling and not relay events: simpler — no skill <-> plugin event-bus
21
- // changes needed. 3-sec poll is well under the latency a human approval flow
22
- // tolerates. Refactor to SSE/relay-push only if measurement shows the poll
23
- // load is meaningful (very unlikely — ~3 req/s per user is negligible).
24
- //
25
- // See docs/APPROVAL_MODE_DESIGN.md §2 (architecture) + §7.3 (re-validation) +
26
- // §10 failure matrix.
27
- import { logger, formatError } from '../logger.js';
28
- import { createOrderTool } from '../tools/create-order.js';
29
- const TAG = 'proposal-decision-listener';
30
- export class ProposalDecisionListener {
31
- opts;
32
- timer = null;
33
- inFlight = null;
34
- /** Current scheduling interval. Starts at active (so the first tick after
35
- * start() fires promptly even if the queue is empty); switches to idle
36
- * after any tick that finds zero pending; resets to active on any tick
37
- * that finds ≥1 pending. */
38
- currentIntervalMs;
39
- health = {
40
- running: false,
41
- ticksTotal: 0,
42
- ticksWithFires: 0,
43
- firesAttempted: 0,
44
- firesSucceeded: 0,
45
- firesAbandonedDrift: 0,
46
- firesFailedTrading: 0,
47
- patchFailures: 0,
48
- pollFailures: 0,
49
- lastTickAt: null,
50
- };
51
- constructor(options) {
52
- this.opts = {
53
- baseUrl: options.baseUrl.replace(/\/+$/, ''),
54
- ingestToken: options.ingestToken,
55
- userId: options.userId,
56
- adapter: options.adapter,
57
- binanceApi: options.binanceApi,
58
- autoCapture: options.autoCapture,
59
- operationLock: options.operationLock,
60
- checkWave9LiveSymbolOwnership: options.checkWave9LiveSymbolOwnership,
61
- pollIntervalMs: options.pollIntervalMs ?? 3_000,
62
- pollIntervalIdleMs: options.pollIntervalIdleMs ?? 15_000,
63
- driftAbandonR: options.driftAbandonR ?? 0.3,
64
- requestTimeoutMs: options.requestTimeoutMs ?? 10_000,
65
- fetchImpl: options.fetchImpl ?? fetch,
66
- };
67
- this.currentIntervalMs = this.opts.pollIntervalMs;
68
- }
69
- /** Begin the poll loop. Idempotent — subsequent calls are no-ops while
70
- * the listener is already running. */
71
- start() {
72
- if (this.health.running)
73
- return;
74
- this.health.running = true;
75
- logger.info(TAG, `Listener started — polling ${this.opts.baseUrl}/api/internal/proposed_orders/pending-decisions (active ${this.opts.pollIntervalMs} ms / idle ${this.opts.pollIntervalIdleMs} ms; userId=${this.opts.userId.slice(0, 8)}…)`);
76
- this.scheduleNextTick();
77
- }
78
- /** Stop the poll loop. If a tick is in flight, awaits its completion so
79
- * the PATCH back to the webapp lands before the process exits. */
80
- async stop() {
81
- this.health.running = false;
82
- if (this.timer) {
83
- clearTimeout(this.timer);
84
- this.timer = null;
85
- }
86
- if (this.inFlight) {
87
- try {
88
- await this.inFlight;
89
- }
90
- catch { /* tick errors are logged inside tick() */ }
91
- }
92
- logger.info(TAG, 'Listener stopped');
93
- }
94
- getHealth() {
95
- return { ...this.health };
96
- }
97
- // ---- Internals ----
98
- scheduleNextTick() {
99
- if (!this.health.running)
100
- return;
101
- this.timer = setTimeout(() => {
102
- void this.runTick();
103
- }, this.currentIntervalMs);
104
- }
105
- async runTick() {
106
- if (!this.health.running)
107
- return;
108
- this.inFlight = this.tick().catch((err) => {
109
- logger.warn(TAG, `Tick threw (caught): ${formatError(err)}`);
110
- });
111
- try {
112
- await this.inFlight;
113
- }
114
- finally {
115
- this.inFlight = null;
116
- this.scheduleNextTick();
117
- }
118
- }
119
- async tick() {
120
- this.health.ticksTotal++;
121
- this.health.lastTickAt = new Date().toISOString();
122
- const pending = await this.fetchPending();
123
- if (pending.length === 0) {
124
- // Idle backoff — schedule next tick at the longer idle interval until
125
- // the queue becomes non-empty. This is the dominant cost-reduction lever
126
- // when Approval Mode is active but the operator is not currently
127
- // working through proposals. The next non-empty tick resets to active.
128
- this.currentIntervalMs = this.opts.pollIntervalIdleMs;
129
- return;
130
- }
131
- // Reset to fast polling so subsequent approvals fire with minimal latency.
132
- this.currentIntervalMs = this.opts.pollIntervalMs;
133
- this.health.ticksWithFires++;
134
- logger.info(TAG, `${pending.length} approved proposal(s) pending fire`);
135
- for (const p of pending) {
136
- try {
137
- await this.firePending(p);
138
- }
139
- catch (err) {
140
- // Defensive — firePending should already write a fireError PATCH on
141
- // any failure path. If something escapes, surface it loudly so the
142
- // operator can diagnose; the proposal will remain in approved state
143
- // and be retried on the next tick (idempotent because firedOrderId
144
- // is still NULL until a successful PATCH writes it).
145
- logger.error(TAG, `Unhandled exception firing proposal ${p.id} (will retry next tick): ${formatError(err)}`);
146
- }
147
- }
148
- }
149
- async fetchPending() {
150
- const url = `${this.opts.baseUrl}/api/internal/proposed_orders/pending-decisions`;
151
- try {
152
- const ac = new AbortController();
153
- const tid = setTimeout(() => ac.abort(), this.opts.requestTimeoutMs);
154
- let res;
155
- try {
156
- res = await this.opts.fetchImpl(url, {
157
- method: 'GET',
158
- headers: {
159
- authorization: `Bearer ${this.opts.ingestToken}`,
160
- 'x-user-id': this.opts.userId,
161
- },
162
- signal: ac.signal,
163
- });
164
- }
165
- finally {
166
- clearTimeout(tid);
167
- }
168
- if (!res.ok) {
169
- this.health.pollFailures++;
170
- logger.warn(TAG, `GET ${url} → ${res.status}`);
171
- return [];
172
- }
173
- const body = await res.json();
174
- return Array.isArray(body.proposals) ? body.proposals : [];
175
- }
176
- catch (err) {
177
- this.health.pollFailures++;
178
- logger.warn(TAG, `GET ${url} threw: ${formatError(err)}`);
179
- return [];
180
- }
181
- }
182
- async firePending(p) {
183
- this.health.firesAttempted++;
184
- // ---- 1. Drift abandon (Locked Decision #6) ----
185
- // Skip if we can't read a current price — better to let the trading path
186
- // surface the error than to silently abandon on a transient ticker miss.
187
- const lastPrice = await this.opts.adapter.getLastPrice(p.symbol).catch(() => null);
188
- if (lastPrice != null && Number.isFinite(lastPrice) && lastPrice > 0) {
189
- const rDistance = Math.abs(p.proposedEntry - p.stopPrice);
190
- if (rDistance > 0) {
191
- const driftR = Math.abs(lastPrice - p.proposedEntry) / rDistance;
192
- if (driftR > this.opts.driftAbandonR) {
193
- const msg = `price_drift: mark ${lastPrice} is ${driftR.toFixed(2)}R from proposed entry ${p.proposedEntry} (limit ${this.opts.driftAbandonR}R)`;
194
- logger.warn(TAG, `Abandoning proposal ${p.id} — ${msg}`);
195
- await this.patchResult(p.id, { fireError: msg });
196
- this.health.firesAbandonedDrift++;
197
- return;
198
- }
199
- }
200
- }
201
- // ---- 2. Fire via createOrderTool (same path toggle-off mode uses) ----
202
- // CRITICAL: do NOT pass proposalManager + userId here. The listener IS the
203
- // consumer of approved proposals; passing proposalManager would recursively
204
- // dual-write another proposal row for the same intent. The agent's path
205
- // dual-writes; the listener's path fires the underlying order.
206
- const result = await createOrderTool({
207
- symbol: p.symbol,
208
- side: p.side,
209
- type: p.orderType,
210
- amount: p.size,
211
- // For limit orders we honour the original proposed entry. For market,
212
- // the create_order tool reads the live ticker (per existing semantics).
213
- price: p.orderType === 'limit' ? p.proposedEntry : undefined,
214
- stopPrice: p.stopPrice,
215
- target_price: p.targetPrice,
216
- setup_type: p.setupType,
217
- thesis: p.thesis,
218
- regime: p.regime,
219
- regime_confidence: p.regimeConfidence,
220
- scorecard_verdict: p.scorecardVerdict,
221
- confluence_score: p.confluenceScore,
222
- }, {
223
- binanceApi: this.opts.binanceApi,
224
- adapter: this.opts.adapter,
225
- autoCapture: this.opts.autoCapture,
226
- operationLock: this.opts.operationLock,
227
- checkWave9LiveSymbolOwnership: this.opts.checkWave9LiveSymbolOwnership,
228
- // proposalManager + userId deliberately omitted — see above.
229
- });
230
- if ('error' in result) {
231
- // Trading-path rejection (risk gate, bracket attach failure, exchange
232
- // rejection, etc.). Surface to the operator via the proposal row.
233
- logger.warn(TAG, `Proposal ${p.id} fire rejected: ${result.error}`);
234
- await this.patchResult(p.id, { fireError: result.error });
235
- this.health.firesFailedTrading++;
236
- return;
237
- }
238
- if ('status' in result && result.status === 'pending_approval') {
239
- // Should be unreachable: the listener calls createOrderTool without
240
- // proposalManager, so the per_trade branch can't trigger. If it does
241
- // (config race or future refactor), surface as a fireError so we don't
242
- // silently lose the proposal.
243
- const msg = `unexpected pending_approval from listener-side fire (proposal_id=${result.proposal_id})`;
244
- logger.error(TAG, msg);
245
- await this.patchResult(p.id, { fireError: msg });
246
- this.health.firesFailedTrading++;
247
- return;
248
- }
249
- const firedOrderId = typeof result.id === 'string' ? result.id : `unknown-${Date.now()}`;
250
- logger.info(TAG, `Proposal ${p.id} fired → order ${firedOrderId}`);
251
- await this.patchResult(p.id, { firedOrderId });
252
- this.health.firesSucceeded++;
253
- }
254
- async patchResult(proposalId, body) {
255
- const url = `${this.opts.baseUrl}/api/internal/proposed_orders/${proposalId}/fire-result`;
256
- try {
257
- const ac = new AbortController();
258
- const tid = setTimeout(() => ac.abort(), this.opts.requestTimeoutMs);
259
- let res;
260
- try {
261
- res = await this.opts.fetchImpl(url, {
262
- method: 'PATCH',
263
- headers: {
264
- 'content-type': 'application/json',
265
- authorization: `Bearer ${this.opts.ingestToken}`,
266
- 'x-user-id': this.opts.userId,
267
- },
268
- body: JSON.stringify(body),
269
- signal: ac.signal,
270
- });
271
- }
272
- finally {
273
- clearTimeout(tid);
274
- }
275
- if (res.status === 409) {
276
- // Already-recorded race — listener double-fired but webapp's idempotency
277
- // guard caught the duplicate. Not an error.
278
- logger.info(TAG, `Proposal ${proposalId} fire-result already recorded (409, expected on retry)`);
279
- return;
280
- }
281
- if (!res.ok) {
282
- this.health.patchFailures++;
283
- logger.warn(TAG, `PATCH ${url} → ${res.status}`);
284
- return;
285
- }
286
- }
287
- catch (err) {
288
- this.health.patchFailures++;
289
- logger.warn(TAG, `PATCH ${url} threw: ${formatError(err)}`);
290
- }
291
- }
292
- }
@@ -1,76 +0,0 @@
1
- import { type SetupBucket } from './setup-buckets.js';
2
- /** Trade params + agent metadata composing a single proposal. Mirrors the
3
- * /api/internal/proposed_orders payload shape. */
4
- export interface ProposalRequest {
5
- symbol: string;
6
- side: 'buy' | 'sell';
7
- orderType: 'market' | 'limit';
8
- size: number;
9
- proposedEntry: number;
10
- stopPrice: number;
11
- targetPrice: number;
12
- riskUsd: number;
13
- thesis: string;
14
- setupType: string;
15
- regime: string;
16
- regimeConfidence: number;
17
- scorecardVerdict: string;
18
- confluenceScore: number;
19
- /** Phase C — when set, the named proposal is atomically marked `superseded`
20
- * by the webapp and the new row links back via supersedes_id. Use this when
21
- * the agent is modifying a still-pending proposal (e.g. after operator
22
- * discussion). Must reference a pending/discussing proposal owned by the
23
- * same user, or the supersede half is a no-op. */
24
- supersedesId?: string;
25
- /** 'shadow' = Phase A telemetry-only row (agent's create_order also fires
26
- * the real order synchronously). The webapp filters these out of the
27
- * operator UI so they don't appear as actionable cards. 'real' = Phase B/C
28
- * actionable proposal the operator decides on. Defaults to 'real' on the
29
- * webapp side if omitted. */
30
- origin?: 'shadow' | 'real';
31
- }
32
- export interface ProposalManagerOptions {
33
- baseUrl: string;
34
- ingestToken: string;
35
- fetchImpl?: typeof fetch;
36
- requestTimeoutMs?: number;
37
- maxAttempts?: number;
38
- baseBackoffMs?: number;
39
- backoffCapMs?: number;
40
- /** Override clock for tests. */
41
- now?: () => Date;
42
- /** Override UUID generator for tests. */
43
- uuid?: () => string;
44
- }
45
- export interface ProposalManagerHealth {
46
- inFlight: number;
47
- totalPosted: number;
48
- totalSucceeded: number;
49
- totalDroppedTerminal: number;
50
- totalDroppedRetriesExhausted: number;
51
- }
52
- /** Result of a propose() call. The proposal_uuid is generated synchronously
53
- * before any network I/O so the caller can correlate logs immediately. */
54
- export interface ProposeResult {
55
- proposalUuid: string;
56
- setupBucket: SetupBucket;
57
- hardExpiresAt: Date;
58
- }
59
- export declare class ProposalManager {
60
- private readonly opts;
61
- private inFlight;
62
- private totalPosted;
63
- private totalSucceeded;
64
- private totalDroppedTerminal;
65
- private totalDroppedRetriesExhausted;
66
- constructor(options: ProposalManagerOptions);
67
- /** Submit a proposal. Generates the proposal_uuid + computes the bucket
68
- * + hard expiry synchronously; the actual POST runs in the background.
69
- * Caller may correlate via the returned proposalUuid before the post lands. */
70
- propose(userId: string, req: ProposalRequest): ProposeResult;
71
- /** Await all in-flight POSTs. Used at shutdown so we don't lose proposals. */
72
- drain(): Promise<void>;
73
- getHealth(): ProposalManagerHealth;
74
- private run;
75
- private sleepBackoff;
76
- }