minara 0.2.3 → 0.2.4

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.
@@ -1,26 +1,68 @@
1
1
  import { Command } from 'commander';
2
2
  import { input, select } from '@inquirer/prompts';
3
3
  import chalk from 'chalk';
4
- import { searchTokens, getTrendingTokens, searchStocks, getFearGreedIndex, getBitcoinMetrics } from '../api/tokens.js';
4
+ import { searchTokens, getTrendingTokens, getTrendingStocks, searchStocks, getFearGreedIndex, getBitcoinMetrics } from '../api/tokens.js';
5
5
  import { spinner, assertApiOk, wrapAction } from '../utils.js';
6
- import { printKV, printTable, printFearGreed, printCryptoMetrics, TOKEN_COLUMNS } from '../formatters.js';
6
+ import { printKV, printTable, printFearGreed, printCryptoMetrics, TOKEN_COLUMNS, STOCK_COLUMNS } from '../formatters.js';
7
+ function flattenStock(item) {
8
+ const td = (item.tradeData ?? {});
9
+ return {
10
+ symbol: item.symbol ?? td.symbol,
11
+ name: item.name ?? td.name,
12
+ price: td.price,
13
+ priceChange24H: td.price_change_24h_percent != null
14
+ ? Number(td.price_change_24h_percent) * 100
15
+ : undefined,
16
+ volume24H: td.volume_24h_usd,
17
+ marketCap: td.market,
18
+ };
19
+ }
7
20
  // ─── trending ────────────────────────────────────────────────────────────
8
21
  const trendingCmd = new Command('trending')
