@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,259 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { NarrativeStatus, } from '@trading-boy/core';
4
- import { padRight, truncate } from '../utils.js';
5
- import { apiRequest, ApiError } from '../api-client.js';
6
- // ─── Helpers ───
7
- const VALID_STATUSES = Object.values(NarrativeStatus);
8
- // ─── Command Registration ───
9
- export function registerNarrativeCommand(program) {
10
- const narrative = program
11
- .command('narrative')
12
- .description('Manage market narratives');
13
- // ─── narrative create ───
14
- narrative
15
- .command('create <name>')
16
- .description('Create a new narrative')
17
- .option('--status <status>', `Initial status (${VALID_STATUSES.join(', ')})`, 'EMERGING')
18
- .option('--momentum <score>', 'Momentum score (0-100)', parseFloat, 0)
19
- .option('--description <desc>', 'Narrative description')
20
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
21
- .action(async (name, options) => {
22
- // Validate non-empty name
23
- if (!name.trim()) {
24
- console.error('Error: Narrative name cannot be empty');
25
- process.exitCode = 1;
26
- return;
27
- }
28
- // Validate status
29
- if (!VALID_STATUSES.includes(options.status)) {
30
- console.error(`Error: Invalid status "${options.status}". Valid values: ${VALID_STATUSES.join(', ')}`);
31
- process.exitCode = 1;
32
- return;
33
- }
34
- // Validate momentum
35
- if (isNaN(options.momentum) || options.momentum < 0 || options.momentum > 100) {
36
- console.error('Error: Momentum score must be a number between 0 and 100');
37
- process.exitCode = 1;
38
- return;
39
- }
40
- try {
41
- const result = await apiRequest('/api/v1/narratives', {
42
- method: 'POST',
43
- body: {
44
- name: name.trim(),
45
- status: options.status,
46
- momentum: options.momentum,
47
- description: options.description,
48
- },
49
- });
50
- if (options.format === 'json') {
51
- console.log(JSON.stringify(result, null, 2));
52
- }
53
- else {
54
- console.log(`Narrative created: id=${result.id}`);
55
- console.log(` Name: ${name}`);
56
- console.log(` Status: ${options.status}`);
57
- console.log(` Momentum: ${options.momentum}`);
58
- if (options.description) {
59
- console.log(` Description: ${options.description}`);
60
- }
61
- }
62
- }
63
- catch (error) {
64
- if (error instanceof ApiError && error.status === 409) {
65
- const body = error.body;
66
- console.error(`Error: Narrative "${name.trim()}" already exists${body?.id ? ` (id=${body.id})` : ''}. Use "narrative update" to modify it.`);
67
- }
68
- else {
69
- const message = error instanceof Error ? error.message : String(error);
70
- console.error(`Error: ${message}`);
71
- }
72
- process.exitCode = error instanceof ApiError ? 2 : 1;
73
- }
74
- });
75
- // ─── narrative update ───
76
- narrative
77
- .command('update <name>')
78
- .description('Update an existing narrative')
79
- .option('--status <status>', `New status (${VALID_STATUSES.join(', ')})`)
80
- .option('--momentum <score>', 'New momentum score (0-100)', parseFloat)
81
- .option('--description <desc>', 'New description')
82
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
83
- .action(async (name, options) => {
84
- // Validate status if provided
85
- if (options.status && !VALID_STATUSES.includes(options.status)) {
86
- console.error(`Error: Invalid status "${options.status}". Valid values: ${VALID_STATUSES.join(', ')}`);
87
- process.exitCode = 1;
88
- return;
89
- }
90
- // Validate momentum if provided
91
- if (options.momentum !== undefined && (isNaN(options.momentum) || options.momentum < 0 || options.momentum > 100)) {
92
- console.error('Error: Momentum score must be a number between 0 and 100');
93
- process.exitCode = 1;
94
- return;
95
- }
96
- // Must provide at least one update
97
- if (!options.status && options.momentum === undefined && !options.description) {
98
- console.error('Error: At least one of --status, --momentum, or --description must be provided');
99
- process.exitCode = 1;
100
- return;
101
- }
102
- try {
103
- const result = await apiRequest(`/api/v1/narratives/${encodeURIComponent(name)}`, {
104
- method: 'PATCH',
105
- body: {
106
- status: options.status,
107
- momentum: options.momentum,
108
- description: options.description,
109
- },
110
- });
111
- if (options.format === 'json') {
112
- console.log(JSON.stringify(result, null, 2));
113
- }
114
- else {
115
- console.log(`Narrative updated: ${name}`);
116
- console.log(` Status: ${result.status}`);
117
- console.log(` Momentum: ${result.momentumScore}`);
118
- if (result.description) {
119
- console.log(` Description: ${result.description}`);
120
- }
121
- }
122
- }
123
- catch (error) {
124
- if (error instanceof ApiError && error.status === 404) {
125
- console.error(`Error: Narrative "${name}" not found`);
126
- }
127
- else {
128
- const message = error instanceof Error ? error.message : String(error);
129
- console.error(`Error: ${message}`);
130
- }
131
- process.exitCode = error instanceof ApiError ? 2 : 1;
132
- }
133
- });
134
- // ─── narrative list ───
135
- narrative
136
- .command('list')
137
- .description('List narratives')
138
- .option('--status <status>', 'Filter by status')
139
- .option('--limit <n>', 'Maximum number of results', parseInt, 20)
140
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
141
- .action(async (options) => {
142
- // Validate status if provided
143
- if (options.status && !VALID_STATUSES.includes(options.status)) {
144
- console.error(`Error: Invalid status "${options.status}". Valid values: ${VALID_STATUSES.join(', ')}`);
145
- process.exitCode = 1;
146
- return;
147
- }
148
- try {
149
- const params = new URLSearchParams();
150
- if (options.status)
151
- params.set('status', options.status);
152
- if (options.limit)
153
- params.set('limit', String(options.limit));
154
- const qs = params.toString() ? `?${params.toString()}` : '';
155
- const result = await apiRequest(`/api/v1/narratives${qs}`);
156
- const records = result.narratives ?? [];
157
- if (records.length === 0) {
158
- console.log('No narratives found.');
159
- return;
160
- }
161
- if (options.format === 'json') {
162
- console.log(JSON.stringify(records, null, 2));
163
- return;
164
- }
165
- // Print formatted table (no token data available from this endpoint)
166
- console.log('');
167
- console.log(padRight('Name', 25) +
168
- padRight('Status', 12) +
169
- padRight('Momentum', 10));
170
- console.log('-'.repeat(47));
171
- for (const n of records) {
172
- console.log(padRight(truncate(n.name, 23), 25) +
173
- padRight(n.status, 12) +
174
- padRight(String(n.momentumScore), 10));
175
- }
176
- console.log('');
177
- console.log(`Total: ${records.length} narrative(s)`);
178
- }
179
- catch (error) {
180
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
181
- console.error(`Error: ${message}`);
182
- process.exitCode = error instanceof ApiError ? 2 : 1;
183
- }
184
- });
185
- // ─── narrative link ───
186
- narrative
187
- .command('link <token> <narrative>')
188
- .description('Link a token to a narrative')
189
- .option('--confidence <score>', 'Confidence score (0-1)', parseFloat, 0.5)
190
- .action(async (token, narrativeName) => {
191
- try {
192
- const result = await apiRequest(`/api/v1/narratives/${encodeURIComponent(narrativeName)}/link`, { method: 'POST', body: { tokenSymbol: token.toUpperCase() } });
193
- console.log(chalk.green(`\n ✓ Linked ${result.tokenSymbol} to narrative "${result.narrative}"\n`));
194
- }
195
- catch (error) {
196
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
197
- console.error(chalk.red(`Error: ${message}`));
198
- process.exitCode = error instanceof ApiError ? 2 : 1;
199
- }
200
- });
201
- // ─── narrative unlink ───
202
- narrative
203
- .command('unlink <token> <narrative>')
204
- .description('Unlink a token from a narrative')
205
- .action(async (token, narrativeName) => {
206
- try {
207
- const result = await apiRequest(`/api/v1/narratives/${encodeURIComponent(narrativeName)}/unlink`, { method: 'POST', body: { tokenSymbol: token.toUpperCase() } });
208
- console.log(chalk.green(`\n ✓ Unlinked ${result.tokenSymbol} from narrative "${result.narrative}"\n`));
209
- }
210
- catch (error) {
211
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
212
- console.error(chalk.red(`Error: ${message}`));
213
- process.exitCode = error instanceof ApiError ? 2 : 1;
214
- }
215
- });
216
- // ─── narrative show ───
217
- narrative
218
- .command('show <name>')
219
- .description('Show narrative details with linked tokens')
220
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
221
- .action(async (name, options) => {
222
- try {
223
- const record = await apiRequest(`/api/v1/narratives/${encodeURIComponent(name)}`);
224
- if (options.format === 'json') {
225
- console.log(JSON.stringify(record, null, 2));
226
- }
227
- else {
228
- console.log('');
229
- console.log(`Narrative: ${record.name}`);
230
- console.log(` ID: ${record.id}`);
231
- console.log(` Status: ${record.status}`);
232
- console.log(` Momentum: ${record.momentumScore}`);
233
- if (record.description) {
234
- console.log(` Description: ${record.description}`);
235
- }
236
- if (record.firstDetected) {
237
- console.log(` First Detected: ${record.firstDetected}`);
238
- }
239
- if (record.peakDate) {
240
- console.log(` Peak Date: ${record.peakDate}`);
241
- }
242
- console.log('');
243
- console.log(' (Linked token details not yet available via API)');
244
- }
245
- }
246
- catch (error) {
247
- if (error instanceof ApiError && error.status === 404) {
248
- console.error(`Error: Narrative "${name}" not found`);
249
- }
250
- else {
251
- const message = error instanceof Error ? error.message : String(error);
252
- console.error(`Error: ${message}`);
253
- }
254
- process.exitCode = error instanceof ApiError ? 2 : 1;
255
- }
256
- });
257
- }
258
- // LinkOptions removed — link now uses API directly
259
- //# sourceMappingURL=narratives.js.map
@@ -1,7 +0,0 @@
1
- /**
2
- * Run the interactive onboarding wizard.
3
- * Called after subscribe completes successfully.
4
- * Gracefully handles Ctrl+C and skipped steps.
5
- */
6
- export declare function runOnboarding(): Promise<void>;
7
- //# sourceMappingURL=onboarding.d.ts.map
@@ -1,281 +0,0 @@
1
- // ─── Post-Subscribe Onboarding Wizard ───
2
- //
3
- // Guided setup after a new user subscribes. Walks through:
4
- // 1. Register a trader profile (name + risk tolerance)
5
- // 2. Identity setup (SOUL wizard)
6
- // 3. LLM provider — ChatGPT OAuth or BYOK API key
7
- // 4. Connect Telegram bot for daily summaries
8
- // 5. Agent runtime overview (scan intervals, autonomy levels)
9
- // 6. Quick reference cheat sheet
10
- import chalk from 'chalk';
11
- import { isRemoteMode, apiRequest, ApiError } from '../api-client.js';
12
- import { runSoulWizardAndUpload } from './soul-wizard.js';
13
- import { connectChatgpt } from './connect-chatgpt.js';
14
- // ─── Onboarding Flow ───
15
- /**
16
- * Run the interactive onboarding wizard.
17
- * Called after subscribe completes successfully.
18
- * Gracefully handles Ctrl+C and skipped steps.
19
- */
20
- export async function runOnboarding() {
21
- const { confirm, input } = await import('@inquirer/prompts');
22
- console.log('');
23
- console.log(chalk.bold.cyan(' Get Started'));
24
- console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
25
- console.log(chalk.dim(' Let\u2019s set up your account. You can skip any step.'));
26
- console.log('');
27
- // ─── Step 1: Register Trader ───
28
- let traderRegistered = false;
29
- let traderName = 'default';
30
- try {
31
- const wantsTrader = await confirm({
32
- message: 'Register your trader profile?',
33
- default: true,
34
- });
35
- if (wantsTrader) {
36
- const name = await input({
37
- message: 'Trader name (this will appear on the public leaderboard — use a pseudonym to stay anonymous)',
38
- default: 'default',
39
- validate: (v) => (v.trim().length > 0 ? true : 'Name cannot be empty'),
40
- });
41
- const maxDrawdown = await input({
42
- message: 'Max drawdown % (risk tolerance)',
43
- default: '15',
44
- validate: (v) => {
45
- const n = parseFloat(v);
46
- if (isNaN(n) || n <= 0 || n > 100)
47
- return 'Enter a number between 1 and 100';
48
- return true;
49
- },
50
- });
51
- try {
52
- if (await isRemoteMode()) {
53
- const result = await apiRequest('/api/v1/traders', {
54
- method: 'POST',
55
- body: { name: name.trim(), riskToleranceMax: parseFloat(maxDrawdown) },
56
- });
57
- console.log(chalk.green(` \u2713 Trader "${result.name}" registered (id: ${result.id})`));
58
- if (result.publicAlias) {
59
- console.log(chalk.dim(` Leaderboard alias: ${result.publicAlias}`));
60
- console.log(chalk.dim(' This alias is public on the leaderboard. Change it anytime:'));
61
- console.log(chalk.dim(' trading-boy trader set-alias <name> <new-alias>'));
62
- }
63
- traderName = name.trim();
64
- traderRegistered = true;
65
- }
66
- else {
67
- console.log(chalk.yellow(' Skipped \u2014 not connected to API. Run: trading-boy trader register'));
68
- }
69
- }
70
- catch (error) {
71
- if (error instanceof ApiError && error.status === 409) {
72
- console.log(chalk.green(' \u2713 Trader profile already exists.'));
73
- traderName = name.trim();
74
- traderRegistered = true;
75
- }
76
- else {
77
- const msg = error instanceof Error ? error.message : String(error);
78
- console.log(chalk.yellow(` Could not register trader: ${msg}`));
79
- console.log(chalk.dim(' You can do this later: trading-boy trader register --name "YourName"'));
80
- }
81
- }
82
- }
83
- else {
84
- console.log(chalk.dim(' Skipped. Run later: trading-boy trader register --name "YourName"'));
85
- }
86
- }
87
- catch (error) {
88
- if (isUserAbort(error))
89
- return;
90
- throw error;
91
- }
92
- console.log('');
93
- // ─── Step 2: Identity Setup ───
94
- if (traderRegistered) {
95
- try {
96
- const wantsIdentity = await confirm({
97
- message: 'Set up your trading identity? (interactive SOUL wizard)',
98
- default: true,
99
- });
100
- if (wantsIdentity) {
101
- console.log('');
102
- console.log(chalk.dim(' Your identity personalizes context — bias warnings, scope checks,'));
103
- console.log(chalk.dim(' and tailored synthesis based on who you are as a trader.'));
104
- console.log('');
105
- try {
106
- await runSoulWizardAndUpload(traderName);
107
- }
108
- catch (wizardError) {
109
- if (isUserAbort(wizardError))
110
- return;
111
- const msg = wizardError instanceof Error ? wizardError.message : String(wizardError);
112
- console.log(chalk.yellow(` Could not complete SOUL wizard: ${msg}`));
113
- console.log(chalk.dim(' You can do this later: trading-boy trader soul-wizard <name>'));
114
- }
115
- }
116
- else {
117
- console.log(chalk.dim(' Skipped. Run later: trading-boy trader soul-wizard <name>'));
118
- }
119
- }
120
- catch (error) {
121
- if (isUserAbort(error))
122
- return;
123
- throw error;
124
- }
125
- console.log('');
126
- }
127
- // ─── Step 3: LLM Provider ───
128
- try {
129
- console.log(chalk.bold.cyan(' LLM Provider (required for agents)'));
130
- console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
131
- console.log(chalk.dim(' Your agent needs an LLM to analyze markets and make decisions.'));
132
- console.log('');
133
- const { select } = await import('@inquirer/prompts');
134
- const llmChoice = await select({
135
- message: 'How do you want to power your agent?',
136
- choices: [
137
- {
138
- name: 'Use my ChatGPT subscription (no API key needed)',
139
- value: 'chatgpt',
140
- description: 'Sign in with your OpenAI account — uses your existing ChatGPT Plus/Pro/Team plan',
141
- },
142
- {
143
- name: 'Bring my own API key (Anthropic, Gemini, OpenAI, etc.)',
144
- value: 'byok',
145
- description: 'Paste an API key from any supported provider',
146
- },
147
- {
148
- name: 'Skip for now',
149
- value: 'skip',
150
- },
151
- ],
152
- });
153
- if (llmChoice === 'chatgpt') {
154
- try {
155
- await connectChatgpt();
156
- }
157
- catch (error) {
158
- const msg = error instanceof Error ? error.message : String(error);
159
- console.log(chalk.yellow(` Could not connect ChatGPT: ${msg}`));
160
- console.log(chalk.dim(' Try later: trading-boy connect-chatgpt'));
161
- }
162
- }
163
- else if (llmChoice === 'byok') {
164
- console.log('');
165
- console.log(chalk.dim(' Supported providers (auto-detected from key prefix):'));
166
- console.log('');
167
- console.log(` ${chalk.white('Anthropic')} ${chalk.dim('(default) — Claude Sonnet/Opus/Haiku')}`);
168
- console.log(` ${chalk.white('Gemini')} ${chalk.dim('— Gemini 2.5 Pro')}`);
169
- console.log(` ${chalk.white('OpenAI')} ${chalk.dim('— GPT-4o / GPT-4.1')}`);
170
- console.log(` ${chalk.white('OpenRouter')} ${chalk.dim('— Any model via OpenRouter')}`);
171
- console.log(` ${chalk.white('Ollama')} ${chalk.dim('— Local models')}`);
172
- console.log('');
173
- const llmKey = await input({
174
- message: 'Paste your API key',
175
- validate: (v) => (v.trim().length > 5 ? true : 'Key is too short'),
176
- });
177
- try {
178
- if (await isRemoteMode()) {
179
- const result = await apiRequest('/api/v1/llm-config', {
180
- method: 'PUT',
181
- body: { apiKey: llmKey.trim() },
182
- });
183
- console.log(chalk.green(` ✓ LLM key saved — ${result.provider} / ${result.model}`));
184
- console.log(chalk.dim(' Change model later: trading-boy config set-llm-key <key> --model <model>'));
185
- }
186
- else {
187
- console.log(chalk.yellow(' Skipped — not connected to API.'));
188
- }
189
- }
190
- catch (error) {
191
- const msg = error instanceof Error ? error.message : String(error);
192
- console.log(chalk.yellow(` Could not save LLM key: ${msg}`));
193
- console.log(chalk.dim(' Set it later: trading-boy config set-llm-key <your-api-key>'));
194
- }
195
- }
196
- else {
197
- console.log('');
198
- console.log(chalk.yellow(' ⚠ Without an LLM provider, agents can scan prices but cannot'));
199
- console.log(chalk.yellow(' analyze markets or make trade decisions.'));
200
- console.log(chalk.dim(' Set it later: trading-boy connect-chatgpt'));
201
- console.log(chalk.dim(' Or BYOK: trading-boy config set-llm-key <your-api-key>'));
202
- }
203
- }
204
- catch (error) {
205
- if (isUserAbort(error))
206
- return;
207
- throw error;
208
- }
209
- console.log('');
210
- // ─── Step 4: Telegram Bot ───
211
- try {
212
- const wantsTelegram = await confirm({
213
- message: 'Connect Telegram for daily summaries?',
214
- default: true,
215
- });
216
- if (wantsTelegram) {
217
- console.log('');
218
- console.log(chalk.white(' Click to open the bot: ') + chalk.cyan.underline('https://t.me/TradingBoy1_Bot'));
219
- console.log(chalk.white(' Send ') + chalk.cyan('/start') + chalk.white(' and paste your API key to connect.'));
220
- console.log('');
221
- console.log(chalk.dim(' The bot will send you a daily trading summary at 08:00 UTC.'));
222
- console.log(chalk.dim(' You can also use /summary, /agents, /positions, /pause, and /soul.'));
223
- }
224
- else {
225
- console.log(chalk.dim(' Skipped. Connect anytime: ') + chalk.dim.underline('https://t.me/TradingBoy1_Bot'));
226
- }
227
- }
228
- catch (error) {
229
- if (isUserAbort(error))
230
- return;
231
- throw error;
232
- }
233
- console.log('');
234
- // ─── Step 5: Agent Runtime Overview ───
235
- console.log(chalk.bold.cyan(' How Agents Work'));
236
- console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
237
- console.log('');
238
- console.log(chalk.dim(' Once you create an agent, it runs continuously on our servers:'));
239
- console.log('');
240
- console.log(` ${chalk.white('Scan')} ${chalk.dim('Every 30 min by default — scans your watchlist for setups')}`);
241
- console.log(` ${chalk.white('Analyze')} ${chalk.dim('When a setup is found — deep context analysis via your LLM')}`);
242
- console.log(` ${chalk.white('Decide')} ${chalk.dim('After analysis — enter/exit/hold based on your strategy')}`);
243
- console.log(` ${chalk.white('Learn')} ${chalk.dim('After trades close — updates edge profile from outcomes')}`);
244
- console.log('');
245
- console.log(chalk.dim(' Scan interval controls how often your agent checks for setups.'));
246
- console.log(chalk.dim(' Lower intervals = more LLM calls = higher cost. Recommended: 30m.'));
247
- console.log(chalk.dim(' Change it: trading-boy agent update <name> --scan-interval 15m'));
248
- console.log('');
249
- console.log(chalk.dim(' Autonomy levels:'));
250
- console.log(` ${chalk.cyan('OBSERVE_ONLY')} ${chalk.dim('Scans and analyzes — takes no action')}`);
251
- console.log(` ${chalk.cyan('SUGGEST')} ${chalk.dim('Sends trade ideas to your Telegram')}`);
252
- console.log(` ${chalk.cyan('AUTO_WITH_APPROVAL')} ${chalk.dim('Proposes trades, waits for your OK')}`);
253
- console.log(` ${chalk.cyan('FULLY_AUTONOMOUS')} ${chalk.dim('Trades within your guardrails, no human in the loop')}`);
254
- console.log('');
255
- console.log(chalk.dim(' Create your first agent:'));
256
- console.log(` ${chalk.white('trading-boy agent create --help')}`);
257
- console.log('');
258
- // ─── Step 6: Quick Reference ───
259
- console.log(chalk.bold.cyan(' Quick Reference'));
260
- console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
261
- console.log('');
262
- console.log(` ${chalk.white('trading-boy context SOL')} ${chalk.dim('Full context for any token')}`);
263
- console.log(` ${chalk.white('trading-boy agent create')} ${chalk.dim('Create an autonomous agent')}`);
264
- console.log(` ${chalk.white('trading-boy agent list')} ${chalk.dim('View your running agents')}`);
265
- console.log(` ${chalk.white('trading-boy decisions')} ${chalk.dim('View trade history')}`);
266
- console.log(` ${chalk.white('trading-boy stats')} ${chalk.dim('Track performance')}`);
267
- console.log(` ${chalk.white('trading-boy narrative list')} ${chalk.dim('Active market narratives')}`);
268
- console.log(` ${chalk.white('trading-boy catalysts')} ${chalk.dim('Upcoming events')}`);
269
- if (traderRegistered) {
270
- console.log(` ${chalk.white('trading-boy edge')} ${chalk.dim('Your edge profile')}`);
271
- console.log(` ${chalk.white('trading-boy behavioral')} ${chalk.dim('Behavioral analysis')}`);
272
- }
273
- console.log('');
274
- console.log(chalk.dim(' Full docs: https://api.cabal.ventures/docs'));
275
- console.log('');
276
- }
277
- // ─── Helpers ───
278
- function isUserAbort(error) {
279
- return error instanceof Error && error.message.includes('User force closed');
280
- }
281
- //# sourceMappingURL=onboarding.js.map
@@ -1,32 +0,0 @@
1
- import { Command } from 'commander';
2
- interface TokenInfo {
3
- name: string | null;
4
- symbol: string;
5
- chains: string[];
6
- narratives: Array<{
7
- name: string;
8
- status: string;
9
- }>;
10
- }
11
- interface PriceInfo {
12
- price: number | null;
13
- change24h: number | null;
14
- lastUpdated: Date | null;
15
- }
16
- interface FundingInfo {
17
- fundingRate: number | null;
18
- lastUpdated: Date | null;
19
- }
20
- interface WhaleInfo {
21
- count: number;
22
- }
23
- export interface QueryResult {
24
- token: TokenInfo;
25
- price: PriceInfo;
26
- funding: FundingInfo;
27
- whaleActivity: WhaleInfo;
28
- }
29
- export declare function formatQueryOutput(result: QueryResult): string;
30
- export declare function registerQueryCommand(program: Command): void;
31
- export {};
32
- //# sourceMappingURL=query.d.ts.map