dexterm-cli 0.1.6 → 0.1.7

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 (331) hide show
  1. package/dist/packages/agents/src/schema.js +22 -1
  2. package/dist/packages/agents/src/story.js +11 -2
  3. package/dist/packages/agents/src/tiers.js +27 -2
  4. package/dist/packages/agents/src/tools.js +30 -2
  5. package/dist/packages/autotrade/assets/exit-profile.schema.json +492 -0
  6. package/dist/packages/autotrade/assets/profiles/moonbag.json +46 -0
  7. package/dist/packages/autotrade/assets/profiles/runner.json +88 -0
  8. package/dist/packages/autotrade/assets/profiles/scalp.json +88 -0
  9. package/dist/packages/autotrade/assets/profiles/swing.json +88 -0
  10. package/dist/packages/autotrade/assets/strategies/moonbag.json +101 -0
  11. package/dist/packages/autotrade/assets/strategies/runner.json +101 -0
  12. package/dist/packages/autotrade/assets/strategies/sample-dip-ladder.json +188 -0
  13. package/dist/packages/autotrade/assets/strategies/scalp.json +98 -0
  14. package/dist/packages/autotrade/assets/strategies/swing.json +97 -0
  15. package/dist/packages/autotrade/assets/strategies/yolo.json +157 -0
  16. package/dist/packages/autotrade/assets/tapes/yolo-rehearsal.json +1 -0
  17. package/dist/packages/autotrade/src/account.js +74 -0
  18. package/dist/packages/autotrade/src/backtest.js +357 -0
  19. package/dist/packages/autotrade/src/basis-text.js +32 -0
  20. package/dist/packages/autotrade/src/chat/approvals.js +484 -0
  21. package/dist/packages/autotrade/src/chat/audit.js +140 -0
  22. package/dist/packages/autotrade/src/chat/config.js +93 -0
  23. package/dist/packages/autotrade/src/chat/connector.js +24 -0
  24. package/dist/packages/autotrade/src/chat/control.js +103 -0
  25. package/dist/packages/autotrade/src/chat/fake.js +100 -0
  26. package/dist/packages/autotrade/src/chat/format.js +71 -0
  27. package/dist/packages/autotrade/src/chat/hub.js +187 -0
  28. package/dist/packages/autotrade/src/chat/index.js +18 -0
  29. package/dist/packages/autotrade/src/chat/notify.js +292 -0
  30. package/dist/packages/autotrade/src/chat/pairing.js +46 -0
  31. package/dist/packages/autotrade/src/chat/redact.js +48 -0
  32. package/dist/packages/autotrade/src/chat/secrets.js +99 -0
  33. package/dist/packages/autotrade/src/chat/service.js +248 -0
  34. package/dist/packages/autotrade/src/chat/telegram.js +290 -0
  35. package/dist/packages/autotrade/src/desk-executor.js +188 -0
  36. package/dist/packages/autotrade/src/engine.js +387 -0
  37. package/dist/packages/autotrade/src/execution-port.js +97 -0
  38. package/dist/packages/autotrade/src/fleet-config.js +169 -0
  39. package/dist/packages/autotrade/src/fleet-control.js +276 -0
  40. package/dist/packages/autotrade/src/fleet.js +639 -0
  41. package/dist/packages/autotrade/src/index.js +53 -0
  42. package/dist/packages/autotrade/src/ledger.js +108 -0
  43. package/dist/packages/autotrade/src/live-source.js +182 -0
  44. package/dist/packages/autotrade/src/monitor-daemon.js +715 -0
  45. package/dist/packages/autotrade/src/monitor.js +190 -0
  46. package/dist/packages/autotrade/src/ollama-sessions.js +137 -0
  47. package/dist/packages/autotrade/src/paper-accounts.js +72 -0
  48. package/dist/packages/autotrade/src/replay.js +198 -0
  49. package/dist/packages/autotrade/src/runner-config.js +99 -0
  50. package/dist/packages/autotrade/src/runner.js +872 -0
  51. package/dist/packages/autotrade/src/safety.js +243 -0
  52. package/dist/packages/autotrade/src/session.js +269 -0
  53. package/dist/packages/autotrade/src/sessions.js +503 -0
  54. package/dist/packages/autotrade/src/store.js +250 -0
  55. package/dist/packages/autotrade/src/strategy.js +256 -0
  56. package/dist/packages/autotrade/src/trade-ledger.js +241 -0
  57. package/dist/packages/autotrade/src/yolo.js +140 -0
  58. package/dist/packages/cli/assets/claude/analyst-system.md +4 -4
  59. package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +1 -1
  60. package/dist/packages/cli/src/ai-cmd.js +412 -0
  61. package/dist/packages/cli/src/analyst/backend.js +82 -15
  62. package/dist/packages/cli/src/analyst/codex.js +14 -9
  63. package/dist/packages/cli/src/analyst/ollama.js +263 -0
  64. package/dist/packages/cli/src/analyst/session.js +5 -2
  65. package/dist/packages/cli/src/app-help-gen.js +44 -8
  66. package/dist/packages/cli/src/autotrade-cmd/audit.js +57 -0
  67. package/dist/packages/cli/src/autotrade-cmd/backtest.js +199 -0
  68. package/dist/packages/cli/src/autotrade-cmd/flatten.js +64 -0
  69. package/dist/packages/cli/src/autotrade-cmd/fleet.js +397 -0
  70. package/dist/packages/cli/src/autotrade-cmd/requests.js +79 -0
  71. package/dist/packages/cli/src/autotrade-cmd/run.js +413 -0
  72. package/dist/packages/cli/src/autotrade-cmd/stop.js +76 -0
  73. package/dist/packages/cli/src/autotrade-cmd/strategies.js +198 -0
  74. package/dist/packages/cli/src/autotrade-cmd/strategy-control.js +174 -0
  75. package/dist/packages/cli/src/autotrade-cmd/telegram-host.js +101 -0
  76. package/dist/packages/cli/src/autotrade-cmd.js +168 -0
  77. package/dist/packages/cli/src/display.js +156 -17
  78. package/dist/packages/cli/src/doctor.js +62 -3
  79. package/dist/packages/cli/src/export.js +10 -2
  80. package/dist/packages/cli/src/index.js +1 -1
  81. package/dist/packages/cli/src/ledger-cmd.js +288 -0
  82. package/dist/packages/cli/src/live/chart-fills.js +46 -0
  83. package/dist/packages/cli/src/live/index.js +23 -89
  84. package/dist/packages/cli/src/live/screens/token-live.js +9 -6
  85. package/dist/packages/cli/src/live/trade.js +12 -457
  86. package/dist/packages/cli/src/live/watchlist.js +1 -1
  87. package/dist/packages/cli/src/main.js +147 -190
  88. package/dist/packages/cli/src/mcp-cmd.js +7 -1
  89. package/dist/packages/cli/src/plan-cmd.js +1 -1
  90. package/dist/packages/cli/src/pnl-app.js +31 -21
  91. package/dist/packages/cli/src/pnl-card.js +158 -21
  92. package/dist/packages/cli/src/popup.js +22 -6
  93. package/dist/packages/cli/src/record-cmd.js +141 -20
  94. package/dist/packages/cli/src/screens/agent-hud.js +34 -2
  95. package/dist/packages/cli/src/screens/analyst-session.js +7 -4
  96. package/dist/packages/cli/src/screens/analyst.js +3 -2
  97. package/dist/packages/cli/src/screens/autotrade-keys.js +169 -0
  98. package/dist/packages/cli/src/screens/autotrade-proposals.js +123 -0
  99. package/dist/packages/cli/src/screens/autotrade-screen.js +725 -0
  100. package/dist/packages/cli/src/screens/autotrade-ui.js +640 -0
  101. package/dist/packages/cli/src/screens/autotrade-worker.js +89 -0
  102. package/dist/packages/cli/src/screens/brain.js +37 -11
  103. package/dist/packages/cli/src/screens/overlay.js +5 -2
  104. package/dist/packages/cli/src/screens/plans.js +5 -17
  105. package/dist/packages/cli/src/screens/pnl-chip.js +9 -8
  106. package/dist/packages/cli/src/screens/positions.js +6 -28
  107. package/dist/packages/cli/src/screens/ticket.js +38 -205
  108. package/dist/packages/cli/src/screens/token.js +3 -3
  109. package/dist/packages/cli/src/state.js +25 -19
  110. package/dist/packages/cli/src/telegram-cmd.js +451 -0
  111. package/dist/packages/cli/src/trade.js +3 -128
  112. package/dist/packages/cli/src/version.js +1 -1
  113. package/dist/packages/cli/src/wallet-cmd.js +39 -340
  114. package/dist/packages/cli/src/wallet-command.js +8 -11
  115. package/dist/packages/cli/src/widgets.js +0 -12
  116. package/dist/packages/custom/src/config.js +20 -2
  117. package/dist/packages/custom/src/schema.js +35 -10
  118. package/dist/packages/custom/src/workspace.js +3 -3
  119. package/dist/packages/data/src/basis.js +191 -0
  120. package/dist/packages/data/src/detail.js +53 -2
  121. package/dist/packages/data/src/index.js +0 -14
  122. package/dist/packages/data/src/store.js +14 -5
  123. package/dist/packages/data/src/trade/agent/paper-desk.js +228 -16
  124. package/dist/packages/data/src/trade/agent/rendezvous.js +3 -2
  125. package/dist/packages/data/src/trade/bridge.js +4 -102
  126. package/dist/packages/data/src/trade/ledger/export.js +101 -0
  127. package/dist/packages/data/src/trade/ledger/file.js +135 -0
  128. package/dist/packages/data/src/trade/ledger/fold.js +191 -0
  129. package/dist/packages/data/src/trade/ledger/index.js +9 -0
  130. package/dist/packages/data/src/trade/ledger/schema.js +83 -0
  131. package/dist/packages/data/src/trade/ledger/sources.js +307 -0
  132. package/dist/packages/data/src/trade/ledger/stats.js +123 -0
  133. package/dist/packages/data/src/trade/ledger/tags.js +116 -0
  134. package/dist/packages/data/src/trade/ledger/view.js +51 -0
  135. package/dist/packages/data/src/trade/plans/index.js +0 -1
  136. package/dist/packages/data/src/trade/plans/service.js +3 -27
  137. package/dist/packages/mcp/assets/kb/app-help/autotrade-chat.md +48 -0
  138. package/dist/packages/mcp/assets/kb/app-help/autotrade-parallel.md +42 -0
  139. package/dist/packages/mcp/assets/kb/app-help/autotrade-runner.md +35 -0
  140. package/dist/packages/mcp/assets/kb/app-help/autotrade-stop.md +37 -0
  141. package/dist/packages/mcp/assets/kb/app-help/autotrade-strategies.md +35 -0
  142. package/dist/packages/mcp/assets/kb/app-help/autotrade-telegram.md +40 -0
  143. package/dist/packages/mcp/assets/kb/app-help/chart-trade-markers.md +42 -0
  144. package/dist/packages/mcp/assets/kb/app-help/link-a-wallet.md +4 -10
  145. package/dist/packages/mcp/assets/kb/app-help/live-trading.md +38 -0
  146. package/dist/packages/mcp/assets/kb/app-help/live-yolo.md +34 -0
  147. package/dist/packages/mcp/assets/kb/app-help/order-plans.md +1 -1
  148. package/dist/packages/mcp/assets/kb/app-help/price-or-marketcap.md +5 -2
  149. package/dist/packages/mcp/assets/kb/app-help/screen-analyst.md +3 -0
  150. package/dist/packages/mcp/assets/kb/app-help/screen-autotrade.md +217 -0
  151. package/dist/packages/mcp/assets/kb/app-help/screen-kol.md +3 -0
  152. package/dist/packages/mcp/assets/kb/app-help/screen-newpairs.md +3 -0
  153. package/dist/packages/mcp/assets/kb/app-help/screen-positions.md +3 -0
  154. package/dist/packages/mcp/assets/kb/app-help/screen-screener.md +3 -0
  155. package/dist/packages/mcp/assets/kb/app-help/screen-token.md +3 -0
  156. package/dist/packages/mcp/assets/kb/app-help/screen-trending.md +3 -0
  157. package/dist/packages/mcp/assets/kb/app-help/screen-watchlist.md +3 -0
  158. package/dist/packages/mcp/assets/kb/app-help/standing-mandates.md +1 -1
  159. package/dist/packages/mcp/assets/kb/app-help/trade-ledger.md +54 -0
  160. package/dist/packages/mcp/assets/kb/app-help/use-local-model.md +38 -0
  161. package/dist/packages/mcp/assets/kb/docs/docs-agents-agent-paper-trading.md +4 -1
  162. package/dist/packages/mcp/assets/kb/docs/docs-agents-reading-your-trade-ledger.md +31 -0
  163. package/dist/packages/mcp/assets/kb/docs/docs-agents-untrusted-by-default.md +1 -1
  164. package/dist/packages/mcp/assets/kb/docs/docs-analyst-if-claude-is-missing.md +1 -1
  165. package/dist/packages/mcp/assets/kb/docs/docs-analyst-use-a-local-model-instead.md +27 -0
  166. package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-it-sees.md +2 -0
  167. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-backtests-and-their-limits.md +56 -0
  168. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-change-a-strategy-by-chat.md +49 -0
  169. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-checking-the-record-of-a-run.md +28 -0
  170. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-comparing-them.md +41 -0
  171. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-exits-and-wakes.md +76 -0
  172. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-how-a-stop-reaches-the-runner.md +32 -0
  173. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-on-the-q-screen.md +37 -0
  174. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-one-strategy-or-all-of-them.md +35 -0
  175. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-paper-accounts.md +50 -0
  176. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-presets.md +37 -0
  177. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-running-it-all-day.md +31 -0
  178. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-sessions-and-their-limits.md +31 -0
  179. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-several-strategies-at-once.md +33 -0
  180. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-stopping-it.md +35 -0
  181. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-strategies-and-presets.md +34 -0
  182. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-autotrade-json-file.md +48 -0
  183. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-heartbeat.md +27 -0
  184. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-run-file-and-the-heartbeat.md +34 -0
  185. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-runner-and-candidate-sessions.md +45 -0
  186. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-each-session-shows-first.md +31 -0
  187. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-costs-claude-usage-per-session.md +58 -0
  188. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-is-paper-self-directed.md +43 -0
  189. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-will-not-do.md +31 -0
  190. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-which-account-day-caps-and-the-usage-guard.md +44 -0
  191. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-your-strategies.md +37 -0
  192. package/dist/packages/mcp/assets/kb/docs/docs-autotrade.md +22 -0
  193. package/dist/packages/mcp/assets/kb/docs/docs-beginners-before-any-experimental-trading.md +2 -2
  194. package/dist/packages/mcp/assets/kb/docs/docs-beginners.md +1 -1
  195. package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-markers.md +30 -0
  196. package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-y-axis.md +1 -1
  197. package/dist/packages/mcp/assets/kb/docs/docs-configuration-environment-variables.md +4 -1
  198. package/dist/packages/mcp/assets/kb/docs/docs-configuration-files-on-disk.md +1 -0
  199. package/dist/packages/mcp/assets/kb/docs/docs-configuration-headless-recorder-dexterm-record.md +3 -1
  200. package/dist/packages/mcp/assets/kb/docs/docs-configuration-price-display-mode.md +8 -6
  201. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-2-the-one-key-mirror-ticket-a-proposal.md +1 -1
  202. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-3-capped-auto-mirror-default-off-less.md +1 -1
  203. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-what-is-proven-what-is-not.md +1 -1
  204. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading.md +1 -1
  205. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-recorded-history-and-retention.md +36 -0
  206. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-sources.md +1 -0
  207. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-first-run.md +1 -1
  208. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-install.md +3 -3
  209. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-requirements.md +1 -1
  210. package/dist/packages/mcp/assets/kb/docs/docs-getting-started.md +1 -1
  211. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-changed-in-0-1-7.md +26 -0
  212. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-stopping.md +28 -0
  213. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-the-short-version.md +34 -0
  214. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-using-a-trading-bot-with-dexterm.md +33 -0
  215. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does-not-do.md +30 -0
  216. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does.md +29 -0
  217. package/dist/packages/mcp/assets/kb/docs/docs-live-trading.md +23 -0
  218. package/dist/packages/mcp/assets/kb/docs/docs-ollama-another-machine.md +28 -0
  219. package/dist/packages/mcp/assets/kb/docs/docs-ollama-autotrade-on-a-local-model.md +29 -0
  220. package/dist/packages/mcp/assets/kb/docs/docs-ollama-check-your-model-dexterm-ai-probe.md +38 -0
  221. package/dist/packages/mcp/assets/kb/docs/docs-ollama-how-we-checked.md +27 -0
  222. package/dist/packages/mcp/assets/kb/docs/docs-ollama-models-without-tool-calling.md +32 -0
  223. package/dist/packages/mcp/assets/kb/docs/docs-ollama-pick-the-engine-globally-or-per-surface.md +43 -0
  224. package/dist/packages/mcp/assets/kb/docs/docs-ollama-restriction-profiles.md +35 -0
  225. package/dist/packages/mcp/assets/kb/docs/docs-ollama-set-it-up-in-two-minutes.md +39 -0
  226. package/dist/packages/mcp/assets/kb/docs/docs-ollama-troubleshooting.md +35 -0
  227. package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-runs-on-a-local-model.md +39 -0
  228. package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-stays-outside-the-model.md +36 -0
  229. package/dist/packages/mcp/assets/kb/docs/docs-ollama-which-model.md +38 -0
  230. package/dist/packages/mcp/assets/kb/docs/docs-ollama-your-own-agent-on-the-local-model.md +28 -0
  231. package/dist/packages/mcp/assets/kb/docs/docs-ollama.md +28 -0
  232. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-letting-an-agent-paper-trade-experimental.md +3 -4
  233. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet-read-only.md +30 -0
  234. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-order-plans-and-standing-mandates.md +3 -4
  235. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-panic.md +4 -7
  236. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-paper-only-mandates.md +6 -7
  237. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-pnl-cards.md +7 -7
  238. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-safety-model.md +34 -0
  239. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-ticket.md +3 -4
  240. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-trade-ledger.md +42 -0
  241. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-wallet.md +4 -5
  242. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-trade-moments.md +4 -5
  243. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading.md +4 -5
  244. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-buy-and-sell-markers.md +37 -0
  245. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-what-it-shows.md +2 -1
  246. package/dist/packages/mcp/assets/kb/docs/docs-screens-autotrade-paper.md +26 -0
  247. package/dist/packages/mcp/assets/kb/docs/docs-screens-order-plans.md +1 -1
  248. package/dist/packages/mcp/assets/kb/docs/docs-screens-token-screen.md +2 -0
  249. package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-brain-view-and-the-pnl-chip.md +1 -1
  250. package/dist/packages/mcp/assets/kb/docs/docs-telegram-approve-one-tap-entries.md +50 -0
  251. package/dist/packages/mcp/assets/kb/docs/docs-telegram-control-the-commands.md +43 -0
  252. package/dist/packages/mcp/assets/kb/docs/docs-telegram-if-something-goes-wrong.md +30 -0
  253. package/dist/packages/mcp/assets/kb/docs/docs-telegram-notify-what-reaches-your-phone.md +41 -0
  254. package/dist/packages/mcp/assets/kb/docs/docs-telegram-set-it-up.md +47 -0
  255. package/dist/packages/mcp/assets/kb/docs/docs-telegram-the-record.md +26 -0
  256. package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-is.md +33 -0
  257. package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-will-not-do.md +31 -0
  258. package/dist/packages/mcp/assets/kb/docs/docs-telegram.md +23 -0
  259. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-common-questions.md +1 -1
  260. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-doctor-lines.md +4 -0
  261. package/dist/packages/mcp/assets/kb/docs/docs-voice-linux-and-windows.md +1 -1
  262. package/dist/packages/mcp/assets/kb/docs/docs-voice.md +1 -1
  263. package/dist/packages/mcp/assets/kb/docs/docs-yolo-1-replay-it-on-your-own-history.md +42 -0
  264. package/dist/packages/mcp/assets/kb/docs/docs-yolo-2-run-it-on-paper.md +34 -0
  265. package/dist/packages/mcp/assets/kb/docs/docs-yolo-3-watch-it-and-stop-it.md +32 -0
  266. package/dist/packages/mcp/assets/kb/docs/docs-yolo-the-rules.md +37 -0
  267. package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-is.md +34 -0
  268. package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-will-not-do.md +31 -0
  269. package/dist/packages/mcp/assets/kb/docs/docs-yolo.md +26 -0
  270. package/dist/packages/mcp/assets/kb/entries/autotrade.md +38 -0
  271. package/dist/packages/mcp/src/app-help.js +1 -1
  272. package/dist/packages/mcp/src/autotrade-tools.js +944 -0
  273. package/dist/packages/mcp/src/backtest-requests.js +71 -0
  274. package/dist/packages/mcp/src/engine/config.js +159 -0
  275. package/dist/packages/mcp/src/engine/index.js +10 -0
  276. package/dist/packages/mcp/src/engine/loop.js +101 -0
  277. package/dist/packages/mcp/src/engine/mcp-client.js +123 -0
  278. package/dist/packages/mcp/src/engine/ollama.js +258 -0
  279. package/dist/packages/mcp/src/engine/probe.js +110 -0
  280. package/dist/packages/mcp/src/engine/reason.js +35 -0
  281. package/dist/packages/mcp/src/engine/restrictions.js +111 -0
  282. package/dist/packages/mcp/src/index.js +7 -1
  283. package/dist/packages/mcp/src/ledger-tools.js +346 -0
  284. package/dist/packages/mcp/src/paper-agent.js +2 -0
  285. package/dist/packages/mcp/src/server.js +127 -19
  286. package/dist/packages/packs/src/backtest.js +3 -1
  287. package/dist/packages/popup/src/pages/chart-lib.js +134 -21
  288. package/dist/packages/popup/src/pages/chart.css +9 -0
  289. package/dist/packages/popup/src/pages/chart.html +3 -1
  290. package/dist/packages/popup/src/pages/chart.js +104 -7
  291. package/dist/packages/popup/src/protocol.js +2 -0
  292. package/dist/packages/popup/src/server.js +4 -0
  293. package/dist/packages/recorder/src/index.js +2 -0
  294. package/dist/packages/recorder/src/recorder.js +63 -6
  295. package/dist/packages/recorder/src/retention.js +100 -0
  296. package/dist/packages/recorder/src/schema.js +34 -1
  297. package/dist/packages/recorder/src/ticks.js +237 -0
  298. package/dist/packages/tui/src/index.js +1 -0
  299. package/dist/packages/tui/src/keymap.js +21 -1
  300. package/dist/packages/tui/src/markers.js +219 -0
  301. package/dist/packages/tui/src/widgets.js +149 -2
  302. package/package.json +2 -1
  303. package/dist/packages/data/src/trade/caps.js +0 -323
  304. package/dist/packages/data/src/trade/executor.js +0 -933
  305. package/dist/packages/data/src/trade/plans/executor-live.js +0 -220
  306. package/dist/packages/data/src/trade/rpc-exec.js +0 -229
  307. package/dist/packages/data/src/trade/signer/client.js +0 -197
  308. package/dist/packages/data/src/trade/signer/fast-wallet.js +0 -154
  309. package/dist/packages/data/src/trade/signer/host.js +0 -97
  310. package/dist/packages/data/src/trade/signer/main.js +0 -121
  311. package/dist/packages/data/src/trade/signer/probe-builder.js +0 -85
  312. package/dist/packages/data/src/trade/signer/protocol.js +0 -92
  313. package/dist/packages/data/src/trade/signer/service.js +0 -400
  314. package/dist/packages/data/src/trade/signer/sol-usd-feed.js +0 -98
  315. package/dist/packages/data/src/trade/sol-usd.js +0 -86
  316. package/dist/packages/data/src/trade/swap-build.js +0 -108
  317. package/dist/packages/data/src/trade/token-delta.js +0 -201
  318. package/dist/packages/data/vendor/solana-web3/LICENSE +0 -20
  319. package/dist/packages/data/vendor/solana-web3/NOTICE.md +0 -13
  320. package/dist/packages/data/vendor/solana-web3/index.iife.min.js +0 -20
  321. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-a-live-ticket.md +0 -42
  322. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-before-you-press-size-vs-caps.md +0 -34
  323. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-devnet-signer-mainnet-token.md +0 -35
  324. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-jupiter-rate-limits.md +0 -33
  325. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet.md +0 -32
  326. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-live-trading-devnet-first.md +0 -30
  327. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-mainnet.md +0 -31
  328. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-live-fire-path-devnet-the-fast-wallet.md +0 -41
  329. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-signer-process.md +0 -34
  330. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-what-the-live-path-keeps.md +0 -37
  331. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-your-first-live-trade.md +0 -41
