@trading-boy/cli 1.12.0 → 2.0.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 (84) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +64 -29
  3. package/dist/api-client.d.ts +4 -7
  4. package/dist/api-client.js +8 -13
  5. package/dist/cli.bundle.js +2314 -33711
  6. package/dist/credentials.js +1 -1
  7. package/dist/index.d.ts +0 -28
  8. package/dist/index.js +0 -24
  9. package/dist/logger.d.ts +8 -0
  10. package/dist/logger.js +12 -0
  11. package/dist/utils.js +3 -3
  12. package/package.json +30 -16
  13. package/dist/cli.d.ts +0 -5
  14. package/dist/cli.js +0 -157
  15. package/dist/commands/agent-cmd.d.ts +0 -9
  16. package/dist/commands/agent-cmd.js +0 -567
  17. package/dist/commands/audit.d.ts +0 -18
  18. package/dist/commands/audit.js +0 -73
  19. package/dist/commands/behavioral.d.ts +0 -73
  20. package/dist/commands/behavioral.js +0 -349
  21. package/dist/commands/benchmark-cmd.d.ts +0 -3
  22. package/dist/commands/benchmark-cmd.js +0 -191
  23. package/dist/commands/billing.d.ts +0 -12
  24. package/dist/commands/billing.js +0 -142
  25. package/dist/commands/catalysts.d.ts +0 -17
  26. package/dist/commands/catalysts.js +0 -151
  27. package/dist/commands/coaching-cmd.d.ts +0 -16
  28. package/dist/commands/coaching-cmd.js +0 -222
  29. package/dist/commands/config-cmd.d.ts +0 -30
  30. package/dist/commands/config-cmd.js +0 -515
  31. package/dist/commands/connect-chatgpt.d.ts +0 -5
  32. package/dist/commands/connect-chatgpt.js +0 -293
  33. package/dist/commands/connect-claude.d.ts +0 -5
  34. package/dist/commands/connect-claude.js +0 -280
  35. package/dist/commands/context.d.ts +0 -41
  36. package/dist/commands/context.js +0 -405
  37. package/dist/commands/cron-cmd.d.ts +0 -3
  38. package/dist/commands/cron-cmd.js +0 -305
  39. package/dist/commands/decisions.d.ts +0 -57
  40. package/dist/commands/decisions.js +0 -364
  41. package/dist/commands/edge-cmd.d.ts +0 -78
  42. package/dist/commands/edge-cmd.js +0 -183
  43. package/dist/commands/edge-guard-cmd.d.ts +0 -36
  44. package/dist/commands/edge-guard-cmd.js +0 -169
  45. package/dist/commands/events.d.ts +0 -3
  46. package/dist/commands/events.js +0 -117
  47. package/dist/commands/infra.d.ts +0 -24
  48. package/dist/commands/infra.js +0 -137
  49. package/dist/commands/journal.d.ts +0 -3
  50. package/dist/commands/journal.js +0 -302
  51. package/dist/commands/login.d.ts +0 -18
  52. package/dist/commands/login.js +0 -127
  53. package/dist/commands/logout.d.ts +0 -8
  54. package/dist/commands/logout.js +0 -108
  55. package/dist/commands/narratives.d.ts +0 -3
  56. package/dist/commands/narratives.js +0 -259
  57. package/dist/commands/onboarding.d.ts +0 -7
  58. package/dist/commands/onboarding.js +0 -281
  59. package/dist/commands/query.d.ts +0 -32
  60. package/dist/commands/query.js +0 -135
  61. package/dist/commands/replay-cmd.d.ts +0 -43
  62. package/dist/commands/replay-cmd.js +0 -184
  63. package/dist/commands/review.d.ts +0 -3
  64. package/dist/commands/review.js +0 -443
  65. package/dist/commands/risk.d.ts +0 -47
  66. package/dist/commands/risk.js +0 -158
  67. package/dist/commands/social.d.ts +0 -43
  68. package/dist/commands/social.js +0 -318
  69. package/dist/commands/soul-wizard.d.ts +0 -29
  70. package/dist/commands/soul-wizard.js +0 -155
  71. package/dist/commands/strategy-cmd.d.ts +0 -44
  72. package/dist/commands/strategy-cmd.js +0 -335
  73. package/dist/commands/subscribe.d.ts +0 -78
  74. package/dist/commands/subscribe.js +0 -552
  75. package/dist/commands/suggestions-cmd.d.ts +0 -24
  76. package/dist/commands/suggestions-cmd.js +0 -148
  77. package/dist/commands/thesis-cmd.d.ts +0 -3
  78. package/dist/commands/thesis-cmd.js +0 -129
  79. package/dist/commands/trader.d.ts +0 -30
  80. package/dist/commands/trader.js +0 -971
  81. package/dist/commands/watch.d.ts +0 -16
  82. package/dist/commands/watch.js +0 -104
  83. package/dist/commands/whoami.d.ts +0 -14
  84. package/dist/commands/whoami.js +0 -105
