@trading-boy/cli 0.2.4 → 0.2.5

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.
@@ -0,0 +1,133 @@
1
+ import { Option } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { isRemoteMode, apiRequest, ApiError } from '../api-client.js';
4
+ // ─── Formatters ───
5
+ export function formatEdgeOutput(data) {
6
+ const lines = [];
7
+ lines.push('');
8
+ lines.push(chalk.bold.cyan(` Edge Ratio Analysis — ${data.traderId}`));
9
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
10
+ if (!data.analysis) {
11
+ lines.push(` ${chalk.dim(data.message ?? 'No data available')}`);
12
+ lines.push('');
13
+ return lines.join('\n');
14
+ }
15
+ const a = data.analysis;
16
+ lines.push(` ${chalk.gray('Edge Ratio:')} ${colorEdge(a.edgeRatio)}`);
17
+ lines.push(` ${chalk.gray('Win Rate:')} ${(a.winRate * 100).toFixed(1)}%`);
18
+ lines.push(` ${chalk.gray('Avg Win/Loss:')} ${a.avgWinLossRatio.toFixed(2)}`);
19
+ lines.push(` ${chalk.gray('Expectancy:')} ${formatUsd(a.expectancy)}`);
20
+ lines.push('');
21
+ lines.push(` ${chalk.gray('Total Trades:')} ${a.totalTrades}`);
22
+ lines.push(` ${chalk.gray('Winners:')} ${chalk.green(String(a.profitableTrades))}`);
23
+ lines.push(` ${chalk.gray('Losers:')} ${chalk.red(String(a.losingTrades))}`);
24
+ lines.push(` ${chalk.gray('Avg Win:')} ${chalk.green(formatUsd(a.avgWinUsd))}`);
25
+ lines.push(` ${chalk.gray('Avg Loss:')} ${chalk.red(formatUsd(a.avgLossUsd))}`);
26
+ if (a.breakdowns && Object.keys(a.breakdowns).length > 0) {
27
+ lines.push('');
28
+ lines.push(chalk.bold(' Breakdowns'));
29
+ for (const [key, val] of Object.entries(a.breakdowns)) {
30
+ lines.push(` ${chalk.gray(key + ':')} ${JSON.stringify(val)}`);
31
+ }
32
+ }
33
+ lines.push('');
34
+ return lines.join('\n');
35
+ }
36
+ export function formatAttributionOutput(data) {
37
+ const lines = [];
38
+ lines.push('');
39
+ lines.push(chalk.bold.cyan(` PnL Attribution — ${data.traderId}`));
40
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
41
+ if (!data.analysis) {
42
+ lines.push(` ${chalk.dim(data.message ?? 'No data available')}`);
43
+ lines.push('');
44
+ return lines.join('\n');
45
+ }
46
+ const s = data.analysis.summary;
47
+ lines.push(chalk.bold(' Summary'));
48
+ lines.push(` ${chalk.gray('Total PnL:')} ${colorPnl(s.totalPnl)}`);
49
+ lines.push(` ${chalk.gray('Signal Alpha:')} ${colorPnl(s.signalAlpha)}`);
50
+ lines.push(` ${chalk.gray('Execution Cost:')} ${colorPnl(s.executionCost)}`);
51
+ lines.push(` ${chalk.gray('Timing Variance:')} ${colorPnl(s.timingVariance)}`);
52
+ lines.push(` ${chalk.gray('Trade Count:')} ${s.tradeCount}`);
53
+ if (data.analysis.attributions.length > 0) {
54
+ lines.push('');
55
+ lines.push(chalk.bold(' Per-Trade Breakdown'));
56
+ lines.push(` ${chalk.gray('Token'.padEnd(10))}${'PnL'.padStart(12)}${'Signal'.padStart(12)}${'Exec'.padStart(12)}${'Timing'.padStart(12)}`);
57
+ lines.push(chalk.gray(' ' + '─'.repeat(58)));
58
+ const shown = data.analysis.attributions.slice(0, 20);
59
+ for (const t of shown) {
60
+ lines.push(` ${t.tokenSymbol.padEnd(10)}${formatUsd(t.totalPnl).padStart(12)}${formatUsd(t.signalAlpha).padStart(12)}${formatUsd(t.executionCost).padStart(12)}${formatUsd(t.timingVariance).padStart(12)}`);
61
+ }
62
+ if (data.analysis.attributions.length > 20) {
63
+ lines.push(chalk.dim(` ... and ${data.analysis.attributions.length - 20} more`));
64
+ }
65
+ }
66
+ lines.push('');
67
+ return lines.join('\n');
68
+ }
69
+ function colorEdge(ratio) {
70
+ const str = ratio.toFixed(3);
71
+ if (ratio >= 1.0)
72
+ return chalk.green(str);
73
+ if (ratio >= 0.5)
74
+ return chalk.yellow(str);
75
+ return chalk.red(str);
76
+ }
77
+ function colorPnl(usd) {
78
+ const str = formatUsd(usd);
79
+ return usd >= 0 ? chalk.green(str) : chalk.red(str);
80
+ }
81
+ function formatUsd(val) {
82
+ const sign = val >= 0 ? '+' : '';
83
+ return `${sign}$${val.toFixed(2)}`;
84
+ }
85
+ // ─── Command Registration ───
86
+ export function registerEdgeCommand(program) {
87
+ program
88
+ .command('edge <traderId>')
89
+ .description('Analyze trade quality — edge ratio and PnL attribution')
90
+ .option('--attribution', 'Show PnL attribution breakdown instead of edge ratio')
91
+ .option('--token <symbol>', 'Filter by token symbol')
92
+ .option('--limit <n>', 'Number of trades to analyze (1-500)', '100')
93
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
94
+ .action(async (traderId, options) => {
95
+ try {
96
+ if (!(await isRemoteMode())) {
97
+ console.error(chalk.red('Error: edge command requires remote mode. Run `trading-boy login` first.'));
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ const query = new URLSearchParams();
102
+ if (options.token)
103
+ query.set('tokenSymbol', options.token.toUpperCase());
104
+ if (options.limit !== '100')
105
+ query.set('limit', options.limit);
106
+ const qs = query.toString() ? `?${query.toString()}` : '';
107
+ if (options.attribution) {
108
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/attribution${qs}`);
109
+ if (options.format === 'json') {
110
+ console.log(JSON.stringify(data, null, 2));
111
+ }
112
+ else {
113
+ console.log(formatAttributionOutput(data));
114
+ }
115
+ }
116
+ else {
117
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge${qs}`);
118
+ if (options.format === 'json') {
119
+ console.log(JSON.stringify(data, null, 2));
120
+ }
121
+ else {
122
+ console.log(formatEdgeOutput(data));
123
+ }
124
+ }
125
+ }
126
+ catch (error) {
127
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
128
+ console.error(chalk.red(`Error: ${message}`));
129
+ process.exitCode = 1;
130
+ }
131
+ });
132
+ }
133
+ //# sourceMappingURL=edge-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-cmd.js","sourceRoot":"","sources":["../../src/commands/edge-cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { Command } from 'commander';
2
+ interface EdgeGuardAssessment {
3
+ traderId: string;
4
+ assessment: {
5
+ status: string;
6
+ escalation: string;
7
+ portfolioEV: number;
8
+ portfolioEVLower: number;
9
+ portfolioEVUpper: number;
10
+ negativeCells: number;
11
+ totalCells: number;
12
+ frictionActive: boolean;
13
+ message: string;
14
+ assessedAt: string;
15
+ cellEstimates: Array<{
16
+ setupType: string;
17
+ regime: string;
18
+ evPoint: number;
19
+ evLower: number;
20
+ evUpper: number;
21
+ winRate: number;
22
+ }>;
23
+ };
24
+ }
25
+ interface FrictionResult {
26
+ traderId: string;
27
+ requiresAcknowledgement: boolean;
28
+ escalation: string;
29
+ message: string;
30
+ acknowledged: boolean;
31
+ }
32
+ export declare function formatAssessmentOutput(data: EdgeGuardAssessment): string;
33
+ export declare function formatFrictionOutput(data: FrictionResult): string;
34
+ export declare function registerEdgeGuardCommand(program: Command): void;
35
+ export {};
36
+ //# sourceMappingURL=edge-guard-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-guard-cmd.d.ts","sourceRoot":"","sources":["../../src/commands/edge-guard-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAM5C,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,OAAO,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,KAAK,CAAC;YACnB,SAAS,EAAE,MAAM,CAAC;YAClB,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;CACvB;AAcD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAwDxE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAuBjE;AAkCD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6E/D"}
@@ -0,0 +1,170 @@
1
+ import { Option } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { isRemoteMode, apiRequest, ApiError } from '../api-client.js';
4
+ // ─── Formatters ───
5
+ export function formatAssessmentOutput(data) {
6
+ const lines = [];
7
+ const a = data.assessment;
8
+ lines.push('');
9
+ lines.push(chalk.bold.cyan(` Edge Guard — ${data.traderId}`));
10
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
11
+ lines.push(` ${chalk.gray('Status:')} ${colorStatus(a.status)}`);
12
+ lines.push(` ${chalk.gray('Escalation:')} ${colorEscalation(a.escalation)}`);
13
+ lines.push(` ${chalk.gray('Friction Active:')} ${a.frictionActive ? chalk.red('YES') : chalk.green('NO')}`);
14
+ lines.push('');
15
+ lines.push(` ${chalk.gray('Portfolio EV:')} ${colorPnl(a.portfolioEV)}`);
16
+ lines.push(` ${chalk.gray('90% CI:')} [${formatUsd(a.portfolioEVLower)}, ${formatUsd(a.portfolioEVUpper)}]`);
17
+ lines.push(` ${chalk.gray('Negative Cells:')} ${a.negativeCells}/${a.totalCells}`);
18
+ if (a.message) {
19
+ lines.push('');
20
+ lines.push(chalk.bold(' Message'));
21
+ // Wrap message at ~70 chars, indented
22
+ const words = a.message.split(' ');
23
+ let line = ' ';
24
+ for (const word of words) {
25
+ if (line.length + word.length > 72) {
26
+ lines.push(line);
27
+ line = ' ';
28
+ }
29
+ line += word + ' ';
30
+ }
31
+ if (line.trim())
32
+ lines.push(line);
33
+ }
34
+ if (a.cellEstimates.length > 0) {
35
+ lines.push('');
36
+ lines.push(chalk.bold(' Cell Estimates'));
37
+ lines.push(` ${chalk.gray('Setup'.padEnd(18))}${'Regime'.padEnd(16)}${'EV'.padStart(10)}${'Win%'.padStart(8)}`);
38
+ lines.push(chalk.gray(' ' + '─'.repeat(52)));
39
+ // Show top negative cells first
40
+ const sorted = [...a.cellEstimates].sort((x, y) => x.evPoint - y.evPoint);
41
+ const shown = sorted.slice(0, 15);
42
+ for (const c of shown) {
43
+ const evStr = formatUsd(c.evPoint);
44
+ const wrStr = (c.winRate * 100).toFixed(1) + '%';
45
+ lines.push(` ${c.setupType.padEnd(18)}${c.regime.padEnd(16)}${(c.evPoint >= 0 ? chalk.green(evStr) : chalk.red(evStr)).padStart(10)}${wrStr.padStart(8)}`);
46
+ }
47
+ if (a.cellEstimates.length > 15) {
48
+ lines.push(chalk.dim(` ... and ${a.cellEstimates.length - 15} more cells`));
49
+ }
50
+ }
51
+ lines.push('');
52
+ return lines.join('\n');
53
+ }
54
+ export function formatFrictionOutput(data) {
55
+ const lines = [];
56
+ lines.push('');
57
+ lines.push(chalk.bold.cyan(` Entry Friction — ${data.traderId}`));
58
+ lines.push(chalk.gray(' ' + '─'.repeat(50)));
59
+ lines.push(` ${chalk.gray('Escalation:')} ${colorEscalation(data.escalation)}`);
60
+ lines.push(` ${chalk.gray('Requires Ack:')} ${data.requiresAcknowledgement ? chalk.red('YES') : chalk.green('NO')}`);
61
+ lines.push(` ${chalk.gray('Acknowledged:')} ${data.acknowledged ? chalk.green('YES') : chalk.dim('NO')}`);
62
+ if (data.message) {
63
+ lines.push('');
64
+ lines.push(` ${data.message}`);
65
+ }
66
+ if (data.requiresAcknowledgement && !data.acknowledged) {
67
+ lines.push('');
68
+ lines.push(chalk.yellow(` Run: trading-boy edge-guard acknowledge ${data.traderId}`));
69
+ }
70
+ lines.push('');
71
+ return lines.join('\n');
72
+ }
73
+ function colorStatus(status) {
74
+ switch (status) {
75
+ case 'POSITIVE_EDGE': return chalk.green(status);
76
+ case 'UNCERTAIN': return chalk.yellow(status);
77
+ case 'NEGATIVE_EDGE_WARNING': return chalk.red(status);
78
+ case 'NEGATIVE_EDGE_CONFIRMED': return chalk.bgRed.white(` ${status} `);
79
+ default: return status;
80
+ }
81
+ }
82
+ function colorEscalation(level) {
83
+ switch (level) {
84
+ case 'NORMAL': return chalk.green(level);
85
+ case 'INCREASED_COACHING': return chalk.yellow(level);
86
+ case 'EXPLICIT_WARNING': return chalk.red(level);
87
+ case 'ENTRY_FRICTION': return chalk.bgRed.white(` ${level} `);
88
+ default: return level;
89
+ }
90
+ }
91
+ function colorPnl(usd) {
92
+ const str = formatUsd(usd);
93
+ return usd >= 0 ? chalk.green(str) : chalk.red(str);
94
+ }
95
+ function formatUsd(val) {
96
+ const sign = val >= 0 ? '+' : '';
97
+ return `${sign}$${val.toFixed(2)}`;
98
+ }
99
+ // ─── Command Registration ───
100
+ export function registerEdgeGuardCommand(program) {
101
+ // Parent command group (no positional arg — subcommands handle their own traderId)
102
+ const cmd = program
103
+ .command('edge-guard')
104
+ .description('Check negative edge status and entry friction');
105
+ // Subcommand: check <traderId> (default assessment)
106
+ cmd
107
+ .command('check <traderId>')
108
+ .description('Assess negative edge status for a trader')
109
+ .option('--friction', 'Check entry friction level only')
110
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
111
+ .action(async (traderId, options) => {
112
+ try {
113
+ if (!(await isRemoteMode())) {
114
+ console.error(chalk.red('Error: edge-guard command requires remote mode. Run `trading-boy login` first.'));
115
+ process.exitCode = 1;
116
+ return;
117
+ }
118
+ if (options.friction) {
119
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard/friction`);
120
+ if (options.format === 'json') {
121
+ console.log(JSON.stringify(data, null, 2));
122
+ }
123
+ else {
124
+ console.log(formatFrictionOutput(data));
125
+ }
126
+ }
127
+ else {
128
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard`);
129
+ if (options.format === 'json') {
130
+ console.log(JSON.stringify(data, null, 2));
131
+ }
132
+ else {
133
+ console.log(formatAssessmentOutput(data));
134
+ }
135
+ }
136
+ }
137
+ catch (error) {
138
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
139
+ console.error(chalk.red(`Error: ${message}`));
140
+ process.exitCode = 1;
141
+ }
142
+ });
143
+ // Subcommand: acknowledge <traderId>
144
+ cmd
145
+ .command('acknowledge <traderId>')
146
+ .description('Acknowledge negative edge warning to proceed with trade')
147
+ .addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
148
+ .action(async (traderId, ackOptions) => {
149
+ try {
150
+ if (!(await isRemoteMode())) {
151
+ console.error(chalk.red('Error: edge-guard command requires remote mode. Run `trading-boy login` first.'));
152
+ process.exitCode = 1;
153
+ return;
154
+ }
155
+ const data = await apiRequest(`/api/v1/traders/${encodeURIComponent(traderId)}/edge-guard/acknowledge`, { method: 'POST' });
156
+ if (ackOptions.format === 'json') {
157
+ console.log(JSON.stringify(data, null, 2));
158
+ }
159
+ else {
160
+ console.log(chalk.green(`\n ✓ Edge warning acknowledged for ${data.traderId}\n`));
161
+ }
162
+ }
163
+ catch (error) {
164
+ const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
165
+ console.error(chalk.red(`Error: ${message}`));
166
+ process.exitCode = 1;
167
+ }
168
+ });
169
+ }
170
+ //# sourceMappingURL=edge-guard-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-guard-cmd.js","sourceRoot":"","sources":["../../src/commands/edge-guard-cmd.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/commands/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAmF5C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqtB7D"}
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/commands/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAmF5C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAouB7D"}
@@ -94,11 +94,11 @@ export function registerJournalCommand(program) {
94
94
  traderId: options.trader,
95
95
  decisionType: 'TRADE_ENTRY',
96
96
  tokenSymbol: symbol.toUpperCase(),
97
- tokenMint: options.mint ?? '',
97
+ ...(options.mint ? { tokenMint: options.mint } : {}),
98
98
  direction: options.direction?.toUpperCase(),
99
99
  entryPrice: options.price,
100
100
  size: options.size,
101
- sizeUsd: options.sizeUsd,
101
+ sizeUsd: options.sizeUsd ?? (options.size && options.price ? options.size * options.price : undefined),
102
102
  thesis: options.thesis,
103
103
  setupType: options.setup,
104
104
  emotionalTag: options.emotion,
@@ -112,6 +112,11 @@ export function registerJournalCommand(program) {
112
112
  catch (error) {
113
113
  const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
114
114
  console.error(`Error: ${message}`);
115
+ if (error instanceof ApiError && error.body && typeof error.body === 'object') {
116
+ const detail = error.body.error ?? error.body.code;
117
+ if (detail)
118
+ console.error(`Detail: ${detail}`);
119
+ }
115
120
  process.exitCode = 1;
116
121
  }
117
122
  return;
@@ -154,7 +159,7 @@ export function registerJournalCommand(program) {
154
159
  decisionType: DecisionType.TRADE_ENTRY,
155
160
  actor: ActorType.HUMAN,
156
161
  tokenSymbol,
157
- tokenMint: options.mint ?? '',
162
+ ...(options.mint ? { tokenMint: options.mint } : {}),
158
163
  eventTime,
159
164
  preState,
160
165
  thesis: options.thesis ?? linkedPlan?.thesis,
@@ -162,7 +167,10 @@ export function registerJournalCommand(program) {
162
167
  direction: (options.direction ?? linkedPlan?.direction),
163
168
  entryPrice: options.price ?? linkedPlan?.entryTarget,
164
169
  size: options.size,
165
- sizeUsd: options.sizeUsd,
170
+ sizeUsd: options.sizeUsd ?? (() => {
171
+ const ep = options.price ?? linkedPlan?.entryTarget;
172
+ return options.size && ep ? options.size * ep : undefined;
173
+ })(),
166
174
  emotionalTag: (options.emotion ?? linkedPlan?.emotionalTag),
167
175
  confidence: options.confidence ?? linkedPlan?.confidence,
168
176
  triggers: options.triggers,
@@ -183,7 +191,7 @@ export function registerJournalCommand(program) {
183
191
  decisionType: DecisionType.TRADE_ENTRY,
184
192
  actor: ActorType.HUMAN,
185
193
  tokenSymbol,
186
- tokenMint: options.mint ?? '',
194
+ ...(options.mint ? { tokenMint: options.mint } : {}),
187
195
  eventTime: eventTime.toISOString(),
188
196
  preState,
189
197
  thesis: options.thesis,
@@ -193,7 +201,7 @@ export function registerJournalCommand(program) {
193
201
  direction: options.direction,
194
202
  entryPrice: options.price,
195
203
  size: options.size,
196
- sizeUsd: options.sizeUsd,
204
+ sizeUsd: options.sizeUsd ?? (options.size && options.price ? options.size * options.price : undefined),
197
205
  txHash: options.txHash,
198
206
  triggers: options.triggers,
199
207
  }).catch((error) => {
@@ -239,11 +247,11 @@ export function registerJournalCommand(program) {
239
247
  traderId: options.trader,
240
248
  decisionType: 'TRADE_EXIT',
241
249
  tokenSymbol: symbol.toUpperCase(),
242
- tokenMint: options.mint ?? '',
250
+ ...(options.mint ? { tokenMint: options.mint } : {}),
243
251
  exitPrice: options.price,
244
252
  thesis: options.thesis,
245
253
  size: options.size,
246
- sizeUsd: options.sizeUsd,
254
+ sizeUsd: options.sizeUsd ?? (options.size && options.price ? options.size * options.price : undefined),
247
255
  txHash: options.txHash,
248
256
  linkedEntryId: options.linkEntry,
249
257
  },
@@ -253,6 +261,11 @@ export function registerJournalCommand(program) {
253
261
  catch (error) {
254
262
  const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
255
263
  console.error(`Error: ${message}`);
264
+ if (error instanceof ApiError && error.body && typeof error.body === 'object') {
265
+ const detail = error.body.error ?? error.body.code;
266
+ if (detail)
267
+ console.error(`Detail: ${detail}`);
268
+ }
256
269
  process.exitCode = 1;
257
270
  }
258
271
  return;
@@ -285,13 +298,13 @@ export function registerJournalCommand(program) {
285
298
  decisionType: DecisionType.TRADE_EXIT,
286
299
  actor: ActorType.HUMAN,
287
300
  tokenSymbol,
288
- tokenMint: options.mint ?? '',
301
+ ...(options.mint ? { tokenMint: options.mint } : {}),
289
302
  eventTime,
290
303
  preState,
291
304
  exitPrice: options.price,
292
305
  thesis: options.thesis,
293
306
  size: options.size,
294
- sizeUsd: options.sizeUsd,
307
+ sizeUsd: options.sizeUsd ?? (options.size && options.price ? options.size * options.price : undefined),
295
308
  txHash: options.txHash,
296
309
  linkedEntryId: options.linkEntry,
297
310
  };
@@ -310,13 +323,13 @@ export function registerJournalCommand(program) {
310
323
  decisionType: DecisionType.TRADE_EXIT,
311
324
  actor: ActorType.HUMAN,
312
325
  tokenSymbol,
313
- tokenMint: options.mint ?? '',
326
+ ...(options.mint ? { tokenMint: options.mint } : {}),
314
327
  eventTime: eventTime.toISOString(),
315
328
  preState,
316
329
  exitPrice: options.price,
317
330
  thesis: options.thesis,
318
331
  size: options.size,
319
- sizeUsd: options.sizeUsd,
332
+ sizeUsd: options.sizeUsd ?? (options.size && options.price ? options.size * options.price : undefined),
320
333
  txHash: options.txHash,
321
334
  linkedEntryId: options.linkEntry,
322
335
  };
@@ -404,6 +417,11 @@ export function registerJournalCommand(program) {
404
417
  catch (error) {
405
418
  const message = error instanceof ApiError ? error.message : (error instanceof Error ? error.message : String(error));
406
419
  console.error(`Error: ${message}`);
420
+ if (error instanceof ApiError && error.body && typeof error.body === 'object') {
421
+ const detail = error.body.error ?? error.body.code;
422
+ if (detail)
423
+ console.error(`Detail: ${detail}`);
424
+ }
407
425
  process.exitCode = 1;
408
426
  }
409
427
  return;