dexterm-cli 0.1.5 → 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 (379) hide show
  1. package/dist/packages/agents/src/index.js +2 -0
  2. package/dist/packages/agents/src/schema.js +22 -1
  3. package/dist/packages/agents/src/spectator.js +54 -0
  4. package/dist/packages/agents/src/story.js +532 -0
  5. package/dist/packages/agents/src/tiers.js +28 -2
  6. package/dist/packages/agents/src/tools.js +31 -2
  7. package/dist/packages/autotrade/assets/exit-profile.schema.json +492 -0
  8. package/dist/packages/autotrade/assets/profiles/moonbag.json +46 -0
  9. package/dist/packages/autotrade/assets/profiles/runner.json +88 -0
  10. package/dist/packages/autotrade/assets/profiles/scalp.json +88 -0
  11. package/dist/packages/autotrade/assets/profiles/swing.json +88 -0
  12. package/dist/packages/autotrade/assets/strategies/moonbag.json +101 -0
  13. package/dist/packages/autotrade/assets/strategies/runner.json +101 -0
  14. package/dist/packages/autotrade/assets/strategies/sample-dip-ladder.json +188 -0
  15. package/dist/packages/autotrade/assets/strategies/scalp.json +98 -0
  16. package/dist/packages/autotrade/assets/strategies/swing.json +97 -0
  17. package/dist/packages/autotrade/assets/strategies/yolo.json +157 -0
  18. package/dist/packages/autotrade/assets/tapes/yolo-rehearsal.json +1 -0
  19. package/dist/packages/autotrade/src/account.js +74 -0
  20. package/dist/packages/autotrade/src/backtest.js +357 -0
  21. package/dist/packages/autotrade/src/basis-text.js +32 -0
  22. package/dist/packages/autotrade/src/chat/approvals.js +484 -0
  23. package/dist/packages/autotrade/src/chat/audit.js +140 -0
  24. package/dist/packages/autotrade/src/chat/config.js +93 -0
  25. package/dist/packages/autotrade/src/chat/connector.js +24 -0
  26. package/dist/packages/autotrade/src/chat/control.js +103 -0
  27. package/dist/packages/autotrade/src/chat/fake.js +100 -0
  28. package/dist/packages/autotrade/src/chat/format.js +71 -0
  29. package/dist/packages/autotrade/src/chat/hub.js +187 -0
  30. package/dist/packages/autotrade/src/chat/index.js +18 -0
  31. package/dist/packages/autotrade/src/chat/notify.js +292 -0
  32. package/dist/packages/autotrade/src/chat/pairing.js +46 -0
  33. package/dist/packages/autotrade/src/chat/redact.js +48 -0
  34. package/dist/packages/autotrade/src/chat/secrets.js +99 -0
  35. package/dist/packages/autotrade/src/chat/service.js +248 -0
  36. package/dist/packages/autotrade/src/chat/telegram.js +290 -0
  37. package/dist/packages/autotrade/src/desk-executor.js +188 -0
  38. package/dist/packages/autotrade/src/engine.js +387 -0
  39. package/dist/packages/autotrade/src/execution-port.js +97 -0
  40. package/dist/packages/autotrade/src/fleet-config.js +169 -0
  41. package/dist/packages/autotrade/src/fleet-control.js +276 -0
  42. package/dist/packages/autotrade/src/fleet.js +639 -0
  43. package/dist/packages/autotrade/src/index.js +53 -0
  44. package/dist/packages/autotrade/src/ledger.js +108 -0
  45. package/dist/packages/autotrade/src/live-source.js +182 -0
  46. package/dist/packages/autotrade/src/monitor-daemon.js +715 -0
  47. package/dist/packages/autotrade/src/monitor.js +190 -0
  48. package/dist/packages/autotrade/src/ollama-sessions.js +137 -0
  49. package/dist/packages/autotrade/src/paper-accounts.js +72 -0
  50. package/dist/packages/autotrade/src/replay.js +198 -0
  51. package/dist/packages/autotrade/src/runner-config.js +99 -0
  52. package/dist/packages/autotrade/src/runner.js +872 -0
  53. package/dist/packages/autotrade/src/safety.js +243 -0
  54. package/dist/packages/autotrade/src/session.js +269 -0
  55. package/dist/packages/autotrade/src/sessions.js +503 -0
  56. package/dist/packages/autotrade/src/store.js +250 -0
  57. package/dist/packages/autotrade/src/strategy.js +256 -0
  58. package/dist/packages/autotrade/src/trade-ledger.js +241 -0
  59. package/dist/packages/autotrade/src/yolo.js +140 -0
  60. package/dist/packages/cli/assets/claude/analyst-system.md +4 -4
  61. package/dist/packages/cli/assets/claude/plugin/skills/REGISTRY.json +1 -1
  62. package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +15 -8
  63. package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +1 -1
  64. package/dist/packages/cli/src/agent-cmd.js +6 -4
  65. package/dist/packages/cli/src/agent-spectator.js +17 -1
  66. package/dist/packages/cli/src/ai-cmd.js +412 -0
  67. package/dist/packages/cli/src/analyst/backend.js +105 -15
  68. package/dist/packages/cli/src/analyst/codex.js +14 -9
  69. package/dist/packages/cli/src/analyst/larp-gauge.js +60 -0
  70. package/dist/packages/cli/src/analyst/ollama.js +263 -0
  71. package/dist/packages/cli/src/analyst/session.js +17 -3
  72. package/dist/packages/cli/src/app-help-gen.js +51 -15
  73. package/dist/packages/cli/src/autotrade-cmd/audit.js +57 -0
  74. package/dist/packages/cli/src/autotrade-cmd/backtest.js +199 -0
  75. package/dist/packages/cli/src/autotrade-cmd/flatten.js +64 -0
  76. package/dist/packages/cli/src/autotrade-cmd/fleet.js +397 -0
  77. package/dist/packages/cli/src/autotrade-cmd/requests.js +79 -0
  78. package/dist/packages/cli/src/autotrade-cmd/run.js +413 -0
  79. package/dist/packages/cli/src/autotrade-cmd/stop.js +76 -0
  80. package/dist/packages/cli/src/autotrade-cmd/strategies.js +198 -0
  81. package/dist/packages/cli/src/autotrade-cmd/strategy-control.js +174 -0
  82. package/dist/packages/cli/src/autotrade-cmd/telegram-host.js +101 -0
  83. package/dist/packages/cli/src/autotrade-cmd.js +168 -0
  84. package/dist/packages/cli/src/backtest-cmd.js +13 -2
  85. package/dist/packages/cli/src/display.js +208 -23
  86. package/dist/packages/cli/src/doctor.js +62 -3
  87. package/dist/packages/cli/src/export.js +10 -2
  88. package/dist/packages/cli/src/index.js +1 -1
  89. package/dist/packages/cli/src/ledger-cmd.js +288 -0
  90. package/dist/packages/cli/src/live/chart-fills.js +46 -0
  91. package/dist/packages/cli/src/live/dev-history.js +31 -15
  92. package/dist/packages/cli/src/live/index.js +28 -90
  93. package/dist/packages/cli/src/live/screens/newpairs-live.js +1 -1
  94. package/dist/packages/cli/src/live/screens/token-live.js +48 -15
  95. package/dist/packages/cli/src/live/screens/watchlist-live.js +1 -1
  96. package/dist/packages/cli/src/live/trade.js +30 -453
  97. package/dist/packages/cli/src/live/watchlist.js +1 -1
  98. package/dist/packages/cli/src/main.js +290 -199
  99. package/dist/packages/cli/src/mcp-cmd.js +7 -1
  100. package/dist/packages/cli/src/mcp-follow.js +103 -6
  101. package/dist/packages/cli/src/plan-cmd.js +15 -5
  102. package/dist/packages/cli/src/pnl-app.js +31 -21
  103. package/dist/packages/cli/src/pnl-card.js +158 -21
  104. package/dist/packages/cli/src/popup.js +38 -6
  105. package/dist/packages/cli/src/record-cmd.js +141 -20
  106. package/dist/packages/cli/src/scan/ui.js +7 -1
  107. package/dist/packages/cli/src/screens/agent-hud.js +773 -0
  108. package/dist/packages/cli/src/screens/analyst-session.js +11 -4
  109. package/dist/packages/cli/src/screens/analyst.js +3 -2
  110. package/dist/packages/cli/src/screens/autotrade-keys.js +169 -0
  111. package/dist/packages/cli/src/screens/autotrade-proposals.js +123 -0
  112. package/dist/packages/cli/src/screens/autotrade-screen.js +725 -0
  113. package/dist/packages/cli/src/screens/autotrade-ui.js +640 -0
  114. package/dist/packages/cli/src/screens/autotrade-worker.js +89 -0
  115. package/dist/packages/cli/src/screens/brain.js +634 -0
  116. package/dist/packages/cli/src/screens/newpairs.js +1 -1
  117. package/dist/packages/cli/src/screens/overlay.js +5 -2
  118. package/dist/packages/cli/src/screens/plans.js +5 -17
  119. package/dist/packages/cli/src/screens/pnl-chip.js +144 -0
  120. package/dist/packages/cli/src/screens/positions.js +6 -28
  121. package/dist/packages/cli/src/screens/screener.js +1 -0
  122. package/dist/packages/cli/src/screens/ticket.js +38 -205
  123. package/dist/packages/cli/src/screens/token.js +18 -9
  124. package/dist/packages/cli/src/screens/trending.js +1 -1
  125. package/dist/packages/cli/src/state.js +88 -18
  126. package/dist/packages/cli/src/telegram-cmd.js +451 -0
  127. package/dist/packages/cli/src/trade.js +3 -128
  128. package/dist/packages/cli/src/version.js +1 -1
  129. package/dist/packages/cli/src/wallet-cmd.js +39 -340
  130. package/dist/packages/cli/src/wallet-command.js +8 -11
  131. package/dist/packages/cli/src/widgets.js +0 -12
  132. package/dist/packages/custom/src/config.js +20 -2
  133. package/dist/packages/custom/src/schema.js +41 -10
  134. package/dist/packages/custom/src/workspace.js +3 -3
  135. package/dist/packages/data/src/basis.js +191 -0
  136. package/dist/packages/data/src/detail.js +53 -2
  137. package/dist/packages/data/src/index.js +2 -14
  138. package/dist/packages/data/src/larp/score.js +220 -0
  139. package/dist/packages/data/src/larp/x-account.js +316 -0
  140. package/dist/packages/data/src/store.js +14 -5
  141. package/dist/packages/data/src/trade/agent/paper-desk.js +300 -23
  142. package/dist/packages/data/src/trade/agent/rendezvous.js +3 -2
  143. package/dist/packages/data/src/trade/bridge.js +4 -102
  144. package/dist/packages/data/src/trade/ledger/export.js +101 -0
  145. package/dist/packages/data/src/trade/ledger/file.js +135 -0
  146. package/dist/packages/data/src/trade/ledger/fold.js +191 -0
  147. package/dist/packages/data/src/trade/ledger/index.js +9 -0
  148. package/dist/packages/data/src/trade/ledger/schema.js +83 -0
  149. package/dist/packages/data/src/trade/ledger/sources.js +307 -0
  150. package/dist/packages/data/src/trade/ledger/stats.js +123 -0
  151. package/dist/packages/data/src/trade/ledger/tags.js +116 -0
  152. package/dist/packages/data/src/trade/ledger/view.js +51 -0
  153. package/dist/packages/data/src/trade/plans/engine.js +7 -0
  154. package/dist/packages/data/src/trade/plans/index.js +0 -1
  155. package/dist/packages/data/src/trade/plans/mandate.js +28 -15
  156. package/dist/packages/data/src/trade/plans/service.js +4 -28
  157. package/dist/packages/mcp/assets/kb/app-help/autotrade-chat.md +48 -0
  158. package/dist/packages/mcp/assets/kb/app-help/autotrade-parallel.md +42 -0
  159. package/dist/packages/mcp/assets/kb/app-help/autotrade-runner.md +35 -0
  160. package/dist/packages/mcp/assets/kb/app-help/autotrade-stop.md +37 -0
  161. package/dist/packages/mcp/assets/kb/app-help/autotrade-strategies.md +35 -0
  162. package/dist/packages/mcp/assets/kb/app-help/autotrade-telegram.md +40 -0
  163. package/dist/packages/mcp/assets/kb/app-help/chart-trade-markers.md +42 -0
  164. package/dist/packages/mcp/assets/kb/app-help/dev-history.md +1 -1
  165. package/dist/packages/mcp/assets/kb/app-help/larp-check.md +5 -1
  166. package/dist/packages/mcp/assets/kb/app-help/link-a-wallet.md +4 -10
  167. package/dist/packages/mcp/assets/kb/app-help/live-trading.md +38 -0
  168. package/dist/packages/mcp/assets/kb/app-help/live-yolo.md +34 -0
  169. package/dist/packages/mcp/assets/kb/app-help/order-plans.md +1 -1
  170. package/dist/packages/mcp/assets/kb/app-help/price-or-marketcap.md +5 -2
  171. package/dist/packages/mcp/assets/kb/app-help/scan-mode.md +1 -1
  172. package/dist/packages/mcp/assets/kb/app-help/screen-analyst.md +3 -0
  173. package/dist/packages/mcp/assets/kb/app-help/screen-autotrade.md +217 -0
  174. package/dist/packages/mcp/assets/kb/app-help/screen-kol.md +3 -0
  175. package/dist/packages/mcp/assets/kb/app-help/screen-newpairs.md +3 -0
  176. package/dist/packages/mcp/assets/kb/app-help/screen-positions.md +3 -0
  177. package/dist/packages/mcp/assets/kb/app-help/screen-screener.md +3 -0
  178. package/dist/packages/mcp/assets/kb/app-help/screen-token.md +6 -0
  179. package/dist/packages/mcp/assets/kb/app-help/screen-trending.md +3 -0
  180. package/dist/packages/mcp/assets/kb/app-help/screen-watchlist.md +3 -0
  181. package/dist/packages/mcp/assets/kb/app-help/spectate-an-agent.md +2 -1
  182. package/dist/packages/mcp/assets/kb/app-help/standing-mandates.md +1 -1
  183. package/dist/packages/mcp/assets/kb/app-help/trade-ledger.md +54 -0
  184. package/dist/packages/mcp/assets/kb/app-help/use-local-model.md +38 -0
  185. package/dist/packages/mcp/assets/kb/docs/docs-agents-agent-paper-trading.md +7 -3
  186. package/dist/packages/mcp/assets/kb/docs/docs-agents-reading-your-trade-ledger.md +31 -0
  187. package/dist/packages/mcp/assets/kb/docs/docs-agents-untrusted-by-default.md +1 -1
  188. package/dist/packages/mcp/assets/kb/docs/docs-analyst-if-claude-is-missing.md +1 -1
  189. package/dist/packages/mcp/assets/kb/docs/docs-analyst-starting-a-run.md +2 -0
  190. package/dist/packages/mcp/assets/kb/docs/docs-analyst-use-a-local-model-instead.md +27 -0
  191. package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-it-sees.md +2 -0
  192. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-backtests-and-their-limits.md +56 -0
  193. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-change-a-strategy-by-chat.md +49 -0
  194. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-checking-the-record-of-a-run.md +28 -0
  195. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-comparing-them.md +41 -0
  196. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-exits-and-wakes.md +76 -0
  197. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-how-a-stop-reaches-the-runner.md +32 -0
  198. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-on-the-q-screen.md +37 -0
  199. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-one-strategy-or-all-of-them.md +35 -0
  200. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-paper-accounts.md +50 -0
  201. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-presets.md +37 -0
  202. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-running-it-all-day.md +31 -0
  203. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-sessions-and-their-limits.md +31 -0
  204. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-several-strategies-at-once.md +33 -0
  205. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-stopping-it.md +35 -0
  206. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-strategies-and-presets.md +34 -0
  207. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-autotrade-json-file.md +48 -0
  208. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-heartbeat.md +27 -0
  209. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-run-file-and-the-heartbeat.md +34 -0
  210. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-runner-and-candidate-sessions.md +45 -0
  211. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-each-session-shows-first.md +31 -0
  212. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-costs-claude-usage-per-session.md +58 -0
  213. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-is-paper-self-directed.md +43 -0
  214. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-will-not-do.md +31 -0
  215. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-which-account-day-caps-and-the-usage-guard.md +44 -0
  216. package/dist/packages/mcp/assets/kb/docs/docs-autotrade-your-strategies.md +37 -0
  217. package/dist/packages/mcp/assets/kb/docs/docs-autotrade.md +22 -0
  218. package/dist/packages/mcp/assets/kb/docs/docs-beginners-before-any-experimental-trading.md +2 -2
  219. package/dist/packages/mcp/assets/kb/docs/docs-beginners.md +1 -1
  220. package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-markers.md +30 -0
  221. package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-y-axis.md +32 -0
  222. package/dist/packages/mcp/assets/kb/docs/docs-configuration-environment-variables.md +4 -1
  223. package/dist/packages/mcp/assets/kb/docs/docs-configuration-files-on-disk.md +1 -0
  224. package/dist/packages/mcp/assets/kb/docs/docs-configuration-headless-recorder-dexterm-record.md +3 -1
  225. package/dist/packages/mcp/assets/kb/docs/docs-configuration-price-display-mode.md +9 -7
  226. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-2-the-one-key-mirror-ticket-a-proposal.md +1 -1
  227. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-3-capped-auto-mirror-default-off-less.md +1 -1
  228. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-what-is-proven-what-is-not.md +1 -1
  229. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading.md +1 -1
  230. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-recorded-history-and-retention.md +36 -0
  231. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-sources.md +1 -0
  232. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-first-run.md +1 -1
  233. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-install.md +3 -3
  234. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-requirements.md +1 -1
  235. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-running-the-tests.md +1 -1
  236. package/dist/packages/mcp/assets/kb/docs/docs-getting-started.md +1 -1
  237. package/dist/packages/mcp/assets/kb/docs/docs-larp-measured-accuracy.md +1 -0
  238. package/dist/packages/mcp/assets/kb/docs/docs-larp-the-larp-score.md +60 -0
  239. package/dist/packages/mcp/assets/kb/docs/docs-larp-the-verdict.md +0 -2
  240. package/dist/packages/mcp/assets/kb/docs/docs-larp-what-it-looks-at.md +4 -1
  241. package/dist/packages/mcp/assets/kb/docs/docs-larp.md +1 -1
  242. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-changed-in-0-1-7.md +26 -0
  243. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-stopping.md +28 -0
  244. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-the-short-version.md +34 -0
  245. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-using-a-trading-bot-with-dexterm.md +33 -0
  246. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does-not-do.md +30 -0
  247. package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does.md +29 -0
  248. package/dist/packages/mcp/assets/kb/docs/docs-live-trading.md +23 -0
  249. package/dist/packages/mcp/assets/kb/docs/docs-ollama-another-machine.md +28 -0
  250. package/dist/packages/mcp/assets/kb/docs/docs-ollama-autotrade-on-a-local-model.md +29 -0
  251. package/dist/packages/mcp/assets/kb/docs/docs-ollama-check-your-model-dexterm-ai-probe.md +38 -0
  252. package/dist/packages/mcp/assets/kb/docs/docs-ollama-how-we-checked.md +27 -0
  253. package/dist/packages/mcp/assets/kb/docs/docs-ollama-models-without-tool-calling.md +32 -0
  254. package/dist/packages/mcp/assets/kb/docs/docs-ollama-pick-the-engine-globally-or-per-surface.md +43 -0
  255. package/dist/packages/mcp/assets/kb/docs/docs-ollama-restriction-profiles.md +35 -0
  256. package/dist/packages/mcp/assets/kb/docs/docs-ollama-set-it-up-in-two-minutes.md +39 -0
  257. package/dist/packages/mcp/assets/kb/docs/docs-ollama-troubleshooting.md +35 -0
  258. package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-runs-on-a-local-model.md +39 -0
  259. package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-stays-outside-the-model.md +36 -0
  260. package/dist/packages/mcp/assets/kb/docs/docs-ollama-which-model.md +38 -0
  261. package/dist/packages/mcp/assets/kb/docs/docs-ollama-your-own-agent-on-the-local-model.md +28 -0
  262. package/dist/packages/mcp/assets/kb/docs/docs-ollama.md +28 -0
  263. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-letting-an-agent-paper-trade-experimental.md +3 -4
  264. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet-read-only.md +30 -0
  265. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-order-plans-and-standing-mandates.md +4 -13
  266. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-panic.md +4 -7
  267. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-paper-only-mandates.md +40 -0
  268. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-pnl-cards.md +7 -7
  269. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-safety-model.md +34 -0
  270. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-ticket.md +3 -4
  271. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-trade-ledger.md +42 -0
  272. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-wallet.md +4 -5
  273. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-trade-moments.md +4 -5
  274. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading.md +4 -5
  275. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-buy-and-sell-markers.md +37 -0
  276. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-market-cap-axis.md +1 -1
  277. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-what-it-shows.md +3 -1
  278. package/dist/packages/mcp/assets/kb/docs/docs-scan-the-read.md +2 -0
  279. package/dist/packages/mcp/assets/kb/docs/docs-screens-autotrade-paper.md +26 -0
  280. package/dist/packages/mcp/assets/kb/docs/docs-screens-dev-history.md +10 -7
  281. package/dist/packages/mcp/assets/kb/docs/docs-screens-order-plans.md +1 -1
  282. package/dist/packages/mcp/assets/kb/docs/docs-screens-token-screen.md +2 -0
  283. package/dist/packages/mcp/assets/kb/docs/docs-spectator-follow-over-mcp-in-the-running-terminal.md +1 -1
  284. package/dist/packages/mcp/assets/kb/docs/docs-spectator-limits.md +2 -0
  285. package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-agent-hud-spectator-v2.md +58 -0
  286. package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-brain-view-and-the-pnl-chip.md +46 -0
  287. package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-three-surfaces.md +1 -1
  288. package/dist/packages/mcp/assets/kb/docs/docs-spectator.md +1 -1
  289. package/dist/packages/mcp/assets/kb/docs/docs-telegram-approve-one-tap-entries.md +50 -0
  290. package/dist/packages/mcp/assets/kb/docs/docs-telegram-control-the-commands.md +43 -0
  291. package/dist/packages/mcp/assets/kb/docs/docs-telegram-if-something-goes-wrong.md +30 -0
  292. package/dist/packages/mcp/assets/kb/docs/docs-telegram-notify-what-reaches-your-phone.md +41 -0
  293. package/dist/packages/mcp/assets/kb/docs/docs-telegram-set-it-up.md +47 -0
  294. package/dist/packages/mcp/assets/kb/docs/docs-telegram-the-record.md +26 -0
  295. package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-is.md +33 -0
  296. package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-will-not-do.md +31 -0
  297. package/dist/packages/mcp/assets/kb/docs/docs-telegram.md +23 -0
  298. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-common-questions.md +1 -1
  299. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-doctor-lines.md +4 -0
  300. package/dist/packages/mcp/assets/kb/docs/docs-voice-linux-and-windows.md +1 -1
  301. package/dist/packages/mcp/assets/kb/docs/docs-voice.md +1 -1
  302. package/dist/packages/mcp/assets/kb/docs/docs-yolo-1-replay-it-on-your-own-history.md +42 -0
  303. package/dist/packages/mcp/assets/kb/docs/docs-yolo-2-run-it-on-paper.md +34 -0
  304. package/dist/packages/mcp/assets/kb/docs/docs-yolo-3-watch-it-and-stop-it.md +32 -0
  305. package/dist/packages/mcp/assets/kb/docs/docs-yolo-the-rules.md +37 -0
  306. package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-is.md +34 -0
  307. package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-will-not-do.md +31 -0
  308. package/dist/packages/mcp/assets/kb/docs/docs-yolo.md +26 -0
  309. package/dist/packages/mcp/assets/kb/entries/autotrade.md +38 -0
  310. package/dist/packages/mcp/src/app-help.js +1 -1
  311. package/dist/packages/mcp/src/autotrade-tools.js +944 -0
  312. package/dist/packages/mcp/src/backtest-requests.js +71 -0
  313. package/dist/packages/mcp/src/engine/config.js +159 -0
  314. package/dist/packages/mcp/src/engine/index.js +10 -0
  315. package/dist/packages/mcp/src/engine/loop.js +101 -0
  316. package/dist/packages/mcp/src/engine/mcp-client.js +123 -0
  317. package/dist/packages/mcp/src/engine/ollama.js +258 -0
  318. package/dist/packages/mcp/src/engine/probe.js +110 -0
  319. package/dist/packages/mcp/src/engine/reason.js +35 -0
  320. package/dist/packages/mcp/src/engine/restrictions.js +111 -0
  321. package/dist/packages/mcp/src/index.js +7 -1
  322. package/dist/packages/mcp/src/ledger-tools.js +346 -0
  323. package/dist/packages/mcp/src/paper-agent.js +5 -2
  324. package/dist/packages/mcp/src/server.js +285 -36
  325. package/dist/packages/mcp/src/spectator-sink.js +85 -0
  326. package/dist/packages/packs/src/backtest.js +3 -1
  327. package/dist/packages/packs/src/index.js +1 -0
  328. package/dist/packages/packs/src/larp-score-backtest.js +119 -0
  329. package/dist/packages/popup/src/pages/chart-lib.js +169 -35
  330. package/dist/packages/popup/src/pages/chart.css +18 -0
  331. package/dist/packages/popup/src/pages/chart.html +6 -1
  332. package/dist/packages/popup/src/pages/chart.js +136 -10
  333. package/dist/packages/popup/src/pages/spectator.css +45 -0
  334. package/dist/packages/popup/src/pages/spectator.html +1 -0
  335. package/dist/packages/popup/src/pages/spectator.js +69 -0
  336. package/dist/packages/popup/src/protocol.js +4 -0
  337. package/dist/packages/popup/src/server.js +9 -1
  338. package/dist/packages/recorder/src/dev-history.js +7 -3
  339. package/dist/packages/recorder/src/index.js +2 -0
  340. package/dist/packages/recorder/src/recorder.js +63 -6
  341. package/dist/packages/recorder/src/retention.js +100 -0
  342. package/dist/packages/recorder/src/schema.js +34 -1
  343. package/dist/packages/recorder/src/ticks.js +237 -0
  344. package/dist/packages/tui/src/canvas.js +7 -0
  345. package/dist/packages/tui/src/fmt.js +53 -0
  346. package/dist/packages/tui/src/index.js +1 -0
  347. package/dist/packages/tui/src/keymap.js +25 -1
  348. package/dist/packages/tui/src/markers.js +219 -0
  349. package/dist/packages/tui/src/widgets.js +158 -6
  350. package/package.json +2 -1
  351. package/dist/packages/data/src/trade/caps.js +0 -323
  352. package/dist/packages/data/src/trade/executor.js +0 -933
  353. package/dist/packages/data/src/trade/plans/executor-live.js +0 -220
  354. package/dist/packages/data/src/trade/rpc-exec.js +0 -229
  355. package/dist/packages/data/src/trade/signer/client.js +0 -197
  356. package/dist/packages/data/src/trade/signer/fast-wallet.js +0 -154
  357. package/dist/packages/data/src/trade/signer/host.js +0 -97
  358. package/dist/packages/data/src/trade/signer/main.js +0 -121
  359. package/dist/packages/data/src/trade/signer/probe-builder.js +0 -85
  360. package/dist/packages/data/src/trade/signer/protocol.js +0 -92
  361. package/dist/packages/data/src/trade/signer/service.js +0 -400
  362. package/dist/packages/data/src/trade/signer/sol-usd-feed.js +0 -98
  363. package/dist/packages/data/src/trade/sol-usd.js +0 -86
  364. package/dist/packages/data/src/trade/swap-build.js +0 -108
  365. package/dist/packages/data/src/trade/token-delta.js +0 -201
  366. package/dist/packages/data/vendor/solana-web3/LICENSE +0 -20
  367. package/dist/packages/data/vendor/solana-web3/NOTICE.md +0 -13
  368. package/dist/packages/data/vendor/solana-web3/index.iife.min.js +0 -20
  369. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-a-live-ticket.md +0 -42
  370. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-before-you-press-size-vs-caps.md +0 -34
  371. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-devnet-signer-mainnet-token.md +0 -35
  372. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-jupiter-rate-limits.md +0 -33
  373. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet.md +0 -32
  374. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-live-trading-devnet-first.md +0 -30
  375. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-mainnet.md +0 -31
  376. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-live-fire-path-devnet-the-fast-wallet.md +0 -41
  377. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-signer-process.md +0 -34
  378. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-what-the-live-path-keeps.md +0 -37
  379. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-your-first-live-trade.md +0 -41