@@ -1,335 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { createLogger, generateRegimeBehavior } from '@trading-boy/core';
4
- import { apiRequest } from '../api-client.js';
5
- import { padRight, handleApiError, ensureRemote } from '../utils.js';
6
- // ─── Logger ───
7
- const logger = createLogger('cli-strategy');
8
- // ─── Helpers ───
9
- function formatShortDate(isoString) {
10
- try {
11
- return new Date(isoString).toISOString().slice(0, 16).replace('T', ' ');
12
- }
13
- catch {
14
- return isoString;
15
- }
16
- }
17
- // ─── Formatters ───
18
- export function formatStrategyDetail(s) {
19
- const lines = [];
20
- lines.push('');
21
- lines.push(chalk.bold.cyan(` Strategy — ${s.name}`));
22
- lines.push(chalk.gray(' ' + '─'.repeat(56)));
23
- lines.push('');
24
- lines.push(` ${chalk.gray('ID:')} ${chalk.white(s.id)}`);
25
- lines.push(` ${chalk.gray('Version:')} ${chalk.white(String(s.version))}`);
26
- lines.push(` ${chalk.gray('Agent ID:')} ${chalk.white(s.agentId)}`);
27
- lines.push(` ${chalk.gray('Trader ID:')} ${chalk.white(s.traderId)}`);
28
- lines.push(` ${chalk.gray('Tenant ID:')} ${chalk.dim(s.tenantId)}`);
29
- lines.push(` ${chalk.gray('Active:')} ${s.active ? chalk.green('YES') : chalk.red('NO')}`);
30
- lines.push('');
31
- lines.push(` ${chalk.gray('Tokens:')} ${chalk.white(s.tokens.join(', ') || chalk.dim('none'))}`);
32
- lines.push(` ${chalk.gray('Setup Types:')} ${chalk.white(s.setupTypes.join(', ') || chalk.dim('none'))}`);
33
- if (s.narrativePreferences.length > 0) {
34
- lines.push(` ${chalk.gray('Narratives:')} ${chalk.white(s.narrativePreferences.join(', '))}`);
35
- }
36
- if (Object.keys(s.signalWeights).length > 0) {
37
- lines.push('');
38
- lines.push(chalk.bold(' Signal Weights'));
39
- for (const [signal, weight] of Object.entries(s.signalWeights)) {
40
- lines.push(` ${chalk.gray(signal + ':')} ${chalk.white(weight.toFixed(3))}`);
41
- }
42
- }
43
- if (Object.keys(s.riskLimits).length > 0) {
44
- lines.push('');
45
- lines.push(chalk.bold(' Risk Limits'));
46
- for (const [key, val] of Object.entries(s.riskLimits)) {
47
- lines.push(` ${chalk.gray(key + ':')} ${chalk.white(JSON.stringify(val))}`);
48
- }
49
- }
50
- if (Object.keys(s.regimeBehavior).length > 0) {
51
- lines.push('');
52
- lines.push(chalk.bold(' Regime Behavior'));
53
- for (const [regime, behavior] of Object.entries(s.regimeBehavior)) {
54
- lines.push(` ${chalk.gray(regime + ':')} ${chalk.white(JSON.stringify(behavior))}`);
55
- }
56
- }
57
- lines.push('');
58
- lines.push(` ${chalk.gray('Created:')} ${chalk.dim(formatShortDate(s.createdAt))}`);
59
- lines.push(` ${chalk.gray('Updated:')} ${chalk.dim(formatShortDate(s.updatedAt))}`);
60
- lines.push('');
61
- return lines.join('\n');
62
- }
63
- export function formatStrategyList(response) {
64
- const lines = [];
65
- lines.push('');
66
- lines.push(chalk.bold.cyan(' Agent Strategies'));
67
- lines.push(chalk.gray(' ' + '─'.repeat(96)));
68
- lines.push('');
69
- if (response.strategies.length === 0) {
70
- lines.push(` ${chalk.dim('No strategies found.')}`);
71
- lines.push('');
72
- return lines.join('\n');
73
- }
74
- // Header
75
- lines.push(' ' +
76
- padRight('Name', 24) +
77
- padRight('ID', 30) +
78
- padRight('Tokens', 20) +
79
- padRight('v', 4) +
80
- padRight('Active', 8) +
81
- 'Updated');
82
- lines.push(' ' + '─'.repeat(96));
83
- for (const s of response.strategies) {
84
- const activeStr = s.active ? chalk.green('YES') : chalk.red('NO');
85
- const tokensStr = s.tokens.slice(0, 3).join(',') + (s.tokens.length > 3 ? '…' : '');
86
- lines.push(' ' +
87
- padRight(s.name, 24) +
88
- padRight(chalk.dim(s.id), 30) +
89
- padRight(tokensStr || chalk.dim('-'), 20) +
90
- padRight(String(s.version), 4) +
91
- padRight(activeStr, 8) +
92
- chalk.dim(formatShortDate(s.updatedAt)));
93
- }
94
- lines.push('');
95
- lines.push(` ${chalk.gray(`Showing ${response.strategies.length} of ${response.total} (offset: ${response.offset})`)}`);
96
- lines.push('');
97
- return lines.join('\n');
98
- }
99
- export function formatHistoryList(response) {
100
- const lines = [];
101
- lines.push('');
102
- lines.push(chalk.bold.cyan(` Strategy History — ${response.strategyId}`));
103
- lines.push(chalk.gray(' ' + '─'.repeat(80)));
104
- lines.push('');
105
- if (response.history.length === 0) {
106
- lines.push(` ${chalk.dim('No history entries found.')}`);
107
- lines.push('');
108
- return lines.join('\n');
109
- }
110
- lines.push(' ' +
111
- padRight('v', 4) +
112
- padRight('Name', 28) +
113
- padRight('Tokens', 24) +
114
- padRight('Setups', 20) +
115
- 'Changed At');
116
- lines.push(' ' + '─'.repeat(80));
117
- for (const entry of response.history) {
118
- const tokensStr = entry.tokens.slice(0, 3).join(',') + (entry.tokens.length > 3 ? '…' : '');
119
- const setupsStr = entry.setupTypes.slice(0, 2).join(',') + (entry.setupTypes.length > 2 ? '…' : '');
120
- lines.push(' ' +
121
- padRight(String(entry.version), 4) +
122
- padRight(entry.name, 28) +
123
- padRight(tokensStr || chalk.dim('-'), 24) +
124
- padRight(setupsStr || chalk.dim('-'), 20) +
125
- chalk.dim(formatShortDate(entry.changedAt)));
126
- }
127
- lines.push('');
128
- return lines.join('\n');
129
- }
130
- // ─── Command Registration ───
131
- export function registerStrategyCommand(program) {
132
- const strategy = program
133
- .command('strategy')
134
- .description('Manage agent strategies (token watch-lists, setup types, signal weights)');
135
- // ─── strategy create ───
136
- strategy
137
- .command('create')
138
- .description('Create a new agent strategy')
139
- .requiredOption('--name <name>', 'Strategy name')
140
- .requiredOption('--trader-id <id>', 'Trader ID')
141
- .requiredOption('--agent-id <id>', 'Agent ID')
142
- .requiredOption('--tokens <tokens>', 'Comma-separated token symbols')
143
- .option('--setups <types>', 'Comma-separated setup types')
144
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
145
- .action(async (options) => {
146
- if (!(await ensureRemote()))
147
- return;
148
- const tokens = options.tokens.split(',').map((t) => t.trim().toUpperCase()).filter(Boolean);
149
- const setupTypes = options.setups
150
- ? options.setups.split(',').map((s) => s.trim().toUpperCase()).filter(Boolean)
151
- : ['BREAKOUT'];
152
- const body = {
153
- name: options.name,
154
- traderId: options.traderId,
155
- agentId: options.agentId,
156
- tokens,
157
- setupTypes,
158
- regimeBehavior: generateRegimeBehavior(setupTypes),
159
- riskLimits: {
160
- maxDrawdown: 0.2,
161
- maxConcurrentPositions: 5,
162
- maxExposurePerToken: 0.3,
163
- maxCorrelatedExposure: 0.5,
164
- },
165
- signalWeights: { price: 0.3, volume: 0.2, momentum: 0.2, sentiment: 0.15, onchain: 0.15 },
166
- narrativePreferences: [],
167
- };
168
- try {
169
- const result = await apiRequest('/api/v1/strategies', {
170
- method: 'POST',
171
- body,
172
- });
173
- if (options.format === 'json') {
174
- console.log(JSON.stringify(result, null, 2));
175
- }
176
- else {
177
- console.log(formatStrategyDetail(result));
178
- }
179
- }
180
- catch (error) {
181
- handleApiError(error, 'Strategy create failed', logger);
182
- }
183
- });
184
- // ─── strategy list ───
185
- strategy
186
- .command('list')
187
- .description('List strategies for a trader')
188
- .requiredOption('--trader-id <id>', 'Trader ID')
189
- .option('--agent-id <id>', 'Filter by agent ID')
190
- .option('--limit <n>', 'Maximum results', '20')
191
- .option('--offset <n>', 'Pagination offset', '0')
192
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
193
- .action(async (options) => {
194
- if (!(await ensureRemote()))
195
- return;
196
- const params = new URLSearchParams();
197
- params.set('traderId', options.traderId);
198
- if (options.agentId)
199
- params.set('agentId', options.agentId);
200
- params.set('limit', options.limit);
201
- params.set('offset', options.offset);
202
- try {
203
- const result = await apiRequest(`/api/v1/strategies?${params.toString()}`);
204
- if (options.format === 'json') {
205
- console.log(JSON.stringify(result, null, 2));
206
- }
207
- else {
208
- console.log(formatStrategyList(result));
209
- }
210
- }
211
- catch (error) {
212
- handleApiError(error, 'Strategy list failed', logger);
213
- }
214
- });
215
- // ─── strategy show <id> ───
216
- strategy
217
- .command('show <id>')
218
- .description('Show full details for a strategy')
219
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
220
- .action(async (id, options) => {
221
- if (!(await ensureRemote()))
222
- return;
223
- try {
224
- const result = await apiRequest(`/api/v1/strategies/${encodeURIComponent(id)}`);
225
- if (options.format === 'json') {
226
- console.log(JSON.stringify(result, null, 2));
227
- }
228
- else {
229
- console.log(formatStrategyDetail(result));
230
- }
231
- }
232
- catch (error) {
233
- handleApiError(error, 'Strategy show failed', logger);
234
- }
235
- });
236
- // ─── strategy update <id> ───
237
- strategy
238
- .command('update <id>')
239
- .description('Update a strategy')
240
- .option('--name <name>', 'New strategy name')
241
- .option('--tokens <tokens>', 'New comma-separated token symbols (replaces existing)')
242
- .option('--setups <types>', 'New comma-separated setup types (replaces existing)')
243
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
244
- .action(async (id, options) => {
245
- if (!(await ensureRemote()))
246
- return;
247
- const body = {};
248
- if (options.name) {
249
- body.name = options.name;
250
- }
251
- if (options.tokens) {
252
- body.tokens = options.tokens.split(',').map((t) => t.trim().toUpperCase()).filter(Boolean);
253
- }
254
- if (options.setups) {
255
- body.setupTypes = options.setups.split(',').map((s) => s.trim().toUpperCase()).filter(Boolean);
256
- }
257
- if (Object.keys(body).length === 0) {
258
- console.error(chalk.red('Error: Provide at least one of --name, --tokens, or --setups to update.'));
259
- process.exitCode = 1;
260
- return;
261
- }
262
- try {
263
- const result = await apiRequest(`/api/v1/strategies/${encodeURIComponent(id)}`, { method: 'PUT', body });
264
- if (options.format === 'json') {
265
- console.log(JSON.stringify(result, null, 2));
266
- }
267
- else {
268
- console.log(formatStrategyDetail(result));
269
- }
270
- }
271
- catch (error) {
272
- handleApiError(error, 'Strategy update failed', logger);
273
- }
274
- });
275
- // ─── strategy history <id> ───
276
- strategy
277
- .command('history <id>')
278
- .description('Show version history for a strategy')
279
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
280
- .action(async (id, options) => {
281
- if (!(await ensureRemote()))
282
- return;
283
- try {
284
- const result = await apiRequest(`/api/v1/strategies/${encodeURIComponent(id)}/history`);
285
- if (options.format === 'json') {
286
- console.log(JSON.stringify(result, null, 2));
287
- }
288
- else {
289
- console.log(formatHistoryList(result));
290
- }
291
- }
292
- catch (error) {
293
- handleApiError(error, 'Strategy history failed', logger);
294
- }
295
- });
296
- // ─── strategy export ───
297
- strategy
298
- .command('export')
299
- .description('Export a strategy in json, elizaos, or freqtrade format')
300
- .requiredOption('--id <id>', 'Strategy ID to export')
301
- .addOption(new Option('--format <format>', 'Export format')
302
- .choices(['json', 'elizaos', 'freqtrade'])
303
- .default('json'))
304
- .option('--output <file>', 'Write output to a file instead of stdout')
305
- .action(async (options) => {
306
- if (!(await ensureRemote()))
307
- return;
308
- try {
309
- const result = await apiRequest(`/api/v1/strategies/${encodeURIComponent(options.id)}/export?format=${encodeURIComponent(options.format)}`);
310
- const output = JSON.stringify(result, null, 2);
311
- if (options.output) {
312
- const { writeFile } = await import('node:fs/promises');
313
- const { resolve } = await import('node:path');
314
- const resolved = resolve(options.output);
315
- // Block writes to system directories
316
- const blocked = ['/etc', '/usr', '/bin', '/sbin', '/var', '/lib', '/boot', '/sys', '/proc', '/dev'];
317
- if (blocked.some((dir) => resolved.startsWith(dir + '/'))) {
318
- console.error(chalk.red(`Error: --output must not write to system directories.`));
319
- console.error(chalk.dim(` Resolved: ${resolved}`));
320
- process.exitCode = 1;
321
- return;
322
- }
323
- await writeFile(resolved, output + '\n', 'utf-8');
324
- console.log(chalk.green(`Strategy exported to ${resolved}`));
325
- }
326
- else {
327
- console.log(output);
328
- }
329
- }
330
- catch (error) {
331
- handleApiError(error, 'Strategy export failed', logger);
332
- }
333
- });
334
- }
335
- //# sourceMappingURL=strategy-cmd.js.map
@@ -1,78 +0,0 @@
1
- import { Command } from 'commander';
2
- export interface CheckoutResponse {
3
- checkoutUrl: string;
4
- provisioningToken: string;
5
- }
6
- export interface ProvisionResponse {
7
- status: 'pending' | 'ready' | 'expired' | 'already_retrieved' | 'not_found';
8
- apiKey?: string;
9
- keyPrefix?: string;
10
- email?: string;
11
- plan?: string;
12
- }
13
- export interface PollResult {
14
- success: boolean;
15
- apiKey?: string;
16
- keyPrefix?: string;
17
- email?: string;
18
- plan?: string;
19
- error?: string;
20
- }
21
- export interface CryptoCheckoutResponse {
22
- reference: string;
23
- provisioningToken: string;
24
- merchantWallet: string;
25
- amountUsdc: number;
26
- tokenSymbol: string;
27
- network: string;
28
- plan: string;
29
- solanaPayUrl: string;
30
- solanaReference: string;
31
- }
32
- export interface CryptoVerifyResponse {
33
- status: 'pending' | 'confirmed' | 'not_found' | 'expired';
34
- }
35
- /**
36
- * Create a Stripe Checkout session via the API.
37
- * This is a public endpoint — no auth needed.
38
- */
39
- export declare function createCheckoutSession(email: string, plan?: string): Promise<CheckoutResponse>;
40
- /**
41
- * Poll the provisioning endpoint for the API key.
42
- * Returns normalized ProvisionResponse regardless of HTTP status.
43
- */
44
- export declare function pollProvisioningToken(token: string): Promise<ProvisionResponse>;
45
- /**
46
- * Create a crypto (USDC) checkout session via the API.
47
- * Public endpoint — no auth needed.
48
- */
49
- export declare function createCryptoCheckout(email: string, plan?: string): Promise<CryptoCheckoutResponse>;
50
- /**
51
- * Check if a USDC payment has been confirmed on Solana.
52
- */
53
- export declare function checkCryptoPayment(reference: string): Promise<CryptoVerifyResponse>;
54
- /**
55
- * Poll until USDC payment is confirmed on Solana, then poll for provisioned API key.
56
- */
57
- export declare function pollCryptoPayment(reference: string, provisioningToken: string, onTick?: (elapsed: number, phase: 'payment' | 'provisioning') => void): Promise<PollResult>;
58
- /**
59
- * Poll the provisioning endpoint until a key is ready or timeout.
60
- */
61
- export declare function pollForApiKey(token: string, onTick?: (elapsed: number) => void): Promise<PollResult>;
62
- /**
63
- * Save API credentials using the credential storage module.
64
- */
65
- export declare function saveApiKey(apiKey: string, metadata: {
66
- keyPrefix?: string;
67
- email?: string;
68
- plan?: string;
69
- }): Promise<void>;
70
- export declare function formatSubscribeSuccess(result: PollResult): string;
71
- export declare function registerSubscribeCommand(program: Command): void;
72
- export interface RegisterResponse {
73
- apiKey: string;
74
- keyPrefix: string;
75
- email: string;
76
- plan: string;
77
- }
78
- //# sourceMappingURL=subscribe.d.ts.map