@targlobal/mission-control 1.5.6 → 1.5.8

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/dist/index.js CHANGED
@@ -503,7 +503,7 @@ const showDashboard = async () => {
503
503
  console.log(chalk_1.default.cyan('┌─────────────────────────────┐'));
504
504
  console.log(chalk_1.default.cyan('│') + ` ${chalk_1.default.bgCyan.black('TASKS')} ${chalk_1.default.bold.white(String(stats.my_tasks).padStart(3))} ${chalk_1.default.bgRed.white('CRIT')} ${chalk_1.default.bold.red(String(stats.critical_count).padStart(2))} ${chalk_1.default.bgYellow.black('OVR')} ${chalk_1.default.bold.yellow(String(stats.overdue_tasks).padStart(2))} ` + chalk_1.default.cyan('│'));
505
505
  console.log(chalk_1.default.cyan('├─────────────────────────────┤'));
506
- console.log(chalk_1.default.cyan('│') + ` ${chalk_1.default.cyan('[1]')}Tasks ${chalk_1.default.cyan('[2]')}New ${chalk_1.default.cyan('[3]')}Pay ${chalk_1.default.cyan('[4]')}Urg ` + chalk_1.default.cyan('│'));
506
+ console.log(chalk_1.default.cyan('│') + ` ${chalk_1.default.cyan('[1]')}Tasks ${chalk_1.default.cyan('[2]')}New ${chalk_1.default.cyan('[3]')}Pay ${chalk_1.default.cyan('[4]')}Urg ${chalk_1.default.cyan('[5]')}Smart ` + chalk_1.default.cyan('│'));
507
507
  console.log(chalk_1.default.cyan('└─────────────────────────────┘'));
508
508
  console.log('');
509
509
  // Show urgent count only in compact mode
@@ -525,7 +525,7 @@ const showDashboard = async () => {
525
525
  console.log(chalk_1.default.cyan('║') + ' ' + chalk_1.default.cyan('║'));
526
526
  console.log(chalk_1.default.cyan('╠══════════════════════════════════════════════════════════════════════╣'));
527
527
  console.log(chalk_1.default.cyan('║') + chalk_1.default.dim(' Quick Actions: ') + chalk_1.default.cyan('║'));
528
- console.log(chalk_1.default.cyan('║') + ` ${chalk_1.default.cyan('[1]')} My Tasks ${chalk_1.default.cyan('[2]')} New Task ${chalk_1.default.cyan('[3]')} Payouts ${chalk_1.default.cyan('[4]')} Urgent ` + chalk_1.default.cyan('║'));
528
+ console.log(chalk_1.default.cyan('║') + ` ${chalk_1.default.cyan('[1]')} My Tasks ${chalk_1.default.cyan('[2]')} New Task ${chalk_1.default.cyan('[3]')} Payouts ${chalk_1.default.cyan('[4]')} Urgent ${chalk_1.default.cyan('[5]')} Smart ` + chalk_1.default.cyan('║'));
529
529
  console.log(chalk_1.default.cyan('║') + ' ' + chalk_1.default.cyan('║'));
530
530
  console.log(chalk_1.default.cyan('╚══════════════════════════════════════════════════════════════════════╝'));
531
531
  console.log('');
@@ -545,6 +545,185 @@ const showDashboard = async () => {
545
545
  // Silently fail - show basic prompt
546
546
  }
547
547
  };
548
+ const runSuperSmartDirect = async () => {
549
+ setTitle('Super Smart');
550
+ const spinner = (0, ora_1.default)('Loading all pending payouts...').start();
551
+ try {
552
+ // Fetch all pending payouts in parallel across all plans
553
+ const [payoutsRes, tarPayRes] = await Promise.all([
554
+ api_1.api.listPayouts({ status: 'pending', limit: 500 }),
555
+ api_1.api.getTarPayPayouts({ status: 'pending_review', limit: 500 }),
556
+ ]);
557
+ const payouts = payoutsRes.data || [];
558
+ const tarPayPayouts = tarPayRes.results || [];
559
+ spinner.stop();
560
+ // Build unified list from both sources
561
+ const allItems = [
562
+ ...payouts.map((p) => ({
563
+ id: p.id,
564
+ user_email: p.user_email,
565
+ crypto: p.crypto_type,
566
+ amount: p.amount,
567
+ remaining_amount: p.remaining_amount !== undefined ? p.remaining_amount : p.amount,
568
+ has_partial_payments: p.has_partial_payments || false,
569
+ paid_percentage: p.paid_percentage || 0,
570
+ plan: p.plan,
571
+ source: 'regular',
572
+ })),
573
+ ...tarPayPayouts.map((p) => ({
574
+ id: p.id,
575
+ user_email: p.user_email,
576
+ crypto: p.currency,
577
+ amount: parseFloat(p.amount),
578
+ remaining_amount: p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount),
579
+ has_partial_payments: p.has_partial_payments || false,
580
+ paid_percentage: p.paid_percentage || 0,
581
+ plan: p.plan,
582
+ source: 'tarpay',
583
+ })),
584
+ ];
585
+ // Group by currency across ALL plans
586
+ const byCurrency = {};
587
+ allItems.forEach((p) => {
588
+ if (!byCurrency[p.crypto])
589
+ byCurrency[p.crypto] = [];
590
+ byCurrency[p.crypto].push(p);
591
+ });
592
+ const totalCount = allItems.length;
593
+ const totalAmount = allItems.reduce((sum, p) => sum + p.remaining_amount, 0);
594
+ const currencySummary = Object.entries(byCurrency)
595
+ .map(([crypto, items]) => `${chalk_1.default.bold(crypto)} ${items.length}`)
596
+ .join(' ');
597
+ // Show overview
598
+ console.log('');
599
+ console.log(chalk_1.default.cyan('╔═══ SUPER SMART ═══╗'));
600
+ console.log(chalk_1.default.cyan('║') + ` Pending: ${chalk_1.default.bold.yellow(String(totalCount))} payouts (${chalk_1.default.green('$' + Math.round(totalAmount).toLocaleString())})`);
601
+ console.log(chalk_1.default.cyan('║') + ` ${currencySummary}`);
602
+ console.log(chalk_1.default.cyan('╚════════════════════╝'));
603
+ console.log('');
604
+ if (totalCount === 0) {
605
+ console.log(chalk_1.default.green(' ✓ No pending payouts\n'));
606
+ return;
607
+ }
608
+ // Step 1: Select currency (with back option)
609
+ const currencies = Object.keys(byCurrency);
610
+ let selectedCurrency;
611
+ if (currencies.length === 1) {
612
+ selectedCurrency = currencies[0];
613
+ }
614
+ else {
615
+ const currencyChoices = [
616
+ { name: chalk_1.default.dim('← Back'), value: '__back__' },
617
+ ...currencies.map((c) => {
618
+ const items = byCurrency[c];
619
+ const total = items.reduce((sum, p) => sum + p.remaining_amount, 0);
620
+ return { name: `${c} (${items.length} payouts, ${formatAmount(total, c)})`, value: c };
621
+ }),
622
+ ];
623
+ const { currency } = await inquirer_1.default.prompt([
624
+ {
625
+ type: 'list',
626
+ name: 'currency',
627
+ message: 'Select currency:',
628
+ choices: currencyChoices,
629
+ },
630
+ ]);
631
+ if (currency === '__back__')
632
+ return;
633
+ selectedCurrency = currency;
634
+ }
635
+ const currencyItems = byCurrency[selectedCurrency];
636
+ // Show plan breakdown for selected currency
637
+ const byPlan = {};
638
+ currencyItems.forEach((p) => {
639
+ if (!byPlan[p.plan])
640
+ byPlan[p.plan] = [];
641
+ byPlan[p.plan].push(p);
642
+ });
643
+ console.log(`\n ${chalk_1.default.bold(selectedCurrency)} - ${currencyItems.length} payouts:`);
644
+ Object.entries(byPlan).forEach(([plan, items]) => {
645
+ const planTotal = items.reduce((sum, p) => sum + p.remaining_amount, 0);
646
+ const icon = PLAN_ICONS[plan] || '📋';
647
+ const color = PLAN_COLORS[plan] || chalk_1.default.white;
648
+ console.log(` ${icon} ${color(plan.toUpperCase().padEnd(12))} ${String(items.length).padStart(2)} │ ${chalk_1.default.green(formatAmount(planTotal, selectedCurrency))}`);
649
+ });
650
+ console.log('');
651
+ const totalPending = currencyItems.reduce((sum, p) => sum + p.remaining_amount, 0);
652
+ // Step 2: Ask available amount (with back)
653
+ const { availableAmount } = await inquirer_1.default.prompt([
654
+ {
655
+ type: 'input',
656
+ name: 'availableAmount',
657
+ message: `How much ${selectedCurrency} available? (pending: ${formatAmount(totalPending, selectedCurrency)})`,
658
+ validate: (input) => {
659
+ if (input.toLowerCase() === 'back' || input.toLowerCase() === 'q')
660
+ return true;
661
+ const num = parseFloat(input);
662
+ if (isNaN(num) || num <= 0)
663
+ return 'Enter a positive number (or "back" to go back)';
664
+ return true;
665
+ },
666
+ },
667
+ ]);
668
+ if (availableAmount.toLowerCase() === 'back' || availableAmount.toLowerCase() === 'q')
669
+ return;
670
+ const available = parseFloat(availableAmount);
671
+ const smartPercentage = Math.min((available / totalPending) * 100, 100);
672
+ const roundedPct = Math.round(smartPercentage * 100) / 100;
673
+ // Plan abbreviations for preview
674
+ const PLAN_ABBREV = {
675
+ hermes: 'HRM',
676
+ alpha: 'ALP',
677
+ mematic: 'MEM',
678
+ validator_v2: 'V2',
679
+ booster: 'BST',
680
+ dumpster: 'DMP',
681
+ christmas: 'XMS',
682
+ recovery: 'RCV',
683
+ };
684
+ // Show preview with plan labels
685
+ console.log('\n' + chalk_1.default.cyan(` Processing ${chalk_1.default.bold(roundedPct + '%')} of ${currencyItems.length} ${selectedCurrency} payouts (${formatAmount(available, selectedCurrency)} / ${formatAmount(totalPending, selectedCurrency)})`));
686
+ console.log(chalk_1.default.dim(' ─────────────────────────────'));
687
+ let previewTotal = 0;
688
+ currencyItems.forEach((p) => {
689
+ const willPay = p.remaining_amount * (smartPercentage / 100);
690
+ previewTotal += willPay;
691
+ const email = p.user_email.length > 20 ? p.user_email.substring(0, 18) + '..' : p.user_email;
692
+ const abbrev = PLAN_ABBREV[p.plan] || p.plan.substring(0, 3).toUpperCase();
693
+ const planColor = PLAN_COLORS[p.plan] || chalk_1.default.white;
694
+ console.log(` ${chalk_1.default.dim('#' + p.id)} ${planColor('[' + abbrev + ']')} ${email.padEnd(20)} ${formatAmount(p.remaining_amount, selectedCurrency).padStart(14)} → pays ${chalk_1.default.green(formatAmount(willPay, selectedCurrency))}`);
695
+ });
696
+ console.log(chalk_1.default.dim(' ─────────────────────────────'));
697
+ console.log(chalk_1.default.bold(` Total to send: ${chalk_1.default.green(formatAmount(previewTotal, selectedCurrency))}\n`));
698
+ // Step 3: Confirm
699
+ const { confirmSmart } = await inquirer_1.default.prompt([
700
+ {
701
+ type: 'confirm',
702
+ name: 'confirmSmart',
703
+ message: chalk_1.default.yellow(`⚠️ Pay ${roundedPct}% of ${currencyItems.length} payout(s)?`),
704
+ default: false,
705
+ },
706
+ ]);
707
+ if (confirmSmart) {
708
+ // Split by source for correct API calls
709
+ const regularIds = currencyItems.filter((p) => p.source === 'regular').map((p) => p.id);
710
+ const tarPayIds = currencyItems.filter((p) => p.source === 'tarpay').map((p) => p.id);
711
+ if (regularIds.length > 0) {
712
+ await processPayoutsWithProgress(regularIds, 'partial', roundedPct);
713
+ }
714
+ if (tarPayIds.length > 0) {
715
+ await processChristmasPayoutsWithProgress(tarPayIds, 'partial', roundedPct);
716
+ }
717
+ }
718
+ else {
719
+ console.log(chalk_1.default.dim('\n Cancelled\n'));
720
+ }
721
+ }
722
+ catch (e) {
723
+ spinner.stop();
724
+ console.log(chalk_1.default.red(` Error: ${e.message}\n`));
725
+ }
726
+ };
548
727
  const runInteractiveShell = async () => {
549
728
  setTitle('Mission Control');
550
729
  await showDashboard();
@@ -589,6 +768,10 @@ const runInteractiveShell = async () => {
589
768
  setTitle('Urgent');
590
769
  await showUrgentCmd();
591
770
  }
771
+ else if (cmd === '5' || cmd === 'queue' || cmd === 'sq' || cmd === 'super' || cmd === 'ss') {
772
+ await runSuperSmartDirect();
773
+ await showDashboard();
774
+ }
592
775
  else {
593
776
  // Regular commands
594
777
  switch (mainCmd) {
@@ -1607,107 +1790,11 @@ const runChristmasPayoutsShell = async () => {
1607
1790
  }
1608
1791
  break;
1609
1792
  case 'smart':
1610
- case 'sp': {
1611
- // Smart partial: pay by available balance for Christmas
1612
- const xmasSmartSpinner = (0, ora_1.default)('Loading Christmas payouts...').start();
1613
- try {
1614
- const xmasData = await api_1.api.getTarPayPayouts({
1615
- plan: 'christmas',
1616
- status: 'pending_review',
1617
- limit: 500,
1618
- });
1619
- const xmasPayouts = xmasData.results || [];
1620
- xmasSmartSpinner.stop();
1621
- if (xmasPayouts.length === 0) {
1622
- console.log(chalk_1.default.green('\n ✓ No pending Christmas payouts\n'));
1623
- break;
1624
- }
1625
- // Group by currency
1626
- const xmasByCurrency = {};
1627
- xmasPayouts.forEach((p) => {
1628
- if (!xmasByCurrency[p.currency])
1629
- xmasByCurrency[p.currency] = [];
1630
- xmasByCurrency[p.currency].push(p);
1631
- });
1632
- const xmasCurrencies = Object.keys(xmasByCurrency);
1633
- console.log('\n' + chalk_1.default.red(` 🎄 CHRISTMAS - Pending Payouts`));
1634
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
1635
- xmasCurrencies.forEach((crypto) => {
1636
- const items = xmasByCurrency[crypto];
1637
- const total = items.reduce((sum, p) => sum + (p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount)), 0);
1638
- console.log(` ${chalk_1.default.bold(crypto.padEnd(5))}: ${String(items.length).padStart(3)} payouts │ Total: ${chalk_1.default.green(formatAmount(total, crypto))}`);
1639
- });
1640
- console.log('');
1641
- let xmasCurrency;
1642
- if (xmasCurrencies.length === 1) {
1643
- xmasCurrency = xmasCurrencies[0];
1644
- }
1645
- else {
1646
- const { currency } = await inquirer_1.default.prompt([
1647
- {
1648
- type: 'list',
1649
- name: 'currency',
1650
- message: 'Which currency to process?',
1651
- choices: xmasCurrencies.map((c) => {
1652
- const items = xmasByCurrency[c];
1653
- const total = items.reduce((sum, p) => sum + (p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount)), 0);
1654
- return { name: `${c} (${items.length} payouts, ${formatAmount(total, c)})`, value: c };
1655
- }),
1656
- },
1657
- ]);
1658
- xmasCurrency = currency;
1659
- }
1660
- const xmasCurrencyPayouts = xmasByCurrency[xmasCurrency];
1661
- const xmasTotalPending = xmasCurrencyPayouts.reduce((sum, p) => sum + (p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount)), 0);
1662
- const { xmasAvailable } = await inquirer_1.default.prompt([
1663
- {
1664
- type: 'input',
1665
- name: 'xmasAvailable',
1666
- message: `How much ${xmasCurrency} do you have available? (total pending: ${formatAmount(xmasTotalPending, xmasCurrency)})`,
1667
- validate: (input) => {
1668
- const num = parseFloat(input);
1669
- if (isNaN(num) || num <= 0)
1670
- return 'Please enter a positive number';
1671
- return true;
1672
- },
1673
- },
1674
- ]);
1675
- const xmasAvailNum = parseFloat(xmasAvailable);
1676
- const xmasPct = Math.min((xmasAvailNum / xmasTotalPending) * 100, 100);
1677
- const xmasRoundedPct = Math.round(xmasPct * 100) / 100;
1678
- console.log('\n' + chalk_1.default.cyan(` Processing ${chalk_1.default.bold(xmasRoundedPct + '%')} of ${xmasCurrencyPayouts.length} ${xmasCurrency} payouts (${formatAmount(xmasAvailNum, xmasCurrency)} / ${formatAmount(xmasTotalPending, xmasCurrency)})`));
1679
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
1680
- let xmasPreviewTotal = 0;
1681
- xmasCurrencyPayouts.forEach((p) => {
1682
- const displayAmt = p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount);
1683
- const willPay = displayAmt * (xmasPct / 100);
1684
- xmasPreviewTotal += willPay;
1685
- const email = p.user_email.length > 22 ? p.user_email.substring(0, 20) + '..' : p.user_email;
1686
- console.log(` ${chalk_1.default.dim('#' + p.id)} ${email.padEnd(22)} ${formatAmount(displayAmt, xmasCurrency).padStart(16)} → pays ${chalk_1.default.green(formatAmount(willPay, xmasCurrency))}`);
1687
- });
1688
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
1689
- console.log(chalk_1.default.bold(` Total to send: ${chalk_1.default.green(formatAmount(xmasPreviewTotal, xmasCurrency))}\n`));
1690
- const { confirmXmasSmart } = await inquirer_1.default.prompt([
1691
- {
1692
- type: 'confirm',
1693
- name: 'confirmXmasSmart',
1694
- message: chalk_1.default.yellow(`⚠️ Pay ${xmasRoundedPct}% of ${xmasCurrencyPayouts.length} payout(s)?`),
1695
- default: false,
1696
- },
1697
- ]);
1698
- if (confirmXmasSmart) {
1699
- const xmasSmartIds = xmasCurrencyPayouts.map((p) => p.id);
1700
- await processChristmasPayoutsWithProgress(xmasSmartIds, 'partial', xmasRoundedPct);
1701
- }
1702
- else {
1703
- console.log(chalk_1.default.dim('\n Cancelled\n'));
1704
- }
1705
- }
1706
- catch (e) {
1707
- xmasSmartSpinner.fail(chalk_1.default.red('Failed to load Christmas payouts'));
1708
- }
1793
+ case 'sp':
1794
+ case 'super':
1795
+ case 'ss':
1796
+ await runSuperSmartDirect();
1709
1797
  break;
