moon-iq 0.2.1 → 0.2.2
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/README.md +41 -0
- package/dist/index.js +460 -30
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# moon-iq
|
|
2
|
+
|
|
3
|
+
Moon IQ command-line interface.
|
|
4
|
+
|
|
5
|
+
- Install: `npm i -g moon-iq`
|
|
6
|
+
- Primary command: `mooniq`
|
|
7
|
+
- Aliases: `miq`, `moon-iq`
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i -g moon-iq
|
|
13
|
+
mooniq login
|
|
14
|
+
mooniq whoami
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Common commands
|
|
18
|
+
|
|
19
|
+
### Wallet + user
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mooniq user retrieve
|
|
23
|
+
# or
|
|
24
|
+
mooniq run user_retrieve
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Balances
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mooniq token balance list --wallet <WALLET> --chain solana
|
|
31
|
+
# or
|
|
32
|
+
mooniq run token_balance_list --input '{"wallet":"<WALLET>","chain":"solana"}'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Troubleshooting
|
|
36
|
+
|
|
37
|
+
- If you see auth/401 errors: run `mooniq login` again.
|
|
38
|
+
|
|
39
|
+
## Related
|
|
40
|
+
|
|
41
|
+
- Skills pack (Anthropic-style `SKILL.md` folders): `npm i -g moon-iq-skills`
|
package/dist/index.js
CHANGED
|
@@ -334,20 +334,48 @@ var TOOL_DEFINITIONS = [
|
|
|
334
334
|
"name": "fiat",
|
|
335
335
|
"type": "string",
|
|
336
336
|
"description": "The fiat currency to convert to",
|
|
337
|
-
"required": true
|
|
337
|
+
"required": true,
|
|
338
|
+
"choices": [
|
|
339
|
+
"USD",
|
|
340
|
+
"EUR"
|
|
341
|
+
]
|
|
338
342
|
},
|
|
339
343
|
{
|
|
340
344
|
"name": "stablecoin",
|
|
341
345
|
"type": "string",
|
|
342
346
|
"description": "The stablecoin token to convert from",
|
|
343
|
-
"required": true
|
|
347
|
+
"required": true,
|
|
348
|
+
"choices": [
|
|
349
|
+
"USDC",
|
|
350
|
+
"USDT",
|
|
351
|
+
"EURC"
|
|
352
|
+
]
|
|
344
353
|
}
|
|
345
354
|
]
|
|
346
355
|
},
|
|
347
356
|
{
|
|
348
357
|
"name": "iron_offramp_initiate",
|
|
349
358
|
"description": "Initiate an offramp by sending stablecoin to the offramp's deposit account. The stablecoin will be converted to fiat and deposited into your registered bank account. This process is asynchronous and may take some time for funds to appear in your bank account.",
|
|
350
|
-
"options": [
|
|
359
|
+
"options": [
|
|
360
|
+
{
|
|
361
|
+
"name": "simulation",
|
|
362
|
+
"type": "boolean",
|
|
363
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
364
|
+
"required": true
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"name": "offrampId",
|
|
368
|
+
"type": "string",
|
|
369
|
+
"description": "The ID of the offramp to initiate",
|
|
370
|
+
"required": true
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"name": "amount",
|
|
374
|
+
"type": "number",
|
|
375
|
+
"description": "The amount of stablecoin to send (in human-readable units, e.g., 100.5)",
|
|
376
|
+
"required": true
|
|
377
|
+
}
|
|
378
|
+
]
|
|
351
379
|
},
|
|
352
380
|
{
|
|
353
381
|
"name": "iron_offramp_list",
|
|
@@ -380,13 +408,22 @@ var TOOL_DEFINITIONS = [
|
|
|
380
408
|
"name": "fiat",
|
|
381
409
|
"type": "string",
|
|
382
410
|
"description": "The fiat currency to convert from",
|
|
383
|
-
"required": true
|
|
411
|
+
"required": true,
|
|
412
|
+
"choices": [
|
|
413
|
+
"USD",
|
|
414
|
+
"EUR"
|
|
415
|
+
]
|
|
384
416
|
},
|
|
385
417
|
{
|
|
386
418
|
"name": "stablecoin",
|
|
387
419
|
"type": "string",
|
|
388
420
|
"description": "The stablecoin token to convert to",
|
|
389
|
-
"required": true
|
|
421
|
+
"required": true,
|
|
422
|
+
"choices": [
|
|
423
|
+
"USDC",
|
|
424
|
+
"USDT",
|
|
425
|
+
"EURC"
|
|
426
|
+
]
|
|
390
427
|
}
|
|
391
428
|
]
|
|
392
429
|
},
|
|
@@ -398,7 +435,15 @@ var TOOL_DEFINITIONS = [
|
|
|
398
435
|
"name": "status",
|
|
399
436
|
"type": "string",
|
|
400
437
|
"description": "Status of the onramps to get",
|
|
401
|
-
"required": true
|
|
438
|
+
"required": true,
|
|
439
|
+
"choices": [
|
|
440
|
+
"Created",
|
|
441
|
+
"Authorized",
|
|
442
|
+
"DepositAccountAdded",
|
|
443
|
+
"Approved",
|
|
444
|
+
"Rejected",
|
|
445
|
+
"Cancelled"
|
|
446
|
+
]
|
|
402
447
|
}
|
|
403
448
|
]
|
|
404
449
|
},
|
|
@@ -422,7 +467,20 @@ var TOOL_DEFINITIONS = [
|
|
|
422
467
|
{
|
|
423
468
|
"name": "lending_deposit",
|
|
424
469
|
"description": "Deposit USDC into your lending account to earn interest.",
|
|
425
|
-
"options": [
|
|
470
|
+
"options": [
|
|
471
|
+
{
|
|
472
|
+
"name": "simulation",
|
|
473
|
+
"type": "boolean",
|
|
474
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
475
|
+
"required": true
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"name": "amount",
|
|
479
|
+
"type": "number",
|
|
480
|
+
"description": "Amount of USDC to deposit",
|
|
481
|
+
"required": true
|
|
482
|
+
}
|
|
483
|
+
]
|
|
426
484
|
},
|
|
427
485
|
{
|
|
428
486
|
"name": "lending_rate_retrieve",
|
|
@@ -444,12 +502,44 @@ var TOOL_DEFINITIONS = [
|
|
|
444
502
|
{
|
|
445
503
|
"name": "lending_withdraw",
|
|
446
504
|
"description": "Withdraw USDC from your lending account.",
|
|
447
|
-
"options": [
|
|
505
|
+
"options": [
|
|
506
|
+
{
|
|
507
|
+
"name": "simulation",
|
|
508
|
+
"type": "boolean",
|
|
509
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
510
|
+
"required": true
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"name": "amount",
|
|
514
|
+
"type": "number",
|
|
515
|
+
"description": "Amount of USDC to withdraw",
|
|
516
|
+
"required": true
|
|
517
|
+
}
|
|
518
|
+
]
|
|
448
519
|
},
|
|
449
520
|
{
|
|
450
521
|
"name": "moonit_buy",
|
|
451
522
|
"description": "Buy tokens on Moonit platform using bonding curve. This tool converts USDC to SOL, then uses the SOL as collateral to buy Moonit tokens. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.",
|
|
452
|
-
"options": [
|
|
523
|
+
"options": [
|
|
524
|
+
{
|
|
525
|
+
"name": "simulation",
|
|
526
|
+
"type": "boolean",
|
|
527
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
528
|
+
"required": true
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
"name": "token",
|
|
532
|
+
"type": "string",
|
|
533
|
+
"description": "Address of the token to buy on Moonit",
|
|
534
|
+
"required": true
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"name": "amount",
|
|
538
|
+
"type": "number",
|
|
539
|
+
"description": "Amount of USDC used to buy the token",
|
|
540
|
+
"required": true
|
|
541
|
+
}
|
|
542
|
+
]
|
|
453
543
|
},
|
|
454
544
|
{
|
|
455
545
|
"name": "moonit_buy_recommend",
|
|
@@ -466,7 +556,26 @@ var TOOL_DEFINITIONS = [
|
|
|
466
556
|
{
|
|
467
557
|
"name": "moonit_sell",
|
|
468
558
|
"description": "Sell tokens on Moonit platform using bonding curve. This tool sells Moonit tokens to get SOL, then converts SOL to USDC. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.",
|
|
469
|
-
"options": [
|
|
559
|
+
"options": [
|
|
560
|
+
{
|
|
561
|
+
"name": "simulation",
|
|
562
|
+
"type": "boolean",
|
|
563
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
564
|
+
"required": true
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
"name": "token",
|
|
568
|
+
"type": "string",
|
|
569
|
+
"description": "Address of the Moonit token to sell",
|
|
570
|
+
"required": true
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"name": "amount",
|
|
574
|
+
"type": "number",
|
|
575
|
+
"description": "Amount of Moonit tokens to sell",
|
|
576
|
+
"required": true
|
|
577
|
+
}
|
|
578
|
+
]
|
|
470
579
|
},
|
|
471
580
|
{
|
|
472
581
|
"name": "moonit_sell_recommend",
|
|
@@ -483,7 +592,40 @@ var TOOL_DEFINITIONS = [
|
|
|
483
592
|
{
|
|
484
593
|
"name": "moonit_token_list",
|
|
485
594
|
"description": "Get the most popular Moonit tokens sorted by market capitalization. Moonit is a token launch platform by DEX Screener x Helio offering bonding curve mechanics, daily LP rewards, and graduation to Raydium/Meteora DEXs.",
|
|
486
|
-
"options": [
|
|
595
|
+
"options": [
|
|
596
|
+
{
|
|
597
|
+
"name": "sort",
|
|
598
|
+
"type": "string",
|
|
599
|
+
"description": "Sort tokens by",
|
|
600
|
+
"required": true,
|
|
601
|
+
"choices": [
|
|
602
|
+
"MARKET_CAP",
|
|
603
|
+
"TRENDING"
|
|
604
|
+
]
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"name": "state",
|
|
608
|
+
"type": "string",
|
|
609
|
+
"description": "Filter tokens by state",
|
|
610
|
+
"required": true,
|
|
611
|
+
"choices": [
|
|
612
|
+
"GRADUATED",
|
|
613
|
+
"NOT_GRADUATED"
|
|
614
|
+
]
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"name": "limit",
|
|
618
|
+
"type": "number",
|
|
619
|
+
"description": "Number of results per page",
|
|
620
|
+
"required": true
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
"name": "page",
|
|
624
|
+
"type": "number",
|
|
625
|
+
"description": "The page number of results",
|
|
626
|
+
"required": true
|
|
627
|
+
}
|
|
628
|
+
]
|
|
487
629
|
},
|
|
488
630
|
{
|
|
489
631
|
"name": "moonpay_buy",
|
|
@@ -528,7 +670,20 @@ var TOOL_DEFINITIONS = [
|
|
|
528
670
|
{
|
|
529
671
|
"name": "rhythm_trade_list",
|
|
530
672
|
"description": "Get whale trades from Rhythm discover",
|
|
531
|
-
"options": [
|
|
673
|
+
"options": [
|
|
674
|
+
{
|
|
675
|
+
"name": "limit",
|
|
676
|
+
"type": "number",
|
|
677
|
+
"description": "Number of results per page",
|
|
678
|
+
"required": true
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
"name": "page",
|
|
682
|
+
"type": "number",
|
|
683
|
+
"description": "The page number of results",
|
|
684
|
+
"required": true
|
|
685
|
+
}
|
|
686
|
+
]
|
|
532
687
|
},
|
|
533
688
|
{
|
|
534
689
|
"name": "token_balance_list",
|
|
@@ -544,7 +699,15 @@ var TOOL_DEFINITIONS = [
|
|
|
544
699
|
"name": "chain",
|
|
545
700
|
"type": "string",
|
|
546
701
|
"description": "Blockchain to check balances on (e.g. 'solana', 'ethereum', 'base')",
|
|
547
|
-
"required": true
|
|
702
|
+
"required": true,
|
|
703
|
+
"choices": [
|
|
704
|
+
"solana",
|
|
705
|
+
"ethereum",
|
|
706
|
+
"base",
|
|
707
|
+
"polygon",
|
|
708
|
+
"arbitrum",
|
|
709
|
+
"optimism"
|
|
710
|
+
]
|
|
548
711
|
}
|
|
549
712
|
]
|
|
550
713
|
},
|
|
@@ -568,14 +731,41 @@ var TOOL_DEFINITIONS = [
|
|
|
568
731
|
"name": "chain",
|
|
569
732
|
"type": "string",
|
|
570
733
|
"description": "Blockchain where the token and wallet exist",
|
|
571
|
-
"required": true
|
|
734
|
+
"required": true,
|
|
735
|
+
"choices": [
|
|
736
|
+
"solana",
|
|
737
|
+
"ethereum",
|
|
738
|
+
"base",
|
|
739
|
+
"polygon",
|
|
740
|
+
"arbitrum",
|
|
741
|
+
"optimism"
|
|
742
|
+
]
|
|
572
743
|
}
|
|
573
744
|
]
|
|
574
745
|
},
|
|
575
746
|
{
|
|
576
747
|
"name": "token_buy",
|
|
577
748
|
"description": "Swap the specified amount of USDC for a token.",
|
|
578
|
-
"options": [
|
|
749
|
+
"options": [
|
|
750
|
+
{
|
|
751
|
+
"name": "simulation",
|
|
752
|
+
"type": "boolean",
|
|
753
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
754
|
+
"required": true
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"name": "token",
|
|
758
|
+
"type": "string",
|
|
759
|
+
"description": "The address of the token to buy",
|
|
760
|
+
"required": true
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
"name": "amount",
|
|
764
|
+
"type": "number",
|
|
765
|
+
"description": "Amount of USDC to spend to buy the token",
|
|
766
|
+
"required": true
|
|
767
|
+
}
|
|
768
|
+
]
|
|
579
769
|
},
|
|
580
770
|
{
|
|
581
771
|
"name": "token_digest_retrieve",
|
|
@@ -591,14 +781,47 @@ var TOOL_DEFINITIONS = [
|
|
|
591
781
|
"name": "chain",
|
|
592
782
|
"type": "string",
|
|
593
783
|
"description": "Blockchain network where the token exists",
|
|
594
|
-
"required": true
|
|
784
|
+
"required": true,
|
|
785
|
+
"choices": [
|
|
786
|
+
"solana",
|
|
787
|
+
"ethereum",
|
|
788
|
+
"base",
|
|
789
|
+
"polygon",
|
|
790
|
+
"arbitrum",
|
|
791
|
+
"optimism"
|
|
792
|
+
]
|
|
595
793
|
}
|
|
596
794
|
]
|
|
597
795
|
},
|
|
598
796
|
{
|
|
599
797
|
"name": "token_limit_buy",
|
|
600
798
|
"description": "Create a limit buy order to swap USDC for a token at a specific price.",
|
|
601
|
-
"options": [
|
|
799
|
+
"options": [
|
|
800
|
+
{
|
|
801
|
+
"name": "simulation",
|
|
802
|
+
"type": "boolean",
|
|
803
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
804
|
+
"required": true
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
"name": "token",
|
|
808
|
+
"type": "string",
|
|
809
|
+
"description": "The address of the token to buy",
|
|
810
|
+
"required": true
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
"name": "amount",
|
|
814
|
+
"type": "number",
|
|
815
|
+
"description": "Amount of USDC to spend to buy the token",
|
|
816
|
+
"required": true
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
"name": "price",
|
|
820
|
+
"type": "number",
|
|
821
|
+
"description": "Price in dollars (USDC) to buy the token",
|
|
822
|
+
"required": true
|
|
823
|
+
}
|
|
824
|
+
]
|
|
602
825
|
},
|
|
603
826
|
{
|
|
604
827
|
"name": "token_limit_buy_recommend",
|
|
@@ -632,7 +855,32 @@ var TOOL_DEFINITIONS = [
|
|
|
632
855
|
{
|
|
633
856
|
"name": "token_limit_sell",
|
|
634
857
|
"description": "Create a limit sell order to swap a token for USDC at a specific price.",
|
|
635
|
-
"options": [
|
|
858
|
+
"options": [
|
|
859
|
+
{
|
|
860
|
+
"name": "simulation",
|
|
861
|
+
"type": "boolean",
|
|
862
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
863
|
+
"required": true
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
"name": "token",
|
|
867
|
+
"type": "string",
|
|
868
|
+
"description": "The address of the token to sell",
|
|
869
|
+
"required": true
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
"name": "amount",
|
|
873
|
+
"type": "number",
|
|
874
|
+
"description": "Amount of the token to sell",
|
|
875
|
+
"required": true
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"name": "price",
|
|
879
|
+
"type": "number",
|
|
880
|
+
"description": "Price in dollars (USDC) to sell the token",
|
|
881
|
+
"required": true
|
|
882
|
+
}
|
|
883
|
+
]
|
|
636
884
|
},
|
|
637
885
|
{
|
|
638
886
|
"name": "token_limit_sell_recommend",
|
|
@@ -649,7 +897,44 @@ var TOOL_DEFINITIONS = [
|
|
|
649
897
|
{
|
|
650
898
|
"name": "token_recurring_buy",
|
|
651
899
|
"description": "Create a recurring buy order (DCA) to swap USDC for a token at regular intervals.",
|
|
652
|
-
"options": [
|
|
900
|
+
"options": [
|
|
901
|
+
{
|
|
902
|
+
"name": "simulation",
|
|
903
|
+
"type": "boolean",
|
|
904
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
905
|
+
"required": true
|
|
906
|
+
},
|
|
907
|
+
{
|
|
908
|
+
"name": "token",
|
|
909
|
+
"type": "string",
|
|
910
|
+
"description": "The address of the token to buy",
|
|
911
|
+
"required": true
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"name": "amount",
|
|
915
|
+
"type": "number",
|
|
916
|
+
"description": "Amount of USDC used to buy the token per order",
|
|
917
|
+
"required": true
|
|
918
|
+
},
|
|
919
|
+
{
|
|
920
|
+
"name": "interval",
|
|
921
|
+
"type": "string",
|
|
922
|
+
"description": "Time interval between orders",
|
|
923
|
+
"required": true,
|
|
924
|
+
"choices": [
|
|
925
|
+
"hour",
|
|
926
|
+
"day",
|
|
927
|
+
"week",
|
|
928
|
+
"month"
|
|
929
|
+
]
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
"name": "numberOfOrders",
|
|
933
|
+
"type": "number",
|
|
934
|
+
"description": "Number of buy orders",
|
|
935
|
+
"required": true
|
|
936
|
+
}
|
|
937
|
+
]
|
|
653
938
|
},
|
|
654
939
|
{
|
|
655
940
|
"name": "token_recurring_order_list",
|
|
@@ -671,7 +956,44 @@ var TOOL_DEFINITIONS = [
|
|
|
671
956
|
{
|
|
672
957
|
"name": "token_recurring_sell",
|
|
673
958
|
"description": "Create a recurring sell order (DCA) to swap a token for USDC at regular intervals.",
|
|
674
|
-
"options": [
|
|
959
|
+
"options": [
|
|
960
|
+
{
|
|
961
|
+
"name": "simulation",
|
|
962
|
+
"type": "boolean",
|
|
963
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
964
|
+
"required": true
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
"name": "token",
|
|
968
|
+
"type": "string",
|
|
969
|
+
"description": "The address of the token to sell",
|
|
970
|
+
"required": true
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
"name": "amount",
|
|
974
|
+
"type": "number",
|
|
975
|
+
"description": "Amount of the token to sell per order",
|
|
976
|
+
"required": true
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
"name": "interval",
|
|
980
|
+
"type": "string",
|
|
981
|
+
"description": "Time interval between orders",
|
|
982
|
+
"required": true,
|
|
983
|
+
"choices": [
|
|
984
|
+
"hour",
|
|
985
|
+
"day",
|
|
986
|
+
"week",
|
|
987
|
+
"month"
|
|
988
|
+
]
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
"name": "numberOfOrders",
|
|
992
|
+
"type": "number",
|
|
993
|
+
"description": "Number of recurring orders to create",
|
|
994
|
+
"required": true
|
|
995
|
+
}
|
|
996
|
+
]
|
|
675
997
|
},
|
|
676
998
|
{
|
|
677
999
|
"name": "token_retrieve",
|
|
@@ -687,7 +1009,15 @@ var TOOL_DEFINITIONS = [
|
|
|
687
1009
|
"name": "chain",
|
|
688
1010
|
"type": "string",
|
|
689
1011
|
"description": "Blockchain network where the token exists",
|
|
690
|
-
"required": true
|
|
1012
|
+
"required": true,
|
|
1013
|
+
"choices": [
|
|
1014
|
+
"solana",
|
|
1015
|
+
"ethereum",
|
|
1016
|
+
"base",
|
|
1017
|
+
"polygon",
|
|
1018
|
+
"arbitrum",
|
|
1019
|
+
"optimism"
|
|
1020
|
+
]
|
|
691
1021
|
}
|
|
692
1022
|
]
|
|
693
1023
|
},
|
|
@@ -705,25 +1035,77 @@ var TOOL_DEFINITIONS = [
|
|
|
705
1035
|
"name": "chain",
|
|
706
1036
|
"type": "string",
|
|
707
1037
|
"description": "Blockchain to search on (e.g. 'solana', 'ethereum', 'base')",
|
|
708
|
-
"required": true
|
|
1038
|
+
"required": true,
|
|
1039
|
+
"choices": [
|
|
1040
|
+
"solana",
|
|
1041
|
+
"ethereum",
|
|
1042
|
+
"base",
|
|
1043
|
+
"polygon",
|
|
1044
|
+
"arbitrum",
|
|
1045
|
+
"optimism"
|
|
1046
|
+
]
|
|
709
1047
|
},
|
|
710
1048
|
{
|
|
711
1049
|
"name": "limit",
|
|
712
|
-
"type": "
|
|
1050
|
+
"type": "string",
|
|
713
1051
|
"description": "Maximum number of results to return (optional, defaults to 5)",
|
|
714
|
-
"required":
|
|
1052
|
+
"required": true
|
|
715
1053
|
}
|
|
716
1054
|
]
|
|
717
1055
|
},
|
|
718
1056
|
{
|
|
719
1057
|
"name": "token_sell",
|
|
720
1058
|
"description": "Swap the specified amount of tokens for USDC.",
|
|
721
|
-
"options": [
|
|
1059
|
+
"options": [
|
|
1060
|
+
{
|
|
1061
|
+
"name": "simulation",
|
|
1062
|
+
"type": "boolean",
|
|
1063
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
1064
|
+
"required": true
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
"name": "token",
|
|
1068
|
+
"type": "string",
|
|
1069
|
+
"description": "The address of the token to sell",
|
|
1070
|
+
"required": true
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
"name": "amount",
|
|
1074
|
+
"type": "number",
|
|
1075
|
+
"description": "Amount of token to sell",
|
|
1076
|
+
"required": true
|
|
1077
|
+
}
|
|
1078
|
+
]
|
|
722
1079
|
},
|
|
723
1080
|
{
|
|
724
1081
|
"name": "token_swap",
|
|
725
1082
|
"description": "Swap the specified amount of input token for output token.",
|
|
726
|
-
"options": [
|
|
1083
|
+
"options": [
|
|
1084
|
+
{
|
|
1085
|
+
"name": "simulation",
|
|
1086
|
+
"type": "boolean",
|
|
1087
|
+
"description": "If true, only simulate the transaction without executing it",
|
|
1088
|
+
"required": true
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"name": "input",
|
|
1092
|
+
"type": "string",
|
|
1093
|
+
"description": "The address of the input token to swap",
|
|
1094
|
+
"required": true
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
"name": "output",
|
|
1098
|
+
"type": "string",
|
|
1099
|
+
"description": "The address of the output token to receive",
|
|
1100
|
+
"required": true
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"name": "amount",
|
|
1104
|
+
"type": "number",
|
|
1105
|
+
"description": "The amount of the input token to swap",
|
|
1106
|
+
"required": true
|
|
1107
|
+
}
|
|
1108
|
+
]
|
|
727
1109
|
},
|
|
728
1110
|
{
|
|
729
1111
|
"name": "token_swap_recommend",
|
|
@@ -740,7 +1122,55 @@ var TOOL_DEFINITIONS = [
|
|
|
740
1122
|
{
|
|
741
1123
|
"name": "token_trending_list",
|
|
742
1124
|
"description": "Get currently trending tokens on a blockchain, sorted by popularity rank, trading volume, or liquidity. Perfect for discovering what's hot right now.",
|
|
743
|
-
"options": [
|
|
1125
|
+
"options": [
|
|
1126
|
+
{
|
|
1127
|
+
"name": "chain",
|
|
1128
|
+
"type": "string",
|
|
1129
|
+
"description": "Blockchain to get trending tokens from (e.g. 'solana', 'ethereum', 'base')",
|
|
1130
|
+
"required": true,
|
|
1131
|
+
"choices": [
|
|
1132
|
+
"solana",
|
|
1133
|
+
"ethereum",
|
|
1134
|
+
"base",
|
|
1135
|
+
"polygon",
|
|
1136
|
+
"arbitrum",
|
|
1137
|
+
"optimism"
|
|
1138
|
+
]
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
"name": "sort",
|
|
1142
|
+
"type": "string",
|
|
1143
|
+
"description": "How to sort results: 'rank' for trending score, 'volume' for highest 24h trading volume, 'liquidity' for most liquid tokens",
|
|
1144
|
+
"required": true,
|
|
1145
|
+
"choices": [
|
|
1146
|
+
"rank",
|
|
1147
|
+
"volume",
|
|
1148
|
+
"liquidity"
|
|
1149
|
+
]
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
"name": "order",
|
|
1153
|
+
"type": "string",
|
|
1154
|
+
"description": "Sort direction: 'asc' for ascending, 'desc' for descending",
|
|
1155
|
+
"required": true,
|
|
1156
|
+
"choices": [
|
|
1157
|
+
"asc",
|
|
1158
|
+
"desc"
|
|
1159
|
+
]
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
"name": "limit",
|
|
1163
|
+
"type": "number",
|
|
1164
|
+
"description": "Number of results per page",
|
|
1165
|
+
"required": true
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
"name": "page",
|
|
1169
|
+
"type": "number",
|
|
1170
|
+
"description": "The page number of results",
|
|
1171
|
+
"required": true
|
|
1172
|
+
}
|
|
1173
|
+
]
|
|
744
1174
|
},
|
|
745
1175
|
{
|
|
746
1176
|
"name": "user_retrieve",
|
|
@@ -761,19 +1191,19 @@ var TOOL_DEFINITIONS = [
|
|
|
761
1191
|
"name": "firstName",
|
|
762
1192
|
"type": "string",
|
|
763
1193
|
"description": "The user's first name, or null to clear it",
|
|
764
|
-
"required":
|
|
1194
|
+
"required": true
|
|
765
1195
|
},
|
|
766
1196
|
{
|
|
767
1197
|
"name": "lastName",
|
|
768
1198
|
"type": "string",
|
|
769
1199
|
"description": "The user's last name, or null to clear it",
|
|
770
|
-
"required":
|
|
1200
|
+
"required": true
|
|
771
1201
|
},
|
|
772
1202
|
{
|
|
773
1203
|
"name": "username",
|
|
774
1204
|
"type": "string",
|
|
775
1205
|
"description": "The user's username (3-20 lowercase letters, numbers, and underscores, must start with a letter), or null to clear it",
|
|
776
|
-
"required":
|
|
1206
|
+
"required": true
|
|
777
1207
|
}
|
|
778
1208
|
]
|
|
779
1209
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/auth.ts","../src/generated/client.ts","../src/client.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, Option } from \"commander\";\nimport {\n clearCredentials,\n getConfig,\n getConfigOrDefault,\n getCredentials,\n getValidToken,\n login,\n refreshCredentials,\n} from \"./auth\";\nimport { callToolWithAuth, TOOL_NAMES } from \"./client\";\nimport {\n TOOL_DEFINITIONS,\n type ToolDefinition,\n type ToolOption,\n} from \"./generated/client\";\n\nconst DEFAULT_BASE_URL = \"https://moon-iq.com\";\n\nconst program = new Command();\n\nprogram.name(\"mooniq\").description(\"Moon IQ CLI\").version(\"0.2.1\");\n\nprogram\n .command(\"login\")\n .description(\"Log in to Moon IQ via OAuth\")\n .option(\n \"-b, --base-url <url>\",\n \"Base URL (default: https://moon-iq.com or from ~/.config/moon-iq/config.json)\",\n )\n .action(async (options) => {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const config = getConfigOrDefault(baseUrl);\n\n try {\n await login({ ...config, baseUrl });\n console.log(\"Logged in successfully.\");\n } catch (error) {\n console.error(\"Login failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"logout\")\n .description(\"Log out and clear stored credentials\")\n .action(() => {\n clearCredentials();\n console.log(\"Logged out.\");\n });\n\nprogram\n .command(\"whoami\")\n .description(\"Show current user info\")\n .action(async () => {\n let token = await getValidToken();\n if (!token) {\n console.error(\"Not logged in. Run `mooniq login` first.\");\n process.exit(1);\n }\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl =\n config?.baseUrl ?? creds?.baseUrl ?? DEFAULT_BASE_URL;\n\n let res = await fetch(`${baseUrl}/api/oauth/userinfo`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (res.status === 401 && creds?.refreshToken && config && config.baseUrl === creds.baseUrl) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n res = await fetch(`${baseUrl}/api/oauth/userinfo`, {\n headers: { Authorization: `Bearer ${newCreds.accessToken}` },\n });\n } catch {\n // Refresh failed, fall through\n }\n }\n\n if (!res.ok) {\n console.error(\"Failed to fetch user info:\", res.status);\n process.exit(1);\n }\n\n const userinfo = await res.json();\n console.log(JSON.stringify(userinfo, null, 2));\n });\n\nprogram\n .command(\"run <tool_name>\")\n .description(\"Run a tool by name. Use --input for JSON params.\")\n .option(\n \"-i, --input <json>\",\n \"Input parameters as JSON (omit for empty params)\",\n )\n .option(\n \"-b, --base-url <url>\",\n \"Base URL (default: from credentials or https://moon-iq.com)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n mooniq run user_retrieve # no params\n mooniq run token_search --input '{\"query\":\"SOL\",\"chain\":\"solana\"}' # with params\n`,\n )\n .action(async (toolName: string, options) => {\n const toolNames = TOOL_NAMES as readonly string[];\n if (!toolNames.includes(toolName)) {\n console.error(`Unknown tool: ${toolName}`);\n console.error(`Available tools: ${toolNames.slice(0, 10).join(\", \")}...`);\n process.exit(1);\n }\n\n let params: Record<string, unknown> = {};\n if (options.input) {\n try {\n params = JSON.parse(options.input);\n } catch {\n console.error(\"Invalid JSON in --input\");\n process.exit(1);\n }\n }\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl =\n options.baseUrl ?? config?.baseUrl ?? creds?.baseUrl ?? DEFAULT_BASE_URL;\n\n try {\n const result = await callToolWithAuth(baseUrl, toolName, params);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(\"Tool call failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"tools\")\n .description(\"List available tools\")\n .action(() => {\n TOOL_NAMES.forEach((name) => console.log(name));\n });\n\n/**\n * Build hierarchical subcommands from tool definitions.\n * e.g., token_balance_list -> mooniq token balance list --wallet <wallet> --chain <chain>\n */\nfunction buildToolCommands(program: Command): void {\n // Build a tree structure from tool names\n type CommandNode = {\n children: Map<string, CommandNode>;\n tool?: ToolDefinition;\n };\n\n const root: CommandNode = { children: new Map() };\n\n // Build the tree\n for (const tool of TOOL_DEFINITIONS) {\n const parts = tool.name.split(\"_\");\n let current = root;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n if (!current.children.has(part)) {\n current.children.set(part, { children: new Map() });\n }\n current = current.children.get(part)!;\n\n // If this is the last part, attach the tool\n if (i === parts.length - 1) {\n current.tool = tool;\n }\n }\n }\n\n // Recursively create Commander commands\n function createCommands(node: CommandNode, parent: Command, path: string[]) {\n for (const [name, child] of node.children) {\n const currentPath = [...path, name];\n\n if (child.tool) {\n // This is a leaf node with a tool\n const cmd = parent\n .command(name)\n .description(child.tool.description || `Run ${child.tool.name}`);\n\n // Add options from the tool schema\n for (const opt of child.tool.options) {\n const optionFlag = createOptionFlag(opt);\n const option = new Option(optionFlag, opt.description);\n\n if (opt.choices) {\n option.choices(opt.choices);\n }\n\n if (opt.required) {\n cmd.addOption(option);\n } else {\n cmd.addOption(option);\n }\n }\n\n // Add base-url option\n cmd.option(\n \"-b, --base-url <url>\",\n \"Base URL (default: from credentials or https://moon-iq.com)\",\n );\n\n // Add action handler\n const toolName = child.tool.name;\n cmd.action(async (options) => {\n const params = buildParams(child.tool!.options, options);\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl =\n options.baseUrl ??\n config?.baseUrl ??\n creds?.baseUrl ??\n DEFAULT_BASE_URL;\n\n try {\n const result = await callToolWithAuth(baseUrl, toolName, params);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(\"Tool call failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n // If there are more children, recurse\n if (child.children.size > 0) {\n createCommands(child, cmd, currentPath);\n }\n } else if (child.children.size > 0) {\n // This is an intermediate node\n const cmd = parent\n .command(name)\n .description(`${name} commands`);\n\n createCommands(child, cmd, currentPath);\n }\n }\n }\n\n createCommands(root, program, []);\n}\n\n/**\n * Create an option flag string for Commander\n */\nfunction createOptionFlag(opt: ToolOption): string {\n const kebabName = opt.name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n\n if (opt.type === \"boolean\") {\n return `--${kebabName}`;\n }\n\n const valuePlaceholder = `<${opt.name}>`;\n return `--${kebabName} ${valuePlaceholder}`;\n}\n\n/**\n * Build params object from options\n */\nfunction buildParams(\n toolOptions: ToolOption[],\n cmdOptions: Record<string, unknown>,\n): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n for (const opt of toolOptions) {\n // Convert kebab-case back to camelCase for lookup\n const kebabName = opt.name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n const camelName = kebabName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n\n // Commander converts --some-option to someOption\n const value = cmdOptions[camelName] ?? cmdOptions[opt.name];\n\n if (value !== undefined) {\n // Convert types as needed\n if (opt.type === \"number\" && typeof value === \"string\") {\n params[opt.name] = parseFloat(value);\n } else if (opt.type === \"boolean\") {\n params[opt.name] = value === true || value === \"true\";\n } else {\n params[opt.name] = value;\n }\n } else if (!opt.required) {\n // Set null for optional params that weren't provided\n params[opt.name] = null;\n }\n }\n\n return params;\n}\n\n// Build all tool commands\nbuildToolCommands(program);\n\nprogram.parse();\n","import { execSync } from \"child_process\";\nimport * as crypto from \"crypto\";\nimport * as fs from \"fs\";\nimport * as http from \"http\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString(\"base64url\");\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), \".config\", \"moon-iq\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\nconst CREDENTIALS_PATH = path.join(CONFIG_DIR, \"credentials.json\");\nconst CALLBACK_PORT = 3847;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\n\n/** Built-in config used when no ~/.config/moon-iq/config.json exists. */\nexport const DEFAULT_CONFIG: Config = {\n baseUrl: \"https://moon-iq.com\",\n clientId: \"mooniq_zin3s5jz3olzkdfxpmbeaogv\",\n};\n\nexport type Config = {\n baseUrl: string;\n clientId: string;\n clientSecret?: string;\n};\n\nexport type Credentials = {\n accessToken: string;\n refreshToken: string | null;\n expiresAt: number;\n baseUrl: string;\n};\n\nfunction ensureConfigDir() {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/** Returns config from file, or null if missing/invalid. Use getConfigOrDefault() for login flow. */\nexport function getConfig(): Config | null {\n if (!fs.existsSync(CONFIG_PATH)) {\n return null;\n }\n try {\n const data = JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\"));\n if (!data.baseUrl || !data.clientId) {\n return null;\n }\n return data as Config;\n } catch {\n return null;\n }\n}\n\n/** Returns config from file, or DEFAULT_CONFIG if none exists. Creates config file on first use. */\nexport function getConfigOrDefault(baseUrl?: string): Config {\n const fromFile = getConfig();\n if (fromFile) return fromFile;\n\n const config: Config = {\n ...DEFAULT_CONFIG,\n baseUrl: baseUrl ?? DEFAULT_CONFIG.baseUrl,\n };\n saveConfig(config);\n return config;\n}\n\nexport function getCredentials(): Credentials | null {\n if (!fs.existsSync(CREDENTIALS_PATH)) {\n return null;\n }\n try {\n const data = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, \"utf-8\"));\n if (!data.accessToken || !data.baseUrl) {\n return null;\n }\n return data as Credentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(creds: Credentials) {\n ensureConfigDir();\n fs.writeFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), \"utf-8\");\n}\n\nexport function saveConfig(config: Config) {\n ensureConfigDir();\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nexport function clearCredentials() {\n if (fs.existsSync(CREDENTIALS_PATH)) {\n fs.unlinkSync(CREDENTIALS_PATH);\n }\n}\n\nfunction openBrowser(url: string) {\n const platform = process.platform;\n const command =\n platform === \"darwin\"\n ? `open \"${url}\"`\n : platform === \"win32\"\n ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`;\n execSync(command);\n}\n\nexport async function login(config: Config): Promise<Credentials> {\n const state = crypto.randomUUID();\n const usePkce = !config.clientSecret;\n\n let codeVerifier: string | undefined;\n if (usePkce) {\n codeVerifier = generateCodeVerifier();\n }\n\n let resolveCallback: (code: string) => void;\n const codePromise = new Promise<string>((resolve) => {\n resolveCallback = resolve;\n });\n\n const sockets = new Set<import(\"net\").Socket>();\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", `http://localhost:${CALLBACK_PORT}`);\n if (url.pathname === \"/callback\") {\n const code = url.searchParams.get(\"code\");\n const error = url.searchParams.get(\"error\");\n const errorDesc = url.searchParams.get(\"error_description\");\n\n if (error) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>OAuth Error</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#fef2f2\"><h1 style=\"color:#b91c1c;margin:0 0 1rem\">OAuth Error</h1><p style=\"color:#991b1b;margin:0\">${error}: ${errorDesc ?? \"Unknown error\"}</p></body></html>`,\n );\n resolveCallback(\"\");\n setTimeout(() => server.close(), 2000);\n } else if (code) {\n // Serve success page inline - don't redirect to app (it may not be running)\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Success</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#f0fdf4\"><h1 style=\"color:#166534;margin:0 0 1rem;font-size:1.5rem\">✓ Success!</h1><p style=\"color:#15803d;margin:0;font-size:1.1rem\">You can close this page and return to the terminal.</p></body></html>`,\n );\n resolveCallback(code);\n } else {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Error</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#fef2f2\"><h1 style=\"color:#b91c1c;margin:0 0 1rem\">Error</h1><p style=\"color:#991b1b;margin:0\">No authorization code received.</p></body></html>`,\n );\n resolveCallback(\"\");\n setTimeout(() => server.close(), 2000);\n }\n } else {\n // Favicon etc - serve minimal response to avoid \"site can't be reached\"\n res.writeHead(204);\n res.end();\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n reject(\n new Error(\n `Port ${CALLBACK_PORT} is in use. Close the other process or run: lsof -i :${CALLBACK_PORT}`,\n ),\n );\n } else {\n reject(err);\n }\n });\n // Track all connections so we can destroy them and allow the process to exit\n server.on(\"connection\", (socket) => {\n sockets.add(socket);\n socket.on(\"close\", () => sockets.delete(socket));\n });\n // Bind to all interfaces so both 127.0.0.1 and ::1 (localhost) can connect\n server.listen(CALLBACK_PORT, \"0.0.0.0\", () => resolve());\n });\n\n console.log(\n `Waiting for callback at http://localhost:${CALLBACK_PORT}/callback`,\n );\n\n const authorizeParams = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: CALLBACK_URL,\n response_type: \"code\",\n scope: \"profile email\",\n state,\n });\n if (usePkce && codeVerifier) {\n authorizeParams.set(\"code_challenge\", generateCodeChallenge(codeVerifier));\n authorizeParams.set(\"code_challenge_method\", \"S256\");\n }\n\n const authorizeUrl = `${config.baseUrl}/api/oauth/authorize?${authorizeParams.toString()}`;\n console.log(\"Opening browser for authorization...\");\n console.log(\"(Make sure you're logged in to Moon IQ in your browser)\\n\");\n openBrowser(authorizeUrl);\n\n const code = await codePromise;\n if (!code) {\n throw new Error(\"No authorization code received\");\n }\n\n const tokenParams: Record<string, string> = {\n grant_type: \"authorization_code\",\n code,\n client_id: config.clientId,\n redirect_uri: CALLBACK_URL,\n };\n if (config.clientSecret) {\n tokenParams.client_secret = config.clientSecret;\n }\n if (usePkce && codeVerifier) {\n tokenParams.code_verifier = codeVerifier;\n }\n\n const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(tokenParams),\n });\n\n if (!tokenResponse.ok) {\n const err = (await tokenResponse.json().catch(() => ({}))) as {\n error?: string;\n error_description?: string;\n };\n const msg = err.error_description ?? err.error ?? tokenResponse.statusText;\n throw new Error(`Token exchange failed: ${msg}`);\n }\n\n const tokens = await tokenResponse.json();\n const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1000;\n\n const creds: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? null,\n expiresAt,\n baseUrl: config.baseUrl,\n };\n\n saveCredentials(creds);\n\n // Close callback server and all connections so the process can exit (no hang after \"Logged in successfully.\")\n server.close();\n for (const socket of sockets) {\n if (\"destroy\" in socket && typeof (socket as { destroy: () => void }).destroy === \"function\") {\n (socket as { destroy: () => void }).destroy();\n }\n }\n sockets.clear();\n\n return creds;\n}\n\nexport async function refreshCredentials(\n creds: Credentials,\n config: Config,\n): Promise<Credentials> {\n if (!creds.refreshToken) {\n throw new Error(\"No refresh token available\");\n }\n\n const refreshParams: Record<string, string> = {\n grant_type: \"refresh_token\",\n refresh_token: creds.refreshToken,\n client_id: config.clientId,\n };\n if (config.clientSecret) {\n refreshParams.client_secret = config.clientSecret;\n }\n\n const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(refreshParams),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(\"Token refresh failed\");\n }\n\n const tokens = await tokenResponse.json();\n const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1000;\n\n const newCreds: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? creds.refreshToken,\n expiresAt,\n baseUrl: config.baseUrl,\n };\n\n saveCredentials(newCreds);\n return newCreds;\n}\n\nconst TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minutes\n\nexport async function getValidToken(): Promise<string | null> {\n const creds = getCredentials();\n if (!creds) return null;\n\n const config = getConfig();\n if (!config || config.baseUrl !== creds.baseUrl) return null;\n\n if (Date.now() >= creds.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n if (creds.refreshToken) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n return newCreds.accessToken;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n return creds.accessToken;\n}\n","// Generated by scripts/generate-cli-client.ts - do not edit\nexport const TOOL_NAMES = [\n \"iron_account_create\",\n \"iron_account_retrieve\",\n \"iron_offramp_create\",\n \"iron_offramp_initiate\",\n \"iron_offramp_list\",\n \"iron_offramp_retrieve\",\n \"iron_onramp_create\",\n \"iron_onramp_list\",\n \"iron_onramp_retrieve\",\n \"lending_account_retrieve\",\n \"lending_deposit\",\n \"lending_rate_retrieve\",\n \"lending_recommend\",\n \"lending_withdraw\",\n \"moonit_buy\",\n \"moonit_buy_recommend\",\n \"moonit_sell\",\n \"moonit_sell_recommend\",\n \"moonit_token_list\",\n \"moonpay_buy\",\n \"rhythm_token_list\",\n \"rhythm_token_trending_list\",\n \"rhythm_trade_list\",\n \"token_balance_list\",\n \"token_balance_retrieve\",\n \"token_buy\",\n \"token_digest_retrieve\",\n \"token_limit_buy\",\n \"token_limit_buy_recommend\",\n \"token_limit_order_list\",\n \"token_limit_recommend\",\n \"token_limit_sell\",\n \"token_limit_sell_recommend\",\n \"token_recurring_buy\",\n \"token_recurring_order_list\",\n \"token_recurring_recommend\",\n \"token_recurring_sell\",\n \"token_retrieve\",\n \"token_search\",\n \"token_sell\",\n \"token_swap\",\n \"token_swap_recommend\",\n \"token_trending_list\",\n \"user_retrieve\",\n \"user_update\"\n] as const;\n\nexport type ToolOption = {\n name: string;\n type: \"string\" | \"number\" | \"boolean\";\n description: string;\n required: boolean;\n choices?: string[];\n};\n\nexport type ToolDefinition = {\n name: string;\n description: string;\n options: ToolOption[];\n};\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n \"name\": \"iron_account_create\",\n \"description\": \"Create a new Iron account for the user.\",\n \"options\": []\n },\n {\n \"name\": \"iron_account_retrieve\",\n \"description\": \"Get the user's Iron account information.\",\n \"options\": []\n },\n {\n \"name\": \"iron_offramp_create\",\n \"description\": \"Create a new offramp for the user to convert crypto to fiat\",\n \"options\": [\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"description\": \"The name of the offramp\",\n \"required\": true\n },\n {\n \"name\": \"fiat\",\n \"type\": \"string\",\n \"description\": \"The fiat currency to convert to\",\n \"required\": true\n },\n {\n \"name\": \"stablecoin\",\n \"type\": \"string\",\n \"description\": \"The stablecoin token to convert from\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_offramp_initiate\",\n \"description\": \"Initiate an offramp by sending stablecoin to the offramp's deposit account. The stablecoin will be converted to fiat and deposited into your registered bank account. This process is asynchronous and may take some time for funds to appear in your bank account.\",\n \"options\": []\n },\n {\n \"name\": \"iron_offramp_list\",\n \"description\": \"Get all offramps for the user\",\n \"options\": []\n },\n {\n \"name\": \"iron_offramp_retrieve\",\n \"description\": \"Get an offramp for the user\",\n \"options\": [\n {\n \"name\": \"offrampId\",\n \"type\": \"string\",\n \"description\": \"The ID of the offramp to retrieve\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_onramp_create\",\n \"description\": \"Create an onramp to convert fiat currency to a stablecoin\",\n \"options\": [\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"description\": \"The name of the onramp\",\n \"required\": true\n },\n {\n \"name\": \"fiat\",\n \"type\": \"string\",\n \"description\": \"The fiat currency to convert from\",\n \"required\": true\n },\n {\n \"name\": \"stablecoin\",\n \"type\": \"string\",\n \"description\": \"The stablecoin token to convert to\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_onramp_list\",\n \"description\": \"Get all onramps for the user\",\n \"options\": [\n {\n \"name\": \"status\",\n \"type\": \"string\",\n \"description\": \"Status of the onramps to get\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_onramp_retrieve\",\n \"description\": \"Get an onramp for the user\",\n \"options\": [\n {\n \"name\": \"onrampId\",\n \"type\": \"string\",\n \"description\": \"The ID of the onramp to retrieve\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"lending_account_retrieve\",\n \"description\": \"Get account details for a lending account by wallet address, including balances, interest earned, and withdrawal limits\",\n \"options\": []\n },\n {\n \"name\": \"lending_deposit\",\n \"description\": \"Deposit USDC into your lending account to earn interest.\",\n \"options\": []\n },\n {\n \"name\": \"lending_rate_retrieve\",\n \"description\": \"Get current and historical interest rates for lending USDC\",\n \"options\": []\n },\n {\n \"name\": \"lending_recommend\",\n \"description\": \"Analyze user's lending account and wallet balances to recommend either a deposit or withdraw action with appropriate parameters. Understands queries like 'should I deposit more?', 'recommend a withdrawal', or 'what should I do with my lending account?'.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language query about lending recommendations. Examples: 'should I deposit more?', 'recommend a withdrawal', 'what should I do with my lending account?'.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"lending_withdraw\",\n \"description\": \"Withdraw USDC from your lending account.\",\n \"options\": []\n },\n {\n \"name\": \"moonit_buy\",\n \"description\": \"Buy tokens on Moonit platform using bonding curve. This tool converts USDC to SOL, then uses the SOL as collateral to buy Moonit tokens. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.\",\n \"options\": []\n },\n {\n \"name\": \"moonit_buy_recommend\",\n \"description\": \"Parse natural language queries into structured buy parameters for Moonit on Solana. Understands queries like 'buy 100 USDC worth of Moonit token', 'buy $50 worth of token ABC', or 'buy all my USDC worth of Moonit token XYZ'. Returns the recommended buy parameters ready to use with moonit_buy.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired buy transaction on Moonit. Examples: 'buy 100 USDC worth of Moonit token', 'buy $50 worth of token ABC', 'buy all my USDC worth of Moonit token XYZ'. The agent will parse token and amount from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_sell\",\n \"description\": \"Sell tokens on Moonit platform using bonding curve. This tool sells Moonit tokens to get SOL, then converts SOL to USDC. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.\",\n \"options\": []\n },\n {\n \"name\": \"moonit_sell_recommend\",\n \"description\": \"Parse natural language queries into structured sell parameters for Moonit on Solana. Understands queries like 'sell 100 SANTAMOON tokens', 'sell all my Moonit tokens', or 'sell 50% of my token ABC'. Returns the recommended sell parameters ready to use with moonit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired sell transaction on Moonit. Examples: 'sell 100 SANTAMOON tokens', 'sell all my Moonit tokens', 'sell 50% of my token ABC'. The agent will parse token and amount from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_token_list\",\n \"description\": \"Get the most popular Moonit tokens sorted by market capitalization. Moonit is a token launch platform by DEX Screener x Helio offering bonding curve mechanics, daily LP rewards, and graduation to Raydium/Meteora DEXs.\",\n \"options\": []\n },\n {\n \"name\": \"moonpay_buy\",\n \"description\": \"Buy a token using Moonpay. Specify either from.amount (USD to spend) or to.amount (tokens to buy), not both.\",\n \"options\": [\n {\n \"name\": \"from\",\n \"type\": \"string\",\n \"description\": \"Payment currency and amount to spend\",\n \"required\": true\n },\n {\n \"name\": \"to\",\n \"type\": \"string\",\n \"description\": \"Destination chain, currency, and token amount\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"rhythm_token_list\",\n \"description\": \"List tokens from Rhythm\",\n \"options\": []\n },\n {\n \"name\": \"rhythm_token_trending_list\",\n \"description\": \"Get trending tokens from Rhythm\",\n \"options\": [\n {\n \"name\": \"type\",\n \"type\": \"string\",\n \"description\": \"Type of trending tokens to get\",\n \"required\": true,\n \"choices\": [\n \"holding_strong\",\n \"survivor\",\n \"legacies\"\n ]\n }\n ]\n },\n {\n \"name\": \"rhythm_trade_list\",\n \"description\": \"Get whale trades from Rhythm discover\",\n \"options\": []\n },\n {\n \"name\": \"token_balance_list\",\n \"description\": \"List all token balances held in a wallet, including amount owned, current value in USD, and token details. Shows the complete token portfolio.\",\n \"options\": [\n {\n \"name\": \"wallet\",\n \"type\": \"string\",\n \"description\": \"Wallet address to check token balances for\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain to check balances on (e.g. 'solana', 'ethereum', 'base')\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_balance_retrieve\",\n \"description\": \"Get the balance of a specific token in a wallet, including the amount owned, current USD value, and token price. Returns zero balance if token is not held.\",\n \"options\": [\n {\n \"name\": \"wallet\",\n \"type\": \"string\",\n \"description\": \"Wallet address to check the balance for\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Token address to check the balance of\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain where the token and wallet exist\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_buy\",\n \"description\": \"Swap the specified amount of USDC for a token.\",\n \"options\": []\n },\n {\n \"name\": \"token_digest_retrieve\",\n \"description\": \"Retrieve a token digest by token and chain.\",\n \"options\": [\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Token address\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain network where the token exists\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_buy\",\n \"description\": \"Create a limit buy order to swap USDC for a token at a specific price.\",\n \"options\": []\n },\n {\n \"name\": \"token_limit_buy_recommend\",\n \"description\": \"Parse natural language queries into structured limit buy parameters. Understands queries like 'buy BONK at $0.00001', 'limit buy 100 USDC worth of SOL when price reaches $150', or 'buy BONK at $0.00001 with 50 USDC'. Returns the recommended limit buy parameters ready to use with token_limit_buy.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit buy order. Examples: 'buy BONK at $0.00001', 'limit buy 100 USDC worth of SOL when price reaches $150', 'buy BONK at $0.00001 with 50 USDC'. The agent will parse token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_order_list\",\n \"description\": \"Get limit orders for the authenticated user.\",\n \"options\": []\n },\n {\n \"name\": \"token_limit_recommend\",\n \"description\": \"Parse natural language queries into structured limit order parameters (buy or sell). Understands queries like 'buy BONK at $0.00001', 'sell BONK at $0.00002', 'limit buy 100 USDC worth of SOL when price reaches $150', or 'sell all my BONK at $0.00002'. Automatically determines if the request is a buy or sell order and returns the appropriate parameters ready to use with token_limit_buy or token_limit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit order (buy or sell). Examples: 'buy BONK at $0.00001', 'sell BONK at $0.00002', 'limit buy 100 USDC worth of SOL when price reaches $150', 'sell all my BONK at $0.00002'. The agent will parse the order type (buy/sell), token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_sell\",\n \"description\": \"Create a limit sell order to swap a token for USDC at a specific price.\",\n \"options\": []\n },\n {\n \"name\": \"token_limit_sell_recommend\",\n \"description\": \"Parse natural language queries into structured limit sell parameters. Understands queries like 'sell BONK at $0.00002', 'limit sell 100 SOL when price reaches $200', or 'sell all my BONK at $0.00002'. Returns the recommended limit sell parameters ready to use with token_limit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit sell order. Examples: 'sell BONK at $0.00002', 'limit sell 100 SOL when price reaches $200', 'sell all my BONK at $0.00002'. The agent will parse token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_recurring_buy\",\n \"description\": \"Create a recurring buy order (DCA) to swap USDC for a token at regular intervals.\",\n \"options\": []\n },\n {\n \"name\": \"token_recurring_order_list\",\n \"description\": \"Get recurring orders.\",\n \"options\": []\n },\n {\n \"name\": \"token_recurring_recommend\",\n \"description\": \"Parse natural language queries into structured recurring order (DCA) parameters (buy or sell). Understands queries like 'buy BONK daily with 50 USDC for 10 days', 'sell BONK daily, 100 tokens per order for 10 days', 'DCA 100 USDC into SOL weekly for a month', or 'recurring sell SOL every day, 0.5 SOL, 20 orders'. Automatically determines if the request is a buy or sell order and returns the appropriate parameters ready to use with token_recurring_buy or token_recurring_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired recurring order (buy or sell). Examples: 'buy BONK daily with 50 USDC for 10 days', 'sell BONK daily, 100 tokens per order for 10 days', 'DCA 100 USDC into SOL weekly for a month', 'recurring sell SOL every day, 0.5 SOL, 20 orders'. The agent will parse the order type (buy/sell), token, amount, interval, and numberOfOrders from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_recurring_sell\",\n \"description\": \"Create a recurring sell order (DCA) to swap a token for USDC at regular intervals.\",\n \"options\": []\n },\n {\n \"name\": \"token_retrieve\",\n \"description\": \"Get detailed token information including market data, price changes, volume, trades, and holder statistics by token address\",\n \"options\": [\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Address of the token to retrieve\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain network where the token exists\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_search\",\n \"description\": \"Search for tokens by name, symbol, or address. Returns matching tokens with their market data including price, volume, and liquidity.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Search term - can be token name (e.g. 'Bitcoin'), symbol (e.g. 'BTC'), or partial match\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain to search on (e.g. 'solana', 'ethereum', 'base')\",\n \"required\": true\n },\n {\n \"name\": \"limit\",\n \"type\": \"number\",\n \"description\": \"Maximum number of results to return (optional, defaults to 5)\",\n \"required\": false\n }\n ]\n },\n {\n \"name\": \"token_sell\",\n \"description\": \"Swap the specified amount of tokens for USDC.\",\n \"options\": []\n },\n {\n \"name\": \"token_swap\",\n \"description\": \"Swap the specified amount of input token for output token.\",\n \"options\": []\n },\n {\n \"name\": \"token_swap_recommend\",\n \"description\": \"Parse natural language queries into structured swap parameters for swapping tokens on Solana. Understands queries like 'swap 100 USDC for SOL', 'swap all my USDC for BONK', or '50 SOL to USDC'. Returns the recommended swap parameters ready to use with token_swap.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired swap on Solana. Examples: 'swap 100 USDC for SOL', 'swap all my USDC for BONK', '50 SOL to USDC', 'convert my SOL to USDC'. The agent will parse tokens and amounts from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_trending_list\",\n \"description\": \"Get currently trending tokens on a blockchain, sorted by popularity rank, trading volume, or liquidity. Perfect for discovering what's hot right now.\",\n \"options\": []\n },\n {\n \"name\": \"user_retrieve\",\n \"description\": \"Retrieve the currently authenticated user from the session context.\",\n \"options\": []\n },\n {\n \"name\": \"user_update\",\n \"description\": \"Update user fields in the database. This is a PUT-style update requiring all updatable fields (developer, firstName, lastName, username) to be sent. You must first call user_retrieve to get the current user state, then update with all four fields.\",\n \"options\": [\n {\n \"name\": \"developer\",\n \"type\": \"boolean\",\n \"description\": \"Whether the user is a developer\",\n \"required\": true\n },\n {\n \"name\": \"firstName\",\n \"type\": \"string\",\n \"description\": \"The user's first name, or null to clear it\",\n \"required\": false\n },\n {\n \"name\": \"lastName\",\n \"type\": \"string\",\n \"description\": \"The user's last name, or null to clear it\",\n \"required\": false\n },\n {\n \"name\": \"username\",\n \"type\": \"string\",\n \"description\": \"The user's username (3-20 lowercase letters, numbers, and underscores, must start with a letter), or null to clear it\",\n \"required\": false\n }\n ]\n }\n];\n\nexport async function callTool(\n baseUrl: string,\n token: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<unknown> {\n const res = await fetch(`${baseUrl}/api/tools/${toolName}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(params),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n throw new Error(data.error ?? \"Tool call failed\");\n }\n\n return data;\n}\n","import {\n getConfig,\n getCredentials,\n getValidToken,\n refreshCredentials,\n} from \"./auth\";\nimport { TOOL_NAMES } from \"./generated/client\";\n\nexport { TOOL_NAMES } from \"./generated/client\";\n\nasync function callToolWithToken(\n baseUrl: string,\n token: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<{ data: unknown; status: number }> {\n const res = await fetch(`${baseUrl}/api/tools/${toolName}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(params),\n });\n\n const data = await res.json();\n return { data, status: res.status };\n}\n\nexport async function callToolWithAuth(\n baseUrl: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<unknown> {\n let token = await getValidToken();\n if (!token) {\n throw new Error(\n \"Not logged in. Run `mooniq login` first and ensure ~/.config/moon-iq/config.json has baseUrl and clientId.\"\n );\n }\n\n let result = await callToolWithToken(baseUrl, token, toolName, params);\n\n if (result.status === 401) {\n const creds = getCredentials();\n const config = getConfig();\n if (creds?.refreshToken && config && config.baseUrl === creds.baseUrl) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n result = await callToolWithToken(\n baseUrl,\n newCreds.accessToken,\n toolName,\n params\n );\n } catch {\n // Refresh failed, fall through and throw the original 401\n }\n }\n }\n\n if (result.status < 200 || result.status >= 300) {\n const err = result.data as { error?: string };\n throw new Error(err?.error ?? \"Tool call failed\");\n }\n\n return result.data;\n}\n"],"mappings":"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","names":["code","program","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/auth.ts","../src/generated/client.ts","../src/client.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command, Option } from \"commander\";\nimport {\n clearCredentials,\n getConfig,\n getConfigOrDefault,\n getCredentials,\n getValidToken,\n login,\n refreshCredentials,\n} from \"./auth\";\nimport { callToolWithAuth, TOOL_NAMES } from \"./client\";\nimport {\n TOOL_DEFINITIONS,\n type ToolDefinition,\n type ToolOption,\n} from \"./generated/client\";\n\nconst DEFAULT_BASE_URL = \"https://moon-iq.com\";\n\nconst program = new Command();\n\nprogram.name(\"mooniq\").description(\"Moon IQ CLI\").version(\"0.2.1\");\n\nprogram\n .command(\"login\")\n .description(\"Log in to Moon IQ via OAuth\")\n .option(\n \"-b, --base-url <url>\",\n \"Base URL (default: https://moon-iq.com or from ~/.config/moon-iq/config.json)\",\n )\n .action(async (options) => {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const config = getConfigOrDefault(baseUrl);\n\n try {\n await login({ ...config, baseUrl });\n console.log(\"Logged in successfully.\");\n } catch (error) {\n console.error(\"Login failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"logout\")\n .description(\"Log out and clear stored credentials\")\n .action(() => {\n clearCredentials();\n console.log(\"Logged out.\");\n });\n\nprogram\n .command(\"whoami\")\n .description(\"Show current user info\")\n .action(async () => {\n let token = await getValidToken();\n if (!token) {\n console.error(\"Not logged in. Run `mooniq login` first.\");\n process.exit(1);\n }\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl = config?.baseUrl ?? creds?.baseUrl ?? DEFAULT_BASE_URL;\n\n let res = await fetch(`${baseUrl}/api/oauth/userinfo`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (\n res.status === 401 &&\n creds?.refreshToken &&\n config &&\n config.baseUrl === creds.baseUrl\n ) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n res = await fetch(`${baseUrl}/api/oauth/userinfo`, {\n headers: { Authorization: `Bearer ${newCreds.accessToken}` },\n });\n } catch {\n // Refresh failed, fall through\n }\n }\n\n if (!res.ok) {\n console.error(\"Failed to fetch user info:\", res.status);\n process.exit(1);\n }\n\n const userinfo = await res.json();\n console.log(JSON.stringify(userinfo, null, 2));\n });\n\nprogram\n .command(\"run <tool_name>\")\n .description(\"Run a tool by name. Use --input for JSON params.\")\n .option(\n \"-i, --input <json>\",\n \"Input parameters as JSON (omit for empty params)\",\n )\n .option(\n \"-b, --base-url <url>\",\n \"Base URL (default: from credentials or https://moon-iq.com)\",\n )\n .addHelpText(\n \"after\",\n `\nExamples:\n mooniq run user_retrieve # no params\n mooniq run token_search --input '{\"query\":\"SOL\",\"chain\":\"solana\"}' # with params\n`,\n )\n .action(async (toolName: string, options) => {\n const toolNames = TOOL_NAMES as readonly string[];\n if (!toolNames.includes(toolName)) {\n console.error(`Unknown tool: ${toolName}`);\n console.error(`Available tools: ${toolNames.slice(0, 10).join(\", \")}...`);\n process.exit(1);\n }\n\n let params: Record<string, unknown> = {};\n if (options.input) {\n try {\n params = JSON.parse(options.input);\n } catch {\n console.error(\"Invalid JSON in --input\");\n process.exit(1);\n }\n }\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl =\n options.baseUrl ?? config?.baseUrl ?? creds?.baseUrl ?? DEFAULT_BASE_URL;\n\n try {\n const result = await callToolWithAuth(baseUrl, toolName, params);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(\"Tool call failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"tools\")\n .description(\"List available tools\")\n .action(() => {\n TOOL_NAMES.forEach((name) => console.log(name));\n });\n\n/**\n * Build hierarchical subcommands from tool definitions.\n * e.g., token_balance_list -> mooniq token balance list --wallet <wallet> --chain <chain>\n */\nfunction buildToolCommands(program: Command): void {\n // Build a tree structure from tool names\n type CommandNode = {\n children: Map<string, CommandNode>;\n tool?: ToolDefinition;\n };\n\n const root: CommandNode = { children: new Map() };\n\n // Build the tree\n for (const tool of TOOL_DEFINITIONS) {\n const parts = tool.name.split(\"_\");\n let current = root;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n if (!current.children.has(part)) {\n current.children.set(part, { children: new Map() });\n }\n current = current.children.get(part)!;\n\n // If this is the last part, attach the tool\n if (i === parts.length - 1) {\n current.tool = tool;\n }\n }\n }\n\n // Recursively create Commander commands\n function createCommands(node: CommandNode, parent: Command, path: string[]) {\n for (const [name, child] of node.children) {\n const currentPath = [...path, name];\n\n if (child.tool) {\n // This is a leaf node with a tool\n const cmd = parent\n .command(name)\n .description(child.tool.description || `Run ${child.tool.name}`);\n\n // Add options from the tool schema\n for (const opt of child.tool.options) {\n const optionFlag = createOptionFlag(opt);\n const option = new Option(optionFlag, opt.description);\n\n if (opt.choices) {\n option.choices(opt.choices);\n }\n\n if (opt.required) {\n cmd.addOption(option);\n } else {\n cmd.addOption(option);\n }\n }\n\n // Add base-url option\n cmd.option(\n \"-b, --base-url <url>\",\n \"Base URL (default: from credentials or https://moon-iq.com)\",\n );\n\n // Add action handler\n const toolName = child.tool.name;\n cmd.action(async (options) => {\n const params = buildParams(child.tool!.options, options);\n\n const creds = getCredentials();\n const config = getConfig();\n const baseUrl =\n options.baseUrl ??\n config?.baseUrl ??\n creds?.baseUrl ??\n DEFAULT_BASE_URL;\n\n try {\n const result = await callToolWithAuth(baseUrl, toolName, params);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.error(\"Tool call failed:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n // If there are more children, recurse\n if (child.children.size > 0) {\n createCommands(child, cmd, currentPath);\n }\n } else if (child.children.size > 0) {\n // This is an intermediate node\n const cmd = parent.command(name).description(`${name} commands`);\n\n createCommands(child, cmd, currentPath);\n }\n }\n }\n\n createCommands(root, program, []);\n}\n\n/**\n * Create an option flag string for Commander\n */\nfunction createOptionFlag(opt: ToolOption): string {\n const kebabName = opt.name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n\n if (opt.type === \"boolean\") {\n return `--${kebabName}`;\n }\n\n const valuePlaceholder = `<${opt.name}>`;\n return `--${kebabName} ${valuePlaceholder}`;\n}\n\n/**\n * Build params object from options\n */\nfunction buildParams(\n toolOptions: ToolOption[],\n cmdOptions: Record<string, unknown>,\n): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n for (const opt of toolOptions) {\n // Convert kebab-case back to camelCase for lookup\n const kebabName = opt.name.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n const camelName = kebabName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n\n // Commander converts --some-option to someOption\n const value = cmdOptions[camelName] ?? cmdOptions[opt.name];\n\n if (value !== undefined) {\n // Convert types as needed\n if (opt.type === \"number\" && typeof value === \"string\") {\n params[opt.name] = parseFloat(value);\n } else if (opt.type === \"boolean\") {\n params[opt.name] = value === true || value === \"true\";\n } else {\n params[opt.name] = value;\n }\n } else if (!opt.required) {\n // Set null for optional params that weren't provided\n params[opt.name] = null;\n }\n }\n\n return params;\n}\n\n// Build all tool commands\nbuildToolCommands(program);\n\nprogram.parse();\n","import { execSync } from \"child_process\";\nimport * as crypto from \"crypto\";\nimport * as fs from \"fs\";\nimport * as http from \"http\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString(\"base64url\");\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), \".config\", \"moon-iq\");\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\nconst CREDENTIALS_PATH = path.join(CONFIG_DIR, \"credentials.json\");\nconst CALLBACK_PORT = 3847;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\n\n/** Built-in config used when no ~/.config/moon-iq/config.json exists. */\nexport const DEFAULT_CONFIG: Config = {\n baseUrl: \"https://moon-iq.com\",\n clientId: \"mooniq_zin3s5jz3olzkdfxpmbeaogv\",\n};\n\nexport type Config = {\n baseUrl: string;\n clientId: string;\n clientSecret?: string;\n};\n\nexport type Credentials = {\n accessToken: string;\n refreshToken: string | null;\n expiresAt: number;\n baseUrl: string;\n};\n\nfunction ensureConfigDir() {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n }\n}\n\n/** Returns config from file, or null if missing/invalid. Use getConfigOrDefault() for login flow. */\nexport function getConfig(): Config | null {\n if (!fs.existsSync(CONFIG_PATH)) {\n return null;\n }\n try {\n const data = JSON.parse(fs.readFileSync(CONFIG_PATH, \"utf-8\"));\n if (!data.baseUrl || !data.clientId) {\n return null;\n }\n return data as Config;\n } catch {\n return null;\n }\n}\n\n/** Returns config from file, or DEFAULT_CONFIG if none exists. Creates config file on first use. */\nexport function getConfigOrDefault(baseUrl?: string): Config {\n const fromFile = getConfig();\n if (fromFile) return fromFile;\n\n const config: Config = {\n ...DEFAULT_CONFIG,\n baseUrl: baseUrl ?? DEFAULT_CONFIG.baseUrl,\n };\n saveConfig(config);\n return config;\n}\n\nexport function getCredentials(): Credentials | null {\n if (!fs.existsSync(CREDENTIALS_PATH)) {\n return null;\n }\n try {\n const data = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, \"utf-8\"));\n if (!data.accessToken || !data.baseUrl) {\n return null;\n }\n return data as Credentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(creds: Credentials) {\n ensureConfigDir();\n fs.writeFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), \"utf-8\");\n}\n\nexport function saveConfig(config: Config) {\n ensureConfigDir();\n fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nexport function clearCredentials() {\n if (fs.existsSync(CREDENTIALS_PATH)) {\n fs.unlinkSync(CREDENTIALS_PATH);\n }\n}\n\nfunction openBrowser(url: string) {\n const platform = process.platform;\n const command =\n platform === \"darwin\"\n ? `open \"${url}\"`\n : platform === \"win32\"\n ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`;\n execSync(command);\n}\n\nexport async function login(config: Config): Promise<Credentials> {\n const state = crypto.randomUUID();\n const usePkce = !config.clientSecret;\n\n let codeVerifier: string | undefined;\n if (usePkce) {\n codeVerifier = generateCodeVerifier();\n }\n\n let resolveCallback: (code: string) => void;\n const codePromise = new Promise<string>((resolve) => {\n resolveCallback = resolve;\n });\n\n const sockets = new Set<import(\"net\").Socket>();\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", `http://localhost:${CALLBACK_PORT}`);\n if (url.pathname === \"/callback\") {\n const code = url.searchParams.get(\"code\");\n const error = url.searchParams.get(\"error\");\n const errorDesc = url.searchParams.get(\"error_description\");\n\n if (error) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>OAuth Error</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#fef2f2\"><h1 style=\"color:#b91c1c;margin:0 0 1rem\">OAuth Error</h1><p style=\"color:#991b1b;margin:0\">${error}: ${errorDesc ?? \"Unknown error\"}</p></body></html>`,\n );\n resolveCallback(\"\");\n setTimeout(() => server.close(), 2000);\n } else if (code) {\n // Serve success page inline - don't redirect to app (it may not be running)\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Success</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#f0fdf4\"><h1 style=\"color:#166534;margin:0 0 1rem;font-size:1.5rem\">✓ Success!</h1><p style=\"color:#15803d;margin:0;font-size:1.1rem\">You can close this page and return to the terminal.</p></body></html>`,\n );\n resolveCallback(code);\n } else {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Error</title></head><body style=\"font-family:system-ui,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100vh;margin:0;padding:2rem;text-align:center;background:#fef2f2\"><h1 style=\"color:#b91c1c;margin:0 0 1rem\">Error</h1><p style=\"color:#991b1b;margin:0\">No authorization code received.</p></body></html>`,\n );\n resolveCallback(\"\");\n setTimeout(() => server.close(), 2000);\n }\n } else {\n // Favicon etc - serve minimal response to avoid \"site can't be reached\"\n res.writeHead(204);\n res.end();\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n reject(\n new Error(\n `Port ${CALLBACK_PORT} is in use. Close the other process or run: lsof -i :${CALLBACK_PORT}`,\n ),\n );\n } else {\n reject(err);\n }\n });\n // Track all connections so we can destroy them and allow the process to exit\n server.on(\"connection\", (socket) => {\n sockets.add(socket);\n socket.on(\"close\", () => sockets.delete(socket));\n });\n // Bind to all interfaces so both 127.0.0.1 and ::1 (localhost) can connect\n server.listen(CALLBACK_PORT, \"0.0.0.0\", () => resolve());\n });\n\n console.log(\n `Waiting for callback at http://localhost:${CALLBACK_PORT}/callback`,\n );\n\n const authorizeParams = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: CALLBACK_URL,\n response_type: \"code\",\n scope: \"profile email\",\n state,\n });\n if (usePkce && codeVerifier) {\n authorizeParams.set(\"code_challenge\", generateCodeChallenge(codeVerifier));\n authorizeParams.set(\"code_challenge_method\", \"S256\");\n }\n\n const authorizeUrl = `${config.baseUrl}/api/oauth/authorize?${authorizeParams.toString()}`;\n console.log(\"Opening browser for authorization...\");\n console.log(\"(Make sure you're logged in to Moon IQ in your browser)\\n\");\n openBrowser(authorizeUrl);\n\n const code = await codePromise;\n if (!code) {\n throw new Error(\"No authorization code received\");\n }\n\n const tokenParams: Record<string, string> = {\n grant_type: \"authorization_code\",\n code,\n client_id: config.clientId,\n redirect_uri: CALLBACK_URL,\n };\n if (config.clientSecret) {\n tokenParams.client_secret = config.clientSecret;\n }\n if (usePkce && codeVerifier) {\n tokenParams.code_verifier = codeVerifier;\n }\n\n const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(tokenParams),\n });\n\n if (!tokenResponse.ok) {\n const err = (await tokenResponse.json().catch(() => ({}))) as {\n error?: string;\n error_description?: string;\n };\n const msg = err.error_description ?? err.error ?? tokenResponse.statusText;\n throw new Error(`Token exchange failed: ${msg}`);\n }\n\n const tokens = await tokenResponse.json();\n const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1000;\n\n const creds: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? null,\n expiresAt,\n baseUrl: config.baseUrl,\n };\n\n saveCredentials(creds);\n\n // Close callback server and all connections so the process can exit (no hang after \"Logged in successfully.\")\n server.close();\n for (const socket of sockets) {\n if (\"destroy\" in socket && typeof (socket as { destroy: () => void }).destroy === \"function\") {\n (socket as { destroy: () => void }).destroy();\n }\n }\n sockets.clear();\n\n return creds;\n}\n\nexport async function refreshCredentials(\n creds: Credentials,\n config: Config,\n): Promise<Credentials> {\n if (!creds.refreshToken) {\n throw new Error(\"No refresh token available\");\n }\n\n const refreshParams: Record<string, string> = {\n grant_type: \"refresh_token\",\n refresh_token: creds.refreshToken,\n client_id: config.clientId,\n };\n if (config.clientSecret) {\n refreshParams.client_secret = config.clientSecret;\n }\n\n const tokenResponse = await fetch(`${config.baseUrl}/api/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams(refreshParams),\n });\n\n if (!tokenResponse.ok) {\n throw new Error(\"Token refresh failed\");\n }\n\n const tokens = await tokenResponse.json();\n const expiresAt = Date.now() + (tokens.expires_in ?? 3600) * 1000;\n\n const newCreds: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? creds.refreshToken,\n expiresAt,\n baseUrl: config.baseUrl,\n };\n\n saveCredentials(newCreds);\n return newCreds;\n}\n\nconst TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minutes\n\nexport async function getValidToken(): Promise<string | null> {\n const creds = getCredentials();\n if (!creds) return null;\n\n const config = getConfig();\n if (!config || config.baseUrl !== creds.baseUrl) return null;\n\n if (Date.now() >= creds.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n if (creds.refreshToken) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n return newCreds.accessToken;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n return creds.accessToken;\n}\n","// Generated by scripts/generate-cli-client.ts - do not edit\nexport const TOOL_NAMES = [\n \"iron_account_create\",\n \"iron_account_retrieve\",\n \"iron_offramp_create\",\n \"iron_offramp_initiate\",\n \"iron_offramp_list\",\n \"iron_offramp_retrieve\",\n \"iron_onramp_create\",\n \"iron_onramp_list\",\n \"iron_onramp_retrieve\",\n \"lending_account_retrieve\",\n \"lending_deposit\",\n \"lending_rate_retrieve\",\n \"lending_recommend\",\n \"lending_withdraw\",\n \"moonit_buy\",\n \"moonit_buy_recommend\",\n \"moonit_sell\",\n \"moonit_sell_recommend\",\n \"moonit_token_list\",\n \"moonpay_buy\",\n \"rhythm_token_list\",\n \"rhythm_token_trending_list\",\n \"rhythm_trade_list\",\n \"token_balance_list\",\n \"token_balance_retrieve\",\n \"token_buy\",\n \"token_digest_retrieve\",\n \"token_limit_buy\",\n \"token_limit_buy_recommend\",\n \"token_limit_order_list\",\n \"token_limit_recommend\",\n \"token_limit_sell\",\n \"token_limit_sell_recommend\",\n \"token_recurring_buy\",\n \"token_recurring_order_list\",\n \"token_recurring_recommend\",\n \"token_recurring_sell\",\n \"token_retrieve\",\n \"token_search\",\n \"token_sell\",\n \"token_swap\",\n \"token_swap_recommend\",\n \"token_trending_list\",\n \"user_retrieve\",\n \"user_update\"\n] as const;\n\nexport type ToolOption = {\n name: string;\n type: \"string\" | \"number\" | \"boolean\";\n description: string;\n required: boolean;\n choices?: string[];\n};\n\nexport type ToolDefinition = {\n name: string;\n description: string;\n options: ToolOption[];\n};\n\nexport const TOOL_DEFINITIONS: ToolDefinition[] = [\n {\n \"name\": \"iron_account_create\",\n \"description\": \"Create a new Iron account for the user.\",\n \"options\": []\n },\n {\n \"name\": \"iron_account_retrieve\",\n \"description\": \"Get the user's Iron account information.\",\n \"options\": []\n },\n {\n \"name\": \"iron_offramp_create\",\n \"description\": \"Create a new offramp for the user to convert crypto to fiat\",\n \"options\": [\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"description\": \"The name of the offramp\",\n \"required\": true\n },\n {\n \"name\": \"fiat\",\n \"type\": \"string\",\n \"description\": \"The fiat currency to convert to\",\n \"required\": true,\n \"choices\": [\n \"USD\",\n \"EUR\"\n ]\n },\n {\n \"name\": \"stablecoin\",\n \"type\": \"string\",\n \"description\": \"The stablecoin token to convert from\",\n \"required\": true,\n \"choices\": [\n \"USDC\",\n \"USDT\",\n \"EURC\"\n ]\n }\n ]\n },\n {\n \"name\": \"iron_offramp_initiate\",\n \"description\": \"Initiate an offramp by sending stablecoin to the offramp's deposit account. The stablecoin will be converted to fiat and deposited into your registered bank account. This process is asynchronous and may take some time for funds to appear in your bank account.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"offrampId\",\n \"type\": \"string\",\n \"description\": \"The ID of the offramp to initiate\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"The amount of stablecoin to send (in human-readable units, e.g., 100.5)\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_offramp_list\",\n \"description\": \"Get all offramps for the user\",\n \"options\": []\n },\n {\n \"name\": \"iron_offramp_retrieve\",\n \"description\": \"Get an offramp for the user\",\n \"options\": [\n {\n \"name\": \"offrampId\",\n \"type\": \"string\",\n \"description\": \"The ID of the offramp to retrieve\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"iron_onramp_create\",\n \"description\": \"Create an onramp to convert fiat currency to a stablecoin\",\n \"options\": [\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"description\": \"The name of the onramp\",\n \"required\": true\n },\n {\n \"name\": \"fiat\",\n \"type\": \"string\",\n \"description\": \"The fiat currency to convert from\",\n \"required\": true,\n \"choices\": [\n \"USD\",\n \"EUR\"\n ]\n },\n {\n \"name\": \"stablecoin\",\n \"type\": \"string\",\n \"description\": \"The stablecoin token to convert to\",\n \"required\": true,\n \"choices\": [\n \"USDC\",\n \"USDT\",\n \"EURC\"\n ]\n }\n ]\n },\n {\n \"name\": \"iron_onramp_list\",\n \"description\": \"Get all onramps for the user\",\n \"options\": [\n {\n \"name\": \"status\",\n \"type\": \"string\",\n \"description\": \"Status of the onramps to get\",\n \"required\": true,\n \"choices\": [\n \"Created\",\n \"Authorized\",\n \"DepositAccountAdded\",\n \"Approved\",\n \"Rejected\",\n \"Cancelled\"\n ]\n }\n ]\n },\n {\n \"name\": \"iron_onramp_retrieve\",\n \"description\": \"Get an onramp for the user\",\n \"options\": [\n {\n \"name\": \"onrampId\",\n \"type\": \"string\",\n \"description\": \"The ID of the onramp to retrieve\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"lending_account_retrieve\",\n \"description\": \"Get account details for a lending account by wallet address, including balances, interest earned, and withdrawal limits\",\n \"options\": []\n },\n {\n \"name\": \"lending_deposit\",\n \"description\": \"Deposit USDC into your lending account to earn interest.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC to deposit\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"lending_rate_retrieve\",\n \"description\": \"Get current and historical interest rates for lending USDC\",\n \"options\": []\n },\n {\n \"name\": \"lending_recommend\",\n \"description\": \"Analyze user's lending account and wallet balances to recommend either a deposit or withdraw action with appropriate parameters. Understands queries like 'should I deposit more?', 'recommend a withdrawal', or 'what should I do with my lending account?'.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language query about lending recommendations. Examples: 'should I deposit more?', 'recommend a withdrawal', 'what should I do with my lending account?'.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"lending_withdraw\",\n \"description\": \"Withdraw USDC from your lending account.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC to withdraw\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_buy\",\n \"description\": \"Buy tokens on Moonit platform using bonding curve. This tool converts USDC to SOL, then uses the SOL as collateral to buy Moonit tokens. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Address of the token to buy on Moonit\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC used to buy the token\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_buy_recommend\",\n \"description\": \"Parse natural language queries into structured buy parameters for Moonit on Solana. Understands queries like 'buy 100 USDC worth of Moonit token', 'buy $50 worth of token ABC', or 'buy all my USDC worth of Moonit token XYZ'. Returns the recommended buy parameters ready to use with moonit_buy.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired buy transaction on Moonit. Examples: 'buy 100 USDC worth of Moonit token', 'buy $50 worth of token ABC', 'buy all my USDC worth of Moonit token XYZ'. The agent will parse token and amount from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_sell\",\n \"description\": \"Sell tokens on Moonit platform using bonding curve. This tool sells Moonit tokens to get SOL, then converts SOL to USDC. It builds, signs, and executes the transaction. Note: This tool requires SOL for transaction fees.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Address of the Moonit token to sell\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of Moonit tokens to sell\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_sell_recommend\",\n \"description\": \"Parse natural language queries into structured sell parameters for Moonit on Solana. Understands queries like 'sell 100 SANTAMOON tokens', 'sell all my Moonit tokens', or 'sell 50% of my token ABC'. Returns the recommended sell parameters ready to use with moonit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired sell transaction on Moonit. Examples: 'sell 100 SANTAMOON tokens', 'sell all my Moonit tokens', 'sell 50% of my token ABC'. The agent will parse token and amount from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonit_token_list\",\n \"description\": \"Get the most popular Moonit tokens sorted by market capitalization. Moonit is a token launch platform by DEX Screener x Helio offering bonding curve mechanics, daily LP rewards, and graduation to Raydium/Meteora DEXs.\",\n \"options\": [\n {\n \"name\": \"sort\",\n \"type\": \"string\",\n \"description\": \"Sort tokens by\",\n \"required\": true,\n \"choices\": [\n \"MARKET_CAP\",\n \"TRENDING\"\n ]\n },\n {\n \"name\": \"state\",\n \"type\": \"string\",\n \"description\": \"Filter tokens by state\",\n \"required\": true,\n \"choices\": [\n \"GRADUATED\",\n \"NOT_GRADUATED\"\n ]\n },\n {\n \"name\": \"limit\",\n \"type\": \"number\",\n \"description\": \"Number of results per page\",\n \"required\": true\n },\n {\n \"name\": \"page\",\n \"type\": \"number\",\n \"description\": \"The page number of results\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"moonpay_buy\",\n \"description\": \"Buy a token using Moonpay. Specify either from.amount (USD to spend) or to.amount (tokens to buy), not both.\",\n \"options\": [\n {\n \"name\": \"from\",\n \"type\": \"string\",\n \"description\": \"Payment currency and amount to spend\",\n \"required\": true\n },\n {\n \"name\": \"to\",\n \"type\": \"string\",\n \"description\": \"Destination chain, currency, and token amount\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"rhythm_token_list\",\n \"description\": \"List tokens from Rhythm\",\n \"options\": []\n },\n {\n \"name\": \"rhythm_token_trending_list\",\n \"description\": \"Get trending tokens from Rhythm\",\n \"options\": [\n {\n \"name\": \"type\",\n \"type\": \"string\",\n \"description\": \"Type of trending tokens to get\",\n \"required\": true,\n \"choices\": [\n \"holding_strong\",\n \"survivor\",\n \"legacies\"\n ]\n }\n ]\n },\n {\n \"name\": \"rhythm_trade_list\",\n \"description\": \"Get whale trades from Rhythm discover\",\n \"options\": [\n {\n \"name\": \"limit\",\n \"type\": \"number\",\n \"description\": \"Number of results per page\",\n \"required\": true\n },\n {\n \"name\": \"page\",\n \"type\": \"number\",\n \"description\": \"The page number of results\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_balance_list\",\n \"description\": \"List all token balances held in a wallet, including amount owned, current value in USD, and token details. Shows the complete token portfolio.\",\n \"options\": [\n {\n \"name\": \"wallet\",\n \"type\": \"string\",\n \"description\": \"Wallet address to check token balances for\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain to check balances on (e.g. 'solana', 'ethereum', 'base')\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n }\n ]\n },\n {\n \"name\": \"token_balance_retrieve\",\n \"description\": \"Get the balance of a specific token in a wallet, including the amount owned, current USD value, and token price. Returns zero balance if token is not held.\",\n \"options\": [\n {\n \"name\": \"wallet\",\n \"type\": \"string\",\n \"description\": \"Wallet address to check the balance for\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Token address to check the balance of\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain where the token and wallet exist\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n }\n ]\n },\n {\n \"name\": \"token_buy\",\n \"description\": \"Swap the specified amount of USDC for a token.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to buy\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC to spend to buy the token\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_digest_retrieve\",\n \"description\": \"Retrieve a token digest by token and chain.\",\n \"options\": [\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Token address\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain network where the token exists\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n }\n ]\n },\n {\n \"name\": \"token_limit_buy\",\n \"description\": \"Create a limit buy order to swap USDC for a token at a specific price.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to buy\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC to spend to buy the token\",\n \"required\": true\n },\n {\n \"name\": \"price\",\n \"type\": \"number\",\n \"description\": \"Price in dollars (USDC) to buy the token\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_buy_recommend\",\n \"description\": \"Parse natural language queries into structured limit buy parameters. Understands queries like 'buy BONK at $0.00001', 'limit buy 100 USDC worth of SOL when price reaches $150', or 'buy BONK at $0.00001 with 50 USDC'. Returns the recommended limit buy parameters ready to use with token_limit_buy.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit buy order. Examples: 'buy BONK at $0.00001', 'limit buy 100 USDC worth of SOL when price reaches $150', 'buy BONK at $0.00001 with 50 USDC'. The agent will parse token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_order_list\",\n \"description\": \"Get limit orders for the authenticated user.\",\n \"options\": []\n },\n {\n \"name\": \"token_limit_recommend\",\n \"description\": \"Parse natural language queries into structured limit order parameters (buy or sell). Understands queries like 'buy BONK at $0.00001', 'sell BONK at $0.00002', 'limit buy 100 USDC worth of SOL when price reaches $150', or 'sell all my BONK at $0.00002'. Automatically determines if the request is a buy or sell order and returns the appropriate parameters ready to use with token_limit_buy or token_limit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit order (buy or sell). Examples: 'buy BONK at $0.00001', 'sell BONK at $0.00002', 'limit buy 100 USDC worth of SOL when price reaches $150', 'sell all my BONK at $0.00002'. The agent will parse the order type (buy/sell), token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_sell\",\n \"description\": \"Create a limit sell order to swap a token for USDC at a specific price.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to sell\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of the token to sell\",\n \"required\": true\n },\n {\n \"name\": \"price\",\n \"type\": \"number\",\n \"description\": \"Price in dollars (USDC) to sell the token\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_limit_sell_recommend\",\n \"description\": \"Parse natural language queries into structured limit sell parameters. Understands queries like 'sell BONK at $0.00002', 'limit sell 100 SOL when price reaches $200', or 'sell all my BONK at $0.00002'. Returns the recommended limit sell parameters ready to use with token_limit_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired limit sell order. Examples: 'sell BONK at $0.00002', 'limit sell 100 SOL when price reaches $200', 'sell all my BONK at $0.00002'. The agent will parse token, amount, and price from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_recurring_buy\",\n \"description\": \"Create a recurring buy order (DCA) to swap USDC for a token at regular intervals.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to buy\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of USDC used to buy the token per order\",\n \"required\": true\n },\n {\n \"name\": \"interval\",\n \"type\": \"string\",\n \"description\": \"Time interval between orders\",\n \"required\": true,\n \"choices\": [\n \"hour\",\n \"day\",\n \"week\",\n \"month\"\n ]\n },\n {\n \"name\": \"numberOfOrders\",\n \"type\": \"number\",\n \"description\": \"Number of buy orders\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_recurring_order_list\",\n \"description\": \"Get recurring orders.\",\n \"options\": []\n },\n {\n \"name\": \"token_recurring_recommend\",\n \"description\": \"Parse natural language queries into structured recurring order (DCA) parameters (buy or sell). Understands queries like 'buy BONK daily with 50 USDC for 10 days', 'sell BONK daily, 100 tokens per order for 10 days', 'DCA 100 USDC into SOL weekly for a month', or 'recurring sell SOL every day, 0.5 SOL, 20 orders'. Automatically determines if the request is a buy or sell order and returns the appropriate parameters ready to use with token_recurring_buy or token_recurring_sell.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired recurring order (buy or sell). Examples: 'buy BONK daily with 50 USDC for 10 days', 'sell BONK daily, 100 tokens per order for 10 days', 'DCA 100 USDC into SOL weekly for a month', 'recurring sell SOL every day, 0.5 SOL, 20 orders'. The agent will parse the order type (buy/sell), token, amount, interval, and numberOfOrders from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_recurring_sell\",\n \"description\": \"Create a recurring sell order (DCA) to swap a token for USDC at regular intervals.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to sell\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of the token to sell per order\",\n \"required\": true\n },\n {\n \"name\": \"interval\",\n \"type\": \"string\",\n \"description\": \"Time interval between orders\",\n \"required\": true,\n \"choices\": [\n \"hour\",\n \"day\",\n \"week\",\n \"month\"\n ]\n },\n {\n \"name\": \"numberOfOrders\",\n \"type\": \"number\",\n \"description\": \"Number of recurring orders to create\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_retrieve\",\n \"description\": \"Get detailed token information including market data, price changes, volume, trades, and holder statistics by token address\",\n \"options\": [\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"Address of the token to retrieve\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain network where the token exists\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n }\n ]\n },\n {\n \"name\": \"token_search\",\n \"description\": \"Search for tokens by name, symbol, or address. Returns matching tokens with their market data including price, volume, and liquidity.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Search term - can be token name (e.g. 'Bitcoin'), symbol (e.g. 'BTC'), or partial match\",\n \"required\": true\n },\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain to search on (e.g. 'solana', 'ethereum', 'base')\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n },\n {\n \"name\": \"limit\",\n \"type\": \"string\",\n \"description\": \"Maximum number of results to return (optional, defaults to 5)\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_sell\",\n \"description\": \"Swap the specified amount of tokens for USDC.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"token\",\n \"type\": \"string\",\n \"description\": \"The address of the token to sell\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"Amount of token to sell\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_swap\",\n \"description\": \"Swap the specified amount of input token for output token.\",\n \"options\": [\n {\n \"name\": \"simulation\",\n \"type\": \"boolean\",\n \"description\": \"If true, only simulate the transaction without executing it\",\n \"required\": true\n },\n {\n \"name\": \"input\",\n \"type\": \"string\",\n \"description\": \"The address of the input token to swap\",\n \"required\": true\n },\n {\n \"name\": \"output\",\n \"type\": \"string\",\n \"description\": \"The address of the output token to receive\",\n \"required\": true\n },\n {\n \"name\": \"amount\",\n \"type\": \"number\",\n \"description\": \"The amount of the input token to swap\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_swap_recommend\",\n \"description\": \"Parse natural language queries into structured swap parameters for swapping tokens on Solana. Understands queries like 'swap 100 USDC for SOL', 'swap all my USDC for BONK', or '50 SOL to USDC'. Returns the recommended swap parameters ready to use with token_swap.\",\n \"options\": [\n {\n \"name\": \"query\",\n \"type\": \"string\",\n \"description\": \"Natural language description of the desired swap on Solana. Examples: 'swap 100 USDC for SOL', 'swap all my USDC for BONK', '50 SOL to USDC', 'convert my SOL to USDC'. The agent will parse tokens and amounts from this query.\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"token_trending_list\",\n \"description\": \"Get currently trending tokens on a blockchain, sorted by popularity rank, trading volume, or liquidity. Perfect for discovering what's hot right now.\",\n \"options\": [\n {\n \"name\": \"chain\",\n \"type\": \"string\",\n \"description\": \"Blockchain to get trending tokens from (e.g. 'solana', 'ethereum', 'base')\",\n \"required\": true,\n \"choices\": [\n \"solana\",\n \"ethereum\",\n \"base\",\n \"polygon\",\n \"arbitrum\",\n \"optimism\"\n ]\n },\n {\n \"name\": \"sort\",\n \"type\": \"string\",\n \"description\": \"How to sort results: 'rank' for trending score, 'volume' for highest 24h trading volume, 'liquidity' for most liquid tokens\",\n \"required\": true,\n \"choices\": [\n \"rank\",\n \"volume\",\n \"liquidity\"\n ]\n },\n {\n \"name\": \"order\",\n \"type\": \"string\",\n \"description\": \"Sort direction: 'asc' for ascending, 'desc' for descending\",\n \"required\": true,\n \"choices\": [\n \"asc\",\n \"desc\"\n ]\n },\n {\n \"name\": \"limit\",\n \"type\": \"number\",\n \"description\": \"Number of results per page\",\n \"required\": true\n },\n {\n \"name\": \"page\",\n \"type\": \"number\",\n \"description\": \"The page number of results\",\n \"required\": true\n }\n ]\n },\n {\n \"name\": \"user_retrieve\",\n \"description\": \"Retrieve the currently authenticated user from the session context.\",\n \"options\": []\n },\n {\n \"name\": \"user_update\",\n \"description\": \"Update user fields in the database. This is a PUT-style update requiring all updatable fields (developer, firstName, lastName, username) to be sent. You must first call user_retrieve to get the current user state, then update with all four fields.\",\n \"options\": [\n {\n \"name\": \"developer\",\n \"type\": \"boolean\",\n \"description\": \"Whether the user is a developer\",\n \"required\": true\n },\n {\n \"name\": \"firstName\",\n \"type\": \"string\",\n \"description\": \"The user's first name, or null to clear it\",\n \"required\": true\n },\n {\n \"name\": \"lastName\",\n \"type\": \"string\",\n \"description\": \"The user's last name, or null to clear it\",\n \"required\": true\n },\n {\n \"name\": \"username\",\n \"type\": \"string\",\n \"description\": \"The user's username (3-20 lowercase letters, numbers, and underscores, must start with a letter), or null to clear it\",\n \"required\": true\n }\n ]\n }\n];\n\nexport async function callTool(\n baseUrl: string,\n token: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<unknown> {\n const res = await fetch(`${baseUrl}/api/tools/${toolName}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(params),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n throw new Error(data.error ?? \"Tool call failed\");\n }\n\n return data;\n}\n","import {\n getConfig,\n getCredentials,\n getValidToken,\n refreshCredentials,\n} from \"./auth\";\nimport { TOOL_NAMES } from \"./generated/client\";\n\nexport { TOOL_NAMES } from \"./generated/client\";\n\nasync function callToolWithToken(\n baseUrl: string,\n token: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<{ data: unknown; status: number }> {\n const res = await fetch(`${baseUrl}/api/tools/${toolName}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(params),\n });\n\n const data = await res.json();\n return { data, status: res.status };\n}\n\nexport async function callToolWithAuth(\n baseUrl: string,\n toolName: string,\n params: Record<string, unknown>\n): Promise<unknown> {\n let token = await getValidToken();\n if (!token) {\n throw new Error(\n \"Not logged in. Run `mooniq login` first and ensure ~/.config/moon-iq/config.json has baseUrl and clientId.\"\n );\n }\n\n let result = await callToolWithToken(baseUrl, token, toolName, params);\n\n if (result.status === 401) {\n const creds = getCredentials();\n const config = getConfig();\n if (creds?.refreshToken && config && config.baseUrl === creds.baseUrl) {\n try {\n const newCreds = await refreshCredentials(creds, config);\n result = await callToolWithToken(\n baseUrl,\n newCreds.accessToken,\n toolName,\n params\n );\n } catch {\n // Refresh failed, fall through and throw the original 401\n }\n }\n }\n\n if (result.status < 200 || result.status >= 300) {\n const err = result.data as { error?: string };\n throw new Error(err?.error ?? \"Tool call failed\");\n }\n\n return result.data;\n}\n"],"mappings":";;;AACA,SAAS,SAAS,cAAc;;;ACDhC,SAAS,gBAAgB;AACzB,YAAY,YAAY;AACxB,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,YAAY,UAAU;AAEtB,SAAS,uBAA+B;AACtC,SAAc,mBAAY,EAAE,EAAE,SAAS,WAAW;AACpD;AAEA,SAAS,sBAAsB,UAA0B;AACvD,SAAc,kBAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,WAAW;AACxE;AAEA,IAAM,aAAkB,UAAQ,WAAQ,GAAG,WAAW,SAAS;AAC/D,IAAM,cAAmB,UAAK,YAAY,aAAa;AACvD,IAAM,mBAAwB,UAAK,YAAY,kBAAkB;AACjE,IAAM,gBAAgB;AACtB,IAAM,eAAe,oBAAoB,aAAa;AAG/C,IAAM,iBAAyB;AAAA,EACpC,SAAS;AAAA,EACT,UAAU;AACZ;AAeA,SAAS,kBAAkB;AACzB,MAAI,CAAI,cAAW,UAAU,GAAG;AAC9B,IAAG,aAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC9C;AACF;AAGO,SAAS,YAA2B;AACzC,MAAI,CAAI,cAAW,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,OAAO,KAAK,MAAS,gBAAa,aAAa,OAAO,CAAC;AAC7D,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,UAAU;AACnC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,mBAAmB,SAA0B;AAC3D,QAAM,WAAW,UAAU;AAC3B,MAAI,SAAU,QAAO;AAErB,QAAM,SAAiB;AAAA,IACrB,GAAG;AAAA,IACH,SAAS,WAAW,eAAe;AAAA,EACrC;AACA,aAAW,MAAM;AACjB,SAAO;AACT;AAEO,SAAS,iBAAqC;AACnD,MAAI,CAAI,cAAW,gBAAgB,GAAG;AACpC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,OAAO,KAAK,MAAS,gBAAa,kBAAkB,OAAO,CAAC;AAClE,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,SAAS;AACtC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,OAAoB;AAClD,kBAAgB;AAChB,EAAG,iBAAc,kBAAkB,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AAC5E;AAEO,SAAS,WAAW,QAAgB;AACzC,kBAAgB;AAChB,EAAG,iBAAc,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;AACxE;AAEO,SAAS,mBAAmB;AACjC,MAAO,cAAW,gBAAgB,GAAG;AACnC,IAAG,cAAW,gBAAgB;AAAA,EAChC;AACF;AAEA,SAAS,YAAY,KAAa;AAChC,QAAM,WAAW,QAAQ;AACzB,QAAM,UACJ,aAAa,WACT,SAAS,GAAG,MACZ,aAAa,UACX,aAAa,GAAG,MAChB,aAAa,GAAG;AACxB,WAAS,OAAO;AAClB;AAEA,eAAsB,MAAM,QAAsC;AAChE,QAAM,QAAe,kBAAW;AAChC,QAAM,UAAU,CAAC,OAAO;AAExB,MAAI;AACJ,MAAI,SAAS;AACX,mBAAe,qBAAqB;AAAA,EACtC;AAEA,MAAI;AACJ,QAAM,cAAc,IAAI,QAAgB,CAAC,YAAY;AACnD,sBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,UAAU,oBAAI,IAA0B;AAE9C,QAAM,SAAc,kBAAa,CAAC,KAAK,QAAQ;AAC7C,UAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,oBAAoB,aAAa,EAAE;AACvE,QAAI,IAAI,aAAa,aAAa;AAChC,YAAMA,QAAO,IAAI,aAAa,IAAI,MAAM;AACxC,YAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,YAAM,YAAY,IAAI,aAAa,IAAI,mBAAmB;AAE1D,UAAI,OAAO;AACT,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI;AAAA,UACF,yXAAyX,KAAK,KAAK,aAAa,eAAe;AAAA,QACja;AACA,wBAAgB,EAAE;AAClB,mBAAW,MAAM,OAAO,MAAM,GAAG,GAAI;AAAA,MACvC,WAAWA,OAAM;AAEf,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI;AAAA,UACF;AAAA,QACF;AACA,wBAAgBA,KAAI;AAAA,MACtB,OAAO;AACL,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI;AAAA,UACF;AAAA,QACF;AACA,wBAAgB,EAAE;AAClB,mBAAW,MAAM,OAAO,MAAM,GAAG,GAAI;AAAA,MACvC;AAAA,IACF,OAAO;AAEL,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI;AAAA,IACV;AAAA,EACF,CAAC;AAED,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAO,GAAG,SAAS,CAAC,QAA+B;AACjD,UAAI,IAAI,SAAS,cAAc;AAC7B;AAAA,UACE,IAAI;AAAA,YACF,QAAQ,aAAa,wDAAwD,aAAa;AAAA,UAC5F;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,CAAC;AAED,WAAO,GAAG,cAAc,CAAC,WAAW;AAClC,cAAQ,IAAI,MAAM;AAClB,aAAO,GAAG,SAAS,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,IACjD,CAAC;AAED,WAAO,OAAO,eAAe,WAAW,MAAM,QAAQ,CAAC;AAAA,EACzD,CAAC;AAED,UAAQ;AAAA,IACN,4CAA4C,aAAa;AAAA,EAC3D;AAEA,QAAM,kBAAkB,IAAI,gBAAgB;AAAA,IAC1C,WAAW,OAAO;AAAA,IAClB,cAAc;AAAA,IACd,eAAe;AAAA,IACf,OAAO;AAAA,IACP;AAAA,EACF,CAAC;AACD,MAAI,WAAW,cAAc;AAC3B,oBAAgB,IAAI,kBAAkB,sBAAsB,YAAY,CAAC;AACzE,oBAAgB,IAAI,yBAAyB,MAAM;AAAA,EACrD;AAEA,QAAM,eAAe,GAAG,OAAO,OAAO,wBAAwB,gBAAgB,SAAS,CAAC;AACxF,UAAQ,IAAI,sCAAsC;AAClD,UAAQ,IAAI,2DAA2D;AACvE,cAAY,YAAY;AAExB,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,QAAM,cAAsC;AAAA,IAC1C,YAAY;AAAA,IACZ;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,cAAc;AAAA,EAChB;AACA,MAAI,OAAO,cAAc;AACvB,gBAAY,gBAAgB,OAAO;AAAA,EACrC;AACA,MAAI,WAAW,cAAc;AAC3B,gBAAY,gBAAgB;AAAA,EAC9B;AAEA,QAAM,gBAAgB,MAAM,MAAM,GAAG,OAAO,OAAO,oBAAoB;AAAA,IACrE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,IAC/D,MAAM,IAAI,gBAAgB,WAAW;AAAA,EACvC,CAAC;AAED,MAAI,CAAC,cAAc,IAAI;AACrB,UAAM,MAAO,MAAM,cAAc,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAIxD,UAAM,MAAM,IAAI,qBAAqB,IAAI,SAAS,cAAc;AAChE,UAAM,IAAI,MAAM,0BAA0B,GAAG,EAAE;AAAA,EACjD;AAEA,QAAM,SAAS,MAAM,cAAc,KAAK;AACxC,QAAM,YAAY,KAAK,IAAI,KAAK,OAAO,cAAc,QAAQ;AAE7D,QAAM,QAAqB;AAAA,IACzB,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO,iBAAiB;AAAA,IACtC;AAAA,IACA,SAAS,OAAO;AAAA,EAClB;AAEA,kBAAgB,KAAK;AAGrB,SAAO,MAAM;AACb,aAAW,UAAU,SAAS;AAC5B,QAAI,aAAa,UAAU,OAAQ,OAAmC,YAAY,YAAY;AAC5F,MAAC,OAAmC,QAAQ;AAAA,IAC9C;AAAA,EACF;AACA,UAAQ,MAAM;AAEd,SAAO;AACT;AAEA,eAAsB,mBACpB,OACA,QACsB;AACtB,MAAI,CAAC,MAAM,cAAc;AACvB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,gBAAwC;AAAA,IAC5C,YAAY;AAAA,IACZ,eAAe,MAAM;AAAA,IACrB,WAAW,OAAO;AAAA,EACpB;AACA,MAAI,OAAO,cAAc;AACvB,kBAAc,gBAAgB,OAAO;AAAA,EACvC;AAEA,QAAM,gBAAgB,MAAM,MAAM,GAAG,OAAO,OAAO,oBAAoB;AAAA,IACrE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,IAC/D,MAAM,IAAI,gBAAgB,aAAa;AAAA,EACzC,CAAC;AAED,MAAI,CAAC,cAAc,IAAI;AACrB,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAEA,QAAM,SAAS,MAAM,cAAc,KAAK;AACxC,QAAM,YAAY,KAAK,IAAI,KAAK,OAAO,cAAc,QAAQ;AAE7D,QAAM,WAAwB;AAAA,IAC5B,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO,iBAAiB,MAAM;AAAA,IAC5C;AAAA,IACA,SAAS,OAAO;AAAA,EAClB;AAEA,kBAAgB,QAAQ;AACxB,SAAO;AACT;AAEA,IAAM,yBAAyB,IAAI,KAAK;AAExC,eAAsB,gBAAwC;AAC5D,QAAM,QAAQ,eAAe;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,UAAU,OAAO,YAAY,MAAM,QAAS,QAAO;AAExD,MAAI,KAAK,IAAI,KAAK,MAAM,YAAY,wBAAwB;AAC1D,QAAI,MAAM,cAAc;AACtB,UAAI;AACF,cAAM,WAAW,MAAM,mBAAmB,OAAO,MAAM;AACvD,eAAO,SAAS;AAAA,MAClB,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,MAAM;AACf;;;AC1UO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAgBO,IAAM,mBAAqC;AAAA,EAChD;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW,CAAC;AAAA,EACd;AAAA,EACA;AAAA,IACE,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,WAAW;AAAA,MACT;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;;;ACv7BA,eAAe,kBACb,SACA,OACA,UACA,QAC4C;AAC5C,QAAM,MAAM,MAAM,MAAM,GAAG,OAAO,cAAc,QAAQ,IAAI;AAAA,IAC1D,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK;AAAA,IAChC;AAAA,IACA,MAAM,KAAK,UAAU,MAAM;AAAA,EAC7B,CAAC;AAED,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,SAAO,EAAE,MAAM,QAAQ,IAAI,OAAO;AACpC;AAEA,eAAsB,iBACpB,SACA,UACA,QACkB;AAClB,MAAI,QAAQ,MAAM,cAAc;AAChC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,MAAM,kBAAkB,SAAS,OAAO,UAAU,MAAM;AAErE,MAAI,OAAO,WAAW,KAAK;AACzB,UAAM,QAAQ,eAAe;AAC7B,UAAM,SAAS,UAAU;AACzB,QAAI,OAAO,gBAAgB,UAAU,OAAO,YAAY,MAAM,SAAS;AACrE,UAAI;AACF,cAAM,WAAW,MAAM,mBAAmB,OAAO,MAAM;AACvD,iBAAS,MAAM;AAAA,UACb;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,OAAO,OAAO,UAAU,KAAK;AAC/C,UAAM,MAAM,OAAO;AACnB,UAAM,IAAI,MAAM,KAAK,SAAS,kBAAkB;AAAA,EAClD;AAEA,SAAO,OAAO;AAChB;;;AHjDA,IAAM,mBAAmB;AAEzB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QAAQ,KAAK,QAAQ,EAAE,YAAY,aAAa,EAAE,QAAQ,OAAO;AAEjE,QACG,QAAQ,OAAO,EACf,YAAY,6BAA6B,EACzC;AAAA,EACC;AAAA,EACA;AACF,EACC,OAAO,OAAO,YAAY;AACzB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,SAAS,mBAAmB,OAAO;AAEzC,MAAI;AACF,UAAM,MAAM,EAAE,GAAG,QAAQ,QAAQ,CAAC;AAClC,YAAQ,IAAI,yBAAyB;AAAA,EACvC,SAAS,OAAO;AACd,YAAQ,MAAM,iBAAkB,MAAgB,OAAO;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,sCAAsC,EAClD,OAAO,MAAM;AACZ,mBAAiB;AACjB,UAAQ,IAAI,aAAa;AAC3B,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,wBAAwB,EACpC,OAAO,YAAY;AAClB,MAAI,QAAQ,MAAM,cAAc;AAChC,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,0CAA0C;AACxD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,eAAe;AAC7B,QAAM,SAAS,UAAU;AACzB,QAAM,UAAU,QAAQ,WAAW,OAAO,WAAW;AAErD,MAAI,MAAM,MAAM,MAAM,GAAG,OAAO,uBAAuB;AAAA,IACrD,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,EAC9C,CAAC;AAED,MACE,IAAI,WAAW,OACf,OAAO,gBACP,UACA,OAAO,YAAY,MAAM,SACzB;AACA,QAAI;AACF,YAAM,WAAW,MAAM,mBAAmB,OAAO,MAAM;AACvD,YAAM,MAAM,MAAM,GAAG,OAAO,uBAAuB;AAAA,QACjD,SAAS,EAAE,eAAe,UAAU,SAAS,WAAW,GAAG;AAAA,MAC7D,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,YAAQ,MAAM,8BAA8B,IAAI,MAAM;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,MAAM,IAAI,KAAK;AAChC,UAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC/C,CAAC;AAEH,QACG,QAAQ,iBAAiB,EACzB,YAAY,kDAAkD,EAC9D;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAKF,EACC,OAAO,OAAO,UAAkB,YAAY;AAC3C,QAAM,YAAY;AAClB,MAAI,CAAC,UAAU,SAAS,QAAQ,GAAG;AACjC,YAAQ,MAAM,iBAAiB,QAAQ,EAAE;AACzC,YAAQ,MAAM,oBAAoB,UAAU,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,KAAK;AACxE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,SAAkC,CAAC;AACvC,MAAI,QAAQ,OAAO;AACjB,QAAI;AACF,eAAS,KAAK,MAAM,QAAQ,KAAK;AAAA,IACnC,QAAQ;AACN,cAAQ,MAAM,yBAAyB;AACvC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,QAAQ,eAAe;AAC7B,QAAM,SAAS,UAAU;AACzB,QAAM,UACJ,QAAQ,WAAW,QAAQ,WAAW,OAAO,WAAW;AAE1D,MAAI;AACF,UAAM,SAAS,MAAM,iBAAiB,SAAS,UAAU,MAAM;AAC/D,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,MAAM,qBAAsB,MAAgB,OAAO;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,sBAAsB,EAClC,OAAO,MAAM;AACZ,aAAW,QAAQ,CAAC,SAAS,QAAQ,IAAI,IAAI,CAAC;AAChD,CAAC;AAMH,SAAS,kBAAkBC,UAAwB;AAOjD,QAAM,OAAoB,EAAE,UAAU,oBAAI,IAAI,EAAE;AAGhD,aAAW,QAAQ,kBAAkB;AACnC,UAAM,QAAQ,KAAK,KAAK,MAAM,GAAG;AACjC,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,CAAC,QAAQ,SAAS,IAAI,IAAI,GAAG;AAC/B,gBAAQ,SAAS,IAAI,MAAM,EAAE,UAAU,oBAAI,IAAI,EAAE,CAAC;AAAA,MACpD;AACA,gBAAU,QAAQ,SAAS,IAAI,IAAI;AAGnC,UAAI,MAAM,MAAM,SAAS,GAAG;AAC1B,gBAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAGA,WAAS,eAAe,MAAmB,QAAiBC,OAAgB;AAC1E,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,UAAU;AACzC,YAAM,cAAc,CAAC,GAAGA,OAAM,IAAI;AAElC,UAAI,MAAM,MAAM;AAEd,cAAM,MAAM,OACT,QAAQ,IAAI,EACZ,YAAY,MAAM,KAAK,eAAe,OAAO,MAAM,KAAK,IAAI,EAAE;AAGjE,mBAAW,OAAO,MAAM,KAAK,SAAS;AACpC,gBAAM,aAAa,iBAAiB,GAAG;AACvC,gBAAM,SAAS,IAAI,OAAO,YAAY,IAAI,WAAW;AAErD,cAAI,IAAI,SAAS;AACf,mBAAO,QAAQ,IAAI,OAAO;AAAA,UAC5B;AAEA,cAAI,IAAI,UAAU;AAChB,gBAAI,UAAU,MAAM;AAAA,UACtB,OAAO;AACL,gBAAI,UAAU,MAAM;AAAA,UACtB;AAAA,QACF;AAGA,YAAI;AAAA,UACF;AAAA,UACA;AAAA,QACF;AAGA,cAAM,WAAW,MAAM,KAAK;AAC5B,YAAI,OAAO,OAAO,YAAY;AAC5B,gBAAM,SAAS,YAAY,MAAM,KAAM,SAAS,OAAO;AAEvD,gBAAM,QAAQ,eAAe;AAC7B,gBAAM,SAAS,UAAU;AACzB,gBAAM,UACJ,QAAQ,WACR,QAAQ,WACR,OAAO,WACP;AAEF,cAAI;AACF,kBAAM,SAAS,MAAM,iBAAiB,SAAS,UAAU,MAAM;AAC/D,oBAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,UAC7C,SAAS,OAAO;AACd,oBAAQ,MAAM,qBAAsB,MAAgB,OAAO;AAC3D,oBAAQ,KAAK,CAAC;AAAA,UAChB;AAAA,QACF,CAAC;AAGD,YAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,yBAAe,OAAO,KAAK,WAAW;AAAA,QACxC;AAAA,MACF,WAAW,MAAM,SAAS,OAAO,GAAG;AAElC,cAAM,MAAM,OAAO,QAAQ,IAAI,EAAE,YAAY,GAAG,IAAI,WAAW;AAE/D,uBAAe,OAAO,KAAK,WAAW;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,MAAMD,UAAS,CAAC,CAAC;AAClC;AAKA,SAAS,iBAAiB,KAAyB;AACjD,QAAM,YAAY,IAAI,KAAK,QAAQ,YAAY,KAAK,EAAE,YAAY;AAElE,MAAI,IAAI,SAAS,WAAW;AAC1B,WAAO,KAAK,SAAS;AAAA,EACvB;AAEA,QAAM,mBAAmB,IAAI,IAAI,IAAI;AACrC,SAAO,KAAK,SAAS,IAAI,gBAAgB;AAC3C;AAKA,SAAS,YACP,aACA,YACyB;AACzB,QAAM,SAAkC,CAAC;AAEzC,aAAW,OAAO,aAAa;AAE7B,UAAM,YAAY,IAAI,KAAK,QAAQ,YAAY,KAAK,EAAE,YAAY;AAClE,UAAM,YAAY,UAAU,QAAQ,aAAa,CAAC,GAAG,MAAM,EAAE,YAAY,CAAC;AAG1E,UAAM,QAAQ,WAAW,SAAS,KAAK,WAAW,IAAI,IAAI;AAE1D,QAAI,UAAU,QAAW;AAEvB,UAAI,IAAI,SAAS,YAAY,OAAO,UAAU,UAAU;AACtD,eAAO,IAAI,IAAI,IAAI,WAAW,KAAK;AAAA,MACrC,WAAW,IAAI,SAAS,WAAW;AACjC,eAAO,IAAI,IAAI,IAAI,UAAU,QAAQ,UAAU;AAAA,MACjD,OAAO;AACL,eAAO,IAAI,IAAI,IAAI;AAAA,MACrB;AAAA,IACF,WAAW,CAAC,IAAI,UAAU;AAExB,aAAO,IAAI,IAAI,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAGA,kBAAkB,OAAO;AAEzB,QAAQ,MAAM;","names":["code","program","path"]}
|