9
- .description('View trending tokens')
10
- .action(wrapAction(async () => {
11
- const spin = spinner('Fetching trending tokens…');
12
- const res = await getTrendingTokens();
13
- spin.stop();
14
- assertApiOk(res, 'Failed to fetch trending tokens');
15
- console.log('');
16
- console.log(chalk.bold('Trending Tokens:'));
17
- if (Array.isArray(res.data) && res.data.length > 0) {
18
- printTable(res.data, TOKEN_COLUMNS);
22
+ .description('View trending tokens or stocks')
23
+ .argument('[category]', 'tokens or stocks (default: interactive)')
24
+ .action(wrapAction(async (categoryArg) => {
25
+ let category = categoryArg?.toLowerCase();
26
+ if (!category || (category !== 'tokens' && category !== 'stocks')) {
27
+ category = await select({
28
+ message: 'Trending:',
29
+ choices: [
30
+ { name: 'Tokens (crypto)', value: 'tokens' },
31
+ { name: 'Stocks (tokenized)', value: 'stocks' },
32
+ ],
33
+ });
19
34
  }
20
- else if (res.data && typeof res.data === 'object') {
21
- printKV(res.data);
35
+ if (category === 'stocks') {
36
+ const spin = spinner('Fetching trending stocks…');
37
+ const res = await getTrendingStocks();
38
+ spin.stop();
39
+ assertApiOk(res, 'Failed to fetch trending stocks');
40
+ console.log('');
41
+ console.log(chalk.bold('Trending Stocks:'));
42
+ if (Array.isArray(res.data) && res.data.length > 0) {
43
+ const rows = res.data.map((s) => flattenStock(s));
44
+ printTable(rows, STOCK_COLUMNS);
45
+ }
46
+ else {
47
+ console.log(chalk.dim(' No trending stocks found.'));
48
+ }
49
+ console.log('');
50
+ }
51
+ else {
52
+ const spin = spinner('Fetching trending tokens…');
53
+ const res = await getTrendingTokens();
54
+ spin.stop();
55
+ assertApiOk(res, 'Failed to fetch trending tokens');
56
+ console.log('');
57
+ console.log(chalk.bold('Trending Tokens:'));
58
+ if (Array.isArray(res.data) && res.data.length > 0) {
59
+ printTable(res.data, TOKEN_COLUMNS);
60
+ }
61
+ else if (res.data && typeof res.data === 'object') {
62
+ printKV(res.data);
63
+ }
64
+ console.log('');
22
65
  }
23
- console.log('');
24
66
  }));
25
67
  // ─── search ──────────────────────────────────────────────────────────────
26
68
  const searchCmd = new Command('search')
@@ -91,7 +133,7 @@ export const discoverCommand = new Command('discover')
91
133
  const action = await select({
92
134
  message: 'Discover:',
93
135
  choices: [
94
- { name: 'Trending tokens', value: 'trending' },
136
+ { name: 'Trending tokens / stocks', value: 'trending' },
95
137
  { name: 'Search tokens / stocks', value: 'search' },
96
138
  { name: 'Fear & Greed Index', value: 'fear-greed' },
97
139
  { name: 'Bitcoin metrics', value: 'btc-metrics' },
@@ -44,6 +44,7 @@ export declare const POSITION_COLUMNS: ColumnDef[];
44
44
  export declare const LIMIT_ORDER_COLUMNS: ColumnDef[];
45
45
  /** Trending / search tokens (TokenInfo[]) */
46
46
  export declare const TOKEN_COLUMNS: ColumnDef[];
47
+ export declare const STOCK_COLUMNS: ColumnDef[];
47
48
  /**
48
49
  * Pretty-print Fear & Greed Index — hides redundant `timestamp` and `price`.
49
50
  */
@@ -309,6 +309,14 @@ export const TOKEN_COLUMNS = [
309
309
  { key: 'volume24H', label: 'Volume 24h', format: compactUsd },
310
310
  { key: 'marketCap', label: 'Market Cap', format: compactUsd },
311
311
  ];
312
+ export const STOCK_COLUMNS = [
313
+ { key: 'symbol', label: 'Symbol', format: (v) => chalk.bold(String(v ?? '—')) },
314
+ { key: 'name', label: 'Name' },
315
+ { key: 'price', label: 'Price', format: (v) => formatValue(v, 'price') },
316
+ { key: 'priceChange24H', label: '24h %', format: (v) => formatValue(v, 'change') },
317
+ { key: 'volume24H', label: 'Volume 24h', format: compactUsd },
318
+ { key: 'marketCap', label: 'Market Cap', format: compactUsd },
319
+ ];
312
320
  // ═══════════════════════════════════════════════════════════════════════════
313
321
  // Specialised display helpers for discover commands
314
322
  // ═══════════════════════════════════════════════════════════════════════════
package/dist/index.js CHANGED
@@ -2,24 +2,28 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { Command } from 'commander';
4
4
  import chalk from 'chalk';
5
+ import { setRawJson } from './formatters.js';
6
+ // Auth & Account
5
7
  import { loginCommand } from './commands/login.js';
6
- const require = createRequire(import.meta.url);
7
- const { version } = require('../package.json');
8
8
  import { logoutCommand } from './commands/logout.js';
9
9
  import { accountCommand } from './commands/account.js';
10
- import { assetsCommand } from './commands/assets.js';
10
+ // Wallet & Funds
11
11
  import { balanceCommand } from './commands/balance.js';
12
+ import { assetsCommand } from './commands/assets.js';
12
13
  import { depositCommand } from './commands/deposit.js';
13
14
  import { withdrawCommand } from './commands/withdraw.js';
15
+ // Trading
14
16
  import { swapCommand } from './commands/swap.js';
15
17
  import { transferCommand } from './commands/transfer.js';
16
18
  import { perpsCommand } from './commands/perps.js';
17
19
  import { limitOrderCommand } from './commands/limit-order.js';
20
+ // AI, Market, Premium, Config
18
21
  import { chatCommand } from './commands/chat.js';
19
22
  import { discoverCommand } from './commands/discover.js';
20
- import { configCommand } from './commands/config.js';
21
23
  import { premiumCommand } from './commands/premium.js';
22
- import { setRawJson } from './formatters.js';
24
+ import { configCommand } from './commands/config.js';
25
+ const require = createRequire(import.meta.url);
26
+ const { version } = require('../package.json');
23
27
  const program = new Command();
24
28
  program
25
29
  .name('minara')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minara",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "CLI client for Minara.ai — login, trade, deposit/withdraw, chat and more from your terminal.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",