@trading-boy/cli 1.12.0 → 2.0.0

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 (83) hide show
  1. package/README.md +50 -22
  2. package/dist/api-client.d.ts +4 -7
  3. package/dist/api-client.js +8 -13
  4. package/dist/cli.bundle.js +1896 -33657
  5. package/dist/credentials.js +1 -1
  6. package/dist/index.d.ts +0 -28
  7. package/dist/index.js +0 -24
  8. package/dist/logger.d.ts +8 -0
  9. package/dist/logger.js +12 -0
  10. package/dist/utils.js +3 -3
  11. package/package.json +20 -5
  12. package/dist/cli.d.ts +0 -5
  13. package/dist/cli.js +0 -157
  14. package/dist/commands/agent-cmd.d.ts +0 -9
  15. package/dist/commands/agent-cmd.js +0 -567
  16. package/dist/commands/audit.d.ts +0 -18
  17. package/dist/commands/audit.js +0 -73
  18. package/dist/commands/behavioral.d.ts +0 -73
  19. package/dist/commands/behavioral.js +0 -349
  20. package/dist/commands/benchmark-cmd.d.ts +0 -3
  21. package/dist/commands/benchmark-cmd.js +0 -191
  22. package/dist/commands/billing.d.ts +0 -12
  23. package/dist/commands/billing.js +0 -142
  24. package/dist/commands/catalysts.d.ts +0 -17
  25. package/dist/commands/catalysts.js +0 -151
  26. package/dist/commands/coaching-cmd.d.ts +0 -16
  27. package/dist/commands/coaching-cmd.js +0 -222
  28. package/dist/commands/config-cmd.d.ts +0 -30
  29. package/dist/commands/config-cmd.js +0 -515
  30. package/dist/commands/connect-chatgpt.d.ts +0 -5
  31. package/dist/commands/connect-chatgpt.js +0 -293
  32. package/dist/commands/connect-claude.d.ts +0 -5
  33. package/dist/commands/connect-claude.js +0 -280
  34. package/dist/commands/context.d.ts +0 -41
  35. package/dist/commands/context.js +0 -405
  36. package/dist/commands/cron-cmd.d.ts +0 -3
  37. package/dist/commands/cron-cmd.js +0 -305
  38. package/dist/commands/decisions.d.ts +0 -57
  39. package/dist/commands/decisions.js +0 -364
  40. package/dist/commands/edge-cmd.d.ts +0 -78
  41. package/dist/commands/edge-cmd.js +0 -183
  42. package/dist/commands/edge-guard-cmd.d.ts +0 -36
  43. package/dist/commands/edge-guard-cmd.js +0 -169
  44. package/dist/commands/events.d.ts +0 -3
  45. package/dist/commands/events.js +0 -117
  46. package/dist/commands/infra.d.ts +0 -24
  47. package/dist/commands/infra.js +0 -137
  48. package/dist/commands/journal.d.ts +0 -3
  49. package/dist/commands/journal.js +0 -302
  50. package/dist/commands/login.d.ts +0 -18
  51. package/dist/commands/login.js +0 -127
  52. package/dist/commands/logout.d.ts +0 -8
  53. package/dist/commands/logout.js +0 -108
  54. package/dist/commands/narratives.d.ts +0 -3
  55. package/dist/commands/narratives.js +0 -259
  56. package/dist/commands/onboarding.d.ts +0 -7
  57. package/dist/commands/onboarding.js +0 -281
  58. package/dist/commands/query.d.ts +0 -32
  59. package/dist/commands/query.js +0 -135
  60. package/dist/commands/replay-cmd.d.ts +0 -43
  61. package/dist/commands/replay-cmd.js +0 -184
  62. package/dist/commands/review.d.ts +0 -3
  63. package/dist/commands/review.js +0 -443
  64. package/dist/commands/risk.d.ts +0 -47
  65. package/dist/commands/risk.js +0 -158
  66. package/dist/commands/social.d.ts +0 -43
  67. package/dist/commands/social.js +0 -318
  68. package/dist/commands/soul-wizard.d.ts +0 -29
  69. package/dist/commands/soul-wizard.js +0 -155
  70. package/dist/commands/strategy-cmd.d.ts +0 -44
  71. package/dist/commands/strategy-cmd.js +0 -335
  72. package/dist/commands/subscribe.d.ts +0 -78
  73. package/dist/commands/subscribe.js +0 -552
  74. package/dist/commands/suggestions-cmd.d.ts +0 -24
  75. package/dist/commands/suggestions-cmd.js +0 -148
  76. package/dist/commands/thesis-cmd.d.ts +0 -3
  77. package/dist/commands/thesis-cmd.js +0 -129
  78. package/dist/commands/trader.d.ts +0 -30
  79. package/dist/commands/trader.js +0 -971
  80. package/dist/commands/watch.d.ts +0 -16
  81. package/dist/commands/watch.js +0 -104
  82. package/dist/commands/whoami.d.ts +0 -14
  83. package/dist/commands/whoami.js +0 -105