@@ -5,14 +5,14 @@
5
5
  // feed. Both go through the data layer's rate limiter + budget meter; neither signs, holds a key, or
6
6
  // sends a transaction — the only trade op is `executor.execute`, a TradeExecutor the UI holds behind
7
7
  // an interface (acceptance (d)).
8
- import { SOL_MINT, lamportsToSol, rawToTokens, positionPnl, shortPubkey, LiveLedger, withPriority, } from '../../../data/src/index.js';
9
- import { openTicket, ticketKey, toOrder, orderValid, buyNotionalSol, capPreflight, devnetMintWarning, DEFAULT_TYPEBACK_THRESHOLD_SOL, } from "../trade.js";
10
- /** task-1368: bounds on the signer's "retry in Ns" before the ticket retries a rate-limited plan by itself. */
8
+ import { SOL_MINT, lamportsToSol, rawToTokens, positionPnl, withPriority, } from '../../../data/src/index.js';
9
+ import { openTicket, ticketKey, toOrder, orderValid, buyNotionalSol, DEFAULT_TYPEBACK_THRESHOLD_SOL, } from "../trade.js";
10
+ /** task-1368: bounds on a rate-limit wait ("retry in Ns"). */
11
11
  export const RETRY_MIN_MS = 1_000;
12
12
  export const RETRY_MAX_MS = 120_000;
