@darksol/terminal 0.9.2 → 0.10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darksol/terminal",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "DARKSOL Terminal — unified CLI for all DARKSOL services. Market intel, trading, oracle, casino, and more.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -17,6 +17,7 @@ import { executeLifiSwap, executeLifiBridge, checkBridgeStatus, showSupportedCha
17
17
  import { topMovers, tokenDetail, compareTokens } from './services/market.js';
18
18
  import { oracleFlip, oracleDice, oracleNumber, oracleShuffle, oracleHealth } from './services/oracle.js';
19
19
  import { casinoBet, casinoTables, casinoStats, casinoReceipt, casinoHealth, casinoVerify } from './services/casino.js';
20
+ import { pokerNewGame, pokerAction, pokerStatus, pokerHistory } from './services/poker.js';
20
21
  import { cardsCatalog, cardsOrder, cardsStatus } from './services/cards.js';
21
22
  import { facilitatorHealth, facilitatorVerify, facilitatorSettle } from './services/facilitator.js';
22
23
  import { buildersLeaderboard, buildersLookup, buildersFeed } from './services/builders.js';
@@ -41,7 +42,7 @@ export function cli(argv) {
41
42
 
42
43
  program
43
44
  .name('darksol')
44
- .description(theme.gold('DARKSOL Terminal') + theme.dim(' Ghost in the machine with teeth 🌑'))
45
+ .description(theme.gold('DARKSOL Terminal') + theme.dim(' - Ghost in the machine with teeth 🌑'))
45
46
  .version(PKG_VERSION)
46
47
  ;
47
48
 
@@ -50,7 +51,7 @@ export function cli(argv) {
50
51
  // ═══════════════════════════════════════
51
52
  const wallet = program
52
53
  .command('wallet')
53
- .description('Wallet management create, import, list, balance');
54
+ .description('Wallet management - create, import, list, balance');
54
55
 
55
56
  wallet
56
57
  .command('create [name]')
@@ -115,7 +116,7 @@ export function cli(argv) {
115
116
  // ═══════════════════════════════════════
116
117
  const trade = program
117
118
  .command('trade')
118
- .description('Trading swap, snipe, DCA');
119
+ .description('Trading - swap, snipe, DCA');
119
120
 
120
121
  trade
121
122
  .command('swap')
@@ -163,14 +164,14 @@ export function cli(argv) {
163
164
  // If LI.FI failed (not cancelled), fall back to direct
164
165
  if (result?.error !== 'cancelled') {
165
166
  const { warn: showWarn, info: showInfo } = await import('./ui/components.js');
166
- showWarn('LI.FI route failed falling back to direct Uniswap V3...');
167
+ showWarn('LI.FI route failed - falling back to direct Uniswap V3...');
167
168
  console.log('');
168
169
  } else {
169
170
  return; // User cancelled, don't fallback
170
171
  }
171
172
  } catch {
172
173
  const { warn: showWarn } = await import('./ui/components.js');
173
- showWarn('LI.FI unavailable falling back to direct Uniswap V3...');
174
+ showWarn('LI.FI unavailable - falling back to direct Uniswap V3...');
174
175
  console.log('');
175
176
  }
176
177
  }
@@ -181,7 +182,7 @@ export function cli(argv) {
181
182
 
182
183
  trade
183
184
  .command('snipe <token>')
184
- .description('Snipe a token fast buy with ETH')
185
+ .description('Snipe a token - fast buy with ETH')
185
186
  .requiredOption('-a, --amount <eth>', 'ETH amount to spend')
186
187
  .option('-s, --slippage <percent>', 'Max slippage %', '1')
187
188
  .option('-g, --gas <multiplier>', 'Gas priority multiplier', '1.5')
@@ -215,7 +216,7 @@ export function cli(argv) {
215
216
  optimism: ['ETH/USDC', 'ETH/OP'],
216
217
  polygon: ['POL/USDC', 'POL/WETH', 'USDC/USDT'],
217
218
  };
218
- showSection(`COMMON PAIRS ${chain.toUpperCase()}`);
219
+ showSection(`COMMON PAIRS - ${chain.toUpperCase()}`);
219
220
  const pairs = byChain[chain] || byChain.base;
220
221
  pairs.forEach((p) => console.log(` ${theme.gold(p)}`));
221
222
  console.log('');
@@ -228,7 +229,7 @@ export function cli(argv) {
228
229
  // ═══════════════════════════════════════
229
230
  const bridge = program
230
231
  .command('bridge')
231
- .description('Cross-chain bridge move tokens between chains via LI.FI');
232
+ .description('Cross-chain bridge - move tokens between chains via LI.FI');
232
233
 
233
234
  bridge
234
235
  .command('send')
@@ -320,7 +321,7 @@ export function cli(argv) {
320
321
  // ═══════════════════════════════════════
321
322
  const market = program
322
323
  .command('market')
323
- .description('Market intel prices, movers, analysis');
324
+ .description('Market intel - prices, movers, analysis');
324
325
 
325
326
  market
326
327
  .command('top')
@@ -331,7 +332,7 @@ export function cli(argv) {
331
332
 
332
333
  market
333
334
  .command('token <query>')
334
- .description('Token detail price, volume, liquidity')
335
+ .description('Token detail - price, volume, liquidity')
335
336
  .action((query) => tokenDetail(query));
336
337
 
337
338
  market
@@ -376,7 +377,7 @@ export function cli(argv) {
376
377
  // ═══════════════════════════════════════
377
378
  const casino = program
378
379
  .command('casino')
379
- .description('The Clawsino on-chain betting');
380
+ .description('The Clawsino - on-chain betting');
380
381
 
381
382
  casino
382
383
  .command('status')
@@ -416,12 +417,29 @@ export function cli(argv) {
416
417
  .description('Verify bet on-chain')
417
418
  .action((id) => casinoVerify(id));
418
419
 
420
+ const poker = program
421
+ .command('poker [subcommand]')
422
+ .description('GTO Poker Arena — heads-up holdem against the house');
423
+
424
+ poker
425
+ .option('--free', 'Free play mode (default)')
426
+ .option('--real', 'Real mode ($1 buy-in, $2 payout on win)')
427
+ .action(async (subcommand, opts) => {
428
+ if (subcommand === 'status') {
429
+ return showPokerCliStatus();
430
+ }
431
+ if (subcommand === 'history') {
432
+ return showPokerCliHistory();
433
+ }
434
+ return playPokerCli(opts);
435
+ });
436
+
419
437
  // ═══════════════════════════════════════
420
438
  // CARDS COMMANDS
421
439
  // ═══════════════════════════════════════
422
440
  const cards = program
423
441
  .command('cards')
424
- .description('Prepaid cards crypto to Visa/MC');
442
+ .description('Prepaid cards - crypto to Visa/MC');
425
443
 
426
444
  cards
427
445
  .command('catalog')
@@ -498,7 +516,7 @@ export function cli(argv) {
498
516
  // ═══════════════════════════════════════
499
517
  const mail = program
500
518
  .command('mail')
501
- .description('📧 AgentMail email for your agent');
519
+ .description('📧 AgentMail - email for your agent');
502
520
 
503
521
  mail
504
522
  .command('setup')
@@ -752,7 +770,7 @@ export function cli(argv) {
752
770
  // ═══════════════════════════════════════
753
771
  program
754
772
  .command('setup')
755
- .description('First-run setup wizard configure AI provider, chain, wallet')
773
+ .description('First-run setup wizard - configure AI provider, chain, wallet')
756
774
  .option('-f, --force', 'Re-run even if already configured')
757
775
  .action((opts) => runSetupWizard({ force: opts.force }));
758
776
 
@@ -860,7 +878,7 @@ export function cli(argv) {
860
878
  // ═══════════════════════════════════════
861
879
  const keys = program
862
880
  .command('keys')
863
- .description('API key vault store keys for LLMs, data providers, RPCs');
881
+ .description('API key vault - store keys for LLMs, data providers, RPCs');
864
882
 
865
883
  keys
866
884
  .command('list')
@@ -883,7 +901,7 @@ export function cli(argv) {
883
901
  // ═══════════════════════════════════════
884
902
  const agent = program
885
903
  .command('agent')
886
- .description('Secure agent signer PK-isolated wallet for AI agents');
904
+ .description('Secure agent signer - PK-isolated wallet for AI agents');
887
905
 
888
906
  agent
889
907
  .command('task <goal...>')
@@ -991,7 +1009,7 @@ export function cli(argv) {
991
1009
  // ═══════════════════════════════════════
992
1010
  const skills = program
993
1011
  .command('skills')
994
- .description('DARKSOL skills directory install agent skills');
1012
+ .description('DARKSOL skills directory - install agent skills');
995
1013
 
996
1014
  skills
997
1015
  .command('list')
@@ -1056,7 +1074,7 @@ export function cli(argv) {
1056
1074
  .action(async (address, opts) => {
1057
1075
  showMiniBanner();
1058
1076
  if (address.length === 42 && address.startsWith('0x')) {
1059
- // Could be token or wallet try token first
1077
+ // Could be token or wallet - try token first
1060
1078
  try {
1061
1079
  await showTokenInfo(address, opts.chain);
1062
1080
  } catch {
@@ -1073,7 +1091,7 @@ export function cli(argv) {
1073
1091
  // ═══════════════════════════════════════
1074
1092
  const script = program
1075
1093
  .command('script')
1076
- .description('Execution scripts automated trading strategies');
1094
+ .description('Execution scripts - automated trading strategies');
1077
1095
 
1078
1096
  script
1079
1097
  .command('create')
@@ -1200,7 +1218,7 @@ export function cli(argv) {
1200
1218
  });
1201
1219
 
1202
1220
  // ═══════════════════════════════════════
1203
- // DASHBOARD (default) commands + optional AI
1221
+ // DASHBOARD (default) - commands + optional AI
1204
1222
  // ═══════════════════════════════════════
1205
1223
  program
1206
1224
  .command('dashboard', { isDefault: true })
@@ -1228,7 +1246,7 @@ export function cli(argv) {
1228
1246
 
1229
1247
  // ── AI nudge or chat prompt ──
1230
1248
  if (hasLLM) {
1231
- console.log(theme.gold(' 💬 AI is ready run ') + theme.label('darksol ai chat') + theme.gold(' or just ') + theme.label('darksol chat'));
1249
+ console.log(theme.gold(' 💬 AI is ready - run ') + theme.label('darksol ai chat') + theme.gold(' or just ') + theme.label('darksol chat'));
1232
1250
  console.log(theme.dim(' "swap 0.1 ETH for USDC" • "what\'s AERO at?" • any question'));
1233
1251
  console.log('');
1234
1252
  } else {
@@ -1252,7 +1270,7 @@ export function cli(argv) {
1252
1270
  const { info, error: showError } = await import('./ui/components.js');
1253
1271
 
1254
1272
  console.log('');
1255
- info(`"${input}" isn't a command asking AI...`);
1273
+ info(`"${input}" isn't a command - asking AI...`);
1256
1274
  console.log('');
1257
1275
 
1258
1276
  try {
@@ -1406,6 +1424,154 @@ async function chatResponse(llm, input) {
1406
1424
  }
1407
1425
  }
1408
1426
 
1427
+ function pokerModeFromOpts(opts = {}) {
1428
+ return opts.real ? 'real' : 'free';
1429
+ }
1430
+
1431
+ function renderPokerCards(cards, hidden = false) {
1432
+ const suitMap = { s: '♠', h: '♥', d: '♦', c: '♣' };
1433
+ const colorize = (card, text) => {
1434
+ const suit = card[1];
1435
+ return suit === 'h' || suit === 'd' ? theme.error(text) : theme.bright(text);
1436
+ };
1437
+
1438
+ const source = hidden ? ['??', '??'] : cards;
1439
+ const rows = ['', '', '', '', ''];
1440
+
1441
+ for (const card of source) {
1442
+ if (card === '??') {
1443
+ rows[0] += `${theme.dim('┌─────┐')} `;
1444
+ rows[1] += `${theme.dim('│░░░░░│')} `;
1445
+ rows[2] += `${theme.dim('│░░▓░░│')} `;
1446
+ rows[3] += `${theme.dim('│░░░░░│')} `;
1447
+ rows[4] += `${theme.dim('└─────┘')} `;
1448
+ continue;
1449
+ }
1450
+
1451
+ const rank = card[0] === 'T' ? '10' : card[0];
1452
+ const suit = suitMap[card[1]];
1453
+ rows[0] += `${theme.dim('┌─────┐')} `;
1454
+ rows[1] += `${theme.dim('│')}${colorize(card, rank.padEnd(2, ' '))}${theme.dim(' │')} `;
1455
+ rows[2] += `${theme.dim('│ ')}${colorize(card, suit)}${theme.dim(' │')} `;
1456
+ rows[3] += `${theme.dim('│ ')}${colorize(card, rank.padStart(2, ' '))}${theme.dim('│')} `;
1457
+ rows[4] += `${theme.dim('└─────┘')} `;
1458
+ }
1459
+
1460
+ rows.forEach((row) => console.log(` ${row}`));
1461
+ }
1462
+
1463
+ function showPokerState(status) {
1464
+ showSection(`POKER ARENA - ${status.mode === 'real' ? 'REAL MODE' : 'FREE MODE'}`);
1465
+ kvDisplay([
1466
+ ['Street', status.street.toUpperCase()],
1467
+ ['Dealer', status.dealer],
1468
+ ['Pot', `${status.pot} chips`],
1469
+ ['Current Bet', `${status.currentBet} chips`],
1470
+ ['Your Stack', `${status.player.stack} chips`],
1471
+ ['House Stack', `${status.house.stack} chips`],
1472
+ ['To Act', status.currentActor || '-'],
1473
+ ]);
1474
+
1475
+ console.log('');
1476
+ console.log(` ${theme.label('House')}`);
1477
+ renderPokerCards(status.house.hole, status.house.holeHidden);
1478
+ console.log('');
1479
+ console.log(` ${theme.label('Board')}`);
1480
+ if (status.community.length) renderPokerCards(status.community);
1481
+ else console.log(` ${theme.dim(' No community cards yet')}`);
1482
+ console.log('');
1483
+ console.log(` ${theme.label('You')}`);
1484
+ renderPokerCards(status.player.hole);
1485
+ console.log('');
1486
+
1487
+ if (status.street === 'finished') {
1488
+ const result = status.winner === 'player'
1489
+ ? theme.success('WIN')
1490
+ : status.winner === 'house'
1491
+ ? theme.error('LOSS')
1492
+ : theme.warning('PUSH');
1493
+ kvDisplay([
1494
+ ['Result', result],
1495
+ ['Summary', status.summary || '-'],
1496
+ ['Your Hand', status.player.hand?.name || '-'],
1497
+ ['House Hand', status.house.hand?.name || '-'],
1498
+ ['Payout', status.mode === 'real' && status.winner === 'player' ? `$${status.payoutUsdc} USDC` : status.mode === 'real' ? '$0 USDC' : 'free mode'],
1499
+ ]);
1500
+ console.log('');
1501
+ } else if (status.availableActions?.length) {
1502
+ info(`Actions: ${status.availableActions.join(', ')}`);
1503
+ }
1504
+ }
1505
+
1506
+ async function playPokerCli(opts = {}) {
1507
+ const inquirer = (await import('inquirer')).default;
1508
+ const mode = pokerModeFromOpts(opts);
1509
+ const spin = spinner(`Opening ${mode === 'real' ? 'real-mode' : 'free-mode'} poker table...`).start();
1510
+
1511
+ try {
1512
+ let status = await pokerNewGame({ mode });
1513
+ spin.succeed('Table ready');
1514
+
1515
+ while (status && status.street !== 'finished') {
1516
+ console.log('');
1517
+ showPokerState(status);
1518
+
1519
+ if (status.currentActor !== 'player') {
1520
+ status = pokerStatus(status.id);
1521
+ continue;
1522
+ }
1523
+
1524
+ const { action } = await inquirer.prompt([{
1525
+ type: 'list',
1526
+ name: 'action',
1527
+ message: theme.gold('Pick your action:'),
1528
+ choices: status.availableActions.map((item) => ({
1529
+ name: item === 'all-in' ? 'all-in' : item,
1530
+ value: item,
1531
+ })),
1532
+ }]);
1533
+
1534
+ status = await pokerAction(status.id, action);
1535
+ }
1536
+
1537
+ console.log('');
1538
+ showPokerState(status);
1539
+ } catch (err) {
1540
+ spin.fail('Poker table unavailable');
1541
+ error(err.message);
1542
+ }
1543
+ }
1544
+
1545
+ function showPokerCliStatus() {
1546
+ showMiniBanner();
1547
+ const status = pokerStatus();
1548
+ if (!status) {
1549
+ info('No active poker game');
1550
+ return;
1551
+ }
1552
+ showPokerState(status);
1553
+ }
1554
+
1555
+ function showPokerCliHistory() {
1556
+ showMiniBanner();
1557
+ const items = pokerHistory();
1558
+ if (!items.length) {
1559
+ info('No poker hands played yet');
1560
+ return;
1561
+ }
1562
+
1563
+ showSection('POKER HISTORY');
1564
+ items.slice(0, 10).forEach((item) => {
1565
+ const verdict = item.winner === 'player'
1566
+ ? theme.success('W')
1567
+ : item.winner === 'house'
1568
+ ? theme.error('L')
1569
+ : theme.warning('P');
1570
+ console.log(` ${verdict} ${theme.gold(item.mode.toUpperCase().padEnd(5))} ${theme.bright(item.summary)}`);
1571
+ });
1572
+ console.log('');
1573
+ }
1574
+
1409
1575
  function showCommandList() {
1410
1576
  console.log('');
1411
1577
  showSection('COMMANDS');
@@ -1429,10 +1595,11 @@ function showCommandList() {
1429
1595
  ['script', 'Execution scripts & strategies'],
1430
1596
  ['market', 'Market intel & token data'],
1431
1597
  ['oracle', 'On-chain random oracle'],
1432
- ['casino', 'The Clawsino betting'],
1598
+ ['casino', 'The Clawsino - betting'],
1599
+ ['poker', 'GTO Poker Arena — heads-up holdem'],
1433
1600
  ['cards', 'Prepaid Visa/MC cards'],
1434
1601
  ['builders', 'ERC-8021 builder index'],
1435
- ['mail', 'AgentMail email for your agent'],
1602
+ ['mail', 'AgentMail - email for your agent'],
1436
1603
  ['facilitator', 'x402 payment facilitator'],
1437
1604
  ['skills', 'Agent skill directory'],
1438
1605
  ['serve', 'Launch web terminal in browser'],