dexterm-cli 0.1.1 → 0.1.3

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 (155) hide show
  1. package/dist/packages/agents/src/bus.js +57 -6
  2. package/dist/packages/agents/src/executor.js +25 -0
  3. package/dist/packages/agents/src/follow.js +105 -0
  4. package/dist/packages/agents/src/gate.js +3 -0
  5. package/dist/packages/agents/src/identity.js +41 -2
  6. package/dist/packages/agents/src/index.js +5 -0
  7. package/dist/packages/agents/src/spectator-server.js +153 -0
  8. package/dist/packages/agents/src/spectator.js +212 -0
  9. package/dist/packages/agents/src/tiers.js +5 -0
  10. package/dist/packages/agents/src/tools.js +3 -0
  11. package/dist/packages/cli/assets/claude/analyst-system.md +6 -1
  12. package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +11 -3
  13. package/dist/packages/cli/assets/claude/plugin/skills/rug-check/SKILL.md +13 -3
  14. package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +3 -3
  15. package/dist/packages/cli/src/agent-cmd.js +107 -10
  16. package/dist/packages/cli/src/agent-spectator.js +37 -0
  17. package/dist/packages/cli/src/alerts/adapters/desktop.js +40 -0
  18. package/dist/packages/cli/src/alerts/adapters/discord.js +36 -0
  19. package/dist/packages/cli/src/alerts/adapters/telegram.js +43 -0
  20. package/dist/packages/cli/src/alerts/adapters/toast.js +16 -0
  21. package/dist/packages/cli/src/alerts/creds.js +83 -0
  22. package/dist/packages/cli/src/alerts/format.js +66 -0
  23. package/dist/packages/cli/src/alerts/index.js +10 -0
  24. package/dist/packages/cli/src/alerts/notifier.js +53 -0
  25. package/dist/packages/cli/src/alerts/route.js +19 -0
  26. package/dist/packages/cli/src/alerts/types.js +1 -0
  27. package/dist/packages/cli/src/alerts-cmd.js +212 -0
  28. package/dist/packages/cli/src/app-help-gen.js +365 -0
  29. package/dist/packages/cli/src/backtest-cmd.js +62 -3
  30. package/dist/packages/cli/src/coin-target.js +2 -0
  31. package/dist/packages/cli/src/doctor.js +21 -6
  32. package/dist/packages/cli/src/export.js +235 -0
  33. package/dist/packages/cli/src/follow-cmd.js +107 -1
  34. package/dist/packages/cli/src/help-cmd.js +48 -0
  35. package/dist/packages/cli/src/live/index.js +66 -3
  36. package/dist/packages/cli/src/live/screens/token-live.js +24 -0
  37. package/dist/packages/cli/src/live/signals.js +109 -0
  38. package/dist/packages/cli/src/live/trade.js +24 -1
  39. package/dist/packages/cli/src/main.js +596 -49
  40. package/dist/packages/cli/src/mcp-cmd.js +321 -0
  41. package/dist/packages/cli/src/pnl-app.js +221 -0
  42. package/dist/packages/cli/src/pnl-card.js +615 -0
  43. package/dist/packages/cli/src/record-cmd.js +455 -0
  44. package/dist/packages/cli/src/rules.js +69 -2
  45. package/dist/packages/cli/src/screens/follows.js +91 -2
  46. package/dist/packages/cli/src/screens/overlay.js +3 -0
  47. package/dist/packages/cli/src/screens/positions.js +1 -1
  48. package/dist/packages/cli/src/screens/rules.js +1 -1
  49. package/dist/packages/cli/src/skill-eval-build.js +109 -0
  50. package/dist/packages/cli/src/spectate-cmd.js +104 -0
  51. package/dist/packages/cli/src/state.js +1 -1
  52. package/dist/packages/cli/src/update.js +294 -0
  53. package/dist/packages/cli/src/version.js +3 -0
  54. package/dist/packages/cli/src/voice-cmd.js +194 -0
  55. package/dist/packages/cli/src/voice-hud.js +1 -1
  56. package/dist/packages/cli/src/watch-cmd.js +190 -0
  57. package/dist/packages/custom/src/rules.js +3 -2
  58. package/dist/packages/custom/src/schema.js +24 -1
  59. package/dist/packages/data/src/analyst-actions.js +130 -3
  60. package/dist/packages/data/src/coin-target.js +82 -0
  61. package/dist/packages/data/src/fast-lane.js +16 -2
  62. package/dist/packages/data/src/index.js +4 -0
  63. package/dist/packages/data/src/intel/helius-history.js +12 -1
  64. package/dist/packages/data/src/intel/live-signals.js +185 -0
  65. package/dist/packages/data/src/larp/link-baseline.js +196 -0
  66. package/dist/packages/data/src/sources/dexscreener.js +14 -0
  67. package/dist/packages/data/src/sources/pumpportal.js +6 -1
  68. package/dist/packages/data/src/trade/copy/index.js +1 -1
  69. package/dist/packages/data/src/trade/copy/stats.js +36 -2
  70. package/dist/packages/data/src/trade/copy/tracker.js +3 -2
  71. package/dist/packages/mcp/assets/kb/app-help/app-help-command.md +35 -0
  72. package/dist/packages/mcp/assets/kb/app-help/ask-the-analyst.md +43 -0
  73. package/dist/packages/mcp/assets/kb/app-help/backtest.md +33 -0
  74. package/dist/packages/mcp/assets/kb/app-help/bubble-map.md +35 -0
  75. package/dist/packages/mcp/assets/kb/app-help/calm-mode.md +31 -0
  76. package/dist/packages/mcp/assets/kb/app-help/change-voice-speed.md +31 -0
  77. package/dist/packages/mcp/assets/kb/app-help/change-voice.md +30 -0
  78. package/dist/packages/mcp/assets/kb/app-help/chart-popup-selftest.md +32 -0
  79. package/dist/packages/mcp/assets/kb/app-help/coin-images.md +29 -0
  80. package/dist/packages/mcp/assets/kb/app-help/configure-rpc-key.md +28 -0
  81. package/dist/packages/mcp/assets/kb/app-help/connect-an-agent-registry.md +35 -0
  82. package/dist/packages/mcp/assets/kb/app-help/connect-an-agent.md +39 -0
  83. package/dist/packages/mcp/assets/kb/app-help/custom-keymap.md +32 -0
  84. package/dist/packages/mcp/assets/kb/app-help/edit-kb-or-skill.md +36 -0
  85. package/dist/packages/mcp/assets/kb/app-help/edit-rules.md +34 -0
  86. package/dist/packages/mcp/assets/kb/app-help/export-a-view.md +36 -0
  87. package/dist/packages/mcp/assets/kb/app-help/follow-a-wallet.md +33 -0
  88. package/dist/packages/mcp/assets/kb/app-help/getting-started.md +37 -0
  89. package/dist/packages/mcp/assets/kb/app-help/kol-lists.md +34 -0
  90. package/dist/packages/mcp/assets/kb/app-help/larp-check.md +36 -0
  91. package/dist/packages/mcp/assets/kb/app-help/link-a-wallet.md +41 -0
  92. package/dist/packages/mcp/assets/kb/app-help/login-with-x.md +33 -0
  93. package/dist/packages/mcp/assets/kb/app-help/narrative-board.md +32 -0
  94. package/dist/packages/mcp/assets/kb/app-help/open-a-coin.md +43 -0
  95. package/dist/packages/mcp/assets/kb/app-help/open-chart-popup.md +33 -0
  96. package/dist/packages/mcp/assets/kb/app-help/order-plans.md +33 -0
  97. package/dist/packages/mcp/assets/kb/app-help/paper-trade.md +36 -0
  98. package/dist/packages/mcp/assets/kb/app-help/price-or-marketcap.md +38 -0
  99. package/dist/packages/mcp/assets/kb/app-help/record-headless.md +34 -0
  100. package/dist/packages/mcp/assets/kb/app-help/recorder-history.md +39 -0
  101. package/dist/packages/mcp/assets/kb/app-help/rug-check.md +39 -0
  102. package/dist/packages/mcp/assets/kb/app-help/run-doctor.md +32 -0
  103. package/dist/packages/mcp/assets/kb/app-help/scan-mode.md +37 -0
  104. package/dist/packages/mcp/assets/kb/app-help/screen-analyst.md +181 -0
  105. package/dist/packages/mcp/assets/kb/app-help/screen-kol.md +190 -0
  106. package/dist/packages/mcp/assets/kb/app-help/screen-newpairs.md +181 -0
  107. package/dist/packages/mcp/assets/kb/app-help/screen-positions.md +180 -0
  108. package/dist/packages/mcp/assets/kb/app-help/screen-screener.md +199 -0
  109. package/dist/packages/mcp/assets/kb/app-help/screen-token.md +240 -0
  110. package/dist/packages/mcp/assets/kb/app-help/screen-trending.md +192 -0
  111. package/dist/packages/mcp/assets/kb/app-help/screen-watchlist.md +181 -0
  112. package/dist/packages/mcp/assets/kb/app-help/set-a-filter.md +36 -0
  113. package/dist/packages/mcp/assets/kb/app-help/setup-neural-voice.md +36 -0
  114. package/dist/packages/mcp/assets/kb/app-help/share-packs.md +34 -0
  115. package/dist/packages/mcp/assets/kb/app-help/sort-the-screener.md +34 -0
  116. package/dist/packages/mcp/assets/kb/app-help/spectate-an-agent.md +36 -0
  117. package/dist/packages/mcp/assets/kb/app-help/standing-mandates.md +33 -0
  118. package/dist/packages/mcp/assets/kb/app-help/switch-theme.md +42 -0
  119. package/dist/packages/mcp/assets/kb/app-help/turn-on-alerts.md +37 -0
  120. package/dist/packages/mcp/assets/kb/app-help/update-dexterm.md +30 -0
  121. package/dist/packages/mcp/assets/kb/app-help/use-presets.md +42 -0
  122. package/dist/packages/mcp/assets/kb/app-help/use-voice-mode.md +36 -0
  123. package/dist/packages/mcp/assets/kb/app-help/watch-a-coin.md +34 -0
  124. package/dist/packages/mcp/assets/kb/app-help/watch-headless.md +35 -0
  125. package/dist/packages/mcp/assets/kb/app-help/what-dexterm-shows-agents.md +31 -0
  126. package/dist/packages/mcp/assets/kb/app-help/workspaces.md +38 -0
  127. package/dist/packages/mcp/src/app-help.js +135 -0
  128. package/dist/packages/mcp/src/index.js +3 -0
  129. package/dist/packages/mcp/src/server.js +179 -5
  130. package/dist/packages/mcp/src/spectator-sink.js +72 -0
  131. package/dist/packages/packs/src/index.js +3 -0
  132. package/dist/packages/packs/src/skill-backtest.js +300 -0
  133. package/dist/packages/packs/src/skill-care.js +206 -0
  134. package/dist/packages/popup/src/pages/spectator.css +45 -0
  135. package/dist/packages/popup/src/pages/spectator.html +25 -0
  136. package/dist/packages/popup/src/pages/spectator.js +74 -0
  137. package/dist/packages/popup/src/selftest.js +19 -0
  138. package/dist/packages/popup/src/server.js +7 -1
  139. package/dist/packages/tui/src/index.js +3 -0
  140. package/dist/packages/tui/src/keymap.js +12 -0
  141. package/dist/packages/tui/src/raster-font.js +195 -0
  142. package/dist/packages/tui/src/raster.js +213 -0
  143. package/dist/packages/voice/src/controller.js +57 -4
  144. package/dist/packages/voice/src/doctor.js +96 -11
  145. package/dist/packages/voice/src/download.js +184 -0
  146. package/dist/packages/voice/src/engines.js +55 -8
  147. package/dist/packages/voice/src/index.js +9 -3
  148. package/dist/packages/voice/src/speakable.js +111 -0
  149. package/dist/packages/voice/src/stt/whisper.js +14 -4
  150. package/dist/packages/voice/src/tts/espeak.js +131 -0
  151. package/dist/packages/voice/src/tts/piper-setup.js +229 -0
  152. package/dist/packages/voice/src/tts/piper.js +449 -0
  153. package/dist/packages/voice/src/tts/say.js +72 -35
  154. package/dist/packages/voice/src/tts/voices.js +209 -0
  155. package/package.json +5 -9
