@nexstone/rift-cli 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 (137) hide show
  1. package/LICENSE +201 -0
  2. package/bin/run.js +22 -0
  3. package/dist/commands/algo.d.ts +32 -0
  4. package/dist/commands/algo.js +719 -0
  5. package/dist/commands/audit.d.ts +13 -0
  6. package/dist/commands/audit.js +37 -0
  7. package/dist/commands/auth-status.d.ts +14 -0
  8. package/dist/commands/auth-status.js +118 -0
  9. package/dist/commands/auth.d.ts +14 -0
  10. package/dist/commands/auth.js +275 -0
  11. package/dist/commands/backtest.d.ts +26 -0
  12. package/dist/commands/backtest.js +283 -0
  13. package/dist/commands/collect/start.d.ts +11 -0
  14. package/dist/commands/collect/start.js +78 -0
  15. package/dist/commands/collect/status.d.ts +6 -0
  16. package/dist/commands/collect/status.js +60 -0
  17. package/dist/commands/compare.d.ts +16 -0
  18. package/dist/commands/compare.js +130 -0
  19. package/dist/commands/config.d.ts +16 -0
  20. package/dist/commands/config.js +143 -0
  21. package/dist/commands/cost.d.ts +20 -0
  22. package/dist/commands/cost.js +104 -0
  23. package/dist/commands/cross-asset.d.ts +14 -0
  24. package/dist/commands/cross-asset.js +39 -0
  25. package/dist/commands/data/fetch.d.ts +15 -0
  26. package/dist/commands/data/fetch.js +82 -0
  27. package/dist/commands/data/list.d.ts +6 -0
  28. package/dist/commands/data/list.js +28 -0
  29. package/dist/commands/data-inventory.d.ts +9 -0
  30. package/dist/commands/data-inventory.js +24 -0
  31. package/dist/commands/deposit.d.ts +10 -0
  32. package/dist/commands/deposit.js +222 -0
  33. package/dist/commands/doctor.d.ts +6 -0
  34. package/dist/commands/doctor.js +87 -0
  35. package/dist/commands/funding-browser.d.ts +12 -0
  36. package/dist/commands/funding-browser.js +33 -0
  37. package/dist/commands/guide.d.ts +6 -0
  38. package/dist/commands/guide.js +15 -0
  39. package/dist/commands/home.d.ts +23 -0
  40. package/dist/commands/home.js +210 -0
  41. package/dist/commands/init.d.ts +7 -0
  42. package/dist/commands/init.js +122 -0
  43. package/dist/commands/install.d.ts +9 -0
  44. package/dist/commands/install.js +89 -0
  45. package/dist/commands/interactive.d.ts +17 -0
  46. package/dist/commands/interactive.js +179 -0
  47. package/dist/commands/lessons.d.ts +12 -0
  48. package/dist/commands/lessons.js +33 -0
  49. package/dist/commands/montecarlo.d.ts +19 -0
  50. package/dist/commands/montecarlo.js +168 -0
  51. package/dist/commands/more.d.ts +11 -0
  52. package/dist/commands/more.js +227 -0
  53. package/dist/commands/new.d.ts +14 -0
  54. package/dist/commands/new.js +306 -0
  55. package/dist/commands/pairs.d.ts +22 -0
  56. package/dist/commands/pairs.js +147 -0
  57. package/dist/commands/perp/close.d.ts +12 -0
  58. package/dist/commands/perp/close.js +57 -0
  59. package/dist/commands/perp/long.d.ts +14 -0
  60. package/dist/commands/perp/long.js +38 -0
  61. package/dist/commands/perp/short.d.ts +14 -0
  62. package/dist/commands/perp/short.js +27 -0
  63. package/dist/commands/perp/status.d.ts +9 -0
  64. package/dist/commands/perp/status.js +26 -0
  65. package/dist/commands/portfolio/alerts.d.ts +6 -0
  66. package/dist/commands/portfolio/alerts.js +47 -0
  67. package/dist/commands/portfolio/backtest.d.ts +12 -0
  68. package/dist/commands/portfolio/backtest.js +178 -0
  69. package/dist/commands/portfolio/create.d.ts +7 -0
  70. package/dist/commands/portfolio/create.js +195 -0
  71. package/dist/commands/portfolio/start.d.ts +9 -0
  72. package/dist/commands/portfolio/start.js +64 -0
  73. package/dist/commands/portfolio/status.d.ts +6 -0
  74. package/dist/commands/portfolio/status.js +128 -0
  75. package/dist/commands/portfolio/stop.d.ts +6 -0
  76. package/dist/commands/portfolio/stop.js +81 -0
  77. package/dist/commands/portfolio-backtest.d.ts +13 -0
  78. package/dist/commands/portfolio-backtest.js +37 -0
  79. package/dist/commands/portfolio-matrix.d.ts +12 -0
  80. package/dist/commands/portfolio-matrix.js +30 -0
  81. package/dist/commands/quick-test.d.ts +17 -0
  82. package/dist/commands/quick-test.js +45 -0
  83. package/dist/commands/research.d.ts +57 -0
  84. package/dist/commands/research.js +1976 -0
  85. package/dist/commands/scout.d.ts +14 -0
  86. package/dist/commands/scout.js +184 -0
  87. package/dist/commands/serve.d.ts +9 -0
  88. package/dist/commands/serve.js +1176 -0
  89. package/dist/commands/setup/proxy.d.ts +10 -0
  90. package/dist/commands/setup/proxy.js +267 -0
  91. package/dist/commands/spot/buy.d.ts +14 -0
  92. package/dist/commands/spot/buy.js +38 -0
  93. package/dist/commands/spot/sell.d.ts +14 -0
  94. package/dist/commands/spot/sell.js +39 -0
  95. package/dist/commands/strategies/list.d.ts +6 -0
  96. package/dist/commands/strategies/list.js +34 -0
  97. package/dist/commands/sweep.d.ts +19 -0
  98. package/dist/commands/sweep.js +137 -0
  99. package/dist/commands/sync.d.ts +17 -0
  100. package/dist/commands/sync.js +54 -0
  101. package/dist/commands/test-trade.d.ts +6 -0
  102. package/dist/commands/test-trade.js +97 -0
  103. package/dist/commands/trade.d.ts +26 -0
  104. package/dist/commands/trade.js +274 -0
  105. package/dist/commands/transfer.d.ts +13 -0
  106. package/dist/commands/transfer.js +65 -0
  107. package/dist/commands/verify.d.ts +16 -0
  108. package/dist/commands/verify.js +38 -0
  109. package/dist/commands/walkforward.d.ts +20 -0
  110. package/dist/commands/walkforward.js +191 -0
  111. package/dist/commands/withdraw.d.ts +12 -0
  112. package/dist/commands/withdraw.js +55 -0
  113. package/dist/commands/workbench-create.d.ts +13 -0
  114. package/dist/commands/workbench-create.js +39 -0
  115. package/dist/lib/account-mode.d.ts +44 -0
  116. package/dist/lib/account-mode.js +96 -0
  117. package/dist/lib/analyzer.d.ts +4 -0
  118. package/dist/lib/analyzer.js +62 -0
  119. package/dist/lib/base-command.d.ts +35 -0
  120. package/dist/lib/base-command.js +49 -0
  121. package/dist/lib/credentials.d.ts +46 -0
  122. package/dist/lib/credentials.js +137 -0
  123. package/dist/lib/engine-passthrough.d.ts +28 -0
  124. package/dist/lib/engine-passthrough.js +60 -0
  125. package/dist/lib/fees.d.ts +52 -0
  126. package/dist/lib/fees.js +97 -0
  127. package/dist/lib/python-bridge.d.ts +24 -0
  128. package/dist/lib/python-bridge.js +182 -0
  129. package/dist/lib/setup-status.d.ts +32 -0
  130. package/dist/lib/setup-status.js +121 -0
  131. package/dist/lib/status-footer.d.ts +35 -0
  132. package/dist/lib/status-footer.js +101 -0
  133. package/dist/lib/tui.d.ts +130 -0
  134. package/dist/lib/tui.js +300 -0
  135. package/dist/lib/walletconnect.d.ts +70 -0
  136. package/dist/lib/walletconnect.js +407 -0
  137. package/package.json +49 -0