@@ -1,43 +0,0 @@
1
- import { Command } from 'commander';
2
- interface TokenSentiment {
3
- sentiment24h: number;
4
- sentimentTrend: string;
5
- signalCount24h: number;
6
- topTierCount: number;
7
- breakdown: {
8
- tier1Avg: number | null;
9
- tier2Avg: number | null;
10
- tier3Avg: number | null;
11
- };
12
- }
13
- interface MindshareRanking {
14
- rank: number;
15
- compositeScore: number;
16
- txCount24h: number;
17
- uniqueWallets24h: number;
18
- whaleVolume24h: number;
19
- }
20
- interface TokenNarrativeRecord {
21
- narrativeName: string;
22
- narrativeStatus: string;
23
- confidence: number;
24
- }
25
- export interface SocialSignalRecord {
26
- id?: string;
27
- platform: string;
28
- sentiment: number;
29
- authorTier: string;
30
- content?: string | null;
31
- authorId?: string | null;
32
- authorHandle?: string | null;
33
- engagementScore?: number | null;
34
- extractedEntities?: string[];
35
- narrativeTags?: string[];
36
- }
37
- /**
38
- * Format the full social query output for a token.
39
- */
40
- export declare function formatTokenSocial(tokenSymbol: string, sentiment: TokenSentiment | null, mindshare: MindshareRanking | null, narratives: TokenNarrativeRecord[], signals: SocialSignalRecord[]): string;
41
- export declare function registerSocialCommand(program: Command): void;
42
- export {};
43
- //# sourceMappingURL=social.d.ts.map
@@ -1,318 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { createLogger, Platform, AuthorTier, } from '@trading-boy/core';
4
- import { formatConnectionError, padRight, truncate, colorSentiment } from '../utils.js';
5
- import { apiRequest, ApiError } from '../api-client.js';
6
- // ─── Logger ───
7
- const logger = createLogger('cli-social');
8
- // ─── Formatters ───
9
- /**
10
- * Color-code a trend direction.
11
- */
12
- function colorTrend(trend) {
13
- switch (trend) {
14
- case 'IMPROVING':
15
- return chalk.green(trend);
16
- case 'DECLINING':
17
- return chalk.red(trend);
18
- case 'STABLE':
19
- default:
20
- return chalk.yellow(trend);
21
- }
22
- }
23
- /**
24
- * Format the full social query output for a token.
25
- */
26
- export function formatTokenSocial(tokenSymbol, sentiment, mindshare, narratives, signals) {
27
- const lines = [];
28
- lines.push('');
29
- lines.push(chalk.bold.cyan(` Social Overview: ${tokenSymbol}`));
30
- lines.push(chalk.gray(' ' + '\u2500'.repeat(60)));
31
- lines.push('');
32
- // ─── Sentiment section ───
33
- lines.push(chalk.bold(' Sentiment'));
34
- if (sentiment) {
35
- lines.push(` ${chalk.gray('24h Sentiment:')} ${colorSentiment(sentiment.sentiment24h)}`);
36
- lines.push(` ${chalk.gray('Trend:')} ${colorTrend(sentiment.sentimentTrend)}`);
37
- lines.push(` ${chalk.gray('Signals (24h):')} ${sentiment.signalCount24h}`);
38
- lines.push(` ${chalk.gray('Top Tier Count:')} ${sentiment.topTierCount}`);
39
- if (sentiment.breakdown.tier1Avg !== null) {
40
- lines.push(` ${chalk.gray('Tier 1 (Mover):')} ${colorSentiment(sentiment.breakdown.tier1Avg)}`);
41
- }
42
- if (sentiment.breakdown.tier2Avg !== null) {
43
- lines.push(` ${chalk.gray('Tier 2 (Alpha):')} ${colorSentiment(sentiment.breakdown.tier2Avg)}`);
44
- }
45
- if (sentiment.breakdown.tier3Avg !== null) {
46
- lines.push(` ${chalk.gray('Tier 3 (Comm.):')} ${colorSentiment(sentiment.breakdown.tier3Avg)}`);
47
- }
48
- }
49
- else {
50
- lines.push(` ${chalk.dim('No sentiment data available.')}`);
51
- }
52
- lines.push('');
53
- // ─── Mindshare section ───
54
- lines.push(chalk.bold(' Mindshare'));
55
- if (mindshare) {
56
- lines.push(` ${chalk.gray('Rank:')} #${mindshare.rank}`);
57
- lines.push(` ${chalk.gray('Composite Score:')} ${mindshare.compositeScore.toFixed(3)}`);
58
- lines.push(` ${chalk.gray('Tx Count (24h):')} ${mindshare.txCount24h.toLocaleString()}`);
59
- lines.push(` ${chalk.gray('Unique Wallets:')} ${mindshare.uniqueWallets24h.toLocaleString()}`);
60
- lines.push(` ${chalk.gray('Whale Volume:')} $${mindshare.whaleVolume24h.toLocaleString()}`);
61
- }
62
- else {
63
- lines.push(` ${chalk.dim('No mindshare data available.')}`);
64
- }
65
- lines.push('');
66
- // ─── Narratives section ───
67
- lines.push(chalk.bold(' Narratives'));
68
- if (narratives.length > 0) {
69
- for (const n of narratives) {
70
- const conf = `${(n.confidence * 100).toFixed(0)}%`;
71
- lines.push(` ${chalk.white(n.narrativeName)} ${chalk.dim(`(${n.narrativeStatus})`)} — confidence: ${conf}`);
72
- }
73
- }
74
- else {
75
- lines.push(` ${chalk.dim('Not linked to any narratives.')}`);
76
- }
77
- lines.push('');
78
- // ─── Recent signals section ───
79
- lines.push(chalk.bold(' Recent Signals'));
80
- if (signals.length > 0) {
81
- for (const s of signals) {
82
- const sentimentStr = colorSentiment(s.sentiment);
83
- const author = s.authorHandle ?? s.authorId ?? chalk.dim('unknown');
84
- const content = s.content ? truncate(s.content, 50) : '-';
85
- lines.push(` ${sentimentStr} ${chalk.dim(s.authorTier)} ${chalk.gray(author)}: ${content}`);
86
- }
87
- }
88
- else {
89
- lines.push(` ${chalk.dim('No recent signals.')}`);
90
- }
91
- lines.push('');
92
- return lines.join('\n');
93
- }
94
- // ─── Command Registration ───
95
- export function registerSocialCommand(program) {
96
- const social = program
97
- .command('social')
98
- .description('Social signal management commands');
99
- // ─── social query ───
100
- social
101
- .command('query <token>')
102
- .description('Show social overview for a token (sentiment, mindshare, narratives, signals)')
103
- .option('--limit <n>', 'Maximum number of recent signals to show', (v) => parseInt(v, 10), 5)
104
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
105
- .action(async (token, options) => {
106
- const tokenSymbol = token.toUpperCase();
107
- try {
108
- const result = await apiRequest(`/api/v1/tokens/${encodeURIComponent(tokenSymbol)}/social?limit=${options.limit}`);
109
- if (options.format === 'json') {
110
- console.log(JSON.stringify(result, null, 2));
111
- return;
112
- }
113
- console.log(formatTokenSocial(tokenSymbol, result.sentiment, result.mindshare, result.narratives, result.signals));
114
- }
115
- catch (error) {
116
- const message = error instanceof Error ? error.message : String(error);
117
- logger.error({ error: message }, 'Failed to query social data');
118
- console.error(chalk.red(`Error: ${message}`));
119
- if (!(error instanceof ApiError)) {
120
- const guidance = formatConnectionError(message);
121
- if (guidance)
122
- console.error(guidance);
123
- }
124
- process.exitCode = error instanceof ApiError ? 2 : 1;
125
- }
126
- });
127
- // ─── social add ───
128
- social
129
- .command('add')
130
- .description('Add a manual social signal')
131
- .requiredOption('--token <symbols...>', 'Token symbol(s) mentioned')
132
- .requiredOption('--sentiment <value>', 'Sentiment score (-1.0 to 1.0)', parseFloat)
133
- .option('--tier <tier>', `Author tier (${Object.values(AuthorTier).join(', ')})`, 'TIER2_ALPHA')
134
- .option('--platform <platform>', `Platform (${Object.values(Platform).join(', ')})`, 'TWITTER')
135
- .option('--content <text>', 'Signal content / note')
136
- .option('--author-id <id>', 'Author identifier')
137
- .option('--author-handle <handle>', 'Author handle (e.g., @username)')
138
- .option('--engagement <score>', 'Engagement score (0-100)', parseFloat)
139
- .option('--narrative <narratives...>', 'Narrative name(s) to link')
140
- .option('--protocol <protocols...>', 'Protocol name(s) to link')
141
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
142
- .action(async (options) => {
143
- // Validate platform
144
- if (!Object.values(Platform).includes(options.platform)) {
145
- console.error(`Error: Invalid platform "${options.platform}". Valid platforms: ${Object.values(Platform).join(', ')}`);
146
- process.exitCode = 1;
147
- return;
148
- }
149
- // Validate author tier
150
- if (!Object.values(AuthorTier).includes(options.tier)) {
151
- console.error(`Error: Invalid author tier "${options.tier}". Valid tiers: ${Object.values(AuthorTier).join(', ')}`);
152
- process.exitCode = 1;
153
- return;
154
- }
155
- // Validate sentiment range
156
- if (isNaN(options.sentiment) || options.sentiment < -1 || options.sentiment > 1) {
157
- console.error('Error: Sentiment must be a number between -1.0 and 1.0');
158
- process.exitCode = 1;
159
- return;
160
- }
161
- try {
162
- const tokens = options.token.map((t) => t.toUpperCase());
163
- const body = {
164
- platform: options.platform,
165
- sentiment: options.sentiment,
166
- authorTier: options.tier,
167
- content: options.content,
168
- authorId: options.authorId,
169
- authorHandle: options.authorHandle,
170
- engagementScore: options.engagement,
171
- extractedEntities: tokens,
172
- narrativeTags: options.narrative ?? [],
173
- tokenSymbol: tokens[0],
174
- protocolNames: options.protocol ?? [],
175
- };
176
- const result = await apiRequest('/api/v1/social/signals', { method: 'POST', body });
177
- if (options.format === 'json') {
178
- console.log(JSON.stringify(result, null, 2));
179
- return;
180
- }
181
- if (result.duplicate) {
182
- console.log(`Duplicate signal detected, existing id=${result.id}`);
183
- return;
184
- }
185
- logger.info({ id: result.id }, 'Social signal created');
186
- console.log(`Signal created: id=${result.id}`);
187
- console.log(` Platform: ${options.platform}`);
188
- console.log(` Sentiment: ${options.sentiment}`);
189
- console.log(` Tier: ${options.tier}`);
190
- console.log(` Tokens: ${tokens.join(', ')}`);
191
- if (options.narrative) {
192
- console.log(` Narratives: ${options.narrative.join(', ')}`);
193
- }
194
- }
195
- catch (error) {
196
- const message = error instanceof Error ? error.message : String(error);
197
- logger.error({ error: message }, 'Failed to add social signal');
198
- console.error(`Error: ${message}`);
199
- process.exitCode = error instanceof ApiError ? 2 : 1;
200
- }
201
- });
202
- // ─── social list ───
203
- social
204
- .command('list')
205
- .description('List recent social signals')
206
- .option('--token <symbol>', 'Filter by token symbol')
207
- .option('--platform <platform>', 'Filter by platform')
208
- .option('--hours <n>', 'Time window in hours', (v) => parseInt(v, 10), 24)
209
- .option('--limit <n>', 'Maximum number of results', (v) => parseInt(v, 10), 20)
210
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
211
- .action(async (options) => {
212
- try {
213
- const params = new URLSearchParams();
214
- if (options.token)
215
- params.set('tokenSymbol', options.token.toUpperCase());
216
- if (options.platform)
217
- params.set('platform', options.platform);
218
- params.set('hours', String(options.hours));
219
- params.set('limit', String(options.limit));
220
- const records = await apiRequest(`/api/v1/social/signals?${params.toString()}`);
221
- if (records.length === 0) {
222
- if (options.format === 'json') {
223
- console.log(JSON.stringify([], null, 2));
224
- }
225
- else {
226
- console.log('No signals found.');
227
- }
228
- return;
229
- }
230
- if (options.format === 'json') {
231
- console.log(JSON.stringify(records, null, 2));
232
- return;
233
- }
234
- // Print formatted table
235
- console.log('');
236
- console.log(padRight('Platform', 12) +
237
- padRight('Sentiment', 11) +
238
- padRight('Tier', 22) +
239
- padRight('Entities', 20) +
240
- padRight('Content', 40));
241
- console.log('-'.repeat(105));
242
- for (const s of records) {
243
- const sentimentStr = formatSentiment(s.sentiment);
244
- const entities = s.extractedEntities
245
- ? s.extractedEntities.join(', ')
246
- : '-';
247
- console.log(padRight(s.platform, 12) +
248
- padRight(sentimentStr, 11) +
249
- padRight(s.authorTier, 22) +
250
- padRight(truncate(entities, 18), 20) +
251
- truncate(s.content ?? '-', 38));
252
- }
253
- console.log('');
254
- console.log(`Total: ${records.length} signal(s)`);
255
- }
256
- catch (error) {
257
- const message = error instanceof Error ? error.message : String(error);
258
- logger.error({ error: message }, 'Failed to list signals');
259
- console.error(`Error: ${message}`);
260
- process.exitCode = error instanceof ApiError ? 2 : 1;
261
- }
262
- });
263
- // ─── social sentiment ───
264
- social
265
- .command('sentiment')
266
- .description('Show aggregated sentiment for a token')
267
- .requiredOption('--token <symbol>', 'Token symbol')
268
- .option('--hours <n>', 'Time window in hours', (v) => parseInt(v, 10), 24)
269
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
270
- .action(async (options) => {
271
- try {
272
- const tokenSymbol = options.token.toUpperCase();
273
- // Fetch signals and compute sentiment from them
274
- const params = new URLSearchParams();
275
- params.set('tokenSymbol', tokenSymbol);
276
- params.set('hours', String(options.hours));
277
- params.set('limit', '1000');
278
- const signals = await apiRequest(`/api/v1/social/signals?${params.toString()}`);
279
- if (signals.length === 0) {
280
- if (options.format === 'json') {
281
- console.log(JSON.stringify({ tokenSymbol, hours: options.hours, signalCount: 0, average: null, min: null, max: null }, null, 2));
282
- }
283
- else {
284
- console.log(`No signals found for ${tokenSymbol} in the last ${options.hours}h.`);
285
- }
286
- return;
287
- }
288
- // Compute sentiment from signals
289
- const sentiments = signals.map(s => s.sentiment);
290
- const avgSentiment = sentiments.reduce((a, b) => a + b, 0) / sentiments.length;
291
- const minSentiment = Math.min(...sentiments);
292
- const maxSentiment = Math.max(...sentiments);
293
- if (options.format === 'json') {
294
- console.log(JSON.stringify({ tokenSymbol, hours: options.hours, signalCount: signals.length, average: avgSentiment, min: minSentiment, max: maxSentiment }, null, 2));
295
- return;
296
- }
297
- console.log('');
298
- console.log(`Sentiment for ${tokenSymbol} (last ${options.hours}h):`);
299
- console.log(` Average: ${formatSentiment(avgSentiment)}`);
300
- console.log(` Signals: ${signals.length}`);
301
- console.log(` Min: ${formatSentiment(minSentiment)}`);
302
- console.log(` Max: ${formatSentiment(maxSentiment)}`);
303
- console.log('');
304
- }
305
- catch (error) {
306
- const message = error instanceof Error ? error.message : String(error);
307
- logger.error({ error: message }, 'Failed to get sentiment');
308
- console.error(`Error: ${message}`);
309
- process.exitCode = error instanceof ApiError ? 2 : 1;
310
- }
311
- });
312
- }
313
- // ─── Helpers ───
314
- function formatSentiment(value) {
315
- const sign = value >= 0 ? '+' : '';
316
- return `${sign}${value.toFixed(2)}`;
317
- }
318
- //# sourceMappingURL=social.js.map
@@ -1,29 +0,0 @@
1
- export interface SoulWizardAnswers {
2
- style: string;
3
- riskTolerance: string;
4
- assets: string[];
5
- timeHorizon: string;
6
- biases: string;
7
- }
8
- /**
9
- * Run the interactive SOUL wizard and return the generated SOUL text.
10
- * Throws if user aborts (Ctrl+C).
11
- */
12
- export declare function runSoulWizard(): Promise<{
13
- answers: SoulWizardAnswers;
14
- soulText: string;
15
- }>;
16
- /**
17
- * Upload a SOUL document to the trader's profile.
18
- */
19
- export declare function uploadSoul(traderName: string, soulText: string): Promise<void>;
20
- /**
21
- * Print the generated SOUL document with chalk styling.
22
- */
23
- export declare function displaySoul(soulText: string): void;
24
- /**
25
- * Run wizard + upload + display. Used by both onboarding and standalone command.
26
- * Returns true if SOUL was uploaded successfully.
27
- */
28
- export declare function runSoulWizardAndUpload(traderName: string): Promise<boolean>;
29
- //# sourceMappingURL=soul-wizard.d.ts.map
@@ -1,155 +0,0 @@
1
- // ─── SOUL Wizard ───
2
- //
3
- // Interactive wizard to generate a SOUL document from guided questions.
4
- // Shared between onboarding flow and standalone `trader soul-wizard` command.
5
- import chalk from 'chalk';
6
- import { apiRequest, ApiError } from '../api-client.js';
7
- // ─── Labels ───
8
- const STYLE_LABELS = {
9
- aggressive_momentum: 'Aggressive Momentum',
10
- conservative_value: 'Conservative Value',
11
- balanced: 'Balanced',
12
- degen: 'Degen / High Risk',
13
- macro: 'Macro / Fundamentals',
14
- };
15
- const RISK_LABELS = {
16
- low: 'Low (1-3% per trade)',
17
- medium: 'Medium (3-7%)',
18
- high: 'High (7-15%)',
19
- degen: 'Degen (15%+)',
20
- };
21
- const ASSET_LABELS = {
22
- crypto: 'Crypto',
23
- commodities: 'Commodities',
24
- equities: 'Equities',
25
- forex: 'Forex',
26
- };
27
- const HORIZON_LABELS = {
28
- scalping: 'Scalping (minutes)',
29
- day: 'Day trading (hours)',
30
- swing: 'Swing (days)',
31
- position: 'Position (weeks+)',
32
- };
33
- // ─── Wizard ───
34
- /**
35
- * Run the interactive SOUL wizard and return the generated SOUL text.
36
- * Throws if user aborts (Ctrl+C).
37
- */
38
- export async function runSoulWizard() {
39
- const { select, checkbox, input } = await import('@inquirer/prompts');
40
- const style = await select({
41
- message: 'What\'s your trading style?',
42
- choices: [
43
- { value: 'aggressive_momentum', name: 'Aggressive Momentum' },
44
- { value: 'conservative_value', name: 'Conservative Value' },
45
- { value: 'balanced', name: 'Balanced' },
46
- { value: 'degen', name: 'Degen / High Risk' },
47
- { value: 'macro', name: 'Macro / Fundamentals' },
48
- ],
49
- });
50
- const riskTolerance = await select({
51
- message: 'Risk tolerance?',
52
- choices: [
53
- { value: 'low', name: 'Low (1-3% per trade)' },
54
- { value: 'medium', name: 'Medium (3-7%)' },
55
- { value: 'high', name: 'High (7-15%)' },
56
- { value: 'degen', name: 'Degen (15%+)' },
57
- ],
58
- });
59
- const assets = await checkbox({
60
- message: 'What assets do you trade?',
61
- choices: [
62
- { value: 'crypto', name: 'Crypto' },
63
- { value: 'commodities', name: 'Commodities' },
64
- { value: 'equities', name: 'Equities' },
65
- { value: 'forex', name: 'Forex' },
66
- ],
67
- });
68
- const timeHorizon = await select({
69
- message: 'Time horizon?',
70
- choices: [
71
- { value: 'scalping', name: 'Scalping (minutes)' },
72
- { value: 'day', name: 'Day trading (hours)' },
73
- { value: 'swing', name: 'Swing (days)' },
74
- { value: 'position', name: 'Position (weeks+)' },
75
- ],
76
- });
77
- const biases = await input({
78
- message: 'Any biases to watch for? (optional, press Enter to skip)',
79
- });
80
- const answers = { style, riskTolerance, assets, timeHorizon, biases };
81
- const soulText = buildSoulDocument(answers);
82
- return { answers, soulText };
83
- }
84
- // ─── SOUL Document Builder ───
85
- function buildSoulDocument(answers) {
86
- const styleLabel = STYLE_LABELS[answers.style] ?? answers.style;
87
- const riskLabel = RISK_LABELS[answers.riskTolerance] ?? answers.riskTolerance;
88
- const assetLabels = answers.assets.map(a => ASSET_LABELS[a] ?? a).join(', ') || 'Not specified';
89
- const horizonLabel = HORIZON_LABELS[answers.timeHorizon] ?? answers.timeHorizon;
90
- const lines = [];
91
- lines.push(`Trading Style: ${styleLabel}`);
92
- lines.push(`Risk Tolerance: ${riskLabel}`);
93
- lines.push(`Asset Classes: ${assetLabels}`);
94
- lines.push(`Time Horizon: ${horizonLabel}`);
95
- if (answers.biases.trim()) {
96
- lines.push(`Known Biases: ${answers.biases.trim()}`);
97
- }
98
- lines.push('');
99
- lines.push(`This trader favors ${styleLabel.toLowerCase()} approaches with ${riskLabel.toLowerCase()} risk tolerance,`);
100
- lines.push(`primarily trading ${assetLabels.toLowerCase()}. They operate on a ${horizonLabel.toLowerCase()} timeframe.`);
101
- if (answers.biases.trim()) {
102
- lines.push(`Watch for: ${answers.biases.trim()}`);
103
- }
104
- return lines.join('\n');
105
- }
106
- // ─── Upload ───
107
- /**
108
- * Upload a SOUL document to the trader's profile.
109
- */
110
- export async function uploadSoul(traderName, soulText) {
111
- await apiRequest(`/api/v1/traders/${encodeURIComponent(traderName)}/soul`, {
112
- method: 'PUT',
113
- body: { document: soulText },
114
- });
115
- }
116
- // ─── Display ───
117
- /**
118
- * Print the generated SOUL document with chalk styling.
119
- */
120
- export function displaySoul(soulText) {
121
- console.log('');
122
- console.log(chalk.bold.cyan(' Generated SOUL Document'));
123
- console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
124
- console.log('');
125
- for (const line of soulText.split('\n')) {
126
- console.log(` ${chalk.white(line)}`);
127
- }
128
- console.log('');
129
- }
130
- // ─── Combined Flow ───
131
- /**
132
- * Run wizard + upload + display. Used by both onboarding and standalone command.
133
- * Returns true if SOUL was uploaded successfully.
134
- */
135
- export async function runSoulWizardAndUpload(traderName) {
136
- const { soulText } = await runSoulWizard();
137
- displaySoul(soulText);
138
- try {
139
- await uploadSoul(traderName, soulText);
140
- console.log(chalk.green(` \u2713 SOUL uploaded for trader "${traderName}"`));
141
- return true;
142
- }
143
- catch (error) {
144
- if (error instanceof ApiError) {
145
- console.log(chalk.yellow(` Could not upload SOUL: ${error.message}`));
146
- }
147
- else {
148
- const msg = error instanceof Error ? error.message : String(error);
149
- console.log(chalk.yellow(` Could not upload SOUL: ${msg}`));
150
- }
151
- console.log(chalk.dim(' You can upload it later: trading-boy trader soul <name> --file soul.md'));
152
- return false;
153
- }
154
- }
155
- //# sourceMappingURL=soul-wizard.js.map
@@ -1,44 +0,0 @@
1
- import { Command } from 'commander';
2
- interface AgentStrategy {
3
- id: string;
4
- agentId: string;
5
- traderId: string;
6
- tenantId: string;
7
- version: number;
8
- name: string;
9
- tokens: string[];
10
- setupTypes: string[];
11
- regimeBehavior: Record<string, unknown>;
12
- riskLimits: Record<string, unknown>;
13
- signalWeights: Record<string, number>;
14
- narrativePreferences: string[];
15
- active: boolean;
16
- createdAt: string;
17
- updatedAt: string;
18
- }
19
- interface StrategyListResponse {
20
- strategies: AgentStrategy[];
21
- total: number;
22
- limit: number;
23
- offset: number;
24
- }
25
- interface StrategyHistoryEntry {
26
- id: string;
27
- strategyId: string;
28
- version: number;
29
- name: string;
30
- tokens: string[];
31
- setupTypes: string[];
32
- changedAt: string;
33
- changedBy?: string;
34
- }
35
- interface StrategyHistoryResponse {
36
- strategyId: string;
37
- history: StrategyHistoryEntry[];
38
- }
39
- export declare function formatStrategyDetail(s: AgentStrategy): string;
40
- export declare function formatStrategyList(response: StrategyListResponse): string;
41
- export declare function formatHistoryList(response: StrategyHistoryResponse): string;
42
- export declare function registerStrategyCommand(program: Command): void;
43
- export {};
44
- //# sourceMappingURL=strategy-cmd.d.ts.map