13
- /** When the signer said rate-limited but gave no wait (an older signer), retry after this. */
13
+ /** When a rate-limit error gave no wait, assume this. */
14
14
  export const RETRY_DEFAULT_MS = 10_000;
15
- /** The signer's rate-limit refusal, if that is what `e` is: the honest wait and its own line. */
15
+ /** A rate-limit error, if that is what `e` is: the honest wait and its own line. */
16
16
  export function rateLimitOf(e) {
17
17
  if (!(e instanceof Error))
18
18
  return null;
@@ -25,14 +25,6 @@ export function rateLimitOf(e) {
25
25
  const ms = typeof given === 'number' && Number.isFinite(given) && given > 0 ? given : parsed ? Number(parsed[1]) * 1000 : RETRY_DEFAULT_MS;
26
26
  return { ms: Math.min(RETRY_MAX_MS, Math.max(RETRY_MIN_MS, ms)), message: plain };
27
27
  }
28
- /** A signer QuoteView → the SwapQuote shape the preview fill and the ticket already understand. */
29
- export function quoteFromView(v) {
30
- return {
31
- inputMint: v.inputMint, outputMint: v.outputMint, inAmount: BigInt(v.inAmountRaw), outAmount: BigInt(v.outAmountRaw), otherAmountThreshold: BigInt(v.minOutRaw),
32
- mode: 'ExactIn', slippageBps: v.slippageBps, priceImpactPct: v.priceImpactPct, route: [...v.route], platformFeeBps: null, platformFeeAmount: null,
33
- usdValue: v.usdValue, contextSlot: null, source: 'jupiter-swap', fetchedAt: v.fetchedAt,
34
- };
35
- }
36
28
  /** Default bound on the confirm-time quote: after this the ticket errors instead of hanging. */
37
29
  export const CONFIRM_QUOTE_TIMEOUT_MS = 8_000;
38
30
  /** A live PAPER trade ticket over one mint. */
@@ -57,21 +49,7 @@ export class TradeTicketLive {
57
49
  confirmAbort = null;
58
50
  /** Set when the user cancels (esc) during `filling`, so confirm() leaves the ticket in editing. */
59
51
  cancelled = false;
60
- // ---- LIVE (task-1328)
61
- liveDeps;
62
- livePositionRaw;
63
52
  onSettled;
64
- signerStatus = null;
65
- livePlan = null;
66
- liveOutcome = null;
67
- liveError = null;
68
- liveProbe = false;
69
- planSeq = 0;
70
- // ---- task-1368: rate-limited plan → wait + auto-retry (never an error phase); the signer's SOL/USD for the preflight
71
- liveRetryAt = null;
72
- liveRetryMsg = null;
73
- retryTimer = null;
74
- liveSolUsd = null;
75
53
  constructor(dl, wallet, exec, seed, opts = {}) {
76
54
  this.dl = dl;
77
55
  this.wallet = wallet;
@@ -80,8 +58,6 @@ export class TradeTicketLive {
80
58
  this.onChange = opts.onChange ?? (() => { });
81
59
  this.threshold = opts.typebackThresholdSol ?? DEFAULT_TYPEBACK_THRESHOLD_SOL;
82
60
  this.confirmTimeoutMs = opts.confirmQuoteTimeoutMs ?? CONFIRM_QUOTE_TIMEOUT_MS;
83
- this.liveDeps = opts.live ?? null;
84
- this.livePositionRaw = opts.livePositionRaw ?? (() => 0n);
85
61
  this.onSettled = opts.onSettled ?? null;
86
62
  this.decimalsKnown = typeof seed.decimals === 'number' && Number.isFinite(seed.decimals) && seed.decimals > 0;
87
63
  this.ticket = openTicket(seed);
@@ -89,278 +65,8 @@ export class TradeTicketLive {
89
65
  this.refreshQuote();
90
66
  }
91
67
  positionTokensRaw() {
92
- if (this.ticket.mode === 'live')
93
- return this.livePositionRaw(this.ticket.mint);
94
68
  return this.wallet.position(this.ticket.mint)?.tokensRaw ?? 0n;
95
69
  }
96
- // ------------------------------------------------------------------------------------ LIVE (task-1328)
97
- /** Is LIVE mode available right now? A reason string when not. */
98
- liveUnavailable() {
99
- if (!this.liveDeps)
100
- return 'LIVE trading is not available in this run';
101
- if (!this.liveDeps.linked())
102
- return 'no wallet linked — /wallet link first';
103
- const s = this.liveDeps.signer();
104
- if (!s)
105
- return 'the signer process is not available';
106
- if (!s.alive)
107
- return 'the signer process died — restart dexterm to trade live';
108
- return null;
109
- }
110
- /**
111
- * Flip PAPER ⇄ LIVE (the user's `L`). Entering LIVE reads the signer's status (its network + caps,
112
- * which the banner shows — never the UI's own flags) and refuses when no wallet is linked or the
113
- * signer is down. Leaving LIVE drops any plan.
114
- */
115
- setMode(mode) {
116
- if (this.ticket.phase !== 'editing')
117
- return;
118
- if (mode === this.ticket.mode)
119
- return;
120
- if (mode === 'live') {
121
- const why = this.liveUnavailable();
122
- if (why) {
123
- this.ticket.message = why;
124
- this.onChange();
125
- return;
126
- }
127
- this.ticket.mode = 'live';
128
- this.liveOutcome = null;
129
- this.liveError = null;
130
- this.livePlan = null;
131
- this.liveProbe = false;
132
- this.ticket.message = 'LIVE: ⏎ builds the plan in the signer · Y on the plan signs in Phantom';
133
- void this.refreshSignerStatus();
134
- }
135
- else {
136
- this.dropPlan();
137
- this.ticket.mode = 'paper';
138
- this.liveProbe = false;
139
- this.ticket.message = 'PAPER';
140
- }
141
- this.refreshQuote();
142
- this.onChange();
143
- }
144
- /** Re-read the signer's status (network, caps, panic). Null when it cannot be reached. */
145
- async refreshSignerStatus() {
146
- const s = this.liveDeps?.signer() ?? null;
147
- if (!s) {
148
- this.signerStatus = null;
149
- return null;
150
- }
151
- try {
152
- this.signerStatus = await s.status();
153
- }
154
- catch (e) {
155
- this.signerStatus = null;
156
- this.liveError = msg(e);
157
- }
158
- this.onChange();
159
- return this.signerStatus;
160
- }
161
- /** LIVE ⏎: ask the signer to quote → build → decode → simulate the plan for this order. */
162
- async planLive() {
163
- const s = this.liveDeps?.signer() ?? null;
164
- const my = ++this.planSeq;
165
- this.livePlan = null;
166
- this.liveOutcome = null;
167
- this.liveError = null;
168
- this.clearRetryTimer();
169
- this.liveRetryAt = null;
170
- this.liveRetryMsg = null;
171
- this.onChange();
172
- try {
173
- if (!s || !s.alive)
174
- throw new Error(this.liveUnavailable() ?? 'signer unavailable');
175
- const ctx = this.ctx();
176
- const order = toOrder(this.ticket, ctx);
177
- if (!this.liveProbe && !orderValid(this.ticket, ctx))
178
- throw new Error('order is no longer valid');
179
- const [plan, status] = await Promise.all([
180
- this.liveProbe ? s.probe() : s.plan({ mint: order.mint, symbol: order.symbol, side: order.side, decimals: order.decimals, amountRaw: order.amountRaw.toString(), slippageBps: order.slippageBps }),
181
- s.status().catch(() => null),
182
- ]);
183
- if (my !== this.planSeq) {
184
- void s.drop(plan.hash).catch(() => { });
185
- return;
186
- } // cancelled meanwhile
187
- this.signerStatus = status;
188
- this.livePlan = plan;
189
- if (this.ticket.phase === 'planning')
190
- this.ticket.phase = 'plan';
191
- }
192
- catch (e) {
193
- if (my !== this.planSeq)
194
- return;
195
- // task-1368: Jupiter rate limiting is NOT a dead end. The ticket stays in `planning`, shows the signer's own
196
- // line with the countdown, retries by itself when the wait is over, and `r` retries now / esc cancels.
197
- const rl = this.ticket.phase === 'planning' ? rateLimitOf(e) : null;
198
- if (rl) {
199
- this.liveRetryAt = this.now() + rl.ms;
200
- this.liveRetryMsg = rl.message;
201
- this.ticket.message = `${rl.message} · r retries now · esc cancels`;
202
- this.scheduleRetry(rl.ms, my);
203
- return;
204
- }
205
- this.liveError = msg(e);
206
- this.ticket.phase = 'error';
207
- this.ticket.message = `plan failed: ${this.liveError}`;
208
- }
209
- finally {
210
- this.onChange();
211
- }
212
- }
213
- /** task-1368: the auto-retry after a rate-limited plan. Fires only if the ticket is still waiting on that very attempt. */
214
- scheduleRetry(ms, seq) {
215
- this.clearRetryTimer();
216
- const h = setTimeout(() => {
217
- this.retryTimer = null;
218
- if (this.ticket.phase === 'planning' && this.planSeq === seq && this.liveRetryAt !== null)
219
- void this.planLive();
220
- }, Math.max(0, ms));
221
- if (typeof h.unref === 'function')
222
- h.unref();
223
- this.retryTimer = h;
224
- }
225
- clearRetryTimer() {
226
- if (this.retryTimer) {
227
- clearTimeout(this.retryTimer);
228
- this.retryTimer = null;
229
- }
230
- }
231
- /** task-1368: `r` while rate limited — retry the plan now instead of waiting out the countdown. No-op otherwise. */
232
- retryPlan() {
233
- if (this.ticket.phase !== 'planning' || this.liveRetryAt === null)
234
- return;
235
- void this.planLive();
236
- }
237
- /** Ms until the automatic retry (0 when due, null when not waiting). */
238
- retryInMs() {
239
- return this.liveRetryAt === null ? null : Math.max(0, this.liveRetryAt - this.now());
240
- }
241
- /** LIVE Y on the plan: the signer re-checks caps, opens Phantom, verifies, re-simulates, submits. */
242
- async confirmLive() {
243
- const s = this.liveDeps?.signer() ?? null;
244
- const plan = this.livePlan;
245
- try {
246
- if (!s || !s.alive)
247
- throw new Error(this.liveUnavailable() ?? 'signer unavailable');
248
- if (!plan)
249
- throw new Error('no plan to confirm');
250
- const out = await s.confirm(plan.hash);
251
- this.liveOutcome = out;
252
- if (out.kind === 'filled') {
253
- this.ticket.phase = 'filled';
254
- this.ticket.message = null;
255
- this.liveDeps?.onFill?.();
256
- }
257
- else if (out.kind === 'refused') {
258
- this.ticket.phase = 'refused';
259
- this.ticket.message = `${out.reason}: ${out.message}`;
260
- }
261
- else {
262
- this.ticket.phase = 'error';
263
- this.ticket.message = out.error;
264
- }
265
- // task-1340: the settled outcome (and only that) reaches the effects. `send-unknown` is deliberately
266
- // excluded: the chain may still confirm it, so there is no verdict to show.
267
- const settled = settledFromConfirm(out, this.ticket.symbol, this.ticket.mint, this.liveProbe);
268
- if (settled)
269
- this.settle(settled);
270
- }
271
- catch (e) {
272
- this.liveError = msg(e);
273
- this.ticket.phase = 'error';
274
- this.ticket.message = `confirm failed: ${this.liveError}`;
275
- this.settle({ status: 'failed', side: this.ticket.side, symbol: this.ticket.symbol, mint: this.ticket.mint, sig: null, solDelta: null, pnlSol: null, pnlPct: null, ledger: 'live', reason: this.liveError });
276
- }
277
- finally {
278
- void this.refreshSignerStatus();
279
- this.onChange();
280
- }
281
- }
282
- /** Esc while planning: forget the in-flight plan (it is dropped when it lands), or stop a rate-limit wait. */
283
- cancelPlan() {
284
- if (this.ticket.phase !== 'planning')
285
- return;
286
- this.planSeq++;
287
- this.clearRetryTimer();
288
- this.liveRetryAt = null;
289
- this.liveRetryMsg = null;
290
- this.ticket.phase = 'editing';
291
- this.ticket.message = 'plan cancelled';
292
- this.onChange();
293
- }
294
- /**
295
- * task-1368: the order's size against the signer's caps, priced at the SIGNER's SOL/USD (the preview quote carries
296
- * it; the status does too). Null on PAPER, without signer status, or for the probe.
297
- */
298
- preflight() {
299
- if (this.ticket.mode !== 'live' || this.liveProbe)
300
- return null;
301
- const st = this.signerStatus;
302
- if (!st)
303
- return null;
304
- const sizeSol = this.ticket.side === 'buy'
305
- ? buyNotionalSol(this.ticket, this.wallet.balance())
306
- : (this.quote && this.quote.inputMint === this.ticket.mint ? lamportsToSol(this.quote.outAmount) : 0);
307
- return capPreflight({
308
- side: this.ticket.side, sizeSol, solUsd: this.liveSolUsd ?? st.solUsd.price,
309
- perTradeUsd: st.caps.perTradeUsd, dailyUsd: st.caps.dailyUsd, spentTodayUsd: st.spentTodayUsd,
310
- });
311
- }
312
- /** task-1368 `f`: size a LIVE buy to the cap (SOL unit). Says why when it cannot. */
313
- fitToCap() {
314
- const pf = this.preflight();
315
- if (!pf) {
316
- this.ticket.message = 'fit to cap needs the signer status (press L again to re-read it)';
317
- return;
318
- }
319
- if (pf.fitSizeSol === null) {
320
- this.ticket.message = pf.sizeUsd === null && pf.sizeSol > 0 ? 'fit to cap needs the signer\'s SOL/USD price (not available yet)' : 'nothing fits: the cap is spent for today';
321
- return;
322
- }
323
- this.ticket.sizeUnit = 'sol';
324
- this.ticket.sizeInput = String(pf.fitSizeSol);
325
- this.ticket.typeback = '';
326
- this.receipt = null;
327
- this.liveOutcome = null;
328
- this.ticket.message = `fit to cap: ${pf.fitSizeSol} SOL (≤ $${pf.capUsd.toFixed(2)} with room for fees + rent)`;
329
- this.scheduleQuote(0);
330
- }
331
- dropPlan() {
332
- const plan = this.livePlan;
333
- this.livePlan = null;
334
- if (plan) {
335
- const s = this.liveDeps?.signer();
336
- if (s?.alive)
337
- void s.drop(plan.hash).catch(() => { });
338
- }
339
- }
340
- /** Make this LIVE ticket the devnet PROBE (wrap-and-unwrap, fees only). The plan comes from the signer. */
341
- startProbe() {
342
- const why = this.liveUnavailable();
343
- if (why)
344
- return why;
345
- this.ticket.mode = 'live';
346
- this.liveProbe = true;
347
- this.ticket.phase = 'planning';
348
- this.ticket.message = 'devnet probe: building the wrap-and-unwrap plan…';
349
- void this.planLive();
350
- return null;
351
- }
352
- liveView() {
353
- if (this.ticket.mode !== 'live')
354
- return undefined;
355
- const st = this.signerStatus;
356
- return {
357
- signer: st, plan: this.livePlan, outcome: this.liveOutcome, error: this.liveError,
358
- linked: this.liveDeps?.linked()?.publicKey ? shortPubkey(this.liveDeps.linked().publicKey) : null, probe: this.liveProbe,
359
- preflight: this.preflight(),
360
- retryAt: this.liveRetryAt, retryMessage: this.liveRetryMsg,
361
- devnetWarning: devnetMintWarning({ network: st?.network ?? null, probe: this.liveProbe, mint: this.ticket.mint, perTradeUsd: st?.caps.perTradeUsd, dailyUsd: st?.caps.dailyUsd }),
362
- };
363
- }
364
70
  notionalSol() {
365
71
  if (this.ticket.side === 'buy')
366
72
  return buyNotionalSol(this.ticket, this.wallet.balance());
@@ -380,25 +86,12 @@ export class TradeTicketLive {
380
86
  /** Apply a key; refetch the warm quote on a change. Returns 'confirm'/'close' for the loop. */
381
87
  key(k) {
382
88
  const eff = ticketKey(this.ticket, k, this.ctx());
383
- if (eff === 'confirm' || eff === 'close' || eff === 'plan')
89
+ if (eff === 'confirm' || eff === 'close')
384
90
  this.clearQuoteTimer();
385
91
  if (eff === 'changed') {
386
92
  this.receipt = null;
387
- this.liveOutcome = null;
388
93
  this.scheduleQuote();
389
94
  }
390
- if (eff === 'toggle-live')
391
- this.setMode(this.ticket.mode === 'live' ? 'paper' : 'live');
392
- if (eff === 'fit-cap')
393
- this.fitToCap();
394
- if (eff === 'drop-plan')
395
- this.dropPlan();
396
- if (eff === 'close')
397
- this.dropPlan();
398
- if (eff === 'plan')
399
- void this.planLive();
400
- if (eff === 'confirm-live')
401
- void this.confirmLive();
402
95
  return eff;
403
96
  }
404
97
  clearQuoteTimer() {
@@ -438,7 +131,7 @@ export class TradeTicketLive {
438
131
  /** Fetch a warm quote for the current order (debounced by a sequence guard). */
439
132
  refreshQuote() {
440
133
  const ctx = this.ctx();
441
- if (!orderValid(this.ticket, ctx) || this.ticket.phase === 'filling' || this.liveProbe) {
134
+ if (!orderValid(this.ticket, ctx) || this.ticket.phase === 'filling') {
442
135
  this.quote = null;
443
136
  return;
444
137
  }
@@ -447,17 +140,9 @@ export class TradeTicketLive {
447
140
  this.loading = true;
448
141
  this.error = null;
449
142
  const req = { inputMint: order.side === 'buy' ? SOL_MINT : order.mint, outputMint: order.side === 'buy' ? order.mint : SOL_MINT, amount: order.amountRaw, slippageBps: order.slippageBps, mode: 'ExactIn' };
450
- // task-1368: a LIVE preview is quoted BY THE SIGNER (its own limiter paces preview, re-quote and build as one,
451
- // and the build reuses this very quote); PAPER keeps the terminal's keyless adapter. A fake signer without
452
- // `quote` falls back to the terminal's adapter. task-1387: the terminal quote runs at `high`
453
- // priority so a user-initiated trade quote preempts the background screener/token enrichment on
454
- // the shared 0.5 rps keyless `jupiter` bucket — otherwise the warm quote queues for seconds.
455
- const s = this.ticket.mode === 'live' ? this.liveDeps?.signer() ?? null : null;
456
- const viaSigner = s && s.alive && typeof s.quote === 'function'
457
- ? s.quote({ mint: order.mint, symbol: order.symbol, side: order.side, decimals: order.decimals, amountRaw: order.amountRaw.toString(), slippageBps: order.slippageBps })
458
- .then((v) => { this.liveSolUsd = v.solUsd.price; return quoteFromView(v); })
459
- : null;
460
- (viaSigner ?? withPriority('high', () => this.dl.jupiterSwap.quote(req)))
143
+ // task-1387: the quote runs at `high` priority so a user-initiated trade quote preempts the background
144
+ // screener/token enrichment on the shared 0.5 rps keyless `jupiter` bucket — otherwise the warm quote queues for seconds.
145
+ withPriority('high', () => this.dl.jupiterSwap.quote(req))
461
146
  .then((q) => { if (my !== this.seq)
462
147
  return; this.quote = q; this.quoteAt = this.now(); this.loading = false; this.onChange(); })
463
148
  .catch((e) => { if (my !== this.seq)
@@ -549,7 +234,7 @@ export class TradeTicketLive {
549
234
  this.onChange();
550
235
  }
551
236
  }
552
- /** The single exit for a settled outcome (paper fill, live fill, refusal, failure). Never called with a quote. */
237
+ /** The single exit for a settled outcome (paper fill or failure). Never called with a quote. */
553
238
  settle(tx) {
554
239
  if (!this.onSettled)
555
240
  return;
@@ -576,7 +261,6 @@ export class TradeTicketLive {
576
261
  receipt: this.ticket.phase === 'filled' ? this.receipt : null,
577
262
  rateLimited: this.ticket.phase === 'filling' && this.jupiterPaused(),
578
263
  decimalsKnown: this.decimalsKnown,
579
- live: this.liveView(),
580
264
  };
581
265
  }
582
266
  }
@@ -586,20 +270,6 @@ export function settledFromFill(f, costBeforeLamports) {
586
270
  const basis = f.side === 'sell' && costBeforeLamports !== null && costBeforeLamports > 0n ? lamportsToSol(costBeforeLamports) : null;
587
271
  return { status: 'confirmed', side: f.side, symbol: f.symbol, mint: f.mint, sig: null, solDelta: lamportsToSol(f.solDelta), pnlSol, pnlPct: basis ? pnlSol / basis : null, ledger: 'paper' };
588
272
  }
589
- /** A signer ConfirmView → the settled outcome, or null when there is none to show (`send-unknown`, probes). */
590
- export function settledFromConfirm(out, symbol, mint, probe) {
591
- if (out.kind === 'send-unknown')
592
- return null;
593
- if (out.kind === 'filled') {
594
- if (probe)
595
- return null; // the devnet wrap-and-unwrap probe is not a trade
596
- const f = out.fill;
597
- const pnlSol = f.side === 'sell' ? lamportsToSol(BigInt(f.realizedLamports)) : 0;
598
- return { status: 'confirmed', side: f.side, symbol: f.symbol || symbol, mint: f.mint || mint, sig: out.signature, solDelta: lamportsToSol(BigInt(f.solDelta)), pnlSol, pnlPct: null, ledger: 'live' };
599
- }
600
- const reason = out.kind === 'refused' ? `${out.reason}: ${out.message}` : out.error;
601
- return { status: 'failed', side: 'buy', symbol, mint, sig: out.kind === 'send-failed' ? out.signature : null, solDelta: null, pnlSol: null, pnlPct: null, ledger: 'live', reason };
602
- }
603
273
  function safePreview(exec, order, q) {
604
274
  try {
605
275
  return exec.previewFill(order, q);
@@ -703,7 +373,7 @@ export class PositionsLive {
703
373
  solUsd() {
704
374
  return this.solPriceUsd;
705
375
  }
706
- /** The last DexScreener mark for a mint (SOL per token), shared with the live positions source. */
376
+ /** The last DexScreener mark for a mint (SOL per token). */
707
377
  markOf(mint) {
708
378
  return this.marks.get(mint) ?? null;
709
379
  }
@@ -844,121 +514,6 @@ export class PositionsLive {
844
514
  };
845
515
  }
846
516
  }
847
- // ---------------------------------------------------------------------------------------------
848
- // task-1328 item 5: LIVE positions. The signer process books confirmed real fills into its live ledger
849
- // file; the UI reads that file READ-ONLY (never writes it) and serves the same PositionSource interface
850
- // the paper ledger does, so the token screen's position row and the popup chart show real positions
851
- // through the task-1323 selector unchanged. A CombinedPositions wraps both: live wins for a mint when
852
- // held live, else paper; every HeldPosition says which ledger it came from.
853
- /** Live positions from the signer's ledger file (read-only). A missing file reads as flat. */
854
- export class LivePositions {
855
- kind = 'live';
856
- path;
857
- now;
858
- mark;
859
- memo = new Map();
860
- rowsMemo = null;
861
- solUsdValue = null;
862
- constructor(path, opts = {}) {
863
- this.path = path;
864
- this.now = opts.now ?? (() => Date.now());
865
- this.mark = opts.mark ?? (() => null);
866
- if (opts.solUsd)
867
- this.solUsdFn = opts.solUsd;
868
- }
869
- solUsdFn = () => this.solUsdValue;
870
- setSolPrice(p) { if (typeof p === 'number' && Number.isFinite(p) && p > 0)
871
- this.solUsdValue = p; }
872
- solUsd() { return this.solUsdFn(); }
873
- /** All positions (open + closed) from the ledger file, memoised HELD_MEMO_MS. Unreadable → []. */
874
- positions() {
875
- const now = this.now();
876
- if (this.rowsMemo && now - this.rowsMemo.at >= 0 && now - this.rowsMemo.at < HELD_MEMO_MS)
877
- return this.rowsMemo.rows;
878
- let rows = [];
879
- try {
880
- const l = new LiveLedger({ path: this.path, readOnly: true });
881
- try {
882
- rows = l.positions();
883
- }
884
- finally {
885
- l.close();
886
- }
887
- }
888
- catch {
889
- rows = [];
890
- }
891
- this.rowsMemo = { at: now, rows };
892
- return rows;
893
- }
894
- /** task-1407: the raw ledger rows (newest first, swaps only) with network + signature, for the LIVE PnL card. */
895
- fills(mint, limit = 500) {
896
- try {
897
- const l = new LiveLedger({ path: this.path, readOnly: true });
898
- try {
899
- return l.trades(limit * 2).filter((r) => r.kind === 'swap' && r.mint === mint).slice(0, limit);
900
- }
901
- finally {
902
- l.close();
903
- }
904
- }
905
- catch {
906
- return [];
907
- }
908
- }
909
- /** Confirmed live fills (newest first) for the popup markers / history; probes excluded. */
910
- records(limit = 100, mint) {
911
- try {
912
- const l = new LiveLedger({ path: this.path, readOnly: true });
913
- try {
914
- return l.records(limit, mint);
915
- }
916
- finally {
917
- l.close();
918
- }
919
- }
920
- catch {
921
- return [];
922
- }
923
- }
924
- held(mint) {
925
- const now = this.now();
926
- const m = this.memo.get(mint);
927
- if (m && now - m.at >= 0 && now - m.at < HELD_MEMO_MS)
928
- return m.v;
929
- const p = this.positions().find((x) => x.mint === mint) ?? null;
930
- const v = p ? heldFromPaper(p, this.mark(mint)) : null;
931
- if (v)
932
- v.kind = 'live';
933
- if (this.memo.size > 64)
934
- this.memo.clear();
935
- this.memo.set(mint, { at: now, v });
936
- return v;
937
- }
938
- /** task-1473 r2: mints of the open live positions (the AI-scan PnL chip). Memoised with positions(). */
939
- openMints() { return this.positions().filter((p) => p.tokensRaw > 0n).map((p) => p.mint); }
940
- /** Forget memoised reads (after a fill). */
941
- invalidate() { this.memo.clear(); this.rowsMemo = null; }
942
- }
943
- /** Paper + live behind one PositionSource: live wins for a mint when held live, else paper. */
944
- export class CombinedPositions {
945
- kind = 'paper';
946
- paper;
947
- live;
948
- constructor(paper, live) { this.paper = paper; this.live = live; }
949
- held(mint) {
950
- const l = this.live?.held(mint) ?? null;
951
- if (l)
952
- return l;
953
- const p = this.paper.held(mint);
954
- if (p)
955
- p.kind = 'paper';
956
- return p;
957
- }
958
- solUsd() { return this.paper.solUsd() ?? this.live?.solUsd() ?? null; }
959
- /** task-1473 r2: every open mint, live first (the AI-scan PnL chip picks one). */
960
- openMints() { return [...new Set([...(this.live?.openMints() ?? []), ...this.paper.openMints()])]; }
961
- }
962
517
  function msg(e) {
963
518
  return e instanceof Error ? e.message : String(e);
964
519
  }
@@ -49,7 +49,7 @@ export class WatchlistLive {
49
49
  this.store.propose({ mint: c.mint, kind: 'mcap', op: '<', value: c.mcap * 0.5, note: 'half mcap vs add' });
50
50
  proposed = 2;
51
51
  }
52
- this.store.log({ mint: c.mint, kind: 'watch', level: 'info', text: `${c.symbol} added to watchlist${c.price !== null ? ` at ${fmtPrice(c.price)}` : c.mcap ? ` at ${fmtAny('mcap', c.mcap)} mcap` : ''}` });
52
+ this.store.log({ mint: c.mint, kind: 'watch', level: 'info', text: `${c.symbol} added to watchlist${c.mcap ? ` at ${fmtAny('mcap', c.mcap)} mcap${c.price !== null ? ` (${fmtPrice(c.price)})` : ''}` : c.price !== null ? ` at ${fmtPrice(c.price)}` : ''}` }); // task-1537: the cap first, both kept
53
53
  this.notice = `watching $${c.symbol}${proposed ? ` · ${proposed} alert proposals (y to arm, x to dismiss)` : ' · no price or mcap yet, so no alert proposals'}`;
54
54
  this.onChange?.();
55
55
  return 'added';