@trading-boy/cli 1.11.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 +1977 -33976
  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 -572
  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 -298
  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 -340
  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,169 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { apiRequest, ApiError } from '../api-client.js';
4
- import { ensureRemote } from '../utils.js';
5
- // ─── Formatters ───
6
- export function formatAssessmentOutput(data) {
7
- const lines = [];
8
- const a = data.assessment;
9
- lines.push('');
10
- lines.push(chalk.bold.cyan(` Edge Guard — ${data.traderId}`));
11
- lines.push(chalk.gray(' ' + '─'.repeat(50)));
12
- lines.push(` ${chalk.gray('Status:')} ${colorStatus(a.status)}`);
13
- lines.push(` ${chalk.gray('Escalation:')} ${colorEscalation(a.escalation)}`);
14
- lines.push(` ${chalk.gray('Friction Active:')} ${a.frictionActive ? chalk.red('YES') : chalk.green('NO')}`);
15
- lines.push('');
16
- lines.push(` ${chalk.gray('Portfolio EV:')} ${colorPnl(a.portfolioEV)}`);
17
- lines.push(` ${chalk.gray('90% CI:')} [${formatUsd(a.portfolioEVLower)}, ${formatUsd(a.portfolioEVUpper)}]`);
18
- lines.push(` ${chalk.gray('Negative Cells:')} ${a.negativeCells}/${a.totalCells}`);
19
- if (a.message) {
20
- lines.push('');
21
- lines.push(chalk.bold(' Message'));
22
- // Wrap message at ~70 chars, indented
23
- const words = a.message.split(' ');
24
- let line = ' ';
25
- for (const word of words) {
26
- if (line.length + word.length > 72) {
27
- lines.push(line);
28
- line = ' ';
29
- }
30
- line += word + ' ';
31
- }
32
- if (line.trim())
33
- lines.push(line);
34
- }
35
- if (a.cellEstimates.length > 0) {
36
- lines.push('');
37
- lines.push(chalk.bold(' Cell Estimates'));
38
- lines.push(` ${chalk.gray('Setup'.padEnd(18))}${'Regime'.padEnd(16)}${'EV'.padStart(10)}${'Win%'.padStart(8)}`);
39
- lines.push(chalk.gray(' ' + '─'.repeat(52)));
40
- // Show top negative cells first
41
- const sorted = [...a.cellEstimates].sort((x, y) => x.evPoint - y.evPoint);
42
- const shown = sorted.slice(0, 15);
43
- for (const c of shown) {
44
- const evStr = formatUsd(c.evPoint);
45
- const wrStr = (c.winRate * 100).toFixed(1) + '%';
46
- lines.push(` ${c.setupType.padEnd(18)}${c.regime.padEnd(16)}${(c.evPoint >= 0 ? chalk.green(evStr) : chalk.red(evStr)).padStart(10)}${wrStr.padStart(8)}`);
47
- }
48
- if (a.cellEstimates.length > 15) {
49
- lines.push(chalk.dim(` ... and ${a.cellEstimates.length - 15} more cells`));
50
- }
51
- }
52
- lines.push('');
53
- return lines.join('\n');
54
- }
55
- export function formatFrictionOutput(data) {
56
- const lines = [];
57
- lines.push('');
58
- lines.push(chalk.bold.cyan(` Entry Friction — ${data.traderId}`));
59
- lines.push(chalk.gray(' ' + '─'.repeat(50)));
60
- lines.push(` ${chalk.gray('Escalation:')} ${colorEscalation(data.escalation)}`);
61
- lines.push(` ${chalk.gray('Requires Ack:')} ${data.requiresAcknowledgement ? chalk.red('YES') : chalk.green('NO')}`);
62
- lines.push(` ${chalk.gray('Acknowledged:')} ${data.acknowledged ? chalk.green('YES') : chalk.dim('NO')}`);
63
- if (data.message) {
64
- lines.push('');
65
- lines.push(` ${data.message}`);
66
- }
67
- if (data.requiresAcknowledgement && !data.acknowledged) {
68
- lines.push('');
69
- lines.push(chalk.yellow(` Run: trading-boy edge-guard acknowledge ${data.traderId}`));
70
- }
71
- lines.push('');
72
- return lines.join('\n');
73
- }
74
- function colorStatus(status) {
75
- switch (status) {
76
- case 'POSITIVE_EDGE': return chalk.green(status);
77
- case 'UNCERTAIN': return chalk.yellow(status);
78
- case 'NEGATIVE_EDGE_WARNING': return chalk.red(status);
79
- case 'NEGATIVE_EDGE_CONFIRMED': return chalk.bgRed.white(` ${status} `);
80
- default: return status;
81
- }
82
- }
83
- function colorEscalation(level) {
84
- switch (level) {
85
- case 'NORMAL': return chalk.green(level);
86
- case 'INCREASED_COACHING': return chalk.yellow(level);
87
- case 'EXPLICIT_WARNING': return chalk.red(level);
88
- case 'ENTRY_FRICTION': return chalk.bgRed.white(` ${level} `);
89
- default: return level;
90
- }
91
- }
92
- function colorPnl(usd) {
93
- const str = formatUsd(usd);
94
- return usd >= 0 ? chalk.green(str) : chalk.red(str);
95
- }
96
- function formatUsd(val) {
97
- const sign = val >= 0 ? '+' : '';
98
- return `${sign}$${val.toFixed(2)}`;
99
- }
100
- // ─── Command Registration ───
101
- export function registerEdgeGuardCommand(program) {
102
- // Parent command group (no positional arg — subcommands handle their own traderId)
103
- const cmd = program
104
- .command('edge-guard')
105
- .description('Check negative edge status and entry friction')
106
- .action(() => {
107
- // Show help when called without a subcommand
108
- cmd.help();
109
- });
110
- // Subcommand: check <traderId> (default assessment)
111
- cmd
112
- .command('check <traderId>')
113
- .description('Assess negative edge status for a trader')
114
- .option('--friction', 'Check entry friction level only')
115
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
116
- .action(async (traderId, options) => {
117
- try {
118
- if (!(await ensureRemote()))
119
- return;
120
- if (options.friction) {
121
- const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard/friction`);
122
- if (options.format === 'json') {
123
- console.log(JSON.stringify(data, null, 2));
124
- }
125
- else {
126
- console.log(formatFrictionOutput(data));
127
- }
128
- }
129
- else {
130
- const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard`);
131
- if (options.format === 'json') {
132
- console.log(JSON.stringify(data, null, 2));
133
- }
134
- else {
135
- console.log(formatAssessmentOutput(data));
136
- }
137
- }
138
- }
139
- catch (error) {
140
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
141
- console.error(chalk.red(`Error: ${message}`));
142
- process.exitCode = error instanceof ApiError ? 2 : 1;
143
- }
144
- });
145
- // Subcommand: acknowledge <traderId>
146
- cmd
147
- .command('acknowledge <traderId>')
148
- .description('Acknowledge negative edge warning to proceed with trade')
149
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
150
- .action(async (traderId, ackOptions) => {
151
- try {
152
- if (!(await ensureRemote()))
153
- return;
154
- const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard/acknowledge`, { method: 'POST' });
155
- if (ackOptions.format === 'json') {
156
- console.log(JSON.stringify(data, null, 2));
157
- }
158
- else {
159
- console.log(chalk.green(`\n ✓ Edge warning acknowledged for ${data.traderId}\n`));
160
- }
161
- }
162
- catch (error) {
163
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
164
- console.error(chalk.red(`Error: ${message}`));
165
- process.exitCode = error instanceof ApiError ? 2 : 1;
166
- }
167
- });
168
- }
169
- //# sourceMappingURL=edge-guard-cmd.js.map
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerEventsCommand(program: Command): void;
3
- //# sourceMappingURL=events.d.ts.map
@@ -1,117 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { createLogger, EventType, Severity } from '@trading-boy/core';
4
- import { apiRequest, ApiError } from '../api-client.js';
5
- import { padRight, truncate, formatDate } from '../utils.js';
6
- const logger = createLogger('cli-events');
7
- // ─── Formatters ───
8
- function colorSeverity(severity) {
9
- switch (severity) {
10
- case 'CRITICAL': return chalk.bgRed.white.bold(` ${severity} `);
11
- case 'HIGH': return chalk.red(severity);
12
- case 'MEDIUM': return chalk.yellow(severity);
13
- case 'LOW': return chalk.green(severity);
14
- default: return chalk.dim(severity);
15
- }
16
- }
17
- function formatEventsList(events) {
18
- const lines = [];
19
- lines.push('');
20
- lines.push(chalk.bold.cyan(' Events'));
21
- lines.push(chalk.gray(' ' + '─'.repeat(80)));
22
- if (events.length === 0) {
23
- lines.push(` ${chalk.dim('No events found.')}`);
24
- lines.push('');
25
- return lines.join('\n');
26
- }
27
- lines.push(' ' + padRight('Date', 14) + padRight('Type', 22) + padRight('Severity', 12) + 'Title');
28
- lines.push(' ' + '─'.repeat(80));
29
- for (const e of events) {
30
- lines.push(' ' +
31
- padRight(formatDate(e.scheduledDate), 14) +
32
- padRight(e.type, 22) +
33
- padRight(colorSeverity(e.severity), 12) +
34
- truncate(e.title, 30));
35
- }
36
- lines.push('');
37
- lines.push(` ${chalk.gray(`${events.length} event(s)`)}`);
38
- lines.push('');
39
- return lines.join('\n');
40
- }
41
- // ─── Command Registration ───
42
- export function registerEventsCommand(program) {
43
- const events = program
44
- .command('events')
45
- .description('Event management commands')
46
- .action(() => { events.help(); });
47
- // events add
48
- events
49
- .command('add')
50
- .description('Add a new event')
51
- .requiredOption('--type <type>', `Event type (${Object.values(EventType).join(', ')})`)
52
- .requiredOption('--title <title>', 'Event title')
53
- .option('--token <symbols...>', 'Token symbol(s) affected')
54
- .option('--date <date>', 'Scheduled date (ISO 8601)')
55
- .option('--description <desc>', 'Event description')
56
- .option('--severity <severity>', `Severity (${Object.values(Severity).join(', ')})`, 'MEDIUM')
57
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
58
- .action(async (options) => {
59
- try {
60
- const body = {
61
- type: options.type,
62
- title: options.title,
63
- severity: options.severity,
64
- };
65
- if (options.token)
66
- body.tokenSymbols = options.token;
67
- if (options.date)
68
- body.scheduledDate = options.date;
69
- if (options.description)
70
- body.description = options.description;
71
- const result = await apiRequest('/api/v1/events', { method: 'POST', body });
72
- if (options.format === 'json') {
73
- console.log(JSON.stringify(result, null, 2));
74
- }
75
- else {
76
- console.log(chalk.green(`\n ✓ Event created: ${result.title} (${result.id})\n`));
77
- }
78
- }
79
- catch (error) {
80
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
81
- logger.error({ error: message }, 'Failed to create event');
82
- console.error(chalk.red(`Error: ${message}`));
83
- process.exitCode = error instanceof ApiError ? 2 : 1;
84
- }
85
- });
86
- // events list
87
- events
88
- .command('list')
89
- .description('List events')
90
- .option('--type <type>', 'Filter by event type')
91
- .option('--days <n>', 'Days to look ahead', parseInt, 30)
92
- .option('--limit <n>', 'Maximum results', parseInt, 50)
93
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
94
- .action(async (options) => {
95
- try {
96
- const params = new URLSearchParams();
97
- params.set('days', String(options.days));
98
- if (options.type)
99
- params.set('type', options.type);
100
- params.set('limit', String(options.limit));
101
- const data = await apiRequest(`/api/v1/events?${params.toString()}`);
102
- if (options.format === 'json') {
103
- console.log(JSON.stringify(data, null, 2));
104
- }
105
- else {
106
- console.log(formatEventsList(data.events));
107
- }
108
- }
109
- catch (error) {
110
- const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
111
- logger.error({ error: message }, 'Failed to list events');
112
- console.error(chalk.red(`Error: ${message}`));
113
- process.exitCode = error instanceof ApiError ? 2 : 1;
114
- }
115
- });
116
- }
117
- //# sourceMappingURL=events.js.map
@@ -1,24 +0,0 @@
1
- import { Command } from 'commander';
2
- interface ServiceHealthResult {
3
- name: string;
4
- healthy: boolean;
5
- message: string;
6
- details?: string;
7
- }
8
- export interface InfraStatusResult {
9
- services: ServiceHealthResult[];
10
- overallHealthy: boolean;
11
- }
12
- /**
13
- * Check infrastructure health via the API /health endpoint.
14
- * Falls back to a basic connectivity check if the API is unreachable.
15
- */
16
- export declare function checkInfraStatus(options?: {
17
- remote?: boolean;
18
- }): Promise<InfraStatusResult>;
19
- export declare function formatInfraStatus(result: InfraStatusResult, options?: {
20
- remote?: boolean;
21
- }): string;
22
- export declare function registerInfraCommand(program: Command): void;
23
- export {};
24
- //# sourceMappingURL=infra.d.ts.map
@@ -1,137 +0,0 @@
1
- import { Option } from 'commander';
2
- import chalk from 'chalk';
3
- import { createLogger } from '@trading-boy/core';
4
- import { padRight } from '../utils.js';
5
- import { getApiBase, isRemoteMode } from '../api-client.js';
6
- // ─── Logger ───
7
- const logger = createLogger('cli-infra');
8
- // ─── Health Check Logic ───
9
- /**
10
- * Check infrastructure health via the API /health endpoint.
11
- * Falls back to a basic connectivity check if the API is unreachable.
12
- */
13
- export async function checkInfraStatus(options) {
14
- const apiBase = getApiBase();
15
- try {
16
- // Call the API health endpoint directly (no auth needed)
17
- const response = await fetch(`${apiBase}/health`);
18
- const data = (await response.json());
19
- const services = [
20
- {
21
- name: 'API Server',
22
- healthy: response.ok,
23
- message: response.ok ? 'Connected' : `Status: ${response.status}`,
24
- details: apiBase,
25
- },
26
- ];
27
- // In remote mode, skip individual DB statuses — they are managed infrastructure
28
- if (!options?.remote && data.services) {
29
- if (data.services.neo4j) {
30
- services.push({
31
- name: 'Neo4j',
32
- healthy: data.services.neo4j.status === 'ok',
33
- message: data.services.neo4j.status === 'ok' ? 'Connected' : (data.services.neo4j.error ?? 'Unhealthy'),
34
- });
35
- }
36
- if (data.services.timescale) {
37
- services.push({
38
- name: 'TimescaleDB',
39
- healthy: data.services.timescale.status === 'ok',
40
- message: data.services.timescale.status === 'ok' ? 'Connected' : (data.services.timescale.error ?? 'Unhealthy'),
41
- });
42
- }
43
- if (data.services.redis) {
44
- services.push({
45
- name: 'Redis',
46
- healthy: data.services.redis.status === 'ok',
47
- message: data.services.redis.status === 'ok' ? 'Connected' : (data.services.redis.error ?? 'Unhealthy'),
48
- });
49
- }
50
- }
51
- // In remote mode, use API response status to determine health
52
- // (services array only contains API Server, but backend may be degraded)
53
- const overallHealthy = options?.remote
54
- ? response.ok && data.status === 'ok'
55
- : services.every((s) => s.healthy);
56
- return { services, overallHealthy };
57
- }
58
- catch (error) {
59
- // API is unreachable
60
- return {
61
- services: [
62
- {
63
- name: 'API Server',
64
- healthy: false,
65
- message: error instanceof Error ? error.message : String(error),
66
- details: apiBase,
67
- },
68
- ],
69
- overallHealthy: false,
70
- };
71
- }
72
- }
73
- // ─── Formatter ───
74
- function formatStatusIndicator(healthy) {
75
- return healthy ? chalk.green('\u2713 UP') : chalk.red('\u2717 DOWN');
76
- }
77
- export function formatInfraStatus(result, options) {
78
- const lines = [];
79
- lines.push('');
80
- lines.push(chalk.bold.cyan(' Infrastructure Status'));
81
- lines.push(chalk.gray(' ' + '\u2500'.repeat(60)));
82
- lines.push('');
83
- for (const service of result.services) {
84
- const status = formatStatusIndicator(service.healthy);
85
- lines.push(` ${status} ${chalk.bold(padRight(service.name, 16))} ${chalk.gray(service.message)}`);
86
- if (service.details) {
87
- lines.push(` ${chalk.dim(service.details)}`);
88
- }
89
- }
90
- lines.push('');
91
- if (options?.remote) {
92
- lines.push(chalk.dim(' Backend services are managed infrastructure. Contact support if issues persist.'));
93
- lines.push('');
94
- }
95
- if (result.overallHealthy) {
96
- lines.push(` ${chalk.green.bold('All services healthy.')}`);
97
- }
98
- else {
99
- const downCount = result.services.filter((s) => !s.healthy).length;
100
- lines.push(` ${chalk.red.bold(`${downCount} service(s) down.`)}`);
101
- }
102
- lines.push('');
103
- return lines.join('\n');
104
- }
105
- // ─── Command Registration ───
106
- export function registerInfraCommand(program) {
107
- const infra = program
108
- .command('infra')
109
- .description('Infrastructure management commands');
110
- infra
111
- .command('status')
112
- .description('Check health of API server and underlying infrastructure')
113
- .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
114
- .action(async (options) => {
115
- try {
116
- const remote = await isRemoteMode();
117
- console.log(chalk.gray(' Checking infrastructure health...'));
118
- const result = await checkInfraStatus({ remote });
119
- if (options.format === 'json') {
120
- console.log(JSON.stringify(result, null, 2));
121
- }
122
- else {
123
- console.log(formatInfraStatus(result, { remote }));
124
- }
125
- if (!result.overallHealthy) {
126
- process.exitCode = 1;
127
- }
128
- }
129
- catch (error) {
130
- const message = error instanceof Error ? error.message : String(error);
131
- logger.error({ error: message }, 'Infra status check failed');
132
- console.error(chalk.red(`Error: ${message}`));
133
- process.exitCode = 1;
134
- }
135
- });
136
- }
137
- //# sourceMappingURL=infra.js.map
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerJournalCommand(program: Command): void;
3
- //# sourceMappingURL=journal.d.ts.map