@@ -0,0 +1,109 @@
1
+ // dexterm — LIVE holder/rug SIGNALS binding (task-1404). Turns the open token's repeatedly-refreshed holder and
2
+ // safety reads (market/authorities/rugcheck panels + the wallet-intel scan + the fast-lane bonding curve) into
3
+ // SIGNAL events through the pure @dexterm/data LiveSignalsEngine, keeps a small per-mint log for the token screen,
4
+ // and exposes the latest numeric values as RULE FIELDS so every signal is an alert trigger (task-1398 pattern).
5
+ //
6
+ // It owns no timers and does no I/O: the UI loop / LiveContext calls observe() whenever the token, the intel scan
7
+ // or a fast-lane push changed something. The engine dedups (only a threshold-crossing change emits), so calling it
8
+ // on every redraw is cheap. Read-only: nothing here trades or signs.
9
+ import { LiveSignalsEngine, bondingProgress, } from '../../../data/src/index.js';
10
+ /** Max signals kept per mint for the token-screen strip (newest first). */
11
+ export const SIGNALS_LOG_MAX = 40;
12
+ function fromPanel(p, value, fallbackSource) {
13
+ if (!p || value == null || !Number.isFinite(value) || p.fetchedAt == null)
14
+ return null;
15
+ return { value, source: p.via ?? fallbackSource, fetchedAt: p.fetchedAt, stale: p.stale || p.state === 'error' };
16
+ }
17
+ function authFromPanel(p, present) {
18
+ if (!p || present == null || p.fetchedAt == null)
19
+ return null;
20
+ return { present, source: p.via ?? 'authorities', fetchedAt: p.fetchedAt, stale: p.stale || p.state === 'error' };
21
+ }
22
+ function fromIntel(value, intel) {
23
+ if (value == null || !Number.isFinite(value) || !intel || intel.fetchedAt == null)
24
+ return null;
25
+ return { value, source: intel.via ?? 'helius', fetchedAt: intel.fetchedAt, stale: false };
26
+ }
27
+ /**
28
+ * Build one observation from the token view + intel scan + fast-lane curve. Each field keeps its OWN source and
29
+ * fetch time so a signal is honest about where it came from and how old the data is. The richer wallet-intel
30
+ * figures (ex-pool top-10, creator %, bundled, snipers, fresh, cluster) are preferred when the scan has landed;
31
+ * otherwise the panel reads (Jupiter audit top-10/dev) stand in. Pure + exported for the tests.
32
+ */
33
+ export function buildObservation(inputs, now) {
34
+ const v = inputs.view;
35
+ const I = inputs.intel?.analysis?.insights ?? null;
36
+ const panels = v.panels ?? {};
37
+ const obs = { mint: v.mint, at: now };
38
+ // top-10 concentration (pools excluded): the scan's ex-pool figure first, else the holders panel's top-10.
39
+ obs.top10 = (I && typeof I.top10.exPool === 'number' ? fromIntel(I.top10.exPool, inputs.intel) : null) ?? fromPanel(panels.holders, v.top10, 'holders');
40
+ // creator / dev share: the scan's creatorPctNow first, else the market panel's Jupiter audit devPct.
41
+ obs.dev = (I ? fromIntel(I.dev.creatorPctNow, inputs.intel) : null) ?? fromPanel(panels.market, v.dev, 'jupiter');
42
+ // bundled / snipers / fresh / cluster only exist once the launch window / funders were read (Helius).
43
+ if (I && I.coverage.launchTxs > 0) {
44
+ obs.bundled = fromIntel(I.bundle.bundlePctOfTopSample, inputs.intel);
45
+ obs.snipers = fromIntel(I.snipers.count, inputs.intel);
46
+ }
47
+ if (I && I.coverage.fundingLookups > 0)
48
+ obs.fresh = fromIntel(I.fresh.freshAtBuyPctOfTopSample, inputs.intel);
49
+ const cluster = inputs.intel?.analysis?.clusters?.[0]?.pct ?? null;
50
+ obs.cluster = fromIntel(cluster, inputs.intel);
51
+ // LP locked (RugCheck), liquidity (market), mint/freeze authority (authorities panel).
52
+ obs.lpLocked = fromPanel(panels.rugcheck, v.lpLocked, 'rugcheck');
53
+ obs.liq = fromPanel(panels.market, v.liq, 'market');
54
+ obs.mintAuth = authFromPanel(panels.authorities, v.mintAuth);
55
+ obs.freezeAuth = authFromPanel(panels.authorities, v.freezeAuth);
56
+ // bonding-curve progress + migration from the on-chain fast-lane push (sub-second), when streaming.
57
+ if (inputs.curve) {
58
+ const bp = bondingProgress(inputs.curve.curve.vToken);
59
+ if (bp != null)
60
+ obs.bonding = { value: bp, source: 'onchain-curve', fetchedAt: inputs.curve.at, stale: false };
61
+ obs.migrated = { value: inputs.curve.curve.complete, source: 'onchain-curve', fetchedAt: inputs.curve.at, stale: false };
62
+ }
63
+ return obs;
64
+ }
65
+ export class LiveSignalsLive {
66
+ engine;
67
+ now;
68
+ onSignal;
69
+ logByMint = new Map();
70
+ /** Signals emitted this session (all mints), newest last — a cheap counter/feed for the smoke script + tests. */
71
+ emitted = [];
72
+ constructor(opts = {}) {
73
+ this.engine = new LiveSignalsEngine({ thresholds: opts.thresholds });
74
+ this.now = opts.now ?? (() => Date.now());
75
+ this.onSignal = opts.onSignal;
76
+ }
77
+ /** Observe one moment of a token's state; records and returns any new signals. */
78
+ observe(inputs) {
79
+ const obs = buildObservation(inputs, this.now());
80
+ const sigs = this.engine.observe(obs);
81
+ for (const s of sigs) {
82
+ const arr = this.logByMint.get(s.mint) ?? [];
83
+ arr.unshift(s);
84
+ if (arr.length > SIGNALS_LOG_MAX)
85
+ arr.length = SIGNALS_LOG_MAX;
86
+ this.logByMint.set(s.mint, arr);
87
+ this.emitted.push(s);
88
+ this.onSignal?.(s);
89
+ }
90
+ return sigs;
91
+ }
92
+ /** Recent signals for a mint, newest first (token-screen LIVE SIGNALS strip). */
93
+ recent(mint, limit = 8) {
94
+ return (this.logByMint.get(mint) ?? []).slice(0, limit);
95
+ }
96
+ /** Latest numeric fields for the rules engine (merged into the open-token RuleRow in ruleRowsOf). */
97
+ fields(mint) {
98
+ return this.engine.fields(mint);
99
+ }
100
+ /** Per-field snapshot (value + source + age + stale) for the strip header. */
101
+ snapshot(mint, now = this.now()) {
102
+ return this.engine.snapshot(mint, now);
103
+ }
104
+ /** Drop a mint the UI no longer tracks. */
105
+ forget(mint) {
106
+ this.engine.forget(mint);
107
+ this.logByMint.delete(mint);
108
+ }
109
+ }
@@ -680,6 +680,8 @@ export class PositionsLive {
680
680
  now;
681
681
  /** mint → current price in SOL per whole token. */
682
682
  marks = new Map();
683
+ /** task-1407: when each mark was taken (ms), so a PnL card can print the mark's age. */
684
+ markTimes = new Map();
683
685
  solPriceUsd = null;
684
686
  loading = false;
685
687
  heldMemo = new Map();
@@ -703,6 +705,10 @@ export class PositionsLive {
703
705
  markOf(mint) {
704
706
  return this.marks.get(mint) ?? null;
705
707
  }
708
+ /** task-1407: when the mark for a mint was taken (ms), or null when there is none. */
709
+ markAt(mint) {
710
+ return this.marks.has(mint) ? this.markTimes.get(mint) ?? null : null;
711
+ }
706
712
  /**
707
713
  * PositionSource: the open paper position for a mint, or null. One indexed SQLite read, reused for
708
714
  * HELD_MEMO_MS so a 30 fps render loop does not hit the ledger every frame. A closed wallet reads as flat.
@@ -758,8 +764,10 @@ export class PositionsLive {
758
764
  continue;
759
765
  }
760
766
  const usd = byMint.get(m)?.pair.priceUsd ?? null;
761
- if (usd && usd > 0)
767
+ if (usd && usd > 0) {
762
768
  this.marks.set(m, usd / this.solPriceUsd);
769
+ this.markTimes.set(m, this.now());
770
+ }
763
771
  }
764
772
  }
765
773
  }
@@ -865,6 +873,21 @@ export class LivePositions {
865
873
  this.rowsMemo = { at: now, rows };
866
874
  return rows;
867
875
  }
876
+ /** task-1407: the raw ledger rows (newest first, swaps only) with network + signature, for the LIVE PnL card. */
877
+ fills(mint, limit = 500) {
878
+ try {
879
+ const l = new LiveLedger({ path: this.path, readOnly: true });
880
+ try {
881
+ return l.trades(limit * 2).filter((r) => r.kind === 'swap' && r.mint === mint).slice(0, limit);
882
+ }
883
+ finally {
884
+ l.close();
885
+ }
886
+ }
887
+ catch {
888
+ return [];
889
+ }
890
+ }
868
891
  /** Confirmed live fills (newest first) for the popup markers / history; probes excluded. */
869
892
  records(limit = 100, mint) {
870
893
  try {