1710
- }
1711
1798
  case 'help':
1712
1799
  case '?':
1713
1800
  console.log(chalk_1.default.red('\n 🎄 Christmas Payout Commands:'));
@@ -1720,7 +1807,7 @@ const runChristmasPayoutsShell = async () => {
1720
1807
  console.log(' select, s Interactive selection mode');
1721
1808
  console.log(' approve, a Select & approve payouts');
1722
1809
  console.log(chalk_1.default.cyan(' partial, p Select & pay partial %'));
1723
- console.log(chalk_1.default.cyan(' smart, sp Smart partial: pay by available balance'));
1810
+ console.log(chalk_1.default.cyan(' smart, sp, ss Super Smart: pay by currency across all plans'));
1724
1811
  console.log(' reject Select & reject payouts');
1725
1812
  console.log(' back, q Return to main payouts');
1726
1813
  console.log(chalk_1.default.dim('\n Note: Payouts > $50 need approval, < $50 auto-sent'));
@@ -1906,162 +1993,9 @@ const runPayoutsShell = async () => {
1906
1993
  break;
1907
1994
  case 'smart':
1908
1995
  case 'sp':
1909
- // Smart partial: pay by available balance
1910
- const { smartPlan } = await inquirer_1.default.prompt([
1911
- {
1912
- type: 'list',
1913
- name: 'smartPlan',
1914
- message: 'Select plan:',
1915
- choices: [
1916
- { name: `${PLAN_ICONS.hermes || '⚡'} Hermes`, value: 'hermes' },
1917
- { name: `${PLAN_ICONS.alpha || '🔷'} Alpha`, value: 'alpha' },
1918
- { name: `${PLAN_ICONS.mematic || '💎'} Mematic`, value: 'mematic' },
1919
- { name: `${PLAN_ICONS.validator_v2 || '🔐'} Validator V2`, value: 'validator_v2' },
1920
- { name: `${PLAN_ICONS.booster || '🚀'} Booster`, value: 'booster' },
1921
- { name: `${PLAN_ICONS.christmas || '🎄'} Christmas`, value: 'christmas' },
1922
- { name: '🔄 Recovery', value: 'recovery' },
1923
- { name: '📋 All Plans', value: undefined },
1924
- ],
1925
- },
1926
- ]);
1927
- const isTarPayPlan = smartPlan === 'christmas';
1928
- const smartSpinner = (0, ora_1.default)('Loading pending payouts...').start();
1929
- try {
1930
- let smartItems = [];
1931
- if (isTarPayPlan) {
1932
- // TarPay payouts (Christmas, etc.)
1933
- const tarData = await api_1.api.getTarPayPayouts({
1934
- plan: smartPlan,
1935
- status: 'pending_review',
1936
- limit: 500,
1937
- });
1938
- const tarPayouts = tarData.results || [];
1939
- smartItems = tarPayouts.map((p) => ({
1940
- id: p.id,
1941
- user_email: p.user_email,
1942
- crypto: p.currency,
1943
- amount: parseFloat(p.amount),
1944
- remaining_amount: p.remaining_amount !== undefined ? p.remaining_amount : parseFloat(p.amount),
1945
- has_partial_payments: p.has_partial_payments || false,
1946
- paid_percentage: p.paid_percentage || 0,
1947
- }));
1948
- }
1949
- else {
1950
- // Regular payouts
1951
- const smartParams = { status: 'pending', limit: 500 };
1952
- if (smartPlan)
1953
- smartParams.plan = smartPlan;
1954
- const smartData = await api_1.api.listPayouts(smartParams);
1955
- const smartPayouts = smartData.data || [];
1956
- smartItems = smartPayouts.map((p) => ({
1957
- id: p.id,
1958
- user_email: p.user_email,
1959
- crypto: p.crypto_type,
1960
- amount: p.amount,
1961
- remaining_amount: p.remaining_amount !== undefined ? p.remaining_amount : p.amount,
1962
- has_partial_payments: p.has_partial_payments || false,
1963
- paid_percentage: p.paid_percentage || 0,
1964
- }));
1965
- }
1966
- smartSpinner.stop();
1967
- if (smartItems.length === 0) {
1968
- console.log(chalk_1.default.green('\n ✓ No pending payouts found\n'));
1969
- break;
1970
- }
1971
- // Group by crypto
1972
- const byCurrency = {};
1973
- smartItems.forEach((p) => {
1974
- if (!byCurrency[p.crypto])
1975
- byCurrency[p.crypto] = [];
1976
- byCurrency[p.crypto].push(p);
1977
- });
1978
- const currencies = Object.keys(byCurrency);
1979
- const planLabel = smartPlan ? smartPlan.toUpperCase() : 'ALL PLANS';
1980
- const planColor = smartPlan ? (PLAN_COLORS[smartPlan] || chalk_1.default.white) : chalk_1.default.white;
1981
- console.log('\n' + planColor(` 📋 ${planLabel} - Pending Payouts`));
1982
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
1983
- currencies.forEach((crypto) => {
1984
- const items = byCurrency[crypto];
1985
- const total = items.reduce((sum, p) => sum + p.remaining_amount, 0);
1986
- console.log(` ${chalk_1.default.bold(crypto.padEnd(5))}: ${String(items.length).padStart(3)} payouts │ Total: ${chalk_1.default.green(formatAmount(total, crypto))}`);
1987
- });
1988
- console.log('');
1989
- // Select currency
1990
- let selectedCurrency;
1991
- if (currencies.length === 1) {
1992
- selectedCurrency = currencies[0];
1993
- }
1994
- else {
1995
- const { currency } = await inquirer_1.default.prompt([
1996
- {
1997
- type: 'list',
1998
- name: 'currency',
1999
- message: 'Which currency to process?',
2000
- choices: currencies.map((c) => {
2001
- const items = byCurrency[c];
2002
- const total = items.reduce((sum, p) => sum + p.remaining_amount, 0);
2003
- return { name: `${c} (${items.length} payouts, ${formatAmount(total, c)})`, value: c };
2004
- }),
2005
- },
2006
- ]);
2007
- selectedCurrency = currency;
2008
- }
2009
- const currencyItems = byCurrency[selectedCurrency];
2010
- const totalPending = currencyItems.reduce((sum, p) => sum + p.remaining_amount, 0);
2011
- // Ask available amount
2012
- const { availableAmount } = await inquirer_1.default.prompt([
2013
- {
2014
- type: 'input',
2015
- name: 'availableAmount',
2016
- message: `How much ${selectedCurrency} do you have available? (total pending: ${formatAmount(totalPending, selectedCurrency)})`,
2017
- validate: (input) => {
2018
- const num = parseFloat(input);
2019
- if (isNaN(num) || num <= 0)
2020
- return 'Please enter a positive number';
2021
- return true;
2022
- },
2023
- },
2024
- ]);
2025
- const available = parseFloat(availableAmount);
2026
- const smartPercentage = Math.min((available / totalPending) * 100, 100);
2027
- const roundedPct = Math.round(smartPercentage * 100) / 100;
2028
- // Show breakdown
2029
- console.log('\n' + chalk_1.default.cyan(` Processing ${chalk_1.default.bold(roundedPct + '%')} of ${currencyItems.length} ${selectedCurrency} payouts (${formatAmount(available, selectedCurrency)} / ${formatAmount(totalPending, selectedCurrency)})`));
2030
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
2031
- let previewTotal = 0;
2032
- currencyItems.forEach((p) => {
2033
- const willPay = p.remaining_amount * (smartPercentage / 100);
2034
- previewTotal += willPay;
2035
- const email = p.user_email.length > 22 ? p.user_email.substring(0, 20) + '..' : p.user_email;
2036
- console.log(` ${chalk_1.default.dim('#' + p.id)} ${email.padEnd(22)} ${formatAmount(p.remaining_amount, selectedCurrency).padStart(16)} → pays ${chalk_1.default.green(formatAmount(willPay, selectedCurrency))}`);
2037
- });
2038
- console.log(chalk_1.default.dim(' ─────────────────────────────'));
2039
- console.log(chalk_1.default.bold(` Total to send: ${chalk_1.default.green(formatAmount(previewTotal, selectedCurrency))}\n`));
2040
- // Confirm
2041
- const { confirmSmart } = await inquirer_1.default.prompt([
2042
- {
2043
- type: 'confirm',
2044
- name: 'confirmSmart',
2045
- message: chalk_1.default.yellow(`⚠️ Pay ${roundedPct}% of ${currencyItems.length} payout(s)?`),
2046
- default: false,
2047
- },
2048
- ]);
2049
- if (confirmSmart) {
2050
- const smartIds = currencyItems.map((p) => p.id);
2051
- if (isTarPayPlan) {
2052
- await processChristmasPayoutsWithProgress(smartIds, 'partial', roundedPct);
2053
- }
2054
- else {
2055
- await processPayoutsWithProgress(smartIds, 'partial', roundedPct);
2056
- }
2057
- }
2058
- else {
2059
- console.log(chalk_1.default.dim('\n Cancelled\n'));
2060
- }
2061
- }
2062
- catch (e) {
2063
- smartSpinner.fail(chalk_1.default.red('Failed to load payouts'));
2064
- }
1996
+ case 'super':
1997
+ case 'ss':
1998
+ await runSuperSmartDirect();
2065
1999
  break;
2066
2000
  case 'hermes':
2067
2001
  case 'alpha':
@@ -2149,7 +2083,7 @@ const runPayoutsShell = async () => {
2149
2083
  console.log(' select [plan] Interactive payout selection');
2150
2084
  console.log(' approve [ids] Approve payouts (interactive if no IDs)');
2151
2085
  console.log(chalk_1.default.cyan(' partial, p Pay partial % (repayment mode)'));
2152
- console.log(chalk_1.default.cyan(' smart, sp Smart partial: pay by available balance'));
2086
+ console.log(chalk_1.default.cyan(' smart, sp, ss Super Smart: pay by currency across all plans'));
2153
2087
  console.log(chalk_1.default.yellow(' all Approve ALL pending payouts'));
2154
2088
  console.log(' cancel [ids] Cancel payouts (interactive if no IDs)');
2155
2089
  console.log(' process Process payouts by plan (interactive)');