@@ -0,0 +1,14 @@
1
+ import { GatedCommand } from '../lib/base-command.js';
2
+ export default class Scout extends GatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ top: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
7
+ tf: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
+ min: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
+ soak: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'no-soak': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ run(): Promise<void>;
13
+ private renderResults;
14
+ }
@@ -0,0 +1,184 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { GatedCommand } from '../lib/base-command.js';
3
+ import { runEngine } from '../lib/python-bridge.js';
4
+ import { green, red, cyan, bold, dim, bar, } from '../lib/tui.js';
5
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
6
+ export default class Scout extends GatedCommand {
7
+ static description = 'Scan the market and find trading opportunities ranked by confluence';
8
+ static examples = [
9
+ '$ rift scout',
10
+ '$ rift scout --top 10',
11
+ '$ rift scout --no-soak # skip 120s websocket soak (faster, less accurate)',
12
+ '$ rift scout --soak 30 # shorter soak window',
13
+ ];
14
+ static flags = {
15
+ top: Flags.integer({ description: 'Number of coins to scan', default: 20 }),
16
+ tf: Flags.string({ description: 'Timeframe (bias)', default: '1h' }),
17
+ min: Flags.integer({ description: 'Minimum confluence score', default: 2 }),
18
+ soak: Flags.integer({
19
+ description: 'Seconds to collect live websocket data (default 120, lower = faster)',
20
+ default: 120,
21
+ }),
22
+ 'no-soak': Flags.boolean({
23
+ description: 'Skip the websocket soak phase entirely (fastest, less accurate)',
24
+ default: false,
25
+ }),
26
+ };
27
+ async run() {
28
+ const { flags } = await this.parse(Scout);
29
+ this.log('');
30
+ this.log(` ${bold('RIFT Scout')} ${dim('— scanning top ' + flags.top + ' coins...')}`);
31
+ this.log('');
32
+ // ─── Startup spinner ─────────────────────────────────────
33
+ //
34
+ // Python boot + HL HTTP roundtrips take 3-5s before the engine emits
35
+ // its first message. Run a spinner so the user knows something's
36
+ // happening. Killed by the first message of any type we render below.
37
+ let firstMessageSeen = false;
38
+ let spinnerFrame = 0;
39
+ let spinnerLine = '';
40
+ const spinnerTimer = setInterval(() => {
41
+ if (firstMessageSeen)
42
+ return;
43
+ if (spinnerLine)
44
+ process.stdout.write('\x1b[1A\x1b[2K');
45
+ const frame = SPINNER_FRAMES[spinnerFrame % SPINNER_FRAMES.length];
46
+ spinnerLine = ` ${cyan(frame)} ${dim('Connecting to Hyperliquid + loading market context...')}`;
47
+ process.stdout.write(spinnerLine + '\n');
48
+ spinnerFrame++;
49
+ }, 80);
50
+ const stopSpinner = () => {
51
+ clearInterval(spinnerTimer);
52
+ if (spinnerLine && !firstMessageSeen) {
53
+ // First-time stop: erase the spinner line so the next render starts clean
54
+ process.stdout.write('\x1b[1A\x1b[2K');
55
+ }
56
+ firstMessageSeen = true;
57
+ spinnerLine = '';
58
+ };
59
+ // ─── Live render state ───────────────────────────────────
60
+ let activeLine = ''; // any single-line indicator currently on screen
61
+ const clearActiveLine = () => {
62
+ if (activeLine) {
63
+ process.stdout.write('\x1b[1A\x1b[2K');
64
+ activeLine = '';
65
+ }
66
+ };
67
+ const renderProgressBar = (pct, label) => {
68
+ const filled = Math.round(pct / 100 * 30);
69
+ const empty = 30 - filled;
70
+ return ` ${cyan('█'.repeat(filled))}${dim('░'.repeat(empty))} ${String(pct).padStart(3)}% ${dim(label)}`;
71
+ };
72
+ // ─── Build engine args ───────────────────────────────────
73
+ const engineArgs = [
74
+ '--top', String(flags.top),
75
+ '--bias-tf', flags.tf,
76
+ '--min', String(flags.min),
77
+ ];
78
+ if (flags['no-soak']) {
79
+ engineArgs.push('--no-soak');
80
+ }
81
+ else {
82
+ engineArgs.push('--soak', String(flags.soak));
83
+ }
84
+ // ─── Run engine ──────────────────────────────────────────
85
+ try {
86
+ await runEngine('scout', engineArgs, (msg) => {
87
+ stopSpinner();
88
+ if (msg.type === 'status') {
89
+ clearActiveLine();
90
+ this.log(` ${dim(String(msg.msg))}`);
91
+ return;
92
+ }
93
+ if (msg.type === 'soak') {
94
+ // Engine emits {elapsed, total, trades} every 10s during the soak.
95
+ const elapsed = msg.elapsed ?? 0;
96
+ const total = msg.total ?? 1;
97
+ const trades = msg.trades ?? 0;
98
+ const pct = Math.min(100, Math.round((elapsed / total) * 100));
99
+ clearActiveLine();
100
+ activeLine = renderProgressBar(pct, `soak ${elapsed}/${total}s · ${trades.toLocaleString()} trades`);
101
+ process.stdout.write(activeLine + '\n');
102
+ return;
103
+ }
104
+ if (msg.type === 'progress') {
105
+ const pct = msg.pct ?? 0;
106
+ const coin = msg.coin ?? '';
107
+ const phase = msg.phase ?? '';
108
+ const label = phase ? `${phase}: ${coin}` : coin;
109
+ clearActiveLine();
110
+ activeLine = renderProgressBar(pct, label);
111
+ process.stdout.write(activeLine + '\n');
112
+ return;
113
+ }
114
+ if (msg.type === 'error') {
115
+ clearActiveLine();
116
+ this.log(` ${red('✘')} ${msg.msg}`);
117
+ return;
118
+ }
119
+ if (msg.type === 'result') {
120
+ clearActiveLine();
121
+ this.renderResults(msg, flags.min);
122
+ }
123
+ });
124
+ }
125
+ catch (error) {
126
+ stopSpinner();
127
+ clearActiveLine();
128
+ this.log(` ${red('✘')} ${error.message}`);
129
+ }
130
+ }
131
+ renderResults(msg, minConfluence) {
132
+ const opportunities = msg.opportunities || [];
133
+ if (opportunities.length === 0) {
134
+ this.log(` ${dim('No opportunities with ' + minConfluence + '+ confluence found.')}`);
135
+ this.log(` ${dim('Try: rift scout --min 1')}`);
136
+ this.log('');
137
+ return;
138
+ }
139
+ this.log(` ${bold('TOP OPPORTUNITIES')}`);
140
+ this.log(` ${dim('─'.repeat(55))}`);
141
+ this.log('');
142
+ for (let i = 0; i < Math.min(opportunities.length, 10); i++) {
143
+ const o = opportunities[i];
144
+ const dir = o.direction;
145
+ const dirColor = dir === 'LONG' ? green : red;
146
+ const conf = o.confluence;
147
+ const score = o.score;
148
+ const confBar = bar(conf, 5, 10);
149
+ this.log(` ${bold('#' + (i + 1))} ${bold(String(o.coin).padEnd(6))} ${dirColor(dir.padEnd(6))} ${confBar} ${conf}/5 confluence Score: ${bold(String(Math.round(score)))}`);
150
+ // Show signals
151
+ const signals = o.signals || [];
152
+ for (const s of signals) {
153
+ this.log(` ${dim(String(s.detail))}`);
154
+ }
155
+ // Entry/Stop/Target
156
+ this.log('');
157
+ const entry = o.entry_price;
158
+ const stop = o.stop_price;
159
+ const target = o.target_price;
160
+ const rr = o.risk_reward;
161
+ const vol = o.volume_24h;
162
+ this.log(` Entry: $${entry?.toLocaleString()} Stop: $${stop?.toLocaleString()} Target: $${target?.toLocaleString()}`);
163
+ this.log(` R/R: ${bold('1:' + (rr || 0).toFixed(1))} 24h Vol: $${_formatVol(vol)}`);
164
+ this.log('');
165
+ }
166
+ this.log(` ${dim('─'.repeat(55))}`);
167
+ this.log('');
168
+ this.log(` ${dim('Execute:')}`);
169
+ for (let i = 0; i < Math.min(3, opportunities.length); i++) {
170
+ const o = opportunities[i];
171
+ this.log(` ${cyan(`rift trade ${o.coin} ${o.direction.toLowerCase()} --size 500`)}`);
172
+ }
173
+ this.log('');
174
+ }
175
+ }
176
+ function _formatVol(vol) {
177
+ if (vol >= 1_000_000_000)
178
+ return (vol / 1_000_000_000).toFixed(1) + 'B';
179
+ if (vol >= 1_000_000)
180
+ return (vol / 1_000_000).toFixed(0) + 'M';
181
+ if (vol >= 1_000)
182
+ return (vol / 1_000).toFixed(0) + 'K';
183
+ return String(Math.round(vol));
184
+ }
@@ -0,0 +1,9 @@
1
+ import { GatedCommand } from '../lib/base-command.js';
2
+ export default class Serve extends GatedCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }