dexterm-cli 0.0.0-stage → 0.1.1

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 (349) hide show
  1. package/LICENSE +661 -0
  2. package/dist/packages/agents/src/audit.js +122 -0
  3. package/dist/packages/agents/src/bus.js +379 -0
  4. package/dist/packages/agents/src/executor.js +177 -0
  5. package/dist/packages/agents/src/gate.js +176 -0
  6. package/dist/packages/agents/src/identity.js +179 -0
  7. package/dist/packages/agents/src/index.js +15 -0
  8. package/dist/packages/agents/src/proposals.js +153 -0
  9. package/dist/packages/agents/src/schema.js +87 -0
  10. package/dist/packages/agents/src/sdk.js +140 -0
  11. package/dist/packages/agents/src/tiers.js +114 -0
  12. package/dist/packages/agents/src/tools.js +69 -0
  13. package/dist/packages/agents/src/ws.js +158 -0
  14. package/dist/packages/cli/assets/claude/analyst-system.md +76 -0
  15. package/dist/packages/cli/assets/claude/plugin/.claude-plugin/plugin.json +5 -0
  16. package/dist/packages/cli/assets/claude/plugin/skills/REGISTRY.json +16 -0
  17. package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +67 -0
  18. package/dist/packages/cli/assets/claude/plugin/skills/rug-check/SKILL.md +64 -0
  19. package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +63 -0
  20. package/dist/packages/cli/assets/claude/plugin/skills/trench-scan/SKILL.md +44 -0
  21. package/dist/packages/cli/assets/claude/schemas/larp.schema.json +117 -0
  22. package/dist/packages/cli/assets/claude/schemas/trench-scan.schema.json +71 -0
  23. package/dist/packages/cli/assets/claude/schemas/verdict.schema.json +115 -0
  24. package/dist/packages/cli/bin/dexterm.mjs +11 -0
  25. package/dist/packages/cli/src/agent-cmd.js +303 -0
  26. package/dist/packages/cli/src/agent-roster.js +26 -0
  27. package/dist/packages/cli/src/analyst/backend.js +526 -0
  28. package/dist/packages/cli/src/analyst/results.js +38 -0
  29. package/dist/packages/cli/src/analyst/session.js +319 -0
  30. package/dist/packages/cli/src/audit.js +51 -0
  31. package/dist/packages/cli/src/backtest-cmd.js +149 -0
  32. package/dist/packages/cli/src/boot-state.js +62 -0
  33. package/dist/packages/cli/src/custom.js +261 -0
  34. package/dist/packages/cli/src/display.js +191 -0
  35. package/dist/packages/cli/src/doctor.js +361 -0
  36. package/dist/packages/cli/src/feed.js +634 -0
  37. package/dist/packages/cli/src/fixtures.js +275 -0
  38. package/dist/packages/cli/src/follow-cmd.js +221 -0
  39. package/dist/packages/cli/src/images-config.js +59 -0
  40. package/dist/packages/cli/src/index.js +31 -0
  41. package/dist/packages/cli/src/kb-skill-cmd.js +240 -0
  42. package/dist/packages/cli/src/larp-record.js +21 -0
  43. package/dist/packages/cli/src/live/copy.js +80 -0
  44. package/dist/packages/cli/src/live/flow.js +233 -0
  45. package/dist/packages/cli/src/live/index.js +509 -0
  46. package/dist/packages/cli/src/live/intel.js +227 -0
  47. package/dist/packages/cli/src/live/newpairs.js +334 -0
  48. package/dist/packages/cli/src/live/screens/newpairs-live.js +219 -0
  49. package/dist/packages/cli/src/live/screens/token-live.js +459 -0
  50. package/dist/packages/cli/src/live/screens/watchlist-live.js +149 -0
  51. package/dist/packages/cli/src/live/token.js +585 -0
  52. package/dist/packages/cli/src/live/trade.js +929 -0
  53. package/dist/packages/cli/src/live/watchlist.js +178 -0
  54. package/dist/packages/cli/src/main.js +5583 -0
  55. package/dist/packages/cli/src/narrative-cmd.js +76 -0
  56. package/dist/packages/cli/src/pack-cmd.js +323 -0
  57. package/dist/packages/cli/src/plan-cmd.js +278 -0
  58. package/dist/packages/cli/src/popup.js +810 -0
  59. package/dist/packages/cli/src/rules-cmd.js +131 -0
  60. package/dist/packages/cli/src/rules.js +339 -0
  61. package/dist/packages/cli/src/scan/command.js +57 -0
  62. package/dist/packages/cli/src/scan/engine.js +419 -0
  63. package/dist/packages/cli/src/scan/observe.js +64 -0
  64. package/dist/packages/cli/src/scan/ui.js +98 -0
  65. package/dist/packages/cli/src/screener/filter.js +241 -0
  66. package/dist/packages/cli/src/screener/presets.js +80 -0
  67. package/dist/packages/cli/src/screener/rows.js +146 -0
  68. package/dist/packages/cli/src/screener/rug.js +50 -0
  69. package/dist/packages/cli/src/screener/sort.js +52 -0
  70. package/dist/packages/cli/src/screener/view.js +183 -0
  71. package/dist/packages/cli/src/screens/analyst-session.js +343 -0
  72. package/dist/packages/cli/src/screens/analyst.js +326 -0
  73. package/dist/packages/cli/src/screens/boot.js +74 -0
  74. package/dist/packages/cli/src/screens/bubbles.js +255 -0
  75. package/dist/packages/cli/src/screens/coin.js +33 -0
  76. package/dist/packages/cli/src/screens/follows.js +201 -0
  77. package/dist/packages/cli/src/screens/kol.js +90 -0
  78. package/dist/packages/cli/src/screens/narrative.js +90 -0
  79. package/dist/packages/cli/src/screens/newpairs.js +150 -0
  80. package/dist/packages/cli/src/screens/overlay.js +257 -0
  81. package/dist/packages/cli/src/screens/plans.js +126 -0
  82. package/dist/packages/cli/src/screens/positions.js +176 -0
  83. package/dist/packages/cli/src/screens/rules.js +170 -0
  84. package/dist/packages/cli/src/screens/screener.js +459 -0
  85. package/dist/packages/cli/src/screens/social-panel.js +107 -0
  86. package/dist/packages/cli/src/screens/ticket.js +342 -0
  87. package/dist/packages/cli/src/screens/token.js +312 -0
  88. package/dist/packages/cli/src/screens/trending.js +181 -0
  89. package/dist/packages/cli/src/screens/watchlist.js +104 -0
  90. package/dist/packages/cli/src/social/demo.js +96 -0
  91. package/dist/packages/cli/src/social/view.js +250 -0
  92. package/dist/packages/cli/src/state.js +463 -0
  93. package/dist/packages/cli/src/theme-cmd.js +126 -0
  94. package/dist/packages/cli/src/trade.js +319 -0
  95. package/dist/packages/cli/src/voice-hud.js +42 -0
  96. package/dist/packages/cli/src/wallet-cmd.js +440 -0
  97. package/dist/packages/cli/src/wallet-command.js +31 -0
  98. package/dist/packages/cli/src/widgets.js +208 -0
  99. package/dist/packages/cli/src/workspace-cmd.js +68 -0
  100. package/dist/packages/cli/src/x-cmd.js +154 -0
  101. package/dist/packages/custom/src/config.js +213 -0
  102. package/dist/packages/custom/src/index.js +10 -0
  103. package/dist/packages/custom/src/keymap.js +107 -0
  104. package/dist/packages/custom/src/layout.js +235 -0
  105. package/dist/packages/custom/src/packs.js +633 -0
  106. package/dist/packages/custom/src/rules.js +704 -0
  107. package/dist/packages/custom/src/schema.js +515 -0
  108. package/dist/packages/custom/src/themes.js +176 -0
  109. package/dist/packages/custom/src/widget-html.js +222 -0
  110. package/dist/packages/custom/src/workspace.js +141 -0
  111. package/dist/packages/data/src/analyst-actions.js +133 -0
  112. package/dist/packages/data/src/budget.js +88 -0
  113. package/dist/packages/data/src/cache.js +142 -0
  114. package/dist/packages/data/src/candles.js +168 -0
  115. package/dist/packages/data/src/clock.js +64 -0
  116. package/dist/packages/data/src/credits.js +137 -0
  117. package/dist/packages/data/src/detail.js +97 -0
  118. package/dist/packages/data/src/fast-lane.js +321 -0
  119. package/dist/packages/data/src/fixtures.js +135 -0
  120. package/dist/packages/data/src/health.js +245 -0
  121. package/dist/packages/data/src/http.js +277 -0
  122. package/dist/packages/data/src/images/cache.js +141 -0
  123. package/dist/packages/data/src/images/decode-worker.js +28 -0
  124. package/dist/packages/data/src/images/decode.js +81 -0
  125. package/dist/packages/data/src/images/fetch.js +162 -0
  126. package/dist/packages/data/src/images/gif.js +214 -0
  127. package/dist/packages/data/src/images/index.js +10 -0
  128. package/dist/packages/data/src/images/jpeg.js +544 -0
  129. package/dist/packages/data/src/images/png.js +310 -0
  130. package/dist/packages/data/src/images/service.js +334 -0
  131. package/dist/packages/data/src/images/types.js +27 -0
  132. package/dist/packages/data/src/index.js +208 -0
  133. package/dist/packages/data/src/intel/helius-history.js +59 -0
  134. package/dist/packages/data/src/intel/holder-class.js +125 -0
  135. package/dist/packages/data/src/intel/rules.js +421 -0
  136. package/dist/packages/data/src/intel/scan.js +170 -0
  137. package/dist/packages/data/src/larp/evidence.js +288 -0
  138. package/dist/packages/data/src/larp/links.js +137 -0
  139. package/dist/packages/data/src/larp/robots.js +90 -0
  140. package/dist/packages/data/src/larp/safe-fetch.js +389 -0
  141. package/dist/packages/data/src/limiter.js +341 -0
  142. package/dist/packages/data/src/model.js +12 -0
  143. package/dist/packages/data/src/paper.js +331 -0
  144. package/dist/packages/data/src/rpc-config.js +126 -0
  145. package/dist/packages/data/src/rpc-pool.js +166 -0
  146. package/dist/packages/data/src/social/chain.js +83 -0
  147. package/dist/packages/data/src/social/dedupe.js +205 -0
  148. package/dist/packages/data/src/social/feed.js +462 -0
  149. package/dist/packages/data/src/social/firewall.js +110 -0
  150. package/dist/packages/data/src/social/index.js +11 -0
  151. package/dist/packages/data/src/social/kol.js +269 -0
  152. package/dist/packages/data/src/social/model.js +11 -0
  153. package/dist/packages/data/src/social/rank.js +184 -0
  154. package/dist/packages/data/src/social/rss.js +113 -0
  155. package/dist/packages/data/src/social/summary.js +104 -0
  156. package/dist/packages/data/src/social/venues.js +186 -0
  157. package/dist/packages/data/src/sources/dexscreener.js +170 -0
  158. package/dist/packages/data/src/sources/geckoterminal.js +133 -0
  159. package/dist/packages/data/src/sources/goplus.js +161 -0
  160. package/dist/packages/data/src/sources/jupiter-swap.js +236 -0
  161. package/dist/packages/data/src/sources/jupiter.js +198 -0
  162. package/dist/packages/data/src/sources/pda.js +113 -0
  163. package/dist/packages/data/src/sources/pump-curve.js +58 -0
  164. package/dist/packages/data/src/sources/pumpportal.js +247 -0
  165. package/dist/packages/data/src/sources/rugcheck.js +71 -0
  166. package/dist/packages/data/src/sources/solana-rpc.js +299 -0
  167. package/dist/packages/data/src/sources/solana-ws.js +287 -0
  168. package/dist/packages/data/src/store.js +289 -0
  169. package/dist/packages/data/src/trade/bridge.js +464 -0
  170. package/dist/packages/data/src/trade/caps.js +323 -0
  171. package/dist/packages/data/src/trade/copy/auto.js +385 -0
  172. package/dist/packages/data/src/trade/copy/follows.js +103 -0
  173. package/dist/packages/data/src/trade/copy/index.js +9 -0
  174. package/dist/packages/data/src/trade/copy/mirror.js +91 -0
  175. package/dist/packages/data/src/trade/copy/stats.js +120 -0
  176. package/dist/packages/data/src/trade/copy/tracker.js +158 -0
  177. package/dist/packages/data/src/trade/copy/trades.js +87 -0
  178. package/dist/packages/data/src/trade/copy/types.js +6 -0
  179. package/dist/packages/data/src/trade/executor.js +933 -0
  180. package/dist/packages/data/src/trade/kill-switch.js +47 -0
  181. package/dist/packages/data/src/trade/link-store.js +52 -0
  182. package/dist/packages/data/src/trade/plans/confirm.js +157 -0
  183. package/dist/packages/data/src/trade/plans/engine.js +784 -0
  184. package/dist/packages/data/src/trade/plans/executor-live.js +220 -0
  185. package/dist/packages/data/src/trade/plans/executor-paper.js +44 -0
  186. package/dist/packages/data/src/trade/plans/executor.js +11 -0
  187. package/dist/packages/data/src/trade/plans/index.js +12 -0
  188. package/dist/packages/data/src/trade/plans/journal.js +77 -0
  189. package/dist/packages/data/src/trade/plans/mandate.js +129 -0
  190. package/dist/packages/data/src/trade/plans/plan.js +179 -0
  191. package/dist/packages/data/src/trade/plans/service.js +168 -0
  192. package/dist/packages/data/src/trade/plans/types.js +6 -0
  193. package/dist/packages/data/src/trade/rpc-exec.js +229 -0
  194. package/dist/packages/data/src/trade/signer/client.js +197 -0
  195. package/dist/packages/data/src/trade/signer/fast-wallet.js +154 -0
  196. package/dist/packages/data/src/trade/signer/host.js +97 -0
  197. package/dist/packages/data/src/trade/signer/main.js +121 -0
  198. package/dist/packages/data/src/trade/signer/probe-builder.js +85 -0
  199. package/dist/packages/data/src/trade/signer/protocol.js +92 -0
  200. package/dist/packages/data/src/trade/signer/service.js +400 -0
  201. package/dist/packages/data/src/trade/signer/sol-usd-feed.js +98 -0
  202. package/dist/packages/data/src/trade/sol-usd.js +86 -0
  203. package/dist/packages/data/src/trade/swap-build.js +108 -0
  204. package/dist/packages/data/src/trade/token-delta.js +201 -0
  205. package/dist/packages/data/src/trade/tx-decode.js +632 -0
  206. package/dist/packages/data/src/util.js +24 -0
  207. package/dist/packages/data/src/watchlist.js +176 -0
  208. package/dist/packages/data/src/x/api.js +256 -0
  209. package/dist/packages/data/src/x/budget.js +66 -0
  210. package/dist/packages/data/src/x/config.js +49 -0
  211. package/dist/packages/data/src/x/index.js +10 -0
  212. package/dist/packages/data/src/x/mock-server.js +217 -0
  213. package/dist/packages/data/src/x/oauth.js +242 -0
  214. package/dist/packages/data/src/x/pkce.js +21 -0
  215. package/dist/packages/data/src/x/source.js +285 -0
  216. package/dist/packages/data/src/x/token-store.js +134 -0
  217. package/dist/packages/data/src/x/transport.js +71 -0
  218. package/dist/packages/data/vendor/solana-web3/LICENSE +20 -0
  219. package/dist/packages/data/vendor/solana-web3/NOTICE.md +13 -0
  220. package/dist/packages/data/vendor/solana-web3/index.iife.min.js +20 -0
  221. package/dist/packages/mcp/assets/cases.json +1194 -0
  222. package/dist/packages/mcp/assets/kb/entries/cabal-and-coordinated-launches.md +28 -0
  223. package/dist/packages/mcp/assets/kb/entries/common-rug-patterns.md +40 -0
  224. package/dist/packages/mcp/assets/kb/entries/dbc-mechanics.md +30 -0
  225. package/dist/packages/mcp/assets/kb/entries/dev-wallet-behaviour.md +33 -0
  226. package/dist/packages/mcp/assets/kb/entries/glossary.md +35 -0
  227. package/dist/packages/mcp/assets/kb/entries/holder-concentration.md +30 -0
  228. package/dist/packages/mcp/assets/kb/entries/jito-bundles.md +29 -0
  229. package/dist/packages/mcp/assets/kb/entries/launchlab-curve.md +31 -0
  230. package/dist/packages/mcp/assets/kb/entries/lp-burn-vs-lock.md +31 -0
  231. package/dist/packages/mcp/assets/kb/entries/metadata-and-copycats.md +29 -0
  232. package/dist/packages/mcp/assets/kb/entries/mint-freeze-authority.md +31 -0
  233. package/dist/packages/mcp/assets/kb/entries/narrative-lifecycle.md +32 -0
  234. package/dist/packages/mcp/assets/kb/entries/pump-bonding-curve.md +33 -0
  235. package/dist/packages/mcp/assets/kb/entries/pumpswap-migration.md +29 -0
  236. package/dist/packages/mcp/assets/kb/entries/sniping-and-snipers.md +29 -0
  237. package/dist/packages/mcp/assets/kb/entries/token2022-extensions-risk.md +32 -0
  238. package/dist/packages/mcp/assets/kb/entries/wash-trading-fake-volume.md +33 -0
  239. package/dist/packages/mcp/assets/skills/rug-check.md +52 -0
  240. package/dist/packages/mcp/assets/skills/token-dossier.md +57 -0
  241. package/dist/packages/mcp/assets/skills/trench-scan.md +40 -0
  242. package/dist/packages/mcp/bin/dexterm-mcp.mjs +16 -0
  243. package/dist/packages/mcp/src/dossier.js +78 -0
  244. package/dist/packages/mcp/src/firewall.js +21 -0
  245. package/dist/packages/mcp/src/index.js +22 -0
  246. package/dist/packages/mcp/src/server.js +849 -0
  247. package/dist/packages/mcp/src/user-content.js +434 -0
  248. package/dist/packages/packs/src/backtest.js +183 -0
  249. package/dist/packages/packs/src/digest.js +95 -0
  250. package/dist/packages/packs/src/firewall.js +57 -0
  251. package/dist/packages/packs/src/index.js +19 -0
  252. package/dist/packages/packs/src/larp-eval.js +100 -0
  253. package/dist/packages/packs/src/narrative.js +309 -0
  254. package/dist/packages/packs/src/reason.js +135 -0
  255. package/dist/packages/packs/src/rug-model.js +137 -0
  256. package/dist/packages/packs/src/schema.js +54 -0
  257. package/dist/packages/packs/src/token-dossier.js +174 -0
  258. package/dist/packages/packs/src/verdicts.js +17 -0
  259. package/dist/packages/packs/src/wallet-dossier.js +105 -0
  260. package/dist/packages/popup/src/config.js +71 -0
  261. package/dist/packages/popup/src/dock.js +271 -0
  262. package/dist/packages/popup/src/host.js +210 -0
  263. package/dist/packages/popup/src/index.js +12 -0
  264. package/dist/packages/popup/src/loopback.js +53 -0
  265. package/dist/packages/popup/src/open.js +183 -0
  266. package/dist/packages/popup/src/pages/bubbles-lib.js +160 -0
  267. package/dist/packages/popup/src/pages/bubbles.css +23 -0
  268. package/dist/packages/popup/src/pages/bubbles.html +36 -0
  269. package/dist/packages/popup/src/pages/bubbles.js +214 -0
  270. package/dist/packages/popup/src/pages/chart-lib.js +262 -0
  271. package/dist/packages/popup/src/pages/chart.css +50 -0
  272. package/dist/packages/popup/src/pages/chart.html +56 -0
  273. package/dist/packages/popup/src/pages/chart.js +554 -0
  274. package/dist/packages/popup/src/pages/common.css +34 -0
  275. package/dist/packages/popup/src/pages/common.js +187 -0
  276. package/dist/packages/popup/src/pages/feeds.html +20 -0
  277. package/dist/packages/popup/src/pages/feeds.js +77 -0
  278. package/dist/packages/popup/src/pages/narrative.html +20 -0
  279. package/dist/packages/popup/src/pages/narrative.js +61 -0
  280. package/dist/packages/popup/src/pages/plans.css +30 -0
  281. package/dist/packages/popup/src/pages/plans.html +26 -0
  282. package/dist/packages/popup/src/pages/plans.js +82 -0
  283. package/dist/packages/popup/src/pages/roster.css +41 -0
  284. package/dist/packages/popup/src/pages/roster.html +25 -0
  285. package/dist/packages/popup/src/pages/roster.js +75 -0
  286. package/dist/packages/popup/src/pages/token.html +20 -0
  287. package/dist/packages/popup/src/pages/token.js +112 -0
  288. package/dist/packages/popup/src/pages/widget-sdk.js +224 -0
  289. package/dist/packages/popup/src/pages/widget.css +5 -0
  290. package/dist/packages/popup/src/pages/widget.html +21 -0
  291. package/dist/packages/popup/src/pages/widget.js +85 -0
  292. package/dist/packages/popup/src/protocol.js +31 -0
  293. package/dist/packages/popup/src/selftest.js +156 -0
  294. package/dist/packages/popup/src/server.js +582 -0
  295. package/dist/packages/popup/src/sinkproxy.js +167 -0
  296. package/dist/packages/popup/src/widget-html.js +231 -0
  297. package/dist/packages/popup/vendor/lightweight-charts/LICENSE +201 -0
  298. package/dist/packages/popup/vendor/lightweight-charts/NOTICE +2 -0
  299. package/dist/packages/popup/vendor/lightweight-charts/README.md +30 -0
  300. package/dist/packages/popup/vendor/lightweight-charts/VERSION +1 -0
  301. package/dist/packages/popup/vendor/lightweight-charts/lightweight-charts.standalone.production.js +7 -0
  302. package/dist/packages/recorder/bin/dexterm-recorder.mjs +11 -0
  303. package/dist/packages/recorder/src/cli.js +113 -0
  304. package/dist/packages/recorder/src/export.js +71 -0
  305. package/dist/packages/recorder/src/index.js +20 -0
  306. package/dist/packages/recorder/src/labels.js +151 -0
  307. package/dist/packages/recorder/src/open.js +29 -0
  308. package/dist/packages/recorder/src/recorder.js +553 -0
  309. package/dist/packages/recorder/src/schedule.js +43 -0
  310. package/dist/packages/recorder/src/schema.js +135 -0
  311. package/dist/packages/recorder/src/snapshot.js +191 -0
  312. package/dist/packages/recorder/src/sweep.js +52 -0
  313. package/dist/packages/recorder/src/verdicts.js +52 -0
  314. package/dist/packages/tui/src/bubbles.js +415 -0
  315. package/dist/packages/tui/src/canvas.js +370 -0
  316. package/dist/packages/tui/src/chrome.js +85 -0
  317. package/dist/packages/tui/src/color.js +133 -0
  318. package/dist/packages/tui/src/flush.js +62 -0
  319. package/dist/packages/tui/src/fmt.js +188 -0
  320. package/dist/packages/tui/src/fx-trade.js +278 -0
  321. package/dist/packages/tui/src/fx.js +527 -0
  322. package/dist/packages/tui/src/images/blocks.js +141 -0
  323. package/dist/packages/tui/src/images/coin.js +22 -0
  324. package/dist/packages/tui/src/images/detect.js +140 -0
  325. package/dist/packages/tui/src/images/index.js +7 -0
  326. package/dist/packages/tui/src/images/layer.js +146 -0
  327. package/dist/packages/tui/src/images/pixels.js +157 -0
  328. package/dist/packages/tui/src/images/protocols.js +87 -0
  329. package/dist/packages/tui/src/index.js +15 -0
  330. package/dist/packages/tui/src/keymap.js +355 -0
  331. package/dist/packages/tui/src/layout.js +11 -0
  332. package/dist/packages/tui/src/sound.js +177 -0
  333. package/dist/packages/tui/src/theme.js +182 -0
  334. package/dist/packages/tui/src/widgets.js +598 -0
  335. package/dist/packages/voice/src/controller.js +395 -0
  336. package/dist/packages/voice/src/doctor.js +63 -0
  337. package/dist/packages/voice/src/engines.js +44 -0
  338. package/dist/packages/voice/src/index.js +16 -0
  339. package/dist/packages/voice/src/router.js +502 -0
  340. package/dist/packages/voice/src/stt/apple-helper.swift.js +103 -0
  341. package/dist/packages/voice/src/stt/apple.js +179 -0
  342. package/dist/packages/voice/src/stt/fake.js +34 -0
  343. package/dist/packages/voice/src/stt/whisper.js +102 -0
  344. package/dist/packages/voice/src/summary.js +44 -0
  345. package/dist/packages/voice/src/tts/fake.js +30 -0
  346. package/dist/packages/voice/src/tts/say.js +96 -0
  347. package/dist/packages/voice/src/types.js +3 -0
  348. package/package.json +42 -4
  349. package/README.md +0 -3
@@ -0,0 +1,415 @@
1
+ import { mix } from "./color.js";
2
+ import { shortAddr } from "./fmt.js";
3
+ export const KIND_LETTER = { 'dev-linked': 'D', dev: 'D', bundle: 'B', funder: 'F', transfer: 'T', sniper: 'S', pool: 'P', cex: 'X', whale: 'W', plain: '·' };
4
+ export const LEGEND = [['dev', 'dev'], ['bundle', 'bundle'], ['funder', 'linked'], ['sniper', 'sniper'], ['pool', 'pool/LP'], ['cex', 'exchange'], ['plain', 'unlinked']];
5
+ export function kindColor(t, kind) {
6
+ switch (kind) {
7
+ case 'dev':
8
+ case 'dev-linked': return t.warn;
9
+ case 'bundle': return t.pump;
10
+ case 'funder': return t.up;
11
+ case 'transfer': return t.dbc;
12
+ case 'sniper': return t.down;
13
+ case 'pool': return t.accent;
14
+ case 'cex':
15
+ case 'whale': return t.muted;
16
+ default: return mix(t.panel, t.up, 0.45);
17
+ }
18
+ }
19
+ /** Display kind of one holder: its cluster's kind when linked, else the strongest of its own labels. */
20
+ export function holderKind(labels, cluster) {
21
+ if (cluster && cluster.members.length > 1 && cluster.kind !== 'single')
22
+ return cluster.kind;
23
+ const ls = new Set(labels.map((l) => l.label));
24
+ if (ls.has('dev'))
25
+ return 'dev';
26
+ if (ls.has('sniper'))
27
+ return 'sniper';
28
+ if (ls.has('pool') || ls.has('LP') || ls.has('contract') || ls.has('unfunded-authority?'))
29
+ return 'pool';
30
+ if (ls.has('cex'))
31
+ return 'cex';
32
+ if (ls.has('multi-token-top20'))
33
+ return 'whale';
34
+ return 'plain';
35
+ }
36
+ export function bubbleVM(a, token) {
37
+ const clusters = a.clusters.map((c) => ({ name: c.name, kind: c.kind, members: c.members.slice(), pct: c.pct, labels: c.labels ?? [], evidence: c.evidence ?? [] }));
38
+ const byOwner = new Map();
39
+ for (const c of clusters)
40
+ for (const m of c.members)
41
+ byOwner.set(m, c);
42
+ const holders = a.holders.map((h) => {
43
+ const c = byOwner.get(h.owner) ?? null;
44
+ return { owner: h.owner, pct: h.pct ?? 0, labels: h.labels ?? [], funder: h.funder ?? null, walletFirstSeen: h.walletFirstSeen ?? null, cluster: c && c.members.length > 1 ? c.name : null, kind: holderKind(h.labels ?? [], c) };
45
+ });
46
+ return { symbol: token.symbol.replace(/^\$/, ''), name: token.name ?? '', mint: token.mint, holders, clusters, holderCount: token.holderCount ?? null, coverage: a.insights?.coverage ?? null };
47
+ }
48
+ function placeCluster(members) {
49
+ const hub = members[0];
50
+ const out = [{ ...hub, dx: 0, dy: 0 }];
51
+ if (members.length === 1)
52
+ return { items: out, R: hub.r + 0.6 };
53
+ let ringR = hub.r;
54
+ let k = 1;
55
+ let maxReach = hub.r;
56
+ while (k < members.length) {
57
+ const ringMembers = [];
58
+ const d0 = ringR + 0.8;
59
+ let angleUsed = 0, biggest = 0;
60
+ while (k < members.length) {
61
+ const m = members[k];
62
+ const d = d0 + m.r;
63
+ const need = 2 * Math.asin(Math.min(1, (m.r + 0.35) / d));
64
+ if (ringMembers.length && angleUsed + need > 2 * Math.PI)
65
+ break;
66
+ ringMembers.push({ m, d, need });
67
+ angleUsed += need;
68
+ biggest = Math.max(biggest, m.r);
69
+ k++;
70
+ }
71
+ const slack = Math.max(0, 2 * Math.PI - angleUsed) / ringMembers.length;
72
+ let a = -Math.PI / 2 + (ringMembers.length % 2 ? 0 : slack / 2) + (out.length * 0.37);
73
+ for (const { m, d, need } of ringMembers) {
74
+ a += need / 2 + slack / 2;
75
+ out.push({ ...m, dx: Math.cos(a) * d, dy: Math.sin(a) * d });
76
+ maxReach = Math.max(maxReach, d + m.r);
77
+ a += need / 2 + slack / 2;
78
+ }
79
+ ringR = d0 + 2 * biggest;
80
+ }
81
+ return { items: out, R: maxReach + 0.6 };
82
+ }
83
+ function packClusters(cls, W, H2, gap = 1.0) {
84
+ const placed = [];
85
+ const cx0 = W / 2, cy0 = H2 / 2;
86
+ const inside = (x, y, R) => x - R >= 0 && x + R <= W && y - R >= 0 && y + R <= H2;
87
+ const free = (x, y, R) => placed.every((p) => Math.hypot(p.x - x, p.y - y) >= p.R + R + gap - 1e-6);
88
+ for (const c of cls) {
89
+ if (!placed.length) {
90
+ if (!inside(cx0, cy0, c.R))
91
+ return null;
92
+ placed.push({ ...c, x: cx0, y: cy0 });
93
+ continue;
94
+ }
95
+ let best = null, bestD = Infinity;
96
+ for (const p of placed) {
97
+ const steps = 48;
98
+ for (let s = 0; s < steps; s++) {
99
+ const th = (s / steps) * 2 * Math.PI;
100
+ const d = p.R + c.R + gap;
101
+ const x = p.x + Math.cos(th) * d, y = p.y + Math.sin(th) * d;
102
+ if (!inside(x, y, c.R) || !free(x, y, c.R))
103
+ continue;
104
+ const dd = (x - cx0) ** 2 + ((y - cy0) * 1.15) ** 2;
105
+ if (dd < bestD) {
106
+ bestD = dd;
107
+ best = { x, y };
108
+ }
109
+ }
110
+ }
111
+ if (!best)
112
+ return null;
113
+ placed.push({ ...c, x: best.x, y: best.y });
114
+ }
115
+ return placed;
116
+ }
117
+ /**
118
+ * Lay out holders in a W×H cell area (pixel space W × 2H). `focus` = a cluster name → only that cluster, filling
119
+ * the area (zoom). Falls back to a tiny grid when nothing packs (never throws).
120
+ */
121
+ export function layoutBubbles(vm, W, H, opts = {}) {
122
+ const H2 = H * 2;
123
+ const idxs = vm.holders.map((_, i) => i).filter((i) => !opts.focus || vm.holders[i].cluster === opts.focus);
124
+ if (!idxs.length || W < 4 || H < 2)
125
+ return { bubbles: [], clusters: [], k: 0, W, H2 };
126
+ const total = idxs.reduce((s, i) => s + Math.max(0.01, vm.holders[i].pct), 0);
127
+ const fill = opts.fill ?? (opts.focus ? 0.62 : 0.5);
128
+ let k = Math.sqrt((fill * W * H2) / (Math.PI * total));
129
+ const rMax = Math.min(W / 5.2, H2 / 2.5);
130
+ for (let iter = 0; iter < 14; iter++) {
131
+ const byCluster = new Map();
132
+ for (const i of idxs) {
133
+ const h = vm.holders[i];
134
+ const r = Math.max(1, Math.min(rMax, k * Math.sqrt(Math.max(0.01, h.pct))));
135
+ const key = h.cluster || `single:${i}`;
136
+ const arr = byCluster.get(key) || [];
137
+ arr.push({ i, r });
138
+ byCluster.set(key, arr);
139
+ }
140
+ const cls = [];
141
+ for (const [key, members] of byCluster) {
142
+ members.sort((a, b) => b.r - a.r);
143
+ const pc = placeCluster(members);
144
+ const c = vm.clusters.find((x) => x.name === key) || null;
145
+ cls.push({ key, name: c ? c.name : null, kind: c ? c.kind : vm.holders[members[0].i].kind, pct: c ? c.pct : vm.holders[members[0].i].pct, items: pc.items, R: pc.R, multi: members.length > 1 });
146
+ }
147
+ cls.sort((a, b) => b.R - a.R);
148
+ const placed = packClusters(cls, W, H2);
149
+ if (placed) {
150
+ const bubbles = [], clusters = [];
151
+ for (const p of placed) {
152
+ for (const it of p.items)
153
+ bubbles.push({ idx: it.i, cx: p.x + it.dx, cy: p.y + it.dy, r: it.r });
154
+ clusters.push({ name: p.name, kind: p.kind, pct: p.pct, cx: p.x, cy: p.y, R: p.R, members: p.items.map((it) => it.i), multi: p.multi });
155
+ }
156
+ return { bubbles, clusters, k, W, H2 };
157
+ }
158
+ k *= 0.86;
159
+ }
160
+ const cols = Math.max(1, Math.floor(W / 4));
161
+ const bubbles = idxs.map((i, n) => ({ idx: i, cx: 2 + (n % cols) * 4, cy: 2 + Math.floor(n / cols) * 4, r: 1 }));
162
+ return { bubbles, clusters: [], k, W, H2, overflow: true };
163
+ }
164
+ // ---------------------------------------------------------------- drawing
165
+ const INK = '#031008';
166
+ /** Draw the packed bubbles into the cell area (x, y, w, h). Returns the pixel ownership grid (for hit tests). */
167
+ export function drawBubbles(c, x, y, w, h, vm, layout, opts = {}) {
168
+ const t = c.theme;
169
+ const bg = opts.bg || t.panel;
170
+ const { W, H2 } = layout;
171
+ const pix = new Int16Array(W * H2).fill(-1);
172
+ const colorOf = (i) => (i === opts.selected ? t.borderFocus : kindColor(t, vm.holders[i].kind));
173
+ for (const b of layout.bubbles) {
174
+ const r2 = b.r * b.r;
175
+ for (let py = Math.max(0, Math.floor(b.cy - b.r)); py < Math.min(H2, Math.ceil(b.cy + b.r)); py++) {
176
+ for (let px = Math.max(0, Math.floor(b.cx - b.r)); px < Math.min(W, Math.ceil(b.cx + b.r)); px++) {
177
+ const dx = px + 0.5 - b.cx, dy = py + 0.5 - b.cy;
178
+ if (dx * dx + dy * dy <= r2)
179
+ pix[py * W + px] = b.idx;
180
+ }
181
+ }
182
+ }
183
+ // cluster rings (soft dots on blank cells), drawn before bubbles so bubbles win
184
+ for (const cl of layout.clusters) {
185
+ if (!cl.multi)
186
+ continue;
187
+ const col = mix(bg, kindColor(t, cl.kind), 0.75);
188
+ for (let s = 0; s < 72; s++) {
189
+ const th = (s / 72) * 2 * Math.PI;
190
+ const px = Math.round(cl.cx + (cl.R + 0.4) * Math.cos(th) - 0.5);
191
+ const py = cl.cy + (cl.R + 0.4) * Math.sin(th);
192
+ if (px < 0 || px >= W || py < 0 || py >= H2)
193
+ continue;
194
+ const cx = x + px, cy = y + Math.floor(py / 2);
195
+ if (cx >= c.w || cy >= c.h)
196
+ continue;
197
+ const i = c.idx(cx, cy);
198
+ if (c.ch[i] === ' ' && pix[Math.floor(py) * W + px] === -1)
199
+ c.put(cx, cy, '·', { fg: col, bg, soft: true });
200
+ }
201
+ }
202
+ // bubbles: pairs of half-rows → ▀ ▄ █
203
+ for (let row = 0; row < h; row++) {
204
+ for (let col = 0; col < w; col++) {
205
+ const top = pix[(2 * row) * W + col], bot = pix[(2 * row + 1) * W + col];
206
+ if (top < 0 && bot < 0)
207
+ continue;
208
+ const cx = x + col, cy = y + row;
209
+ if (top >= 0 && bot >= 0) {
210
+ if (top === bot)
211
+ c.put(cx, cy, '█', { fg: colorOf(top), bg, soft: true });
212
+ else
213
+ c.put(cx, cy, '▀', { fg: colorOf(top), bg: colorOf(bot), soft: true });
214
+ }
215
+ else if (top >= 0)
216
+ c.put(cx, cy, '▀', { fg: colorOf(top), bg, soft: true });
217
+ else
218
+ c.put(cx, cy, '▄', { fg: colorOf(bot), bg, soft: true });
219
+ }
220
+ }
221
+ // dotted edges from the selected holder to its cluster mates (blank cells only)
222
+ if (opts.selected != null) {
223
+ const sb = layout.bubbles.find((b) => b.idx === opts.selected);
224
+ const cl = sb && layout.clusters.find((k) => k.members.includes(opts.selected));
225
+ if (sb && cl && cl.multi) {
226
+ for (const m of cl.members) {
227
+ if (m === opts.selected)
228
+ continue;
229
+ const mb = layout.bubbles.find((b) => b.idx === m);
230
+ if (mb)
231
+ line(c, x, y, W, H2, pix, sb, mb, t.accent, bg);
232
+ }
233
+ }
234
+ }
235
+ // labels inside bubbles (hard cells)
236
+ for (const b of layout.bubbles) {
237
+ if (b.r < 2.5)
238
+ continue;
239
+ const hd = vm.holders[b.idx];
240
+ const color = colorOf(b.idx);
241
+ const widthAtCentre = Math.floor(2 * b.r) - 1;
242
+ const row = Math.floor(b.cy / 2);
243
+ const lines = [];
244
+ const addr = shortAddr(hd.owner, 4);
245
+ const pct = `${hd.pct.toFixed(hd.pct >= 10 ? 1 : 2)}%`;
246
+ if (widthAtCentre >= addr.length)
247
+ lines.push(addr);
248
+ else if (widthAtCentre >= pct.length)
249
+ lines.push(pct);
250
+ if (b.r >= 4 && lines[0] === addr && widthAtCentre >= pct.length)
251
+ lines.push(pct);
252
+ if (b.r >= 6 && hd.kind !== 'plain')
253
+ lines.push(hd.kind.toUpperCase().slice(0, widthAtCentre));
254
+ const startRow = row - Math.floor((lines.length - 1) / 2);
255
+ lines.forEach((s, li) => {
256
+ const ry = startRow + li;
257
+ if (ry < 0 || ry >= h)
258
+ return;
259
+ const x0 = Math.round(b.cx - s.length / 2);
260
+ for (let k = 0; k < s.length; k++) {
261
+ const px = x0 + k;
262
+ if (px < 0 || px >= W)
263
+ continue;
264
+ if (pix[(2 * ry) * W + px] !== b.idx || pix[(2 * ry + 1) * W + px] !== b.idx)
265
+ continue; // stay inside the disc
266
+ c.put(x + px, y + ry, s[k], { fg: INK, bg: color, b: li === 0, hard: true });
267
+ }
268
+ });
269
+ }
270
+ // cluster tags (above the ring when there is room, else below), only on blank cells
271
+ for (const cl of layout.clusters) {
272
+ if (!cl.multi)
273
+ continue;
274
+ const color = kindColor(t, cl.kind);
275
+ const tag = `${KIND_LETTER[cl.kind] || '·'}·${cl.name} ${cl.members.length}w ${cl.pct.toFixed(1)}%`;
276
+ const x0 = Math.round(cl.cx - tag.length / 2);
277
+ const above = Math.floor((cl.cy - cl.R) / 2) - 1, below = Math.floor((cl.cy + cl.R) / 2) + 1;
278
+ for (const ry of [above, below]) {
279
+ if (ry < 0 || ry >= h)
280
+ continue;
281
+ let ok = x0 >= 0 && x0 + tag.length <= W;
282
+ for (let k = 0; ok && k < tag.length; k++) {
283
+ const i = c.idx(x + x0 + k, y + ry);
284
+ if (c.ch[i] !== ' ' && c.ch[i] !== '·')
285
+ ok = false;
286
+ }
287
+ if (!ok)
288
+ continue;
289
+ c.text(x + x0, y + ry, tag, { fg: color, bg, b: true });
290
+ break;
291
+ }
292
+ }
293
+ return pix;
294
+ }
295
+ function line(c, x, y, W, H2, pix, a, b, fg, bg) {
296
+ let x0 = Math.round(a.cx), y0 = Math.round(a.cy / 2);
297
+ const x1 = Math.round(b.cx), y1 = Math.round(b.cy / 2);
298
+ const dx = Math.abs(x1 - x0), dy = -Math.abs(y1 - y0), sx = x0 < x1 ? 1 : -1, sy = y0 < y1 ? 1 : -1;
299
+ let err = dx + dy;
300
+ for (let n = 0; n < 400; n++) {
301
+ if (x0 >= 0 && x0 < W && y0 >= 0 && y0 * 2 < H2) {
302
+ const covered = pix[(2 * y0) * W + x0] !== -1 || pix[(2 * y0 + 1) * W + x0] !== -1;
303
+ const i = c.idx(x + x0, y + y0);
304
+ if (!covered && c.ch[i] === ' ')
305
+ c.put(x + x0, y + y0, '∙', { fg, bg, soft: true });
306
+ }
307
+ if (x0 === x1 && y0 === y1)
308
+ break;
309
+ const e2 = 2 * err;
310
+ if (e2 >= dy) {
311
+ err += dy;
312
+ x0 += sx;
313
+ }
314
+ if (e2 <= dx) {
315
+ err += dx;
316
+ y0 += sy;
317
+ }
318
+ }
319
+ }
320
+ function squarify(children, rect) {
321
+ const out = [];
322
+ let i = 0;
323
+ const rem = { ...rect };
324
+ while (i < children.length && rem.w > 0 && rem.h > 0) {
325
+ const vertical = rem.w >= rem.h;
326
+ const side = vertical ? rem.h : rem.w;
327
+ let row = [], sum = 0, bestWorst = Infinity;
328
+ while (i < children.length) {
329
+ const v = children[i].value;
330
+ const cand = [...row, children[i]], s = sum + v, thick = s / side;
331
+ let worst = 0;
332
+ for (const ch of cand) {
333
+ const len = ch.value / thick;
334
+ worst = Math.max(worst, len / thick, thick / len);
335
+ }
336
+ if (row.length && worst > bestWorst)
337
+ break;
338
+ row = cand;
339
+ sum = s;
340
+ bestWorst = worst;
341
+ i++;
342
+ }
343
+ const thick = sum / side;
344
+ let off = 0;
345
+ for (const ch of row) {
346
+ const len = ch.value / thick;
347
+ out.push(vertical ? { item: ch.item, x: rem.x, y: rem.y + off, w: thick, h: len } : { item: ch.item, x: rem.x + off, y: rem.y, w: len, h: thick });
348
+ off += len;
349
+ }
350
+ if (vertical) {
351
+ rem.x += thick;
352
+ rem.w -= thick;
353
+ }
354
+ else {
355
+ rem.y += thick;
356
+ rem.h -= thick;
357
+ }
358
+ }
359
+ return out;
360
+ }
361
+ export function drawTreemap(c, x, y, w, h, vm, opts = {}) {
362
+ const t = c.theme;
363
+ const bg = opts.bg || t.panel;
364
+ const items = vm.clusters.slice().sort((a, b) => b.pct - a.pct).map((cl) => ({ item: cl, value: Math.max(0.05, cl.pct) }));
365
+ const total = items.reduce((s, it) => s + it.value, 0);
366
+ if (!total)
367
+ return;
368
+ const area = w * (h * 2);
369
+ for (const it of items)
370
+ it.value = (it.value / total) * area;
371
+ const rects = squarify(items, { x: 0, y: 0, w, h: h * 2 });
372
+ for (const r of rects) {
373
+ const rx = Math.round(r.x), ry = Math.round(r.y / 2);
374
+ const rw = Math.max(1, Math.round(r.x + r.w) - rx), rh = Math.max(1, Math.round((r.y + r.h) / 2) - ry);
375
+ if (rx >= w || ry >= h)
376
+ continue;
377
+ const cl = r.item;
378
+ const sel = opts.selected != null && cl.members.includes(vm.holders[opts.selected]?.owner);
379
+ const color = sel ? t.borderFocus : kindColor(t, cl.kind);
380
+ const fillBg = mix(bg, color, sel ? 0.4 : 0.22);
381
+ c.fill(x + rx, y + ry, Math.min(rw, w - rx), Math.min(rh, h - ry), ' ', { bg: fillBg });
382
+ for (let k = 0; k < Math.min(rh, h - ry); k++)
383
+ c.put(x + rx, y + ry + k, '▌', { fg: color, bg: fillBg, soft: true });
384
+ if (rw >= 6) {
385
+ const head = cl.members.length > 1 ? `${KIND_LETTER[cl.kind] || '·'}·${cl.name}` : shortAddr(cl.members[0], 3);
386
+ c.text(x + rx + 1, y + ry, head, { fg: color, bg: fillBg, b: true }, Math.min(rw, w - rx) - 1);
387
+ if (rh >= 2)
388
+ c.text(x + rx + 1, y + ry + 1, `${cl.pct.toFixed(1)}%${cl.members.length > 1 ? ` ${cl.members.length}w` : ''}`, { fg: t.text, bg: fillBg }, Math.min(rw, w - rx) - 1);
389
+ }
390
+ }
391
+ }
392
+ /** The legend row: glyph + word per kind (colour-blind second encoding). Returns the x after the last entry. */
393
+ export function legendRow(c, x, y, w, bg) {
394
+ const t = c.theme;
395
+ let cx = x;
396
+ for (const [kind, word] of LEGEND) {
397
+ const s = `${kind === 'plain' ? '○' : '●'} ${word} `;
398
+ if (cx + s.length > x + w)
399
+ break;
400
+ cx = c.text(cx, y, s, { fg: kindColor(t, kind), bg });
401
+ }
402
+ return cx;
403
+ }
404
+ /** "sample top 20 accts of 142.5K holders · 55 % supply · launch 300 txs" (every people-metric prints its sample). */
405
+ export function sampleCaption(vm, fmtNum) {
406
+ const cov = vm.coverage;
407
+ if (!cov)
408
+ return 'sample unknown';
409
+ return `sample top ${cov.topHoldersFetched} accts${vm.holderCount ? ` of ${fmtNum(vm.holderCount)} holders` : ''} · ${cov.supplyCoveredPct}% supply · funders ${cov.fundingLookups}/${cov.topHoldersFetched} · launch ${cov.launchTxs} txs`;
410
+ }
411
+ /** The holder index under a cell (x, y) of the drawn map, or -1 (hover / click hit test). */
412
+ export function holderAt(pix, W, col, row) {
413
+ const top = pix[(2 * row) * W + col], bot = pix[(2 * row + 1) * W + col];
414
+ return top >= 0 ? top : bot >= 0 ? bot : -1;
415
+ }