@@ -49,13 +49,15 @@ function keysDisplay(b) {
49
49
  * `--fixtures`.
50
50
  */
51
51
  export function OVERLAY_HINTS(screen, fixtures) {
52
+ // task-1508: on the AUTOTRADE screen c / n / u / d / x are its own verbs (the loop skips calm and the demo keys there).
53
+ const own = screen === 'autotrade';
52
54
  const rows = [
53
- { keys: 'c', label: 'calm mode (effects off)' },
55
+ ...(own ? [] : [{ keys: 'c', label: 'calm mode (effects off)' }]),
54
56
  { keys: '?', label: 'this help' },
55
57
  ];
56
58
  if (screen === 'analyst')
57
59
  rows.unshift({ keys: 'type', label: 'ask a follow-up · ⏎ send · esc clear/back' });
58
- if (fixtures)
60
+ if (fixtures && !own)
59
61
  rows.push({ keys: 'n/u/d/x', label: 'demo: new pair · pump · dump · rug' });
60
62
  return rows;
61
63
  }
@@ -102,6 +104,7 @@ const SCREEN_TITLE = {
102
104
  ticket: 'Paper trade ticket', positions: 'Paper positions',
103
105
  trending: 'Trending in the space', kol: 'KOL lists', bubbles: 'Bubble map', narrative: 'Narrative board',
104
106
  plans: 'Order plans & mandates', follows: 'Followed wallets', rules: 'Rules (alerts + proposals only)',
107
+ autotrade: 'Autotrade (paper)',
105
108
  };
106
109
  /** Draw a centered modal card and return its inner rect, or null when the terminal is too small. */
107
110
  function card(c, want, title, caption) {
@@ -27,11 +27,10 @@ export function renderPlans(c, state) {
27
27
  const top = 2, bottom = c.h - 1;
28
28
  const risk = svc ? svc.riskStatus() : { gateOff: false, acceptedAt: null, expiresAt: null, active: false };
29
29
  const gateLabel = risk.active ? 'HANDS-FREE' : 'GATE ON';
30
- // task-1363: the fire path. Anything not provably paper renders LIVE (fail-safe).
31
- const liveFire = svc ? svc.mode() === 'live' : false;
32
- const fireLabel = liveFire ? '◉ LIVE · DEVNET · FAST WALLET' : 'PAPER';
30
+ // task-1571: plans fire on PAPER only (dexterm holds no key; there is no live fire path).
31
+ const fireLabel = 'PAPER';
33
32
  const title = `ORDER PLANS & MANDATES · ${tab === 'plans' ? `${plans.length} plans` : `${mandates.length} mandates`} · ${fireLabel} · ${gateLabel}`;
34
- const caption = bp === 'compact' ? undefined : 'voice/agents PROPOSE only · arming needs a physical keypress hold · caps are signer-side · panic revokes all';
33
+ const caption = bp === 'compact' ? undefined : 'voice/agents PROPOSE only · arming needs a physical keypress hold · paper fills only · panic revokes all';
35
34
  const box = c.box(0, top, c.w, bottom - top, { title, caption, focus: true });
36
35
  const bg = box.bg;
37
36
  const now = state.now.getTime();
@@ -89,7 +88,7 @@ export function renderPlans(c, state) {
89
88
  const mbox = c.box(mx, my, mw, mh, { title: '⚠ ARM — physical keypress', focus: true });
90
89
  const label = a.kind === 'plan' ? `Arm plan ${a.id} into ${a.mandateId}?` : `Arm standing mandate ${a.id}?`;
91
90
  c.textC(mbox.x, mbox.y, mbox.w, label, { fg: t.text, bg: mbox.bg, b: true });
92
- c.textC(mbox.x, mbox.y + 1, mbox.w, a.kind === 'mandate' ? 'armed plans can fire at machine speed from the capped fast wallet' : 'the signer re-checks caps on every fill; voice/agents can never arm', { fg: t.muted, bg: mbox.bg });
91
+ c.textC(mbox.x, mbox.y + 1, mbox.w, a.kind === 'mandate' ? 'armed plans can fire at machine speed on paper (simulated fills)' : 'the caps are re-checked on every paper fill; voice/agents can never arm', { fg: t.muted, bg: mbox.bg });
93
92
  c.textC(mbox.x, mbox.y + 3, mbox.w, 'Hold and release [enter] or [y] to confirm · [esc] cancels · a pipe/agent cannot arm', { fg: t.accent, bg: mbox.bg });
94
93
  }
95
94
  // The "less safe" hands-free opt-in modal (Tier 4): keypress-only, journaled, auto-expires 24h, reversible.
@@ -102,17 +101,6 @@ export function renderPlans(c, state) {
102
101
  c.textC(mbox.x, mbox.y + 3, mbox.w, 'signer caps, allow-lists and panic still apply · this auto-expires in 24h · logged to the journal', { fg: t.muted, bg: mbox.bg });
103
102
  c.textC(mbox.x, mbox.y + 5, mbox.w, risk.active ? 'Hold+release [enter]/[y] to restore the gate · [esc] cancels' : 'Hold+release [enter]/[y] to accept (keypress only) · [esc] cancels · a pipe/agent cannot', { fg: t.accent, bg: mbox.bg });
104
103
  }
105
- // task-1363: the FIRE PATH modal (paper ⇄ live). Switched by a captured keypress in the loop; this paints the prompt.
106
- if (ui?.liveModal) {
107
- const mw = Math.min(box.w - 4, 78), mh = 9;
108
- const mx = box.x + Math.floor((box.w - mw) / 2), my = box.y + Math.floor((box.h - mh) / 2);
109
- const mbox = c.box(mx, my, mw, mh, { title: liveFire ? 'FIRE PATH — back to PAPER' : '⚠ FIRE PATH — go LIVE on DEVNET', focus: true });
110
- c.textC(mbox.x, mbox.y, mbox.w, liveFire ? 'Switch plan fills back to the paper executor?' : 'Fire armed plans through the SIGNER from the capped fast wallet (devnet)?', { fg: t.text, bg: mbox.bg, b: true });
111
- c.textC(mbox.x, mbox.y + 2, mbox.w, liveFire ? 'fills are then simulated again at the tick price; nothing on chain' : 'real devnet lamports move (fees of a wrap-and-unwrap sized to the plan); the token leg is modelled — Jupiter has no devnet', { fg: liveFire ? t.muted : t.down, bg: mbox.bg });
112
- c.textC(mbox.x, mbox.y + 3, mbox.w, 'the signer re-checks policy, simulation, USD per-trade/daily caps and the 0.05 SOL per-fill ceiling on every fill', { fg: t.muted, bg: mbox.bg });
113
- c.textC(mbox.x, mbox.y + 4, mbox.w, 'needs: a live run with the signer, `dexterm wallet fast create`, no armed/filled plans · never mainnet · journaled', { fg: t.muted, bg: mbox.bg });
114
- c.textC(mbox.x, mbox.y + 6, mbox.w, 'Hold+release [enter]/[y] to switch (keypress only) · [esc] cancels · a pipe/agent/voice cannot', { fg: t.accent, bg: mbox.bg });
115
- }
116
104
  // task-1366: the selected plan's levels with BOTH market cap and price (display only; mc first in mcap mode)
117
105
  if (tab === 'plans' && svc && !ui?.notice) {
118
106
  const r = rows[sel];
@@ -122,5 +110,5 @@ export function renderPlans(c, state) {
122
110
  }
123
111
  if (ui?.notice)
124
112
  c.text(box.x + 1, box.y + box.h - 1, ui.notice, { fg: t.accent, bg });
125
- footer(c, [['↑↓', 'move'], ['tab', 'plans/mandates'], ['a', 'arm (hold)'], tab === 'plans' ? ['c', 'cancel'] : ['r', 'revoke'], ['L', liveFire ? 'paper' : 'live (devnet)'], ['G', risk.active ? 'gate on' : 'hands-free'], ['!', 'PANIC'], ['esc', 'back'], ['q', 'quit']], t.name);
113
+ footer(c, [['↑↓', 'move'], ['tab', 'plans/mandates'], ['a', 'arm (hold)'], tab === 'plans' ? ['c', 'cancel'] : ['r', 'revoke'], ['G', risk.active ? 'gate on' : 'hands-free'], ['!', 'PANIC'], ['esc', 'back'], ['q', 'quit']], t.name);
126
114
  }
@@ -0,0 +1,144 @@
1
+ // dexterm — the persistent POSITION PnL chip (task-1473). While an auto mode runs and a position is open, one compact
2
+ // readout is on every terminal screen and on the chart popup: coin, mark PnL % with sign (and $ when the size is
3
+ // known), entry → mark, peak, drawdown from the peak, time held and the take-profit. Sources (state.ts pnlChipFor):
4
+ // · following an agent (task-1466 HUD) that holds a PAPER ticket — the folded story, TP = what the agent said;
5
+ // · AI scan mode with the user's OWN paper or live position (OwnPnlTracker; session peak, TP = the ledger target).
6
+ // Where it draws: the HUD dock's signal row when the dock is up (≥ HUD_MIN_H rows while following), else the band
7
+ // under the header (row 1, right-aligned: short terminals, scan mode), and the chart popup's chip strip (ChartVM.chip).
8
+ // It updates on every mark tick, flashes on a new peak (a ★ glyph says the same under calm mode / NO_COLOR) and drops
9
+ // fields from the right as the width shrinks. Display only: it has no input and reads only folded / ledger state.
10
+ import { mix } from '../../../tui/src/index.js';
11
+ import { fmtPx } from '../../../agents/src/index.js';
12
+ import { planFromThoughts, fmtDur } from "./brain.js";
13
+ export const PEAK_FLASH_MS = 1200;
14
+ export const CHIP_PRICE_LEVEL = (u) => `$${fmtPx(u)}`;
15
+ const PRICE_LEVEL = CHIP_PRICE_LEVEL;
16
+ export function pnlChipVM(v, now, lvl = PRICE_LEVEL) {
17
+ const a = v.arc;
18
+ if (!a || a.stage !== 'open')
19
+ return null;
20
+ const dd = a.pnlPct !== null && a.peakPct !== null ? (1 + a.pnlPct) / (1 + a.peakPct) - 1 : null;
21
+ return {
22
+ kind: 'PAPER',
23
+ symbol: a.symbol,
24
+ pnlPct: a.pnlPct,
25
+ pnlUsd: a.pnlPct !== null && a.sizeUsd !== null ? a.sizeUsd * a.pnlPct : null,
26
+ entry: a.entryUsd !== null ? lvl(a.entryUsd, a.mint) : '—',
27
+ mark: a.mark ? lvl(a.mark.priceUsd, a.mint) : '—',
28
+ peakPct: a.peakPct,
29
+ ddPct: dd,
30
+ heldMs: a.filledAt !== null ? now - a.filledAt : null,
31
+ tp: planFromThoughts(v.thoughts, a.openedAt).tp,
32
+ newPeak: a.peakAt !== null && now - a.peakAt < PEAK_FLASH_MS && a.peakPct !== null && a.peakPct > 0,
33
+ };
34
+ }
35
+ /**
36
+ * The user's own position chip in AI scan mode. The ledgers keep no peak, so the peak is this session's highest
37
+ * mark (reset when the held coin or ledger changes, or the position goes flat). Display only.
38
+ */
39
+ export class OwnPnlTracker {
40
+ cur = null;
41
+ update(s, now) {
42
+ if (!s) {
43
+ this.cur = null;
44
+ return;
45
+ }
46
+ const seed = !this.cur || this.cur.s.mint !== s.mint || this.cur.s.kind !== s.kind;
47
+ if (seed)
48
+ this.cur = { s, peakPct: s.pnlPct, peakAt: null }; // the first mark is not a "new peak" flash
49
+ const c = this.cur;
50
+ c.s = s;
51
+ if (!seed && s.pnlPct !== null && (c.peakPct === null || s.pnlPct > c.peakPct + 1e-9)) {
52
+ c.peakPct = s.pnlPct;
53
+ c.peakAt = now;
54
+ }
55
+ }
56
+ get mint() { return this.cur?.s.mint ?? null; }
57
+ vm(now, lvl = PRICE_LEVEL) {
58
+ const c = this.cur;
59
+ if (!c)
60
+ return null;
61
+ const s = c.s;
62
+ const dd = s.pnlPct !== null && c.peakPct !== null ? (1 + s.pnlPct) / (1 + c.peakPct) - 1 : null;
63
+ return {
64
+ kind: s.kind === 'live' ? 'LIVE' : 'PAPER',
65
+ symbol: s.symbol,
66
+ pnlPct: s.pnlPct,
67
+ pnlUsd: s.pnlUsd,
68
+ entry: s.entryUsd !== null ? lvl(s.entryUsd, s.mint) : '—',
69
+ mark: s.markUsd !== null ? lvl(s.markUsd, s.mint) : '—',
70
+ peakPct: c.peakPct,
71
+ ddPct: dd,
72
+ heldMs: s.openedAt !== null ? Math.max(0, now - s.openedAt) : null,
73
+ tp: s.targetUsd !== null ? lvl(s.targetUsd, s.mint) : null,
74
+ tpNone: 'not set',
75
+ newPeak: c.peakAt !== null && now - c.peakAt < PEAK_FLASH_MS && c.peakPct !== null && c.peakPct > 0,
76
+ };
77
+ }
78
+ }
79
+ const pct = (r) => `${r >= 0 ? '+' : '−'}${Math.abs(r * 100).toFixed(1)}%`;
80
+ const usd = (n) => `${n >= 0 ? '+' : '−'}$${Math.abs(n).toFixed(2)}`;
81
+ /** The chip's segments in priority order (the first ones survive the narrowest widths). */
82
+ export function chipSegments(m) {
83
+ const segs = [];
84
+ const dir = m.pnlPct === null ? '·' : m.pnlPct >= 0 ? '▲' : '▼';
85
+ segs.push({ id: 'head', text: `${m.kind} $${m.symbol}` });
86
+ segs.push({ id: 'pnl', text: `${dir} ${m.pnlPct === null ? '—' : pct(m.pnlPct)}${m.pnlUsd !== null ? ` ${usd(m.pnlUsd)}` : ''}` });
87
+ if (m.peakPct !== null)
88
+ segs.push({ id: 'peak', text: `peak ${pct(m.peakPct)}${m.newPeak ? ' ★' : ''}` });
89
+ segs.push({ id: 'px', text: `${m.entry} → ${m.mark}` });
90
+ if (m.heldMs !== null)
91
+ segs.push({ id: 'held', text: `held ${fmtDur(m.heldMs)}` });
92
+ if (m.ddPct !== null && m.ddPct < -0.0005)
93
+ segs.push({ id: 'dd', text: `dd ${pct(m.ddPct)}` });
94
+ segs.push({ id: 'tp', text: m.tp ? `TP ${m.tp}` : `TP ${m.tpNone ?? 'agent-managed'}` });
95
+ return segs;
96
+ }
97
+ const SEP = ' │ ';
98
+ /** The chip text that fits in `maxW` (segments drop from the end). Pure, for tests. */
99
+ export function chipText(m, maxW) {
100
+ const segs = chipSegments(m);
101
+ let n = segs.length;
102
+ const join = (k) => ` ${segs.slice(0, k).map((s) => s.text).join(SEP)} `;
103
+ while (n > 1 && join(n).length > maxW)
104
+ n--;
105
+ const s = join(n);
106
+ return s.length <= maxW ? s : '';
107
+ }
108
+ /**
109
+ * Draw the chip right-aligned to `right` (exclusive) on row `y`, no wider than `maxW`. Returns the x it starts at
110
+ * (or `right` when nothing fits).
111
+ */
112
+ export function renderPnlChip(c, right, y, maxW, m, o) {
113
+ const t = c.theme;
114
+ const text = chipText(m, maxW);
115
+ if (!text)
116
+ return right;
117
+ const x0 = right - text.length;
118
+ const bg = mix(t.bg, t.magenta, 0.22);
119
+ const col = m.pnlPct === null ? t.muted : m.pnlPct >= 0 ? t.up : t.down;
120
+ c.text(x0, y, text, { fg: t.text, bg });
121
+ // re-colour the segments: head magenta, PnL red/green bold (flash on a new peak), peak green, dd warn
122
+ let x = x0 + 1;
123
+ for (const s of chipSegments(m)) {
124
+ if (x + s.text.length > right - 1)
125
+ break;
126
+ if (s.id === 'head')
127
+ c.text(x, y, s.text, { fg: t.magenta, bg, b: true });
128
+ else if (s.id === 'pnl') {
129
+ const flash = m.newPeak && !o.reduced;
130
+ c.text(x, y, s.text, flash ? { fg: t.bg, bg: t.up, b: true } : { fg: col, bg, b: true });
131
+ }
132
+ else if (s.id === 'peak')
133
+ c.text(x, y, s.text, { fg: m.peakPct !== null && m.peakPct >= 0 ? t.up : t.down, bg, b: m.newPeak });
134
+ else if (s.id === 'dd')
135
+ c.text(x, y, s.text, { fg: t.warn, bg });
136
+ else
137
+ c.text(x, y, s.text, { fg: t.muted, bg });
138
+ x += s.text.length;
139
+ if (x + SEP.length < right)
140
+ c.text(x, y, SEP, { fg: mix(bg, t.border, 0.8), bg });
141
+ x += SEP.length;
142
+ }
143
+ return x0;
144
+ }
@@ -4,7 +4,7 @@
4
4
  import { Canvas, header, footer, breakpoint, mix, isCalm, fmtPriceBare, fmtMcap, fmtNum, fmtPct, fmtAgeSec, shortAddr, } from '../../../tui/src/index.js';
5
5
  import { lamportsToSol, rawToTokens, positionPnl } from '../../../data/src/index.js';
6
6
  import { headerModel } from "../state.js";
7
- import { priceModeOf, supplyRatio, FALLBACK_MARK } from "../display.js";
7
+ import { priceModeOf, supplyRatio, supplyForMint, FALLBACK_MARK } from "../display.js";
8
8
  export function sol(n, digits = 4) {
9
9
  return `${n >= 0 ? '' : '-'}${Math.abs(n).toFixed(digits)}`;
10
10
  }
@@ -75,7 +75,7 @@ export function renderPositions(c, state) {
75
75
  // task-1366: mcap mode reads AVG / PRICE as market cap = SOL price × SOL/USD × the token's CURRENT supply (from the
76
76
  // screener rows); a token without a supply (or no SOL/USD yet) keeps its SOL price, marked ᵖ. PnL stays SOL.
77
77
  const mode = priceModeOf(state);
78
- const supplyOf = (mint) => { const row = state.screener.rows.find((x) => x.mint === mint); return row ? supplyRatio(row.price, row.mcap) : null; };
78
+ const supplyOf = (mint) => supplyForMint(state, mint); // task-1537: + the open token view and pump.fun's 1B
79
79
  const mcCell = (pSol, mint) => {
80
80
  if (pSol === null)
81
81
  return '—';
@@ -126,33 +126,9 @@ export function renderPositions(c, state) {
126
126
  }
127
127
  py += 1;
128
128
  }
129
- // task-1328: LIVE positions (the signer's ledger file, read-only), only when there are any.
130
- const liveSrc = state.live?.livePositions ?? null;
131
- const livePos = liveSrc ? liveSrc.positions().filter((p) => p.tokensRaw > 0n) : [];
132
129
  y += half;
133
- if (livePos.length > 0) {
134
- const lh = Math.min(livePos.length + 3, Math.max(5, Math.floor((bottom - y) * 0.4)));
135
- const lb = c.box(0, y, c.w, lh, { title: '◉ LIVE POSITIONS', titleFg: t.up, caption: 'confirmed on-chain fills · signer ledger' });
136
- let ly = lb.y;
137
- for (const p of livePos) {
138
- if (ly >= lb.y + lb.h)
139
- break;
140
- const mark = liveSrc?.held(p.mint)?.markSol ?? null;
141
- const pnl = positionPnl(p, mark);
142
- let cx = c.text(lb.x + 1, ly, `$${p.symbol}`, { fg: t.text, bg: lb.bg, b: true });
143
- cx = c.text(cx + 2, ly, fmtNum(rawToTokens(p.tokensRaw, p.decimals)), { fg: t.muted, bg: lb.bg });
144
- cx = c.text(cx + 2, ly, `cost ${sol(pnl.costSol)} SOL`, { fg: t.dim, bg: lb.bg });
145
- if (pnl.avgEntrySol !== null)
146
- cx = c.text(cx + 2, ly, `avg ${fmtPriceBare(pnl.avgEntrySol)}`, { fg: t.dim, bg: lb.bg });
147
- if (pnl.unrealizedSol !== null)
148
- c.text(cx + 2, ly, `uPnL ${signedSol(pnl.unrealizedSol)} SOL${pnl.unrealizedPct !== null ? ` ${fmtPct(pnl.unrealizedPct * 100)}` : ''}`, { fg: pnl.unrealizedSol >= 0 ? t.up : t.down, bg: lb.bg, b: true });
149
- c.textR(lb.x + 1, ly, lb.w - 2, `${shortAddr(p.mint, 4)} · LIVE`, { fg: t.up, bg: lb.bg });
150
- ly += 1;
151
- }
152
- y += lh;
153
- }
154
130
  // history
155
- const hb = c.box(0, y, c.w, bottom - y, { title: 'TRADE HISTORY', caption: `${v.history.length} paper fills${liveSrc ? ` · ${liveSrc.records(50).length} live` : ''}` });
131
+ const hb = c.box(0, y, c.w, bottom - y, { title: 'TRADE HISTORY', caption: `${v.history.length} paper fills` });
156
132
  let yy = hb.y;
157
133
  for (const h of v.history) {
158
134
  if (yy >= hb.y + hb.h)
@@ -163,7 +139,9 @@ export function renderPositions(c, state) {
163
139
  let cx = c.text(hb.x + 1, yy, fmtAgeSec(Math.max(0, Math.round((state.now.getTime() - h.t) / 1000))).padStart(4), { fg: t.dim, bg: hb.bg });
164
140
  cx = c.text(cx + 1, yy, h.side === 'buy' ? '▲ BUY ' : '▼ SELL', { fg: sideColor, bg: hb.bg, b: true });
165
141
  cx = c.text(cx + 1, yy, `$${h.symbol}`, { fg: t.text, bg: hb.bg, b: true });
166
- cx = c.text(cx + 1, yy, `${fmtNum(gotTokens)} @ ${fmtPriceBare(h.priceSol)} SOL`, { fg: t.muted, bg: hb.bg });
142
+ // task-1537: a fill reads as the market cap it filled at (the coin's current known supply), the SOL price kept
143
+ const hsup = mode === 'mcap' ? supplyOf(h.mint) : null;
144
+ cx = c.text(cx + 1, yy, `${fmtNum(gotTokens)} @ ${hsup !== null && v.solPriceUsd ? `${fmtMcap(h.priceSol * v.solPriceUsd * hsup)} mcap (${fmtPriceBare(h.priceSol)} SOL)` : `${fmtPriceBare(h.priceSol)} SOL`}`, { fg: t.muted, bg: hb.bg });
167
145
  cx = c.text(cx + 2, yy, `${signedSol(solAmt)} SOL`, { fg: solAmt >= 0 ? t.up : t.muted, bg: hb.bg });
168
146
  if (h.side === 'sell')
169
147
  c.text(cx + 2, yy, `pnl ${signedSol(lamportsToSol(h.realizedLamports))}`, { fg: h.realizedLamports >= 0n ? t.up : t.down, bg: hb.bg });
@@ -195,6 +195,7 @@ export function renderScreener(c, state) {
195
195
  : null;
196
196
  table(c, box.x + 1, box.y, box.w - 2, box.h, {
197
197
  columns: screenerColumns(c, bp, sc.gates, state.larpByMint ?? null, icon, mode), rows, selected: sel, scroll: Math.max(0, scroll), sortKey: sc.sort.key, sortDir: sc.sort.dir, bg: box.bg,
198
+ rowKey: (r) => r.mint, // task-1466: the agent HUD finds the rows it scanned
198
199
  });
199
200
  if (rows.length === 0)
200
201
  emptyState(c, box, sc);