@robinmordasiewicz/f5xc-xcsh 2.0.21-2601091525 → 2.0.21-2601091916

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.
Files changed (2) hide show
  1. package/dist/index.js +3015 -1214
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -1372,7 +1372,7 @@ var require_react_development = __commonJS({
1372
1372
  }
1373
1373
  return dispatcher.useContext(Context);
1374
1374
  }
1375
- function useState9(initialState) {
1375
+ function useState11(initialState) {
1376
1376
  var dispatcher = resolveDispatcher();
1377
1377
  return dispatcher.useState(initialState);
1378
1378
  }
@@ -1380,11 +1380,11 @@ var require_react_development = __commonJS({
1380
1380
  var dispatcher = resolveDispatcher();
1381
1381
  return dispatcher.useReducer(reducer, initialArg, init);
1382
1382
  }
1383
- function useRef4(initialValue) {
1383
+ function useRef5(initialValue) {
1384
1384
  var dispatcher = resolveDispatcher();
1385
1385
  return dispatcher.useRef(initialValue);
1386
1386
  }
1387
- function useEffect7(create2, deps) {
1387
+ function useEffect9(create2, deps) {
1388
1388
  var dispatcher = resolveDispatcher();
1389
1389
  return dispatcher.useEffect(create2, deps);
1390
1390
  }
@@ -1396,7 +1396,7 @@ var require_react_development = __commonJS({
1396
1396
  var dispatcher = resolveDispatcher();
1397
1397
  return dispatcher.useLayoutEffect(create2, deps);
1398
1398
  }
1399
- function useCallback7(callback, deps) {
1399
+ function useCallback8(callback, deps) {
1400
1400
  var dispatcher = resolveDispatcher();
1401
1401
  return dispatcher.useCallback(callback, deps);
1402
1402
  }
@@ -2163,19 +2163,19 @@ var require_react_development = __commonJS({
2163
2163
  exports.memo = memo;
2164
2164
  exports.startTransition = startTransition;
2165
2165
  exports.unstable_act = act;
2166
- exports.useCallback = useCallback7;
2166
+ exports.useCallback = useCallback8;
2167
2167
  exports.useContext = useContext7;
2168
2168
  exports.useDebugValue = useDebugValue;
2169
2169
  exports.useDeferredValue = useDeferredValue;
2170
- exports.useEffect = useEffect7;
2170
+ exports.useEffect = useEffect9;
2171
2171
  exports.useId = useId;
2172
2172
  exports.useImperativeHandle = useImperativeHandle;
2173
2173
  exports.useInsertionEffect = useInsertionEffect;
2174
2174
  exports.useLayoutEffect = useLayoutEffect2;
2175
2175
  exports.useMemo = useMemo3;
2176
2176
  exports.useReducer = useReducer;
2177
- exports.useRef = useRef4;
2178
- exports.useState = useState9;
2177
+ exports.useRef = useRef5;
2178
+ exports.useState = useState11;
2179
2179
  exports.useSyncExternalStore = useSyncExternalStore;
2180
2180
  exports.useTransition = useTransition;
2181
2181
  exports.version = ReactVersion;
@@ -7870,9 +7870,9 @@ var require_react_reconciler_development = __commonJS({
7870
7870
  module.exports = function $$$reconciler($$$hostConfig) {
7871
7871
  var exports2 = {};
7872
7872
  "use strict";
7873
- var React14 = require_react();
7873
+ var React16 = require_react();
7874
7874
  var Scheduler = require_scheduler();
7875
- var ReactSharedInternals = React14.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
7875
+ var ReactSharedInternals = React16.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
7876
7876
  var suppressWarning = false;
7877
7877
  function setSuppressWarning(newSuppressWarning) {
7878
7878
  {
@@ -37515,7 +37515,7 @@ var require_react_jsx_runtime_development = __commonJS({
37515
37515
  if (process.env.NODE_ENV !== "production") {
37516
37516
  (function() {
37517
37517
  "use strict";
37518
- var React14 = require_react();
37518
+ var React16 = require_react();
37519
37519
  var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.element");
37520
37520
  var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
37521
37521
  var REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment");
@@ -37541,7 +37541,7 @@ var require_react_jsx_runtime_development = __commonJS({
37541
37541
  }
37542
37542
  return null;
37543
37543
  }
37544
- var ReactSharedInternals = React14.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
37544
+ var ReactSharedInternals = React16.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
37545
37545
  function error(format) {
37546
37546
  {
37547
37547
  {
@@ -38391,11 +38391,11 @@ var require_react_jsx_runtime_development = __commonJS({
38391
38391
  return jsxWithValidation(type, props, key, false);
38392
38392
  }
38393
38393
  }
38394
- var jsx6 = jsxWithValidationDynamic;
38395
- var jsxs5 = jsxWithValidationStatic;
38394
+ var jsx7 = jsxWithValidationDynamic;
38395
+ var jsxs6 = jsxWithValidationStatic;
38396
38396
  exports.Fragment = REACT_FRAGMENT_TYPE;
38397
- exports.jsx = jsx6;
38398
- exports.jsxs = jsxs5;
38397
+ exports.jsx = jsx7;
38398
+ exports.jsxs = jsxs6;
38399
38399
  })();
38400
38400
  }
38401
38401
  }
@@ -38413,6 +38413,1651 @@ var require_jsx_runtime = __commonJS({
38413
38413
  }
38414
38414
  });
38415
38415
 
38416
+ // node_modules/ink-spinner/node_modules/cli-spinners/spinners.json
38417
+ var require_spinners = __commonJS({
38418
+ "node_modules/ink-spinner/node_modules/cli-spinners/spinners.json"(exports, module) {
38419
+ module.exports = {
38420
+ dots: {
38421
+ interval: 80,
38422
+ frames: [
38423
+ "\u280B",
38424
+ "\u2819",
38425
+ "\u2839",
38426
+ "\u2838",
38427
+ "\u283C",
38428
+ "\u2834",
38429
+ "\u2826",
38430
+ "\u2827",
38431
+ "\u2807",
38432
+ "\u280F"
38433
+ ]
38434
+ },
38435
+ dots2: {
38436
+ interval: 80,
38437
+ frames: [
38438
+ "\u28FE",
38439
+ "\u28FD",
38440
+ "\u28FB",
38441
+ "\u28BF",
38442
+ "\u287F",
38443
+ "\u28DF",
38444
+ "\u28EF",
38445
+ "\u28F7"
38446
+ ]
38447
+ },
38448
+ dots3: {
38449
+ interval: 80,
38450
+ frames: [
38451
+ "\u280B",
38452
+ "\u2819",
38453
+ "\u281A",
38454
+ "\u281E",
38455
+ "\u2816",
38456
+ "\u2826",
38457
+ "\u2834",
38458
+ "\u2832",
38459
+ "\u2833",
38460
+ "\u2813"
38461
+ ]
38462
+ },
38463
+ dots4: {
38464
+ interval: 80,
38465
+ frames: [
38466
+ "\u2804",
38467
+ "\u2806",
38468
+ "\u2807",
38469
+ "\u280B",
38470
+ "\u2819",
38471
+ "\u2838",
38472
+ "\u2830",
38473
+ "\u2820",
38474
+ "\u2830",
38475
+ "\u2838",
38476
+ "\u2819",
38477
+ "\u280B",
38478
+ "\u2807",
38479
+ "\u2806"
38480
+ ]
38481
+ },
38482
+ dots5: {
38483
+ interval: 80,
38484
+ frames: [
38485
+ "\u280B",
38486
+ "\u2819",
38487
+ "\u281A",
38488
+ "\u2812",
38489
+ "\u2802",
38490
+ "\u2802",
38491
+ "\u2812",
38492
+ "\u2832",
38493
+ "\u2834",
38494
+ "\u2826",
38495
+ "\u2816",
38496
+ "\u2812",
38497
+ "\u2810",
38498
+ "\u2810",
38499
+ "\u2812",
38500
+ "\u2813",
38501
+ "\u280B"
38502
+ ]
38503
+ },
38504
+ dots6: {
38505
+ interval: 80,
38506
+ frames: [
38507
+ "\u2801",
38508
+ "\u2809",
38509
+ "\u2819",
38510
+ "\u281A",
38511
+ "\u2812",
38512
+ "\u2802",
38513
+ "\u2802",
38514
+ "\u2812",
38515
+ "\u2832",
38516
+ "\u2834",
38517
+ "\u2824",
38518
+ "\u2804",
38519
+ "\u2804",
38520
+ "\u2824",
38521
+ "\u2834",
38522
+ "\u2832",
38523
+ "\u2812",
38524
+ "\u2802",
38525
+ "\u2802",
38526
+ "\u2812",
38527
+ "\u281A",
38528
+ "\u2819",
38529
+ "\u2809",
38530
+ "\u2801"
38531
+ ]
38532
+ },
38533
+ dots7: {
38534
+ interval: 80,
38535
+ frames: [
38536
+ "\u2808",
38537
+ "\u2809",
38538
+ "\u280B",
38539
+ "\u2813",
38540
+ "\u2812",
38541
+ "\u2810",
38542
+ "\u2810",
38543
+ "\u2812",
38544
+ "\u2816",
38545
+ "\u2826",
38546
+ "\u2824",
38547
+ "\u2820",
38548
+ "\u2820",
38549
+ "\u2824",
38550
+ "\u2826",
38551
+ "\u2816",
38552
+ "\u2812",
38553
+ "\u2810",
38554
+ "\u2810",
38555
+ "\u2812",
38556
+ "\u2813",
38557
+ "\u280B",
38558
+ "\u2809",
38559
+ "\u2808"
38560
+ ]
38561
+ },
38562
+ dots8: {
38563
+ interval: 80,
38564
+ frames: [
38565
+ "\u2801",
38566
+ "\u2801",
38567
+ "\u2809",
38568
+ "\u2819",
38569
+ "\u281A",
38570
+ "\u2812",
38571
+ "\u2802",
38572
+ "\u2802",
38573
+ "\u2812",
38574
+ "\u2832",
38575
+ "\u2834",
38576
+ "\u2824",
38577
+ "\u2804",
38578
+ "\u2804",
38579
+ "\u2824",
38580
+ "\u2820",
38581
+ "\u2820",
38582
+ "\u2824",
38583
+ "\u2826",
38584
+ "\u2816",
38585
+ "\u2812",
38586
+ "\u2810",
38587
+ "\u2810",
38588
+ "\u2812",
38589
+ "\u2813",
38590
+ "\u280B",
38591
+ "\u2809",
38592
+ "\u2808",
38593
+ "\u2808"
38594
+ ]
38595
+ },
38596
+ dots9: {
38597
+ interval: 80,
38598
+ frames: [
38599
+ "\u28B9",
38600
+ "\u28BA",
38601
+ "\u28BC",
38602
+ "\u28F8",
38603
+ "\u28C7",
38604
+ "\u2867",
38605
+ "\u2857",
38606
+ "\u284F"
38607
+ ]
38608
+ },
38609
+ dots10: {
38610
+ interval: 80,
38611
+ frames: [
38612
+ "\u2884",
38613
+ "\u2882",
38614
+ "\u2881",
38615
+ "\u2841",
38616
+ "\u2848",
38617
+ "\u2850",
38618
+ "\u2860"
38619
+ ]
38620
+ },
38621
+ dots11: {
38622
+ interval: 100,
38623
+ frames: [
38624
+ "\u2801",
38625
+ "\u2802",
38626
+ "\u2804",
38627
+ "\u2840",
38628
+ "\u2880",
38629
+ "\u2820",
38630
+ "\u2810",
38631
+ "\u2808"
38632
+ ]
38633
+ },
38634
+ dots12: {
38635
+ interval: 80,
38636
+ frames: [
38637
+ "\u2880\u2800",
38638
+ "\u2840\u2800",
38639
+ "\u2804\u2800",
38640
+ "\u2882\u2800",
38641
+ "\u2842\u2800",
38642
+ "\u2805\u2800",
38643
+ "\u2883\u2800",
38644
+ "\u2843\u2800",
38645
+ "\u280D\u2800",
38646
+ "\u288B\u2800",
38647
+ "\u284B\u2800",
38648
+ "\u280D\u2801",
38649
+ "\u288B\u2801",
38650
+ "\u284B\u2801",
38651
+ "\u280D\u2809",
38652
+ "\u280B\u2809",
38653
+ "\u280B\u2809",
38654
+ "\u2809\u2819",
38655
+ "\u2809\u2819",
38656
+ "\u2809\u2829",
38657
+ "\u2808\u2899",
38658
+ "\u2808\u2859",
38659
+ "\u2888\u2829",
38660
+ "\u2840\u2899",
38661
+ "\u2804\u2859",
38662
+ "\u2882\u2829",
38663
+ "\u2842\u2898",
38664
+ "\u2805\u2858",
38665
+ "\u2883\u2828",
38666
+ "\u2843\u2890",
38667
+ "\u280D\u2850",
38668
+ "\u288B\u2820",
38669
+ "\u284B\u2880",
38670
+ "\u280D\u2841",
38671
+ "\u288B\u2801",
38672
+ "\u284B\u2801",
38673
+ "\u280D\u2809",
38674
+ "\u280B\u2809",
38675
+ "\u280B\u2809",
38676
+ "\u2809\u2819",
38677
+ "\u2809\u2819",
38678
+ "\u2809\u2829",
38679
+ "\u2808\u2899",
38680
+ "\u2808\u2859",
38681
+ "\u2808\u2829",
38682
+ "\u2800\u2899",
38683
+ "\u2800\u2859",
38684
+ "\u2800\u2829",
38685
+ "\u2800\u2898",
38686
+ "\u2800\u2858",
38687
+ "\u2800\u2828",
38688
+ "\u2800\u2890",
38689
+ "\u2800\u2850",
38690
+ "\u2800\u2820",
38691
+ "\u2800\u2880",
38692
+ "\u2800\u2840"
38693
+ ]
38694
+ },
38695
+ dots13: {
38696
+ interval: 80,
38697
+ frames: [
38698
+ "\u28FC",
38699
+ "\u28F9",
38700
+ "\u28BB",
38701
+ "\u283F",
38702
+ "\u285F",
38703
+ "\u28CF",
38704
+ "\u28E7",
38705
+ "\u28F6"
38706
+ ]
38707
+ },
38708
+ dots8Bit: {
38709
+ interval: 80,
38710
+ frames: [
38711
+ "\u2800",
38712
+ "\u2801",
38713
+ "\u2802",
38714
+ "\u2803",
38715
+ "\u2804",
38716
+ "\u2805",
38717
+ "\u2806",
38718
+ "\u2807",
38719
+ "\u2840",
38720
+ "\u2841",
38721
+ "\u2842",
38722
+ "\u2843",
38723
+ "\u2844",
38724
+ "\u2845",
38725
+ "\u2846",
38726
+ "\u2847",
38727
+ "\u2808",
38728
+ "\u2809",
38729
+ "\u280A",
38730
+ "\u280B",
38731
+ "\u280C",
38732
+ "\u280D",
38733
+ "\u280E",
38734
+ "\u280F",
38735
+ "\u2848",
38736
+ "\u2849",
38737
+ "\u284A",
38738
+ "\u284B",
38739
+ "\u284C",
38740
+ "\u284D",
38741
+ "\u284E",
38742
+ "\u284F",
38743
+ "\u2810",
38744
+ "\u2811",
38745
+ "\u2812",
38746
+ "\u2813",
38747
+ "\u2814",
38748
+ "\u2815",
38749
+ "\u2816",
38750
+ "\u2817",
38751
+ "\u2850",
38752
+ "\u2851",
38753
+ "\u2852",
38754
+ "\u2853",
38755
+ "\u2854",
38756
+ "\u2855",
38757
+ "\u2856",
38758
+ "\u2857",
38759
+ "\u2818",
38760
+ "\u2819",
38761
+ "\u281A",
38762
+ "\u281B",
38763
+ "\u281C",
38764
+ "\u281D",
38765
+ "\u281E",
38766
+ "\u281F",
38767
+ "\u2858",
38768
+ "\u2859",
38769
+ "\u285A",
38770
+ "\u285B",
38771
+ "\u285C",
38772
+ "\u285D",
38773
+ "\u285E",
38774
+ "\u285F",
38775
+ "\u2820",
38776
+ "\u2821",
38777
+ "\u2822",
38778
+ "\u2823",
38779
+ "\u2824",
38780
+ "\u2825",
38781
+ "\u2826",
38782
+ "\u2827",
38783
+ "\u2860",
38784
+ "\u2861",
38785
+ "\u2862",
38786
+ "\u2863",
38787
+ "\u2864",
38788
+ "\u2865",
38789
+ "\u2866",
38790
+ "\u2867",
38791
+ "\u2828",
38792
+ "\u2829",
38793
+ "\u282A",
38794
+ "\u282B",
38795
+ "\u282C",
38796
+ "\u282D",
38797
+ "\u282E",
38798
+ "\u282F",
38799
+ "\u2868",
38800
+ "\u2869",
38801
+ "\u286A",
38802
+ "\u286B",
38803
+ "\u286C",
38804
+ "\u286D",
38805
+ "\u286E",
38806
+ "\u286F",
38807
+ "\u2830",
38808
+ "\u2831",
38809
+ "\u2832",
38810
+ "\u2833",
38811
+ "\u2834",
38812
+ "\u2835",
38813
+ "\u2836",
38814
+ "\u2837",
38815
+ "\u2870",
38816
+ "\u2871",
38817
+ "\u2872",
38818
+ "\u2873",
38819
+ "\u2874",
38820
+ "\u2875",
38821
+ "\u2876",
38822
+ "\u2877",
38823
+ "\u2838",
38824
+ "\u2839",
38825
+ "\u283A",
38826
+ "\u283B",
38827
+ "\u283C",
38828
+ "\u283D",
38829
+ "\u283E",
38830
+ "\u283F",
38831
+ "\u2878",
38832
+ "\u2879",
38833
+ "\u287A",
38834
+ "\u287B",
38835
+ "\u287C",
38836
+ "\u287D",
38837
+ "\u287E",
38838
+ "\u287F",
38839
+ "\u2880",
38840
+ "\u2881",
38841
+ "\u2882",
38842
+ "\u2883",
38843
+ "\u2884",
38844
+ "\u2885",
38845
+ "\u2886",
38846
+ "\u2887",
38847
+ "\u28C0",
38848
+ "\u28C1",
38849
+ "\u28C2",
38850
+ "\u28C3",
38851
+ "\u28C4",
38852
+ "\u28C5",
38853
+ "\u28C6",
38854
+ "\u28C7",
38855
+ "\u2888",
38856
+ "\u2889",
38857
+ "\u288A",
38858
+ "\u288B",
38859
+ "\u288C",
38860
+ "\u288D",
38861
+ "\u288E",
38862
+ "\u288F",
38863
+ "\u28C8",
38864
+ "\u28C9",
38865
+ "\u28CA",
38866
+ "\u28CB",
38867
+ "\u28CC",
38868
+ "\u28CD",
38869
+ "\u28CE",
38870
+ "\u28CF",
38871
+ "\u2890",
38872
+ "\u2891",
38873
+ "\u2892",
38874
+ "\u2893",
38875
+ "\u2894",
38876
+ "\u2895",
38877
+ "\u2896",
38878
+ "\u2897",
38879
+ "\u28D0",
38880
+ "\u28D1",
38881
+ "\u28D2",
38882
+ "\u28D3",
38883
+ "\u28D4",
38884
+ "\u28D5",
38885
+ "\u28D6",
38886
+ "\u28D7",
38887
+ "\u2898",
38888
+ "\u2899",
38889
+ "\u289A",
38890
+ "\u289B",
38891
+ "\u289C",
38892
+ "\u289D",
38893
+ "\u289E",
38894
+ "\u289F",
38895
+ "\u28D8",
38896
+ "\u28D9",
38897
+ "\u28DA",
38898
+ "\u28DB",
38899
+ "\u28DC",
38900
+ "\u28DD",
38901
+ "\u28DE",
38902
+ "\u28DF",
38903
+ "\u28A0",
38904
+ "\u28A1",
38905
+ "\u28A2",
38906
+ "\u28A3",
38907
+ "\u28A4",
38908
+ "\u28A5",
38909
+ "\u28A6",
38910
+ "\u28A7",
38911
+ "\u28E0",
38912
+ "\u28E1",
38913
+ "\u28E2",
38914
+ "\u28E3",
38915
+ "\u28E4",
38916
+ "\u28E5",
38917
+ "\u28E6",
38918
+ "\u28E7",
38919
+ "\u28A8",
38920
+ "\u28A9",
38921
+ "\u28AA",
38922
+ "\u28AB",
38923
+ "\u28AC",
38924
+ "\u28AD",
38925
+ "\u28AE",
38926
+ "\u28AF",
38927
+ "\u28E8",
38928
+ "\u28E9",
38929
+ "\u28EA",
38930
+ "\u28EB",
38931
+ "\u28EC",
38932
+ "\u28ED",
38933
+ "\u28EE",
38934
+ "\u28EF",
38935
+ "\u28B0",
38936
+ "\u28B1",
38937
+ "\u28B2",
38938
+ "\u28B3",
38939
+ "\u28B4",
38940
+ "\u28B5",
38941
+ "\u28B6",
38942
+ "\u28B7",
38943
+ "\u28F0",
38944
+ "\u28F1",
38945
+ "\u28F2",
38946
+ "\u28F3",
38947
+ "\u28F4",
38948
+ "\u28F5",
38949
+ "\u28F6",
38950
+ "\u28F7",
38951
+ "\u28B8",
38952
+ "\u28B9",
38953
+ "\u28BA",
38954
+ "\u28BB",
38955
+ "\u28BC",
38956
+ "\u28BD",
38957
+ "\u28BE",
38958
+ "\u28BF",
38959
+ "\u28F8",
38960
+ "\u28F9",
38961
+ "\u28FA",
38962
+ "\u28FB",
38963
+ "\u28FC",
38964
+ "\u28FD",
38965
+ "\u28FE",
38966
+ "\u28FF"
38967
+ ]
38968
+ },
38969
+ sand: {
38970
+ interval: 80,
38971
+ frames: [
38972
+ "\u2801",
38973
+ "\u2802",
38974
+ "\u2804",
38975
+ "\u2840",
38976
+ "\u2848",
38977
+ "\u2850",
38978
+ "\u2860",
38979
+ "\u28C0",
38980
+ "\u28C1",
38981
+ "\u28C2",
38982
+ "\u28C4",
38983
+ "\u28CC",
38984
+ "\u28D4",
38985
+ "\u28E4",
38986
+ "\u28E5",
38987
+ "\u28E6",
38988
+ "\u28EE",
38989
+ "\u28F6",
38990
+ "\u28F7",
38991
+ "\u28FF",
38992
+ "\u287F",
38993
+ "\u283F",
38994
+ "\u289F",
38995
+ "\u281F",
38996
+ "\u285B",
38997
+ "\u281B",
38998
+ "\u282B",
38999
+ "\u288B",
39000
+ "\u280B",
39001
+ "\u280D",
39002
+ "\u2849",
39003
+ "\u2809",
39004
+ "\u2811",
39005
+ "\u2821",
39006
+ "\u2881"
39007
+ ]
39008
+ },
39009
+ line: {
39010
+ interval: 130,
39011
+ frames: [
39012
+ "-",
39013
+ "\\",
39014
+ "|",
39015
+ "/"
39016
+ ]
39017
+ },
39018
+ line2: {
39019
+ interval: 100,
39020
+ frames: [
39021
+ "\u2802",
39022
+ "-",
39023
+ "\u2013",
39024
+ "\u2014",
39025
+ "\u2013",
39026
+ "-"
39027
+ ]
39028
+ },
39029
+ pipe: {
39030
+ interval: 100,
39031
+ frames: [
39032
+ "\u2524",
39033
+ "\u2518",
39034
+ "\u2534",
39035
+ "\u2514",
39036
+ "\u251C",
39037
+ "\u250C",
39038
+ "\u252C",
39039
+ "\u2510"
39040
+ ]
39041
+ },
39042
+ simpleDots: {
39043
+ interval: 400,
39044
+ frames: [
39045
+ ". ",
39046
+ ".. ",
39047
+ "...",
39048
+ " "
39049
+ ]
39050
+ },
39051
+ simpleDotsScrolling: {
39052
+ interval: 200,
39053
+ frames: [
39054
+ ". ",
39055
+ ".. ",
39056
+ "...",
39057
+ " ..",
39058
+ " .",
39059
+ " "
39060
+ ]
39061
+ },
39062
+ star: {
39063
+ interval: 70,
39064
+ frames: [
39065
+ "\u2736",
39066
+ "\u2738",
39067
+ "\u2739",
39068
+ "\u273A",
39069
+ "\u2739",
39070
+ "\u2737"
39071
+ ]
39072
+ },
39073
+ star2: {
39074
+ interval: 80,
39075
+ frames: [
39076
+ "+",
39077
+ "x",
39078
+ "*"
39079
+ ]
39080
+ },
39081
+ flip: {
39082
+ interval: 70,
39083
+ frames: [
39084
+ "_",
39085
+ "_",
39086
+ "_",
39087
+ "-",
39088
+ "`",
39089
+ "`",
39090
+ "'",
39091
+ "\xB4",
39092
+ "-",
39093
+ "_",
39094
+ "_",
39095
+ "_"
39096
+ ]
39097
+ },
39098
+ hamburger: {
39099
+ interval: 100,
39100
+ frames: [
39101
+ "\u2631",
39102
+ "\u2632",
39103
+ "\u2634"
39104
+ ]
39105
+ },
39106
+ growVertical: {
39107
+ interval: 120,
39108
+ frames: [
39109
+ "\u2581",
39110
+ "\u2583",
39111
+ "\u2584",
39112
+ "\u2585",
39113
+ "\u2586",
39114
+ "\u2587",
39115
+ "\u2586",
39116
+ "\u2585",
39117
+ "\u2584",
39118
+ "\u2583"
39119
+ ]
39120
+ },
39121
+ growHorizontal: {
39122
+ interval: 120,
39123
+ frames: [
39124
+ "\u258F",
39125
+ "\u258E",
39126
+ "\u258D",
39127
+ "\u258C",
39128
+ "\u258B",
39129
+ "\u258A",
39130
+ "\u2589",
39131
+ "\u258A",
39132
+ "\u258B",
39133
+ "\u258C",
39134
+ "\u258D",
39135
+ "\u258E"
39136
+ ]
39137
+ },
39138
+ balloon: {
39139
+ interval: 140,
39140
+ frames: [
39141
+ " ",
39142
+ ".",
39143
+ "o",
39144
+ "O",
39145
+ "@",
39146
+ "*",
39147
+ " "
39148
+ ]
39149
+ },
39150
+ balloon2: {
39151
+ interval: 120,
39152
+ frames: [
39153
+ ".",
39154
+ "o",
39155
+ "O",
39156
+ "\xB0",
39157
+ "O",
39158
+ "o",
39159
+ "."
39160
+ ]
39161
+ },
39162
+ noise: {
39163
+ interval: 100,
39164
+ frames: [
39165
+ "\u2593",
39166
+ "\u2592",
39167
+ "\u2591"
39168
+ ]
39169
+ },
39170
+ bounce: {
39171
+ interval: 120,
39172
+ frames: [
39173
+ "\u2801",
39174
+ "\u2802",
39175
+ "\u2804",
39176
+ "\u2802"
39177
+ ]
39178
+ },
39179
+ boxBounce: {
39180
+ interval: 120,
39181
+ frames: [
39182
+ "\u2596",
39183
+ "\u2598",
39184
+ "\u259D",
39185
+ "\u2597"
39186
+ ]
39187
+ },
39188
+ boxBounce2: {
39189
+ interval: 100,
39190
+ frames: [
39191
+ "\u258C",
39192
+ "\u2580",
39193
+ "\u2590",
39194
+ "\u2584"
39195
+ ]
39196
+ },
39197
+ triangle: {
39198
+ interval: 50,
39199
+ frames: [
39200
+ "\u25E2",
39201
+ "\u25E3",
39202
+ "\u25E4",
39203
+ "\u25E5"
39204
+ ]
39205
+ },
39206
+ binary: {
39207
+ interval: 80,
39208
+ frames: [
39209
+ "010010",
39210
+ "001100",
39211
+ "100101",
39212
+ "111010",
39213
+ "111101",
39214
+ "010111",
39215
+ "101011",
39216
+ "111000",
39217
+ "110011",
39218
+ "110101"
39219
+ ]
39220
+ },
39221
+ arc: {
39222
+ interval: 100,
39223
+ frames: [
39224
+ "\u25DC",
39225
+ "\u25E0",
39226
+ "\u25DD",
39227
+ "\u25DE",
39228
+ "\u25E1",
39229
+ "\u25DF"
39230
+ ]
39231
+ },
39232
+ circle: {
39233
+ interval: 120,
39234
+ frames: [
39235
+ "\u25E1",
39236
+ "\u2299",
39237
+ "\u25E0"
39238
+ ]
39239
+ },
39240
+ squareCorners: {
39241
+ interval: 180,
39242
+ frames: [
39243
+ "\u25F0",
39244
+ "\u25F3",
39245
+ "\u25F2",
39246
+ "\u25F1"
39247
+ ]
39248
+ },
39249
+ circleQuarters: {
39250
+ interval: 120,
39251
+ frames: [
39252
+ "\u25F4",
39253
+ "\u25F7",
39254
+ "\u25F6",
39255
+ "\u25F5"
39256
+ ]
39257
+ },
39258
+ circleHalves: {
39259
+ interval: 50,
39260
+ frames: [
39261
+ "\u25D0",
39262
+ "\u25D3",
39263
+ "\u25D1",
39264
+ "\u25D2"
39265
+ ]
39266
+ },
39267
+ squish: {
39268
+ interval: 100,
39269
+ frames: [
39270
+ "\u256B",
39271
+ "\u256A"
39272
+ ]
39273
+ },
39274
+ toggle: {
39275
+ interval: 250,
39276
+ frames: [
39277
+ "\u22B6",
39278
+ "\u22B7"
39279
+ ]
39280
+ },
39281
+ toggle2: {
39282
+ interval: 80,
39283
+ frames: [
39284
+ "\u25AB",
39285
+ "\u25AA"
39286
+ ]
39287
+ },
39288
+ toggle3: {
39289
+ interval: 120,
39290
+ frames: [
39291
+ "\u25A1",
39292
+ "\u25A0"
39293
+ ]
39294
+ },
39295
+ toggle4: {
39296
+ interval: 100,
39297
+ frames: [
39298
+ "\u25A0",
39299
+ "\u25A1",
39300
+ "\u25AA",
39301
+ "\u25AB"
39302
+ ]
39303
+ },
39304
+ toggle5: {
39305
+ interval: 100,
39306
+ frames: [
39307
+ "\u25AE",
39308
+ "\u25AF"
39309
+ ]
39310
+ },
39311
+ toggle6: {
39312
+ interval: 300,
39313
+ frames: [
39314
+ "\u101D",
39315
+ "\u1040"
39316
+ ]
39317
+ },
39318
+ toggle7: {
39319
+ interval: 80,
39320
+ frames: [
39321
+ "\u29BE",
39322
+ "\u29BF"
39323
+ ]
39324
+ },
39325
+ toggle8: {
39326
+ interval: 100,
39327
+ frames: [
39328
+ "\u25CD",
39329
+ "\u25CC"
39330
+ ]
39331
+ },
39332
+ toggle9: {
39333
+ interval: 100,
39334
+ frames: [
39335
+ "\u25C9",
39336
+ "\u25CE"
39337
+ ]
39338
+ },
39339
+ toggle10: {
39340
+ interval: 100,
39341
+ frames: [
39342
+ "\u3282",
39343
+ "\u3280",
39344
+ "\u3281"
39345
+ ]
39346
+ },
39347
+ toggle11: {
39348
+ interval: 50,
39349
+ frames: [
39350
+ "\u29C7",
39351
+ "\u29C6"
39352
+ ]
39353
+ },
39354
+ toggle12: {
39355
+ interval: 120,
39356
+ frames: [
39357
+ "\u2617",
39358
+ "\u2616"
39359
+ ]
39360
+ },
39361
+ toggle13: {
39362
+ interval: 80,
39363
+ frames: [
39364
+ "=",
39365
+ "*",
39366
+ "-"
39367
+ ]
39368
+ },
39369
+ arrow: {
39370
+ interval: 100,
39371
+ frames: [
39372
+ "\u2190",
39373
+ "\u2196",
39374
+ "\u2191",
39375
+ "\u2197",
39376
+ "\u2192",
39377
+ "\u2198",
39378
+ "\u2193",
39379
+ "\u2199"
39380
+ ]
39381
+ },
39382
+ arrow2: {
39383
+ interval: 80,
39384
+ frames: [
39385
+ "\u2B06\uFE0F ",
39386
+ "\u2197\uFE0F ",
39387
+ "\u27A1\uFE0F ",
39388
+ "\u2198\uFE0F ",
39389
+ "\u2B07\uFE0F ",
39390
+ "\u2199\uFE0F ",
39391
+ "\u2B05\uFE0F ",
39392
+ "\u2196\uFE0F "
39393
+ ]
39394
+ },
39395
+ arrow3: {
39396
+ interval: 120,
39397
+ frames: [
39398
+ "\u25B9\u25B9\u25B9\u25B9\u25B9",
39399
+ "\u25B8\u25B9\u25B9\u25B9\u25B9",
39400
+ "\u25B9\u25B8\u25B9\u25B9\u25B9",
39401
+ "\u25B9\u25B9\u25B8\u25B9\u25B9",
39402
+ "\u25B9\u25B9\u25B9\u25B8\u25B9",
39403
+ "\u25B9\u25B9\u25B9\u25B9\u25B8"
39404
+ ]
39405
+ },
39406
+ bouncingBar: {
39407
+ interval: 80,
39408
+ frames: [
39409
+ "[ ]",
39410
+ "[= ]",
39411
+ "[== ]",
39412
+ "[=== ]",
39413
+ "[====]",
39414
+ "[ ===]",
39415
+ "[ ==]",
39416
+ "[ =]",
39417
+ "[ ]",
39418
+ "[ =]",
39419
+ "[ ==]",
39420
+ "[ ===]",
39421
+ "[====]",
39422
+ "[=== ]",
39423
+ "[== ]",
39424
+ "[= ]"
39425
+ ]
39426
+ },
39427
+ bouncingBall: {
39428
+ interval: 80,
39429
+ frames: [
39430
+ "( \u25CF )",
39431
+ "( \u25CF )",
39432
+ "( \u25CF )",
39433
+ "( \u25CF )",
39434
+ "( \u25CF)",
39435
+ "( \u25CF )",
39436
+ "( \u25CF )",
39437
+ "( \u25CF )",
39438
+ "( \u25CF )",
39439
+ "(\u25CF )"
39440
+ ]
39441
+ },
39442
+ smiley: {
39443
+ interval: 200,
39444
+ frames: [
39445
+ "\u{1F604} ",
39446
+ "\u{1F61D} "
39447
+ ]
39448
+ },
39449
+ monkey: {
39450
+ interval: 300,
39451
+ frames: [
39452
+ "\u{1F648} ",
39453
+ "\u{1F648} ",
39454
+ "\u{1F649} ",
39455
+ "\u{1F64A} "
39456
+ ]
39457
+ },
39458
+ hearts: {
39459
+ interval: 100,
39460
+ frames: [
39461
+ "\u{1F49B} ",
39462
+ "\u{1F499} ",
39463
+ "\u{1F49C} ",
39464
+ "\u{1F49A} ",
39465
+ "\u2764\uFE0F "
39466
+ ]
39467
+ },
39468
+ clock: {
39469
+ interval: 100,
39470
+ frames: [
39471
+ "\u{1F55B} ",
39472
+ "\u{1F550} ",
39473
+ "\u{1F551} ",
39474
+ "\u{1F552} ",
39475
+ "\u{1F553} ",
39476
+ "\u{1F554} ",
39477
+ "\u{1F555} ",
39478
+ "\u{1F556} ",
39479
+ "\u{1F557} ",
39480
+ "\u{1F558} ",
39481
+ "\u{1F559} ",
39482
+ "\u{1F55A} "
39483
+ ]
39484
+ },
39485
+ earth: {
39486
+ interval: 180,
39487
+ frames: [
39488
+ "\u{1F30D} ",
39489
+ "\u{1F30E} ",
39490
+ "\u{1F30F} "
39491
+ ]
39492
+ },
39493
+ material: {
39494
+ interval: 17,
39495
+ frames: [
39496
+ "\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39497
+ "\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39498
+ "\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39499
+ "\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39500
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39501
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39502
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39503
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39504
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39505
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39506
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39507
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39508
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39509
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581",
39510
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581",
39511
+ "\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581",
39512
+ "\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581",
39513
+ "\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581",
39514
+ "\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581",
39515
+ "\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39516
+ "\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39517
+ "\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581",
39518
+ "\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581",
39519
+ "\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39520
+ "\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39521
+ "\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39522
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39523
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39524
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39525
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39526
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39527
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39528
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39529
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39530
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39531
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39532
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39533
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39534
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588",
39535
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588",
39536
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588",
39537
+ "\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588",
39538
+ "\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588",
39539
+ "\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588",
39540
+ "\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588",
39541
+ "\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588",
39542
+ "\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39543
+ "\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39544
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39545
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39546
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39547
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39548
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39549
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39550
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39551
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39552
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39553
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581",
39554
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581\u2581",
39555
+ "\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581",
39556
+ "\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581\u2581",
39557
+ "\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581\u2581",
39558
+ "\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39559
+ "\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39560
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39561
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39562
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581\u2581",
39563
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581",
39564
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581\u2581",
39565
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39566
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39567
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39568
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39569
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2581",
39570
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39571
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
39572
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588\u2588",
39573
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588",
39574
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588",
39575
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588\u2588",
39576
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588",
39577
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588\u2588",
39578
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588",
39579
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588",
39580
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588\u2588",
39581
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39582
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39583
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2588",
39584
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39585
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39586
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581",
39587
+ "\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581\u2581"
39588
+ ]
39589
+ },
39590
+ moon: {
39591
+ interval: 80,
39592
+ frames: [
39593
+ "\u{1F311} ",
39594
+ "\u{1F312} ",
39595
+ "\u{1F313} ",
39596
+ "\u{1F314} ",
39597
+ "\u{1F315} ",
39598
+ "\u{1F316} ",
39599
+ "\u{1F317} ",
39600
+ "\u{1F318} "
39601
+ ]
39602
+ },
39603
+ runner: {
39604
+ interval: 140,
39605
+ frames: [
39606
+ "\u{1F6B6} ",
39607
+ "\u{1F3C3} "
39608
+ ]
39609
+ },
39610
+ pong: {
39611
+ interval: 80,
39612
+ frames: [
39613
+ "\u2590\u2802 \u258C",
39614
+ "\u2590\u2808 \u258C",
39615
+ "\u2590 \u2802 \u258C",
39616
+ "\u2590 \u2820 \u258C",
39617
+ "\u2590 \u2840 \u258C",
39618
+ "\u2590 \u2820 \u258C",
39619
+ "\u2590 \u2802 \u258C",
39620
+ "\u2590 \u2808 \u258C",
39621
+ "\u2590 \u2802 \u258C",
39622
+ "\u2590 \u2820 \u258C",
39623
+ "\u2590 \u2840 \u258C",
39624
+ "\u2590 \u2820 \u258C",
39625
+ "\u2590 \u2802 \u258C",
39626
+ "\u2590 \u2808 \u258C",
39627
+ "\u2590 \u2802\u258C",
39628
+ "\u2590 \u2820\u258C",
39629
+ "\u2590 \u2840\u258C",
39630
+ "\u2590 \u2820 \u258C",
39631
+ "\u2590 \u2802 \u258C",
39632
+ "\u2590 \u2808 \u258C",
39633
+ "\u2590 \u2802 \u258C",
39634
+ "\u2590 \u2820 \u258C",
39635
+ "\u2590 \u2840 \u258C",
39636
+ "\u2590 \u2820 \u258C",
39637
+ "\u2590 \u2802 \u258C",
39638
+ "\u2590 \u2808 \u258C",
39639
+ "\u2590 \u2802 \u258C",
39640
+ "\u2590 \u2820 \u258C",
39641
+ "\u2590 \u2840 \u258C",
39642
+ "\u2590\u2820 \u258C"
39643
+ ]
39644
+ },
39645
+ shark: {
39646
+ interval: 120,
39647
+ frames: [
39648
+ "\u2590|\\____________\u258C",
39649
+ "\u2590_|\\___________\u258C",
39650
+ "\u2590__|\\__________\u258C",
39651
+ "\u2590___|\\_________\u258C",
39652
+ "\u2590____|\\________\u258C",
39653
+ "\u2590_____|\\_______\u258C",
39654
+ "\u2590______|\\______\u258C",
39655
+ "\u2590_______|\\_____\u258C",
39656
+ "\u2590________|\\____\u258C",
39657
+ "\u2590_________|\\___\u258C",
39658
+ "\u2590__________|\\__\u258C",
39659
+ "\u2590___________|\\_\u258C",
39660
+ "\u2590____________|\\\u258C",
39661
+ "\u2590____________/|\u258C",
39662
+ "\u2590___________/|_\u258C",
39663
+ "\u2590__________/|__\u258C",
39664
+ "\u2590_________/|___\u258C",
39665
+ "\u2590________/|____\u258C",
39666
+ "\u2590_______/|_____\u258C",
39667
+ "\u2590______/|______\u258C",
39668
+ "\u2590_____/|_______\u258C",
39669
+ "\u2590____/|________\u258C",
39670
+ "\u2590___/|_________\u258C",
39671
+ "\u2590__/|__________\u258C",
39672
+ "\u2590_/|___________\u258C",
39673
+ "\u2590/|____________\u258C"
39674
+ ]
39675
+ },
39676
+ dqpb: {
39677
+ interval: 100,
39678
+ frames: [
39679
+ "d",
39680
+ "q",
39681
+ "p",
39682
+ "b"
39683
+ ]
39684
+ },
39685
+ weather: {
39686
+ interval: 100,
39687
+ frames: [
39688
+ "\u2600\uFE0F ",
39689
+ "\u2600\uFE0F ",
39690
+ "\u2600\uFE0F ",
39691
+ "\u{1F324} ",
39692
+ "\u26C5\uFE0F ",
39693
+ "\u{1F325} ",
39694
+ "\u2601\uFE0F ",
39695
+ "\u{1F327} ",
39696
+ "\u{1F328} ",
39697
+ "\u{1F327} ",
39698
+ "\u{1F328} ",
39699
+ "\u{1F327} ",
39700
+ "\u{1F328} ",
39701
+ "\u26C8 ",
39702
+ "\u{1F328} ",
39703
+ "\u{1F327} ",
39704
+ "\u{1F328} ",
39705
+ "\u2601\uFE0F ",
39706
+ "\u{1F325} ",
39707
+ "\u26C5\uFE0F ",
39708
+ "\u{1F324} ",
39709
+ "\u2600\uFE0F ",
39710
+ "\u2600\uFE0F "
39711
+ ]
39712
+ },
39713
+ christmas: {
39714
+ interval: 400,
39715
+ frames: [
39716
+ "\u{1F332}",
39717
+ "\u{1F384}"
39718
+ ]
39719
+ },
39720
+ grenade: {
39721
+ interval: 80,
39722
+ frames: [
39723
+ "\u060C ",
39724
+ "\u2032 ",
39725
+ " \xB4 ",
39726
+ " \u203E ",
39727
+ " \u2E0C",
39728
+ " \u2E0A",
39729
+ " |",
39730
+ " \u204E",
39731
+ " \u2055",
39732
+ " \u0DF4 ",
39733
+ " \u2053",
39734
+ " ",
39735
+ " ",
39736
+ " "
39737
+ ]
39738
+ },
39739
+ point: {
39740
+ interval: 125,
39741
+ frames: [
39742
+ "\u2219\u2219\u2219",
39743
+ "\u25CF\u2219\u2219",
39744
+ "\u2219\u25CF\u2219",
39745
+ "\u2219\u2219\u25CF",
39746
+ "\u2219\u2219\u2219"
39747
+ ]
39748
+ },
39749
+ layer: {
39750
+ interval: 150,
39751
+ frames: [
39752
+ "-",
39753
+ "=",
39754
+ "\u2261"
39755
+ ]
39756
+ },
39757
+ betaWave: {
39758
+ interval: 80,
39759
+ frames: [
39760
+ "\u03C1\u03B2\u03B2\u03B2\u03B2\u03B2\u03B2",
39761
+ "\u03B2\u03C1\u03B2\u03B2\u03B2\u03B2\u03B2",
39762
+ "\u03B2\u03B2\u03C1\u03B2\u03B2\u03B2\u03B2",
39763
+ "\u03B2\u03B2\u03B2\u03C1\u03B2\u03B2\u03B2",
39764
+ "\u03B2\u03B2\u03B2\u03B2\u03C1\u03B2\u03B2",
39765
+ "\u03B2\u03B2\u03B2\u03B2\u03B2\u03C1\u03B2",
39766
+ "\u03B2\u03B2\u03B2\u03B2\u03B2\u03B2\u03C1"
39767
+ ]
39768
+ },
39769
+ fingerDance: {
39770
+ interval: 160,
39771
+ frames: [
39772
+ "\u{1F918} ",
39773
+ "\u{1F91F} ",
39774
+ "\u{1F596} ",
39775
+ "\u270B ",
39776
+ "\u{1F91A} ",
39777
+ "\u{1F446} "
39778
+ ]
39779
+ },
39780
+ fistBump: {
39781
+ interval: 80,
39782
+ frames: [
39783
+ "\u{1F91C}\u3000\u3000\u3000\u3000\u{1F91B} ",
39784
+ "\u{1F91C}\u3000\u3000\u3000\u3000\u{1F91B} ",
39785
+ "\u{1F91C}\u3000\u3000\u3000\u3000\u{1F91B} ",
39786
+ "\u3000\u{1F91C}\u3000\u3000\u{1F91B}\u3000 ",
39787
+ "\u3000\u3000\u{1F91C}\u{1F91B}\u3000\u3000 ",
39788
+ "\u3000\u{1F91C}\u2728\u{1F91B}\u3000\u3000 ",
39789
+ "\u{1F91C}\u3000\u2728\u3000\u{1F91B}\u3000 "
39790
+ ]
39791
+ },
39792
+ soccerHeader: {
39793
+ interval: 80,
39794
+ frames: [
39795
+ " \u{1F9D1}\u26BD\uFE0F \u{1F9D1} ",
39796
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39797
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39798
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39799
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39800
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39801
+ "\u{1F9D1} \u26BD\uFE0F\u{1F9D1} ",
39802
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39803
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39804
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39805
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} ",
39806
+ "\u{1F9D1} \u26BD\uFE0F \u{1F9D1} "
39807
+ ]
39808
+ },
39809
+ mindblown: {
39810
+ interval: 160,
39811
+ frames: [
39812
+ "\u{1F610} ",
39813
+ "\u{1F610} ",
39814
+ "\u{1F62E} ",
39815
+ "\u{1F62E} ",
39816
+ "\u{1F626} ",
39817
+ "\u{1F626} ",
39818
+ "\u{1F627} ",
39819
+ "\u{1F627} ",
39820
+ "\u{1F92F} ",
39821
+ "\u{1F4A5} ",
39822
+ "\u2728 ",
39823
+ "\u3000 ",
39824
+ "\u3000 ",
39825
+ "\u3000 "
39826
+ ]
39827
+ },
39828
+ speaker: {
39829
+ interval: 160,
39830
+ frames: [
39831
+ "\u{1F508} ",
39832
+ "\u{1F509} ",
39833
+ "\u{1F50A} ",
39834
+ "\u{1F509} "
39835
+ ]
39836
+ },
39837
+ orangePulse: {
39838
+ interval: 100,
39839
+ frames: [
39840
+ "\u{1F538} ",
39841
+ "\u{1F536} ",
39842
+ "\u{1F7E0} ",
39843
+ "\u{1F7E0} ",
39844
+ "\u{1F536} "
39845
+ ]
39846
+ },
39847
+ bluePulse: {
39848
+ interval: 100,
39849
+ frames: [
39850
+ "\u{1F539} ",
39851
+ "\u{1F537} ",
39852
+ "\u{1F535} ",
39853
+ "\u{1F535} ",
39854
+ "\u{1F537} "
39855
+ ]
39856
+ },
39857
+ orangeBluePulse: {
39858
+ interval: 100,
39859
+ frames: [
39860
+ "\u{1F538} ",
39861
+ "\u{1F536} ",
39862
+ "\u{1F7E0} ",
39863
+ "\u{1F7E0} ",
39864
+ "\u{1F536} ",
39865
+ "\u{1F539} ",
39866
+ "\u{1F537} ",
39867
+ "\u{1F535} ",
39868
+ "\u{1F535} ",
39869
+ "\u{1F537} "
39870
+ ]
39871
+ },
39872
+ timeTravel: {
39873
+ interval: 100,
39874
+ frames: [
39875
+ "\u{1F55B} ",
39876
+ "\u{1F55A} ",
39877
+ "\u{1F559} ",
39878
+ "\u{1F558} ",
39879
+ "\u{1F557} ",
39880
+ "\u{1F556} ",
39881
+ "\u{1F555} ",
39882
+ "\u{1F554} ",
39883
+ "\u{1F553} ",
39884
+ "\u{1F552} ",
39885
+ "\u{1F551} ",
39886
+ "\u{1F550} "
39887
+ ]
39888
+ },
39889
+ aesthetic: {
39890
+ interval: 80,
39891
+ frames: [
39892
+ "\u25B0\u25B1\u25B1\u25B1\u25B1\u25B1\u25B1",
39893
+ "\u25B0\u25B0\u25B1\u25B1\u25B1\u25B1\u25B1",
39894
+ "\u25B0\u25B0\u25B0\u25B1\u25B1\u25B1\u25B1",
39895
+ "\u25B0\u25B0\u25B0\u25B0\u25B1\u25B1\u25B1",
39896
+ "\u25B0\u25B0\u25B0\u25B0\u25B0\u25B1\u25B1",
39897
+ "\u25B0\u25B0\u25B0\u25B0\u25B0\u25B0\u25B1",
39898
+ "\u25B0\u25B0\u25B0\u25B0\u25B0\u25B0\u25B0",
39899
+ "\u25B0\u25B1\u25B1\u25B1\u25B1\u25B1\u25B1"
39900
+ ]
39901
+ },
39902
+ dwarfFortress: {
39903
+ interval: 80,
39904
+ frames: [
39905
+ " \u2588\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39906
+ "\u263A\u2588\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39907
+ "\u263A\u2588\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39908
+ "\u263A\u2593\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39909
+ "\u263A\u2593\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39910
+ "\u263A\u2592\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39911
+ "\u263A\u2592\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39912
+ "\u263A\u2591\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39913
+ "\u263A\u2591\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39914
+ "\u263A \u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39915
+ " \u263A\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39916
+ " \u263A\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39917
+ " \u263A\u2593\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39918
+ " \u263A\u2593\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39919
+ " \u263A\u2592\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39920
+ " \u263A\u2592\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39921
+ " \u263A\u2591\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39922
+ " \u263A\u2591\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39923
+ " \u263A \u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39924
+ " \u263A\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39925
+ " \u263A\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
39926
+ " \u263A\u2593\u2588\u2588\u2588\xA3\xA3\xA3 ",
39927
+ " \u263A\u2593\u2588\u2588\u2588\xA3\xA3\xA3 ",
39928
+ " \u263A\u2592\u2588\u2588\u2588\xA3\xA3\xA3 ",
39929
+ " \u263A\u2592\u2588\u2588\u2588\xA3\xA3\xA3 ",
39930
+ " \u263A\u2591\u2588\u2588\u2588\xA3\xA3\xA3 ",
39931
+ " \u263A\u2591\u2588\u2588\u2588\xA3\xA3\xA3 ",
39932
+ " \u263A \u2588\u2588\u2588\xA3\xA3\xA3 ",
39933
+ " \u263A\u2588\u2588\u2588\xA3\xA3\xA3 ",
39934
+ " \u263A\u2588\u2588\u2588\xA3\xA3\xA3 ",
39935
+ " \u263A\u2593\u2588\u2588\xA3\xA3\xA3 ",
39936
+ " \u263A\u2593\u2588\u2588\xA3\xA3\xA3 ",
39937
+ " \u263A\u2592\u2588\u2588\xA3\xA3\xA3 ",
39938
+ " \u263A\u2592\u2588\u2588\xA3\xA3\xA3 ",
39939
+ " \u263A\u2591\u2588\u2588\xA3\xA3\xA3 ",
39940
+ " \u263A\u2591\u2588\u2588\xA3\xA3\xA3 ",
39941
+ " \u263A \u2588\u2588\xA3\xA3\xA3 ",
39942
+ " \u263A\u2588\u2588\xA3\xA3\xA3 ",
39943
+ " \u263A\u2588\u2588\xA3\xA3\xA3 ",
39944
+ " \u263A\u2593\u2588\xA3\xA3\xA3 ",
39945
+ " \u263A\u2593\u2588\xA3\xA3\xA3 ",
39946
+ " \u263A\u2592\u2588\xA3\xA3\xA3 ",
39947
+ " \u263A\u2592\u2588\xA3\xA3\xA3 ",
39948
+ " \u263A\u2591\u2588\xA3\xA3\xA3 ",
39949
+ " \u263A\u2591\u2588\xA3\xA3\xA3 ",
39950
+ " \u263A \u2588\xA3\xA3\xA3 ",
39951
+ " \u263A\u2588\xA3\xA3\xA3 ",
39952
+ " \u263A\u2588\xA3\xA3\xA3 ",
39953
+ " \u263A\u2593\xA3\xA3\xA3 ",
39954
+ " \u263A\u2593\xA3\xA3\xA3 ",
39955
+ " \u263A\u2592\xA3\xA3\xA3 ",
39956
+ " \u263A\u2592\xA3\xA3\xA3 ",
39957
+ " \u263A\u2591\xA3\xA3\xA3 ",
39958
+ " \u263A\u2591\xA3\xA3\xA3 ",
39959
+ " \u263A \xA3\xA3\xA3 ",
39960
+ " \u263A\xA3\xA3\xA3 ",
39961
+ " \u263A\xA3\xA3\xA3 ",
39962
+ " \u263A\u2593\xA3\xA3 ",
39963
+ " \u263A\u2593\xA3\xA3 ",
39964
+ " \u263A\u2592\xA3\xA3 ",
39965
+ " \u263A\u2592\xA3\xA3 ",
39966
+ " \u263A\u2591\xA3\xA3 ",
39967
+ " \u263A\u2591\xA3\xA3 ",
39968
+ " \u263A \xA3\xA3 ",
39969
+ " \u263A\xA3\xA3 ",
39970
+ " \u263A\xA3\xA3 ",
39971
+ " \u263A\u2593\xA3 ",
39972
+ " \u263A\u2593\xA3 ",
39973
+ " \u263A\u2592\xA3 ",
39974
+ " \u263A\u2592\xA3 ",
39975
+ " \u263A\u2591\xA3 ",
39976
+ " \u263A\u2591\xA3 ",
39977
+ " \u263A \xA3 ",
39978
+ " \u263A\xA3 ",
39979
+ " \u263A\xA3 ",
39980
+ " \u263A\u2593 ",
39981
+ " \u263A\u2593 ",
39982
+ " \u263A\u2592 ",
39983
+ " \u263A\u2592 ",
39984
+ " \u263A\u2591 ",
39985
+ " \u263A\u2591 ",
39986
+ " \u263A ",
39987
+ " \u263A &",
39988
+ " \u263A \u263C&",
39989
+ " \u263A \u263C &",
39990
+ " \u263A\u263C &",
39991
+ " \u263A\u263C & ",
39992
+ " \u203C & ",
39993
+ " \u263A & ",
39994
+ " \u203C & ",
39995
+ " \u263A & ",
39996
+ " \u203C & ",
39997
+ " \u263A & ",
39998
+ "\u203C & ",
39999
+ " & ",
40000
+ " & ",
40001
+ " & \u2591 ",
40002
+ " & \u2592 ",
40003
+ " & \u2593 ",
40004
+ " & \xA3 ",
40005
+ " & \u2591\xA3 ",
40006
+ " & \u2592\xA3 ",
40007
+ " & \u2593\xA3 ",
40008
+ " & \xA3\xA3 ",
40009
+ " & \u2591\xA3\xA3 ",
40010
+ " & \u2592\xA3\xA3 ",
40011
+ "& \u2593\xA3\xA3 ",
40012
+ "& \xA3\xA3\xA3 ",
40013
+ " \u2591\xA3\xA3\xA3 ",
40014
+ " \u2592\xA3\xA3\xA3 ",
40015
+ " \u2593\xA3\xA3\xA3 ",
40016
+ " \u2588\xA3\xA3\xA3 ",
40017
+ " \u2591\u2588\xA3\xA3\xA3 ",
40018
+ " \u2592\u2588\xA3\xA3\xA3 ",
40019
+ " \u2593\u2588\xA3\xA3\xA3 ",
40020
+ " \u2588\u2588\xA3\xA3\xA3 ",
40021
+ " \u2591\u2588\u2588\xA3\xA3\xA3 ",
40022
+ " \u2592\u2588\u2588\xA3\xA3\xA3 ",
40023
+ " \u2593\u2588\u2588\xA3\xA3\xA3 ",
40024
+ " \u2588\u2588\u2588\xA3\xA3\xA3 ",
40025
+ " \u2591\u2588\u2588\u2588\xA3\xA3\xA3 ",
40026
+ " \u2592\u2588\u2588\u2588\xA3\xA3\xA3 ",
40027
+ " \u2593\u2588\u2588\u2588\xA3\xA3\xA3 ",
40028
+ " \u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40029
+ " \u2591\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40030
+ " \u2592\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40031
+ " \u2593\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40032
+ " \u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40033
+ " \u2591\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40034
+ " \u2592\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40035
+ " \u2593\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40036
+ " \u2588\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 ",
40037
+ " \u2588\u2588\u2588\u2588\u2588\u2588\xA3\xA3\xA3 "
40038
+ ]
40039
+ }
40040
+ };
40041
+ }
40042
+ });
40043
+
40044
+ // node_modules/ink-spinner/node_modules/cli-spinners/index.js
40045
+ var require_cli_spinners = __commonJS({
40046
+ "node_modules/ink-spinner/node_modules/cli-spinners/index.js"(exports, module) {
40047
+ "use strict";
40048
+ var spinners2 = Object.assign({}, require_spinners());
40049
+ var spinnersList = Object.keys(spinners2);
40050
+ Object.defineProperty(spinners2, "random", {
40051
+ get() {
40052
+ const randomIndex = Math.floor(Math.random() * spinnersList.length);
40053
+ const spinnerName = spinnersList[randomIndex];
40054
+ return spinners2[spinnerName];
40055
+ }
40056
+ });
40057
+ module.exports = spinners2;
40058
+ }
40059
+ });
40060
+
38416
40061
  // node_modules/ink/build/render.js
38417
40062
  import { Stream } from "stream";
38418
40063
  import process12 from "process";
@@ -46994,8 +48639,8 @@ function getLogoModeFromEnv(envPrefix) {
46994
48639
  var CLI_NAME = "xcsh";
46995
48640
  var CLI_FULL_NAME = "F5 Distributed Cloud Shell";
46996
48641
  function getVersion() {
46997
- if ("v2.0.21-2601091525") {
46998
- return "v2.0.21-2601091525";
48642
+ if ("v2.0.21-2601091916") {
48643
+ return "v2.0.21-2601091916";
46999
48644
  }
47000
48645
  if (process.env.XCSH_VERSION) {
47001
48646
  return process.env.XCSH_VERSION;
@@ -74093,7 +75738,7 @@ function buildPlainPrompt(session) {
74093
75738
  }
74094
75739
 
74095
75740
  // src/repl/App.tsx
74096
- var import_react29 = __toESM(require_react(), 1);
75741
+ var import_react31 = __toESM(require_react(), 1);
74097
75742
 
74098
75743
  // src/repl/components/InputBox.tsx
74099
75744
  var import_react23 = __toESM(require_react(), 1);
@@ -74489,271 +76134,1026 @@ function Suggestions({
74489
76134
  );
74490
76135
  }
74491
76136
 
74492
- // src/repl/hooks/useDoubleCtrlC.ts
74493
- var import_react25 = __toESM(require_react(), 1);
74494
- function useDoubleCtrlC(options = {}) {
74495
- const { windowMs = 500, onFirstPress, onDoublePress } = options;
74496
- const lastPressRef = (0, import_react25.useRef)(0);
74497
- const [isWaiting, setIsWaiting] = (0, import_react25.useState)(false);
74498
- const timeoutRef = (0, import_react25.useRef)(null);
74499
- const reset = (0, import_react25.useCallback)(() => {
74500
- lastPressRef.current = 0;
74501
- setIsWaiting(false);
74502
- if (timeoutRef.current) {
74503
- clearTimeout(timeoutRef.current);
74504
- timeoutRef.current = null;
74505
- }
74506
- }, []);
74507
- const handleCtrlC = (0, import_react25.useCallback)(() => {
74508
- const now = Date.now();
74509
- const elapsed = now - lastPressRef.current;
74510
- if (elapsed < windowMs && lastPressRef.current !== 0) {
74511
- reset();
74512
- onDoublePress?.();
74513
- return true;
74514
- }
74515
- lastPressRef.current = now;
74516
- setIsWaiting(true);
74517
- onFirstPress?.();
74518
- if (timeoutRef.current) {
74519
- clearTimeout(timeoutRef.current);
74520
- }
74521
- timeoutRef.current = setTimeout(() => {
74522
- setIsWaiting(false);
74523
- }, windowMs);
74524
- return false;
74525
- }, [windowMs, onFirstPress, onDoublePress, reset]);
74526
- return {
74527
- handleCtrlC,
74528
- reset,
74529
- isWaiting
74530
- };
74531
- }
74532
-
74533
- // src/repl/hooks/useHistory.ts
76137
+ // src/repl/components/ChatMode.tsx
74534
76138
  var import_react26 = __toESM(require_react(), 1);
74535
- function useHistory(options) {
74536
- const { history, onSelect } = options;
74537
- const [historyIndex, setHistoryIndex] = (0, import_react26.useState)(-1);
74538
- const reset = (0, import_react26.useCallback)(() => {
74539
- setHistoryIndex(-1);
74540
- }, []);
74541
- const navigateUp = (0, import_react26.useCallback)(() => {
74542
- if (history.length === 0) {
74543
- return null;
74544
- }
74545
- const newIndex = Math.min(historyIndex + 1, history.length - 1);
74546
- setHistoryIndex(newIndex);
74547
- const command = history[history.length - 1 - newIndex];
74548
- if (command !== void 0) {
74549
- onSelect?.(command);
74550
- return command;
74551
- }
74552
- return null;
74553
- }, [history, historyIndex, onSelect]);
74554
- const navigateDown = (0, import_react26.useCallback)(() => {
74555
- if (historyIndex <= 0) {
74556
- if (historyIndex === 0) {
74557
- setHistoryIndex(-1);
74558
- onSelect?.("");
74559
- return "";
74560
- }
74561
- return null;
74562
- }
74563
- const newIndex = historyIndex - 1;
74564
- setHistoryIndex(newIndex);
74565
- const command = history[history.length - 1 - newIndex];
74566
- if (command !== void 0) {
74567
- onSelect?.(command);
74568
- return command;
74569
- }
74570
- return null;
74571
- }, [history, historyIndex, onSelect]);
74572
- return {
74573
- navigateUp,
74574
- navigateDown,
74575
- reset,
74576
- isNavigating: historyIndex >= 0,
74577
- currentIndex: historyIndex
74578
- };
74579
- }
74580
76139
 
74581
- // src/repl/hooks/useCompletion.ts
74582
- var import_react27 = __toESM(require_react(), 1);
76140
+ // node_modules/ink-spinner/build/index.js
76141
+ var import_react25 = __toESM(require_react(), 1);
76142
+ var import_cli_spinners = __toESM(require_cli_spinners(), 1);
76143
+ function Spinner({ type = "dots" }) {
76144
+ const [frame, setFrame] = (0, import_react25.useState)(0);
76145
+ const spinner = import_cli_spinners.default[type];
76146
+ (0, import_react25.useEffect)(() => {
76147
+ const timer = setInterval(() => {
76148
+ setFrame((previousFrame) => {
76149
+ const isLastFrame = previousFrame === spinner.frames.length - 1;
76150
+ return isLastFrame ? 0 : previousFrame + 1;
76151
+ });
76152
+ }, spinner.interval);
76153
+ return () => {
76154
+ clearInterval(timer);
76155
+ };
76156
+ }, [spinner]);
76157
+ return import_react25.default.createElement(Text, null, spinner.frames[frame]);
76158
+ }
76159
+ var build_default2 = Spinner;
74583
76160
 
74584
- // src/domains/login/profile/list.ts
74585
- var listCommand = {
74586
- name: "list",
74587
- description: "Display all saved connection profiles with their tenant URLs and authentication types. Highlights the currently active profile for easy identification when managing multiple tenants.",
74588
- descriptionShort: "List all saved profiles",
74589
- descriptionMedium: "Show all profiles with tenant URLs, auth types, and active status indicator.",
74590
- aliases: ["ls"],
74591
- async execute(args, session) {
74592
- const { options } = parseDomainOutputFlags(
74593
- args,
74594
- session.getOutputFormat()
76161
+ // src/domains/ai_services/client.ts
76162
+ var GenAIClient = class {
76163
+ constructor(apiClient) {
76164
+ this.apiClient = apiClient;
76165
+ }
76166
+ /**
76167
+ * Query the AI assistant
76168
+ *
76169
+ * @param namespace - The namespace context for the query
76170
+ * @param query - The natural language query
76171
+ * @returns The AI assistant response with query_id and response data
76172
+ */
76173
+ async query(namespace, query) {
76174
+ const request = {
76175
+ current_query: query,
76176
+ namespace
76177
+ };
76178
+ const response = await this.apiClient.post(
76179
+ `/api/gen-ai/namespaces/${namespace}/query`,
76180
+ request
74595
76181
  );
74596
- const manager = getProfileManager();
74597
- try {
74598
- const profiles = await manager.list();
74599
- const activeProfile = await manager.getActive();
74600
- if (profiles.length === 0) {
74601
- if (options.format === "none") {
74602
- return successResult([]);
74603
- }
74604
- return successResult([
74605
- "No profiles configured.",
74606
- "",
74607
- "Create a profile with: login profile create <name>"
74608
- ]);
74609
- }
74610
- const data = profiles.map((profile) => {
74611
- const isActive = profile.name === activeProfile;
74612
- const authType = profile.apiToken ? "token" : profile.cert ? "cert" : profile.p12Bundle ? "p12" : "none";
74613
- return {
74614
- name: profile.name,
74615
- apiUrl: profile.apiUrl,
74616
- authType,
74617
- active: isActive
74618
- };
74619
- });
74620
- if (options.format === "none") {
74621
- return successResult([]);
74622
- }
74623
- if (options.format === "json" || options.format === "yaml" || options.format === "tsv") {
74624
- return successResult(formatListOutput(data, options));
74625
- }
74626
- const output = ["Saved profiles:"];
74627
- for (const item of data) {
74628
- const marker = item.active ? " [active]" : "";
74629
- output.push(
74630
- ` ${item.name}${marker} - ${item.apiUrl} (${item.authType})`
74631
- );
74632
- }
74633
- return successResult(output);
74634
- } catch (error) {
74635
- return errorResult(
74636
- `Failed to list profiles: ${error instanceof Error ? error.message : "Unknown error"}`
76182
+ if (!response.ok) {
76183
+ throw new Error(
76184
+ `GenAI query failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
74637
76185
  );
74638
76186
  }
76187
+ return response.data;
74639
76188
  }
74640
- };
74641
-
74642
- // src/domains/login/profile/show.ts
74643
- var showCommand = {
74644
- name: "show",
74645
- description: "Display detailed configuration for a specific profile. Shows tenant URL, authentication method, and namespace settings with sensitive credentials securely masked for safe viewing.",
74646
- descriptionShort: "Show profile details (masked credentials)",
74647
- descriptionMedium: "Display profile configuration with tenant URL, auth type, and masked credentials.",
74648
- usage: "<name>",
74649
- aliases: ["get", "view"],
74650
- async execute(args, session) {
74651
- const { options, remainingArgs } = parseDomainOutputFlags(
74652
- args,
74653
- session.getOutputFormat()
76189
+ /**
76190
+ * Submit feedback for a query
76191
+ *
76192
+ * @param request - The feedback request with query_id and feedback type
76193
+ */
76194
+ async feedback(request) {
76195
+ const response = await this.apiClient.post(
76196
+ `/api/gen-ai/namespaces/${request.namespace}/query_feedback`,
76197
+ request
74654
76198
  );
74655
- const manager = getProfileManager();
74656
- const name = remainingArgs[0];
74657
- if (!name) {
74658
- return errorResult("Usage: login profile show <name>");
76199
+ if (!response.ok) {
76200
+ throw new Error(
76201
+ `GenAI feedback failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
76202
+ );
74659
76203
  }
74660
- try {
74661
- const profile = await manager.get(name);
74662
- if (!profile) {
74663
- return errorResult(`Profile '${name}' not found.`);
74664
- }
74665
- const masked = manager.maskProfile(profile);
74666
- const activeProfile = await manager.getActive();
74667
- const isActive = profile.name === activeProfile;
74668
- if (options.format === "none") {
74669
- return successResult([]);
74670
- }
74671
- const data = {
74672
- name: profile.name,
74673
- apiUrl: masked.apiUrl,
74674
- active: isActive
74675
- };
74676
- if (masked.apiToken) data.apiToken = masked.apiToken;
74677
- if (masked.p12Bundle) data.p12Bundle = masked.p12Bundle;
74678
- if (masked.cert) data.cert = masked.cert;
74679
- if (masked.key) data.key = masked.key;
74680
- if (masked.defaultNamespace)
74681
- data.namespace = masked.defaultNamespace;
74682
- if (options.format === "json" || options.format === "yaml" || options.format === "tsv") {
74683
- return successResult(
74684
- formatKeyValueOutput(data, {
74685
- ...options,
74686
- title: "Profile"
74687
- })
74688
- );
74689
- }
74690
- const output = [
74691
- `Profile: ${profile.name}${isActive ? " [active]" : ""}`,
74692
- ``,
74693
- ` API URL: ${masked.apiUrl}`
74694
- ];
74695
- if (masked.apiToken) {
74696
- output.push(` API Token: ${masked.apiToken}`);
74697
- }
74698
- if (masked.p12Bundle) {
74699
- output.push(` P12 Bundle: ${masked.p12Bundle}`);
74700
- }
74701
- if (masked.cert) {
74702
- output.push(` Certificate: ${masked.cert}`);
74703
- }
74704
- if (masked.key) {
74705
- output.push(` Private Key: ${masked.key}`);
74706
- }
74707
- if (masked.defaultNamespace) {
74708
- output.push(` Namespace: ${masked.defaultNamespace}`);
74709
- }
74710
- return successResult(output);
74711
- } catch (error) {
74712
- return errorResult(
74713
- `Failed to show profile: ${error instanceof Error ? error.message : "Unknown error"}`
76204
+ }
76205
+ /**
76206
+ * Query the AI assistant in eval mode (for RBAC testing)
76207
+ *
76208
+ * @param namespace - The namespace context for the query
76209
+ * @param query - The natural language query
76210
+ * @returns The AI assistant response
76211
+ */
76212
+ async evalQuery(namespace, query) {
76213
+ const request = {
76214
+ current_query: query,
76215
+ namespace
76216
+ };
76217
+ const response = await this.apiClient.post(
76218
+ `/api/gen-ai/namespaces/${namespace}/eval_query`,
76219
+ request
76220
+ );
76221
+ if (!response.ok) {
76222
+ throw new Error(
76223
+ `GenAI eval query failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
74714
76224
  );
74715
76225
  }
74716
- },
74717
- async completion(partial, _args, _session) {
74718
- const manager = getProfileManager();
74719
- const profiles = await manager.list();
74720
- return profiles.map((p) => p.name).filter(
74721
- (name) => name.toLowerCase().startsWith(partial.toLowerCase())
76226
+ return response.data;
76227
+ }
76228
+ /**
76229
+ * Submit feedback for an eval query
76230
+ *
76231
+ * @param request - The feedback request with query_id and feedback type
76232
+ */
76233
+ async evalFeedback(request) {
76234
+ const response = await this.apiClient.post(
76235
+ `/api/gen-ai/namespaces/${request.namespace}/eval_query_feedback`,
76236
+ request
74722
76237
  );
76238
+ if (!response.ok) {
76239
+ throw new Error(
76240
+ `GenAI eval feedback failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
76241
+ );
76242
+ }
74723
76243
  }
74724
76244
  };
76245
+ var cachedClient = null;
76246
+ function getGenAIClient(apiClient) {
76247
+ if (!cachedClient) {
76248
+ cachedClient = new GenAIClient(apiClient);
76249
+ }
76250
+ return cachedClient;
76251
+ }
74725
76252
 
74726
- // src/domains/login/profile/connection-table.ts
74727
- var UNICODE_BOX2 = {
74728
- topLeft: "\u256D",
74729
- //
74730
- topRight: "\u256E",
74731
- //
74732
- bottomLeft: "\u2570",
74733
- //
74734
- bottomRight: "\u256F",
74735
- // ╯
74736
- horizontal: "\u2500",
74737
- //
74738
- vertical: "\u2502",
74739
- //
74740
- leftT: "\u251C",
74741
- //
74742
- rightT: "\u2524"
74743
- //
74744
- };
74745
- var ASCII_BOX2 = {
74746
- topLeft: "+",
74747
- topRight: "+",
74748
- bottomLeft: "+",
74749
- bottomRight: "+",
74750
- horizontal: "-",
74751
- vertical: "|",
74752
- leftT: "+",
74753
- rightT: "+"
74754
- };
74755
- function extractTenantFromUrl(url) {
74756
- try {
76253
+ // src/domains/ai_services/types.ts
76254
+ function getResponseType(response) {
76255
+ if (response.generic_response) return "generic_response";
76256
+ if (response.explain_log) return "explain_log";
76257
+ if (response.gen_dashboard_filter) return "gen_dashboard_filter";
76258
+ if (response.list_response) return "list_response";
76259
+ if (response.site_analysis_response) return "site_analysis_response";
76260
+ if (response.widget_response) return "widget_response";
76261
+ return null;
76262
+ }
76263
+ var FEEDBACK_TYPE_MAP = {
76264
+ other: "OTHER",
76265
+ inaccurate: "INACCURATE_DATA",
76266
+ irrelevant: "IRRELEVANT_CONTENT",
76267
+ poor_format: "POOR_FORMAT",
76268
+ slow: "SLOW_RESPONSE"
76269
+ };
76270
+ function getValidFeedbackTypes() {
76271
+ return Object.keys(FEEDBACK_TYPE_MAP);
76272
+ }
76273
+
76274
+ // src/domains/ai_services/response-renderer.ts
76275
+ function renderResponse(response) {
76276
+ const lines = [];
76277
+ const responseType = getResponseType(response);
76278
+ switch (responseType) {
76279
+ case "generic_response":
76280
+ lines.push(...renderGenericResponse(response.generic_response));
76281
+ break;
76282
+ case "explain_log":
76283
+ lines.push(...renderExplainLog(response.explain_log));
76284
+ break;
76285
+ case "gen_dashboard_filter":
76286
+ lines.push(
76287
+ ...renderDashboardFilter(response.gen_dashboard_filter)
76288
+ );
76289
+ break;
76290
+ case "list_response":
76291
+ lines.push(...renderListResponse(response.list_response));
76292
+ break;
76293
+ case "site_analysis_response":
76294
+ lines.push(...renderSiteAnalysis(response.site_analysis_response));
76295
+ break;
76296
+ case "widget_response":
76297
+ lines.push(...renderWidgetResponse(response.widget_response));
76298
+ break;
76299
+ default:
76300
+ lines.push("No response content.");
76301
+ }
76302
+ if (response.follow_up_queries && response.follow_up_queries.length > 0) {
76303
+ lines.push("");
76304
+ lines.push("Suggested follow-up questions:");
76305
+ response.follow_up_queries.forEach((q, i) => {
76306
+ lines.push(` ${i + 1}. ${q}`);
76307
+ });
76308
+ }
76309
+ return lines;
76310
+ }
76311
+ function stripHtml(html) {
76312
+ return html.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n\n").replace(/<\/li>/gi, "\n").replace(/<\/h[1-6]>/gi, "\n\n").replace(/<hr\s*\/?>/gi, "\n---\n").replace(/<a[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, "$2 ($1)").replace(/<code>([^<]*)<\/code>/gi, "`$1`").replace(/<li[^>]*>/gi, " \u2022 ").replace(/<h3[^>]*>/gi, "\n### ").replace(/<h[1-6][^>]*>/gi, "\n").replace(/<ol[^>]*>/gi, "").replace(/<\/ol>/gi, "").replace(/<ul[^>]*>/gi, "").replace(/<\/ul>/gi, "").replace(/<strong>([^<]*)<\/strong>/gi, "**$1**").replace(/<b>([^<]*)<\/b>/gi, "**$1**").replace(/<em>([^<]*)<\/em>/gi, "*$1*").replace(/<i>([^<]*)<\/i>/gi, "*$1*").replace(/<[^>]+>/g, "").replace(/\n{3,}/g, "\n\n").trim();
76313
+ }
76314
+ function renderGenericResponse(response) {
76315
+ const lines = [];
76316
+ if (response.is_error || response.error && response.error !== null) {
76317
+ lines.push(`Error: ${response.error ?? "Unknown error"}`);
76318
+ return lines;
76319
+ }
76320
+ const content = response.summary ?? response.text;
76321
+ if (content) {
76322
+ const plainText = stripHtml(content);
76323
+ lines.push(...plainText.split("\n"));
76324
+ }
76325
+ if (response.links && response.links.length > 0) {
76326
+ lines.push("");
76327
+ lines.push("Related links:");
76328
+ for (const link3 of response.links) {
76329
+ lines.push(` - ${link3.title}: ${link3.url}`);
76330
+ }
76331
+ }
76332
+ return lines;
76333
+ }
76334
+ function renderExplainLog(response) {
76335
+ const lines = [];
76336
+ lines.push("=== Security Event Analysis ===");
76337
+ lines.push("");
76338
+ if (response.summary) {
76339
+ lines.push("Summary:");
76340
+ lines.push(` ${response.summary}`);
76341
+ lines.push("");
76342
+ }
76343
+ if (response.action) {
76344
+ lines.push(`Action Taken: ${response.action}`);
76345
+ }
76346
+ if (response.accuracy) {
76347
+ lines.push(`Accuracy: ${response.accuracy}`);
76348
+ }
76349
+ if (response.violations && response.violations.length > 0) {
76350
+ lines.push("");
76351
+ lines.push("Violations Detected:");
76352
+ for (const v of response.violations) {
76353
+ lines.push(` - ${v.name}: ${v.description}`);
76354
+ }
76355
+ }
76356
+ if (response.threat_campaigns && response.threat_campaigns.length > 0) {
76357
+ lines.push("");
76358
+ lines.push("Threat Campaigns:");
76359
+ for (const campaign of response.threat_campaigns) {
76360
+ lines.push(` - ${campaign}`);
76361
+ }
76362
+ }
76363
+ if (response.request_details) {
76364
+ lines.push("");
76365
+ lines.push("Request Details:");
76366
+ lines.push(` ${JSON.stringify(response.request_details, null, 2)}`);
76367
+ }
76368
+ return lines;
76369
+ }
76370
+ function renderDashboardFilter(response) {
76371
+ const lines = [];
76372
+ lines.push("=== Dashboard Filter ===");
76373
+ lines.push("");
76374
+ if (response.filter_expression) {
76375
+ lines.push("Filter Expression:");
76376
+ lines.push(` ${response.filter_expression}`);
76377
+ }
76378
+ if (response.dashboard_context) {
76379
+ lines.push("");
76380
+ lines.push("Dashboard Context:");
76381
+ lines.push(` ${response.dashboard_context}`);
76382
+ }
76383
+ return lines;
76384
+ }
76385
+ function renderListResponse(response) {
76386
+ const lines = [];
76387
+ if (response.formatted_list) {
76388
+ lines.push(response.formatted_list);
76389
+ return lines;
76390
+ }
76391
+ if (response.items && response.items.length > 0) {
76392
+ if (response.total_count !== void 0) {
76393
+ lines.push(`Total: ${response.total_count} items`);
76394
+ lines.push("");
76395
+ }
76396
+ for (const item of response.items) {
76397
+ lines.push(JSON.stringify(item, null, 2));
76398
+ lines.push("");
76399
+ }
76400
+ } else {
76401
+ lines.push("No items found.");
76402
+ }
76403
+ return lines;
76404
+ }
76405
+ function renderSiteAnalysis(response) {
76406
+ const lines = [];
76407
+ lines.push("=== Site Analysis ===");
76408
+ lines.push("");
76409
+ if (response.site_name) {
76410
+ lines.push(`Site: ${response.site_name}`);
76411
+ }
76412
+ if (response.health_status) {
76413
+ lines.push(`Health: ${response.health_status}`);
76414
+ }
76415
+ if (response.metrics) {
76416
+ lines.push("");
76417
+ lines.push("Metrics:");
76418
+ for (const [key, value] of Object.entries(response.metrics)) {
76419
+ lines.push(` ${key}: ${JSON.stringify(value)}`);
76420
+ }
76421
+ }
76422
+ if (response.recommendations && response.recommendations.length > 0) {
76423
+ lines.push("");
76424
+ lines.push("Recommendations:");
76425
+ for (const rec of response.recommendations) {
76426
+ lines.push(` - ${rec}`);
76427
+ }
76428
+ }
76429
+ return lines;
76430
+ }
76431
+ function renderWidgetResponse(response) {
76432
+ const lines = [];
76433
+ if (response.display_type) {
76434
+ lines.push(`Widget Type: ${response.display_type}`);
76435
+ lines.push("");
76436
+ }
76437
+ if (response.table) {
76438
+ for (const row of response.table.rows) {
76439
+ const cells = row.cells.map((cell) => {
76440
+ let value = cell.value;
76441
+ if (cell.properties?.status_style) {
76442
+ value = `[${cell.properties.status_style}] ${value}`;
76443
+ }
76444
+ return value;
76445
+ });
76446
+ lines.push(cells.join(" | "));
76447
+ }
76448
+ }
76449
+ if (response.links && response.links.length > 0) {
76450
+ lines.push("");
76451
+ lines.push("Links:");
76452
+ for (const link3 of response.links) {
76453
+ lines.push(` - ${link3.title}: ${link3.url}`);
76454
+ }
76455
+ }
76456
+ return lines;
76457
+ }
76458
+
76459
+ // src/domains/ai_services/query.ts
76460
+ var lastQueryState = {
76461
+ namespace: "",
76462
+ lastQueryId: null,
76463
+ lastQuery: null,
76464
+ followUpQueries: [],
76465
+ isActive: false
76466
+ };
76467
+ function getLastQueryState() {
76468
+ return lastQueryState;
76469
+ }
76470
+ function updateLastQueryState(partial) {
76471
+ lastQueryState = { ...lastQueryState, ...partial };
76472
+ }
76473
+ function clearLastQueryState() {
76474
+ lastQueryState = {
76475
+ namespace: "",
76476
+ lastQueryId: null,
76477
+ lastQuery: null,
76478
+ followUpQueries: [],
76479
+ isActive: false
76480
+ };
76481
+ }
76482
+ function parseQueryArgs(args, session) {
76483
+ const { options, remainingArgs } = parseDomainOutputFlags(
76484
+ args,
76485
+ session.getOutputFormat()
76486
+ );
76487
+ let spec = false;
76488
+ let namespace = session.getNamespace();
76489
+ const questionParts = [];
76490
+ let i = 0;
76491
+ while (i < remainingArgs.length) {
76492
+ const arg = remainingArgs[i];
76493
+ if (arg === "--spec") {
76494
+ spec = true;
76495
+ } else if (arg === "--namespace" || arg === "-ns") {
76496
+ if (i + 1 < remainingArgs.length) {
76497
+ namespace = remainingArgs[i + 1] ?? namespace;
76498
+ i++;
76499
+ }
76500
+ } else {
76501
+ questionParts.push(arg ?? "");
76502
+ }
76503
+ i++;
76504
+ }
76505
+ return {
76506
+ format: options.format,
76507
+ noColor: options.noColor,
76508
+ spec,
76509
+ namespace,
76510
+ question: questionParts.join(" ")
76511
+ };
76512
+ }
76513
+ var queryCommand = {
76514
+ name: "query",
76515
+ description: "Send a natural language query to the F5 Distributed Cloud AI assistant. Ask about load balancers, WAF configurations, site status, security events, or any platform topic. Returns AI-generated responses with optional follow-up suggestions. Use --namespace to specify the context for namespace-scoped resources.",
76516
+ descriptionShort: "Query the AI assistant",
76517
+ descriptionMedium: "Send natural language queries to the AI assistant for help with F5 XC platform operations, configurations, and troubleshooting.",
76518
+ usage: "<question> [--namespace <ns>]",
76519
+ aliases: ["ask", "q"],
76520
+ async execute(args, session) {
76521
+ const { format, noColor, spec, namespace, question } = parseQueryArgs(
76522
+ args,
76523
+ session
76524
+ );
76525
+ if (spec) {
76526
+ const cmdSpec = getCommandSpec("ai_services query");
76527
+ if (cmdSpec) {
76528
+ return successResult([formatSpec(cmdSpec)]);
76529
+ }
76530
+ }
76531
+ if (!question.trim()) {
76532
+ return errorResult(
76533
+ "Please provide a question. Usage: ai query <question>"
76534
+ );
76535
+ }
76536
+ const apiClient = session.getAPIClient();
76537
+ if (!apiClient) {
76538
+ return errorResult(
76539
+ "Not connected to API. Please configure connection first."
76540
+ );
76541
+ }
76542
+ if (!session.isTokenValidated()) {
76543
+ return errorResult(
76544
+ "Not authenticated. Please check your API token."
76545
+ );
76546
+ }
76547
+ try {
76548
+ const client = getGenAIClient(apiClient);
76549
+ const response = await client.query(namespace, question);
76550
+ updateLastQueryState({
76551
+ namespace,
76552
+ lastQueryId: response.query_id,
76553
+ lastQuery: question,
76554
+ followUpQueries: response.follow_up_queries ?? [],
76555
+ isActive: true
76556
+ });
76557
+ if (format === "none") {
76558
+ return successResult([]);
76559
+ }
76560
+ if (format === "json" || format === "yaml" || format === "tsv") {
76561
+ return successResult(
76562
+ formatDomainOutput(response, { format, noColor })
76563
+ );
76564
+ }
76565
+ const lines = renderResponse(response);
76566
+ return successResult(lines);
76567
+ } catch (error) {
76568
+ const message = error instanceof Error ? error.message : String(error);
76569
+ return errorResult(`Query failed: ${message}`);
76570
+ }
76571
+ }
76572
+ };
76573
+
76574
+ // src/repl/components/ChatMode.tsx
76575
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
76576
+ function HorizontalRule2({ width }) {
76577
+ const rule = "\u2500".repeat(Math.max(width, 1));
76578
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "#CA260A", children: rule });
76579
+ }
76580
+ function ChatMode({
76581
+ session,
76582
+ namespace,
76583
+ width,
76584
+ onExit
76585
+ }) {
76586
+ const [input, setInput] = (0, import_react26.useState)("");
76587
+ const [inputKey, setInputKey] = (0, import_react26.useState)(0);
76588
+ const [messages, setMessages] = (0, import_react26.useState)([]);
76589
+ const messageIdRef = (0, import_react26.useRef)(0);
76590
+ const [isLoading, setIsLoading] = (0, import_react26.useState)(false);
76591
+ const [followUps, setFollowUps] = (0, import_react26.useState)([]);
76592
+ const addMessage = (0, import_react26.useCallback)(
76593
+ (role, content) => {
76594
+ const id = messageIdRef.current++;
76595
+ setMessages((prev) => [...prev, { id, role, content }]);
76596
+ },
76597
+ []
76598
+ );
76599
+ (0, import_react26.useEffect)(() => {
76600
+ addMessage("system", "=== F5 XC AI Assistant Chat ===");
76601
+ addMessage("system", `Namespace: ${namespace}`);
76602
+ addMessage("system", "Type /help for commands, /exit to quit.");
76603
+ addMessage("system", "");
76604
+ }, [namespace, addMessage]);
76605
+ const showHelp = (0, import_react26.useCallback)(() => {
76606
+ addMessage("system", "");
76607
+ addMessage("system", "=== AI Chat Commands ===");
76608
+ addMessage("system", "");
76609
+ addMessage("system", " /exit, /quit, /q - Exit chat mode");
76610
+ addMessage("system", " /help, /h - Show this help");
76611
+ addMessage(
76612
+ "system",
76613
+ " /clear, /c - Clear conversation context"
76614
+ );
76615
+ addMessage(
76616
+ "system",
76617
+ " /feedback <type> - Submit feedback (positive/negative)"
76618
+ );
76619
+ addMessage(
76620
+ "system",
76621
+ " 1, 2, 3... - Select a follow-up question"
76622
+ );
76623
+ addMessage("system", "");
76624
+ addMessage(
76625
+ "system",
76626
+ "Just type your question to query the AI assistant."
76627
+ );
76628
+ addMessage("system", "");
76629
+ }, [addMessage]);
76630
+ const handleFeedback = (0, import_react26.useCallback)(
76631
+ async (feedbackInput) => {
76632
+ const state = getLastQueryState();
76633
+ if (!state.lastQueryId || !state.lastQuery) {
76634
+ addMessage(
76635
+ "system",
76636
+ "No previous query to provide feedback for."
76637
+ );
76638
+ return;
76639
+ }
76640
+ const parts = feedbackInput.split(/\s+/);
76641
+ const feedbackType = parts[1]?.toLowerCase();
76642
+ if (!feedbackType) {
76643
+ addMessage("system", "Usage: /feedback <positive|negative>");
76644
+ return;
76645
+ }
76646
+ const apiClient = session.getAPIClient();
76647
+ if (!apiClient) {
76648
+ addMessage("system", "Not connected to API.");
76649
+ return;
76650
+ }
76651
+ try {
76652
+ const client = getGenAIClient(apiClient);
76653
+ if (feedbackType === "positive" || feedbackType === "+") {
76654
+ await client.feedback({
76655
+ query: state.lastQuery,
76656
+ query_id: state.lastQueryId,
76657
+ namespace: state.namespace,
76658
+ positive_feedback: {}
76659
+ });
76660
+ addMessage(
76661
+ "system",
76662
+ "Positive feedback submitted. Thank you!"
76663
+ );
76664
+ } else if (feedbackType === "negative" || feedbackType === "-") {
76665
+ const negType = parts[2]?.toLowerCase();
76666
+ const mappedType = negType ? FEEDBACK_TYPE_MAP[negType] : void 0;
76667
+ const comment = parts.slice(3).join(" ") || void 0;
76668
+ await client.feedback({
76669
+ query: state.lastQuery,
76670
+ query_id: state.lastQueryId,
76671
+ namespace: state.namespace,
76672
+ negative_feedback: {
76673
+ remarks: mappedType ? [mappedType] : ["OTHER"]
76674
+ },
76675
+ comment
76676
+ });
76677
+ addMessage(
76678
+ "system",
76679
+ "Negative feedback submitted. Thank you for helping improve the AI."
76680
+ );
76681
+ } else {
76682
+ addMessage(
76683
+ "system",
76684
+ `Unknown feedback type: ${feedbackType}. Use 'positive' or 'negative'.`
76685
+ );
76686
+ }
76687
+ } catch (error) {
76688
+ const message = error instanceof Error ? error.message : String(error);
76689
+ addMessage("system", `Feedback failed: ${message}`);
76690
+ }
76691
+ },
76692
+ [session, addMessage]
76693
+ );
76694
+ const handleFollowUp = (0, import_react26.useCallback)(
76695
+ async (num) => {
76696
+ const state = getLastQueryState();
76697
+ if (num < 1 || num > state.followUpQueries.length) {
76698
+ addMessage(
76699
+ "system",
76700
+ `Invalid selection. Choose 1-${state.followUpQueries.length} from suggested follow-ups.`
76701
+ );
76702
+ return;
76703
+ }
76704
+ const followUp = state.followUpQueries[num - 1];
76705
+ if (!followUp) return;
76706
+ addMessage("user", followUp);
76707
+ setFollowUps([]);
76708
+ setIsLoading(true);
76709
+ const apiClient = session.getAPIClient();
76710
+ if (!apiClient) {
76711
+ addMessage("system", "Not connected to API.");
76712
+ setIsLoading(false);
76713
+ return;
76714
+ }
76715
+ try {
76716
+ const client = getGenAIClient(apiClient);
76717
+ const response = await client.query(namespace, followUp);
76718
+ updateLastQueryState({
76719
+ namespace,
76720
+ lastQueryId: response.query_id,
76721
+ lastQuery: followUp,
76722
+ followUpQueries: response.follow_up_queries ?? []
76723
+ });
76724
+ const lines = renderResponse(response);
76725
+ for (const line of lines) {
76726
+ addMessage("ai", line);
76727
+ }
76728
+ setFollowUps(response.follow_up_queries ?? []);
76729
+ } catch (error) {
76730
+ const message = error instanceof Error ? error.message : String(error);
76731
+ addMessage("system", `Query failed: ${message}`);
76732
+ } finally {
76733
+ setIsLoading(false);
76734
+ }
76735
+ },
76736
+ [session, namespace, addMessage]
76737
+ );
76738
+ const sendQuery = (0, import_react26.useCallback)(
76739
+ async (query) => {
76740
+ addMessage("user", query);
76741
+ setFollowUps([]);
76742
+ setIsLoading(true);
76743
+ const apiClient = session.getAPIClient();
76744
+ if (!apiClient) {
76745
+ addMessage("system", "Not connected to API.");
76746
+ setIsLoading(false);
76747
+ return;
76748
+ }
76749
+ try {
76750
+ const client = getGenAIClient(apiClient);
76751
+ const response = await client.query(namespace, query);
76752
+ updateLastQueryState({
76753
+ namespace,
76754
+ lastQueryId: response.query_id,
76755
+ lastQuery: query,
76756
+ followUpQueries: response.follow_up_queries ?? []
76757
+ });
76758
+ addMessage("ai", "");
76759
+ const lines = renderResponse(response);
76760
+ for (const line of lines) {
76761
+ addMessage("ai", line);
76762
+ }
76763
+ setFollowUps(response.follow_up_queries ?? []);
76764
+ } catch (error) {
76765
+ const message = error instanceof Error ? error.message : String(error);
76766
+ addMessage("system", `Query failed: ${message}`);
76767
+ } finally {
76768
+ setIsLoading(false);
76769
+ }
76770
+ },
76771
+ [session, namespace, addMessage]
76772
+ );
76773
+ const handleSubmit = (0, import_react26.useCallback)(
76774
+ async (value) => {
76775
+ const trimmed = value.trim();
76776
+ if (!trimmed) return;
76777
+ setInput("");
76778
+ setInputKey((k) => k + 1);
76779
+ if (trimmed === "/exit" || trimmed === "/quit" || trimmed === "/q") {
76780
+ addMessage("system", "Exiting chat mode.");
76781
+ const allMessages = messages.map((m) => {
76782
+ if (m.role === "user") return `You: ${m.content}`;
76783
+ if (m.role === "ai") return `AI: ${m.content}`;
76784
+ return m.content;
76785
+ });
76786
+ allMessages.push("Chat session ended.");
76787
+ onExit(allMessages);
76788
+ return;
76789
+ }
76790
+ if (trimmed === "/help" || trimmed === "/h") {
76791
+ showHelp();
76792
+ return;
76793
+ }
76794
+ if (trimmed === "/clear" || trimmed === "/c") {
76795
+ clearLastQueryState();
76796
+ setFollowUps([]);
76797
+ addMessage("system", "Conversation context cleared.");
76798
+ return;
76799
+ }
76800
+ if (trimmed.startsWith("/feedback")) {
76801
+ await handleFeedback(trimmed);
76802
+ return;
76803
+ }
76804
+ if (/^\d+$/.test(trimmed)) {
76805
+ const num = parseInt(trimmed, 10);
76806
+ const state = getLastQueryState();
76807
+ if (state.followUpQueries.length > 0) {
76808
+ await handleFollowUp(num);
76809
+ return;
76810
+ }
76811
+ }
76812
+ if (trimmed.startsWith("/")) {
76813
+ addMessage(
76814
+ "system",
76815
+ `Unknown command: ${trimmed}. Type /help for commands.`
76816
+ );
76817
+ return;
76818
+ }
76819
+ await sendQuery(trimmed);
76820
+ },
76821
+ [
76822
+ messages,
76823
+ onExit,
76824
+ showHelp,
76825
+ handleFeedback,
76826
+ handleFollowUp,
76827
+ sendQuery,
76828
+ addMessage
76829
+ ]
76830
+ );
76831
+ use_input_default((char, key) => {
76832
+ if (key.ctrl && char === "c") {
76833
+ addMessage("system", "Exiting chat mode.");
76834
+ const allMessages = messages.map((m) => {
76835
+ if (m.role === "user") return `You: ${m.content}`;
76836
+ if (m.role === "ai") return `AI: ${m.content}`;
76837
+ return m.content;
76838
+ });
76839
+ allMessages.push("Chat session ended.");
76840
+ onExit(allMessages);
76841
+ return;
76842
+ }
76843
+ });
76844
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", width, children: [
76845
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { flexDirection: "column", marginBottom: 1, children: messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
76846
+ Text,
76847
+ {
76848
+ color: msg.role === "user" ? "#00BFFF" : msg.role === "ai" ? "#FFFFFF" : "#888888",
76849
+ children: msg.role === "user" ? `You: ${msg.content}` : msg.content
76850
+ },
76851
+ msg.id
76852
+ )) }),
76853
+ followUps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
76854
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "#888888", children: "Follow-up suggestions:" }),
76855
+ followUps.map((fu, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "#AAAAAA", children: [
76856
+ " ",
76857
+ "[",
76858
+ i + 1,
76859
+ "] ",
76860
+ fu
76861
+ ] }, i))
76862
+ ] }),
76863
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "#00BFFF", children: [
76864
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(build_default2, { type: "dots" }),
76865
+ " Thinking..."
76866
+ ] }) }),
76867
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HorizontalRule2, { width }),
76868
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { children: [
76869
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { bold: true, color: "#00BFFF", children: [
76870
+ "ai",
76871
+ ">",
76872
+ " "
76873
+ ] }),
76874
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
76875
+ build_default,
76876
+ {
76877
+ value: input,
76878
+ onChange: setInput,
76879
+ onSubmit: handleSubmit,
76880
+ focus: !isLoading
76881
+ },
76882
+ inputKey
76883
+ )
76884
+ ] }),
76885
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HorizontalRule2, { width }),
76886
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { paddingX: 1, justifyContent: "space-between", children: [
76887
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "#666666", children: "/exit: quit | /help: commands | /clear: clear chat" }),
76888
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "#666666", children: "Ctrl+C to exit" })
76889
+ ] })
76890
+ ] });
76891
+ }
76892
+
76893
+ // src/repl/hooks/useDoubleCtrlC.ts
76894
+ var import_react27 = __toESM(require_react(), 1);
76895
+ function useDoubleCtrlC(options = {}) {
76896
+ const { windowMs = 500, onFirstPress, onDoublePress } = options;
76897
+ const lastPressRef = (0, import_react27.useRef)(0);
76898
+ const [isWaiting, setIsWaiting] = (0, import_react27.useState)(false);
76899
+ const timeoutRef = (0, import_react27.useRef)(null);
76900
+ const reset = (0, import_react27.useCallback)(() => {
76901
+ lastPressRef.current = 0;
76902
+ setIsWaiting(false);
76903
+ if (timeoutRef.current) {
76904
+ clearTimeout(timeoutRef.current);
76905
+ timeoutRef.current = null;
76906
+ }
76907
+ }, []);
76908
+ const handleCtrlC = (0, import_react27.useCallback)(() => {
76909
+ const now = Date.now();
76910
+ const elapsed = now - lastPressRef.current;
76911
+ if (elapsed < windowMs && lastPressRef.current !== 0) {
76912
+ reset();
76913
+ onDoublePress?.();
76914
+ return true;
76915
+ }
76916
+ lastPressRef.current = now;
76917
+ setIsWaiting(true);
76918
+ onFirstPress?.();
76919
+ if (timeoutRef.current) {
76920
+ clearTimeout(timeoutRef.current);
76921
+ }
76922
+ timeoutRef.current = setTimeout(() => {
76923
+ setIsWaiting(false);
76924
+ }, windowMs);
76925
+ return false;
76926
+ }, [windowMs, onFirstPress, onDoublePress, reset]);
76927
+ return {
76928
+ handleCtrlC,
76929
+ reset,
76930
+ isWaiting
76931
+ };
76932
+ }
76933
+
76934
+ // src/repl/hooks/useHistory.ts
76935
+ var import_react28 = __toESM(require_react(), 1);
76936
+ function useHistory(options) {
76937
+ const { history, onSelect } = options;
76938
+ const [historyIndex, setHistoryIndex] = (0, import_react28.useState)(-1);
76939
+ const reset = (0, import_react28.useCallback)(() => {
76940
+ setHistoryIndex(-1);
76941
+ }, []);
76942
+ const navigateUp = (0, import_react28.useCallback)(() => {
76943
+ if (history.length === 0) {
76944
+ return null;
76945
+ }
76946
+ const newIndex = Math.min(historyIndex + 1, history.length - 1);
76947
+ setHistoryIndex(newIndex);
76948
+ const command = history[history.length - 1 - newIndex];
76949
+ if (command !== void 0) {
76950
+ onSelect?.(command);
76951
+ return command;
76952
+ }
76953
+ return null;
76954
+ }, [history, historyIndex, onSelect]);
76955
+ const navigateDown = (0, import_react28.useCallback)(() => {
76956
+ if (historyIndex <= 0) {
76957
+ if (historyIndex === 0) {
76958
+ setHistoryIndex(-1);
76959
+ onSelect?.("");
76960
+ return "";
76961
+ }
76962
+ return null;
76963
+ }
76964
+ const newIndex = historyIndex - 1;
76965
+ setHistoryIndex(newIndex);
76966
+ const command = history[history.length - 1 - newIndex];
76967
+ if (command !== void 0) {
76968
+ onSelect?.(command);
76969
+ return command;
76970
+ }
76971
+ return null;
76972
+ }, [history, historyIndex, onSelect]);
76973
+ return {
76974
+ navigateUp,
76975
+ navigateDown,
76976
+ reset,
76977
+ isNavigating: historyIndex >= 0,
76978
+ currentIndex: historyIndex
76979
+ };
76980
+ }
76981
+
76982
+ // src/repl/hooks/useCompletion.ts
76983
+ var import_react29 = __toESM(require_react(), 1);
76984
+
76985
+ // src/domains/login/profile/list.ts
76986
+ var listCommand = {
76987
+ name: "list",
76988
+ description: "Display all saved connection profiles with their tenant URLs and authentication types. Highlights the currently active profile for easy identification when managing multiple tenants.",
76989
+ descriptionShort: "List all saved profiles",
76990
+ descriptionMedium: "Show all profiles with tenant URLs, auth types, and active status indicator.",
76991
+ async execute(args, session) {
76992
+ const { options } = parseDomainOutputFlags(
76993
+ args,
76994
+ session.getOutputFormat()
76995
+ );
76996
+ const manager = getProfileManager();
76997
+ try {
76998
+ const profiles = await manager.list();
76999
+ const activeProfile = await manager.getActive();
77000
+ if (profiles.length === 0) {
77001
+ if (options.format === "none") {
77002
+ return successResult([]);
77003
+ }
77004
+ return successResult([
77005
+ "No profiles configured.",
77006
+ "",
77007
+ "Create a profile with: login profile create <name>"
77008
+ ]);
77009
+ }
77010
+ const data = profiles.map((profile) => {
77011
+ const isActive = profile.name === activeProfile;
77012
+ const authType = profile.apiToken ? "token" : profile.cert ? "cert" : profile.p12Bundle ? "p12" : "none";
77013
+ return {
77014
+ name: profile.name,
77015
+ apiUrl: profile.apiUrl,
77016
+ authType,
77017
+ active: isActive
77018
+ };
77019
+ });
77020
+ if (options.format === "none") {
77021
+ return successResult([]);
77022
+ }
77023
+ if (options.format === "json" || options.format === "yaml" || options.format === "tsv") {
77024
+ return successResult(formatListOutput(data, options));
77025
+ }
77026
+ const output = ["Saved profiles:"];
77027
+ for (const item of data) {
77028
+ const marker = item.active ? " [active]" : "";
77029
+ output.push(
77030
+ ` ${item.name}${marker} - ${item.apiUrl} (${item.authType})`
77031
+ );
77032
+ }
77033
+ return successResult(output);
77034
+ } catch (error) {
77035
+ return errorResult(
77036
+ `Failed to list profiles: ${error instanceof Error ? error.message : "Unknown error"}`
77037
+ );
77038
+ }
77039
+ }
77040
+ };
77041
+
77042
+ // src/domains/login/profile/show.ts
77043
+ var showCommand = {
77044
+ name: "show",
77045
+ description: "Display detailed configuration for a specific profile. Shows tenant URL, authentication method, and namespace settings with sensitive credentials securely masked for safe viewing.",
77046
+ descriptionShort: "Show profile details (masked credentials)",
77047
+ descriptionMedium: "Display profile configuration with tenant URL, auth type, and masked credentials.",
77048
+ usage: "<name>",
77049
+ aliases: ["get", "view"],
77050
+ async execute(args, session) {
77051
+ const { options, remainingArgs } = parseDomainOutputFlags(
77052
+ args,
77053
+ session.getOutputFormat()
77054
+ );
77055
+ const manager = getProfileManager();
77056
+ const name = remainingArgs[0];
77057
+ if (!name) {
77058
+ return errorResult("Usage: login profile show <name>");
77059
+ }
77060
+ try {
77061
+ const profile = await manager.get(name);
77062
+ if (!profile) {
77063
+ return errorResult(`Profile '${name}' not found.`);
77064
+ }
77065
+ const masked = manager.maskProfile(profile);
77066
+ const activeProfile = await manager.getActive();
77067
+ const isActive = profile.name === activeProfile;
77068
+ if (options.format === "none") {
77069
+ return successResult([]);
77070
+ }
77071
+ const data = {
77072
+ name: profile.name,
77073
+ apiUrl: masked.apiUrl,
77074
+ active: isActive
77075
+ };
77076
+ if (masked.apiToken) data.apiToken = masked.apiToken;
77077
+ if (masked.p12Bundle) data.p12Bundle = masked.p12Bundle;
77078
+ if (masked.cert) data.cert = masked.cert;
77079
+ if (masked.key) data.key = masked.key;
77080
+ if (masked.defaultNamespace)
77081
+ data.namespace = masked.defaultNamespace;
77082
+ if (options.format === "json" || options.format === "yaml" || options.format === "tsv") {
77083
+ return successResult(
77084
+ formatKeyValueOutput(data, {
77085
+ ...options,
77086
+ title: "Profile"
77087
+ })
77088
+ );
77089
+ }
77090
+ const output = [
77091
+ `Profile: ${profile.name}${isActive ? " [active]" : ""}`,
77092
+ ``,
77093
+ ` API URL: ${masked.apiUrl}`
77094
+ ];
77095
+ if (masked.apiToken) {
77096
+ output.push(` API Token: ${masked.apiToken}`);
77097
+ }
77098
+ if (masked.p12Bundle) {
77099
+ output.push(` P12 Bundle: ${masked.p12Bundle}`);
77100
+ }
77101
+ if (masked.cert) {
77102
+ output.push(` Certificate: ${masked.cert}`);
77103
+ }
77104
+ if (masked.key) {
77105
+ output.push(` Private Key: ${masked.key}`);
77106
+ }
77107
+ if (masked.defaultNamespace) {
77108
+ output.push(` Namespace: ${masked.defaultNamespace}`);
77109
+ }
77110
+ return successResult(output);
77111
+ } catch (error) {
77112
+ return errorResult(
77113
+ `Failed to show profile: ${error instanceof Error ? error.message : "Unknown error"}`
77114
+ );
77115
+ }
77116
+ },
77117
+ async completion(partial, _args, _session) {
77118
+ const manager = getProfileManager();
77119
+ const profiles = await manager.list();
77120
+ return profiles.map((p) => p.name).filter(
77121
+ (name) => name.toLowerCase().startsWith(partial.toLowerCase())
77122
+ );
77123
+ }
77124
+ };
77125
+
77126
+ // src/domains/login/profile/connection-table.ts
77127
+ var UNICODE_BOX2 = {
77128
+ topLeft: "\u256D",
77129
+ // ╭
77130
+ topRight: "\u256E",
77131
+ // ╮
77132
+ bottomLeft: "\u2570",
77133
+ // ╰
77134
+ bottomRight: "\u256F",
77135
+ // ╯
77136
+ horizontal: "\u2500",
77137
+ // ─
77138
+ vertical: "\u2502",
77139
+ // │
77140
+ leftT: "\u251C",
77141
+ // ├
77142
+ rightT: "\u2524"
77143
+ // ┤
77144
+ };
77145
+ var ASCII_BOX2 = {
77146
+ topLeft: "+",
77147
+ topRight: "+",
77148
+ bottomLeft: "+",
77149
+ bottomRight: "+",
77150
+ horizontal: "-",
77151
+ vertical: "|",
77152
+ leftT: "+",
77153
+ rightT: "+"
77154
+ };
77155
+ function extractTenantFromUrl(url) {
77156
+ try {
74757
77157
  const parsed = new URL(url);
74758
77158
  const hostname = parsed.hostname;
74759
77159
  const parts = hostname.split(".");
@@ -76740,7 +79140,6 @@ var statusCommand = {
76740
79140
  descriptionShort: "Get overall cloud status indicator",
76741
79141
  descriptionMedium: "Check overall service health status. Use --quiet for exit code suitable for scripts.",
76742
79142
  usage: "[--quiet]",
76743
- aliases: ["st"],
76744
79143
  async execute(args, session) {
76745
79144
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
76746
79145
  args,
@@ -76792,7 +79191,6 @@ var summaryCommand = {
76792
79191
  descriptionShort: "Get complete status summary",
76793
79192
  descriptionMedium: "Show combined overview of health, components, incidents, and maintenance windows.",
76794
79193
  usage: "[--brief]",
76795
- aliases: ["sum"],
76796
79194
  async execute(args, session) {
76797
79195
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
76798
79196
  args,
@@ -76832,7 +79230,6 @@ var componentsCommand = {
76832
79230
  descriptionShort: "List all components and status",
76833
79231
  descriptionMedium: "Display service component health. Use --degraded-only to show only affected components.",
76834
79232
  usage: "[--degraded-only]",
76835
- aliases: ["comp"],
76836
79233
  async execute(args, session) {
76837
79234
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
76838
79235
  args,
@@ -76889,7 +79286,6 @@ var incidentsCommand = {
76889
79286
  descriptionShort: "List active and recent incidents",
76890
79287
  descriptionMedium: "Display incidents with impact levels and updates. Use --active-only for ongoing issues.",
76891
79288
  usage: "[--active-only]",
76892
- aliases: ["inc"],
76893
79289
  async execute(args, session) {
76894
79290
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
76895
79291
  args,
@@ -76942,7 +79338,6 @@ var maintenanceCommand = {
76942
79338
  descriptionShort: "List scheduled maintenance windows",
76943
79339
  descriptionMedium: "Show maintenance schedules and timing. Use --upcoming for future windows only.",
76944
79340
  usage: "[--upcoming]",
76945
- aliases: ["maint"],
76946
79341
  async execute(args, session) {
76947
79342
  const { format, noColor, spec, filteredArgs } = parseOutputArgs(
76948
79343
  args,
@@ -77112,7 +79507,7 @@ var cloudstatusDomain = {
77112
79507
  ]),
77113
79508
  subcommands: /* @__PURE__ */ new Map()
77114
79509
  };
77115
- var cloudstatusAliases = ["cs", "status"];
79510
+ var cloudstatusAliases = [];
77116
79511
 
77117
79512
  // src/completion/registry.ts
77118
79513
  var CompletionRegistry = class {
@@ -77466,690 +79861,276 @@ ${customDomainCompletions.join("\n")}
77466
79861
  esac
77467
79862
  ;;
77468
79863
  *)
77469
- # Third+ word: flags
77470
- if [[ "\${cur}" == -* ]]; then
77471
- local action_flags="--name -n --namespace -ns --output -o --json --yaml --limit --label --spec"
77472
- COMPREPLY=($(compgen -W "\${action_flags}" -- "\${cur}"))
77473
- fi
77474
- return 0
77475
- ;;
77476
- esac
77477
- }
77478
-
77479
- complete -F _xcsh_completions xcsh
77480
- `;
77481
- }
77482
- function generateZshCompletion() {
77483
- const domains = completionRegistry.getDomains();
77484
- const domainDescriptions = domains.map((d) => {
77485
- const escaped = escapeForZsh(d.description);
77486
- return `'${d.name}:${escaped}'`;
77487
- }).join("\n ");
77488
- const aliasDescriptions = domains.filter((d) => d.aliases && d.aliases.length > 0).flatMap((d) => d.aliases.map((a) => `'${a}:Alias for ${d.name}'`)).join("\n ");
77489
- const actionDescriptions2 = getActionDescriptions();
77490
- const actionDescArray = Object.entries(actionDescriptions2).map(([action, desc]) => {
77491
- const escaped = escapeForZsh(desc);
77492
- return `'${action}:${escaped}'`;
77493
- }).join("\n ");
77494
- const customDomainCompletions = [];
77495
- for (const domain of domains) {
77496
- if (domain.source !== "custom" || !domain.children) continue;
77497
- const childDescriptions = [];
77498
- for (const child of domain.children.values()) {
77499
- const escaped = escapeForZsh(child.description);
77500
- childDescriptions.push(`'${child.name}:${escaped}'`);
77501
- }
77502
- if (childDescriptions.length > 0) {
77503
- customDomainCompletions.push(
77504
- ` (${domain.name})`,
77505
- ` _values 'command' ${childDescriptions.join(" ")}`,
77506
- ` ;;`
77507
- );
77508
- }
77509
- }
77510
- return `#compdef xcsh
77511
- # zsh completion for xcsh
77512
- # Generated by xcsh completion zsh
77513
-
77514
- _xcsh() {
77515
- local curcontext="$curcontext" state line
77516
- typeset -A opt_args
77517
-
77518
- local -a global_opts
77519
- global_opts=(
77520
- '(-h --help)'{-h,--help}'[Show help information]'
77521
- '(-v --version)'{-v,--version}'[Show version number]'
77522
- '--no-color[Disable color output]'
77523
- '(-o --output)'{-o,--output}'[Output format]:format:(${ALL_OUTPUT_FORMATS.join(" ")})'
77524
- '(-ns --namespace)'{-ns,--namespace}'[Namespace]:namespace:_xcsh_namespaces'
77525
- '--spec[Output command specification as JSON for AI assistants]'
77526
- )
77527
-
77528
- _arguments -C \\
77529
- "\${global_opts[@]}" \\
77530
- '1: :->domain' \\
77531
- '2: :->action' \\
77532
- '*: :->args'
77533
-
77534
- case $state in
77535
- (domain)
77536
- local -a domains builtins
77537
- domains=(
77538
- ${domainDescriptions}
77539
- ${aliasDescriptions}
77540
- )
77541
- builtins=(
77542
- 'help:Show help information'
77543
- 'quit:Exit the shell'
77544
- 'exit:Exit the shell'
77545
- 'clear:Clear the screen'
77546
- 'history:Show command history'
77547
- 'refresh:Refresh git status in statusline'
77548
- 'context:Show current navigation context'
77549
- 'ctx:Show current navigation context'
77550
- )
77551
- _describe -t domains 'domain' domains
77552
- _describe -t builtins 'builtin' builtins
77553
- ;;
77554
- (action)
77555
- case \${line[1]} in
77556
- ${customDomainCompletions.join("\n")}
77557
- (help|quit|exit|clear|history|refresh|context|ctx)
77558
- ;;
77559
- (*)
77560
- local -a actions
77561
- actions=(
77562
- ${actionDescArray}
77563
- )
77564
- _describe -t actions 'action' actions
77565
- ;;
77566
- esac
77567
- ;;
77568
- (args)
77569
- local -a action_opts
77570
- action_opts=(
77571
- '(-n --name)'{-n,--name}'[Resource name]:name:'
77572
- '(-ns --namespace)'{-ns,--namespace}'[Namespace]:namespace:_xcsh_namespaces'
77573
- '(-o --output)'{-o,--output}'[Output format]:format:(${ALL_OUTPUT_FORMATS.join(" ")})'
77574
- '--limit[Maximum results]:limit:'
77575
- '--label[Filter by label]:label:'
77576
- '(-f --file)'{-f,--file}'[Configuration file]:file:_files'
77577
- '--spec[Output command specification as JSON for AI assistants]'
77578
- )
77579
- _arguments "\${action_opts[@]}"
77580
- ;;
77581
- esac
77582
- }
77583
-
77584
- _xcsh_namespaces() {
77585
- local -a namespaces
77586
- namespaces=('default' 'system' 'shared')
77587
- _describe -t namespaces 'namespace' namespaces
77588
- }
77589
-
77590
- _xcsh "$@"
77591
- `;
77592
- }
77593
- function generateFishCompletion() {
77594
- const domains = completionRegistry.getDomains();
77595
- const actionDescriptions2 = getActionDescriptions();
77596
- const domainCompletions = domains.map((d) => {
77597
- const escaped = escapeForFish(d.description);
77598
- return `complete -c xcsh -n "__fish_use_subcommand" -a "${d.name}" -d '${escaped}'`;
77599
- }).join("\n");
77600
- const aliasCompletions = domains.filter((d) => d.aliases && d.aliases.length > 0).flatMap(
77601
- (d) => d.aliases.map(
77602
- (a) => `complete -c xcsh -n "__fish_use_subcommand" -a "${a}" -d 'Alias for ${d.name}'`
77603
- )
77604
- ).join("\n");
77605
- const customDomainCompletions = [];
77606
- for (const domain of domains) {
77607
- if (domain.source !== "custom" || !domain.children) continue;
77608
- for (const child of domain.children.values()) {
77609
- const escaped = escapeForFish(child.description);
77610
- customDomainCompletions.push(
77611
- `complete -c xcsh -n "__fish_seen_subcommand_from ${domain.name}" -a "${child.name}" -d '${escaped}'`
77612
- );
77613
- if (child.children) {
77614
- for (const nested of child.children.values()) {
77615
- const nestedEscaped = escapeForFish(nested.description);
77616
- customDomainCompletions.push(
77617
- `complete -c xcsh -n "__fish_seen_subcommand_from ${domain.name}; and __fish_seen_subcommand_from ${child.name}" -a "${nested.name}" -d '${nestedEscaped}'`
77618
- );
77619
- }
77620
- }
77621
- }
77622
- }
77623
- const apiDomains = domains.filter((d) => d.source === "api");
77624
- const actionCompletions = apiDomains.map(
77625
- (d) => Object.entries(actionDescriptions2).map(
77626
- ([action, desc]) => `complete -c xcsh -n "__fish_seen_subcommand_from ${d.name}" -a "${action}" -d '${escapeForFish(desc)}'`
77627
- ).join("\n")
77628
- ).join("\n");
77629
- return `# fish completion for xcsh
77630
- # Generated by xcsh completion fish
77631
-
77632
- # Disable file completions for xcsh
77633
- complete -c xcsh -f
77634
-
77635
- # Global options
77636
- complete -c xcsh -s h -l help -d 'Show help information'
77637
- complete -c xcsh -s v -l version -d 'Show version number'
77638
- complete -c xcsh -l no-color -d 'Disable color output'
77639
- complete -c xcsh -s o -l output -d 'Output format' -xa '${ALL_OUTPUT_FORMATS.join(" ")}'
77640
- complete -c xcsh -l namespace -s ns -d 'Namespace' -xa 'default system shared'
77641
- complete -c xcsh -l spec -d 'Output command specification as JSON for AI assistants'
77642
-
77643
- # Builtin commands
77644
- complete -c xcsh -n "__fish_use_subcommand" -a "help" -d 'Show help information'
77645
- complete -c xcsh -n "__fish_use_subcommand" -a "quit" -d 'Exit the shell'
77646
- complete -c xcsh -n "__fish_use_subcommand" -a "exit" -d 'Exit the shell'
77647
- complete -c xcsh -n "__fish_use_subcommand" -a "clear" -d 'Clear the screen'
77648
- complete -c xcsh -n "__fish_use_subcommand" -a "history" -d 'Show command history'
77649
- complete -c xcsh -n "__fish_use_subcommand" -a "refresh" -d 'Refresh git status in statusline'
77650
- complete -c xcsh -n "__fish_use_subcommand" -a "context" -d 'Show current navigation context'
77651
- complete -c xcsh -n "__fish_use_subcommand" -a "ctx" -d 'Show current navigation context'
77652
-
77653
- # Domain completions
77654
- ${domainCompletions}
77655
-
77656
- # Alias completions
77657
- ${aliasCompletions}
77658
-
77659
- # Custom domain subcommands
77660
- ${customDomainCompletions.join("\n")}
77661
-
77662
- # Action completions for API domains
77663
- ${actionCompletions}
77664
-
77665
- # Action-specific flags
77666
- complete -c xcsh -l name -s n -d 'Resource name'
77667
- complete -c xcsh -l limit -d 'Maximum results'
77668
- complete -c xcsh -l label -d 'Filter by label'
77669
- complete -c xcsh -s f -l file -d 'Configuration file' -r
77670
- complete -c xcsh -l force -d 'Force deletion'
77671
- complete -c xcsh -l cascade -d 'Cascade delete'
77672
- complete -c xcsh -l spec -d 'Output command specification as JSON for AI assistants'
77673
- `;
77674
- }
77675
-
77676
- // src/domains/completion/index.ts
77677
- var bashCommand = {
77678
- name: "bash",
77679
- description: "Generate a bash shell completion script for xcsh. Output the script to stdout for manual installation or pipe to a file. Enables tab-completion for commands, domains, actions, and option flags.",
77680
- descriptionShort: "Generate bash completion script",
77681
- descriptionMedium: "Output bash completion script for tab-completion of commands, domains, and flags.",
77682
- async execute() {
77683
- try {
77684
- const script = generateBashCompletion();
77685
- return successResult([script]);
77686
- } catch (error) {
77687
- return errorResult(
77688
- `Failed to generate bash completion: ${error instanceof Error ? error.message : "Unknown error"}`
77689
- );
77690
- }
77691
- }
77692
- };
77693
- var zshCommand = {
77694
- name: "zsh",
77695
- description: "Generate a zsh shell completion script for xcsh. Output the script to stdout for manual installation or add to your fpath. Provides rich tab-completion with descriptions for commands, domains, and options.",
77696
- descriptionShort: "Generate zsh completion script",
77697
- descriptionMedium: "Output zsh completion script with rich descriptions for commands and options.",
77698
- async execute() {
77699
- try {
77700
- const script = generateZshCompletion();
77701
- return successResult([script]);
77702
- } catch (error) {
77703
- return errorResult(
77704
- `Failed to generate zsh completion: ${error instanceof Error ? error.message : "Unknown error"}`
77705
- );
77706
- }
77707
- }
77708
- };
77709
- var fishCommand = {
77710
- name: "fish",
77711
- description: "Generate a fish shell completion script for xcsh. Output the script to stdout for manual installation or save to your fish completions directory. Enables intelligent tab-completion with inline descriptions.",
77712
- descriptionShort: "Generate fish completion script",
77713
- descriptionMedium: "Output fish completion script with inline descriptions for commands and options.",
77714
- async execute() {
77715
- try {
77716
- const script = generateFishCompletion();
77717
- return successResult([script]);
77718
- } catch (error) {
77719
- return errorResult(
77720
- `Failed to generate fish completion: ${error instanceof Error ? error.message : "Unknown error"}`
77721
- );
77722
- }
77723
- }
77724
- };
77725
- var completionDomain = {
77726
- name: "completion",
77727
- description: "Generate shell completion scripts for bash, zsh, and fish shells. Enables tab-completion for xcsh commands, domains, actions, and flags in your preferred shell environment.",
77728
- descriptionShort: "Shell completion script generation",
77729
- descriptionMedium: "Generate tab-completion scripts for bash, zsh, and fish shells to enhance the xcsh command-line experience.",
77730
- commands: /* @__PURE__ */ new Map([
77731
- ["bash", bashCommand],
77732
- ["zsh", zshCommand],
77733
- ["fish", fishCommand]
77734
- ]),
77735
- subcommands: /* @__PURE__ */ new Map()
77736
- };
77737
-
77738
- // src/domains/ai_services/client.ts
77739
- var GenAIClient = class {
77740
- constructor(apiClient) {
77741
- this.apiClient = apiClient;
77742
- }
77743
- /**
77744
- * Query the AI assistant
77745
- *
77746
- * @param namespace - The namespace context for the query
77747
- * @param query - The natural language query
77748
- * @returns The AI assistant response with query_id and response data
77749
- */
77750
- async query(namespace, query) {
77751
- const request = {
77752
- current_query: query,
77753
- namespace
77754
- };
77755
- const response = await this.apiClient.post(
77756
- `/api/gen-ai/namespaces/${namespace}/query`,
77757
- request
77758
- );
77759
- if (!response.ok) {
77760
- throw new Error(
77761
- `GenAI query failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
77762
- );
77763
- }
77764
- return response.data;
77765
- }
77766
- /**
77767
- * Submit feedback for a query
77768
- *
77769
- * @param request - The feedback request with query_id and feedback type
77770
- */
77771
- async feedback(request) {
77772
- const response = await this.apiClient.post(
77773
- `/api/gen-ai/namespaces/${request.namespace}/query_feedback`,
77774
- request
77775
- );
77776
- if (!response.ok) {
77777
- throw new Error(
77778
- `GenAI feedback failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
77779
- );
77780
- }
77781
- }
77782
- /**
77783
- * Query the AI assistant in eval mode (for RBAC testing)
77784
- *
77785
- * @param namespace - The namespace context for the query
77786
- * @param query - The natural language query
77787
- * @returns The AI assistant response
77788
- */
77789
- async evalQuery(namespace, query) {
77790
- const request = {
77791
- current_query: query,
77792
- namespace
77793
- };
77794
- const response = await this.apiClient.post(
77795
- `/api/gen-ai/namespaces/${namespace}/eval_query`,
77796
- request
77797
- );
77798
- if (!response.ok) {
77799
- throw new Error(
77800
- `GenAI eval query failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
77801
- );
77802
- }
77803
- return response.data;
77804
- }
77805
- /**
77806
- * Submit feedback for an eval query
77807
- *
77808
- * @param request - The feedback request with query_id and feedback type
77809
- */
77810
- async evalFeedback(request) {
77811
- const response = await this.apiClient.post(
77812
- `/api/gen-ai/namespaces/${request.namespace}/eval_query_feedback`,
77813
- request
77814
- );
77815
- if (!response.ok) {
77816
- throw new Error(
77817
- `GenAI eval feedback failed: ${response.statusCode} - ${JSON.stringify(response.data)}`
77818
- );
77819
- }
77820
- }
77821
- };
77822
- var cachedClient = null;
77823
- function getGenAIClient(apiClient) {
77824
- if (!cachedClient) {
77825
- cachedClient = new GenAIClient(apiClient);
77826
- }
77827
- return cachedClient;
77828
- }
77829
-
77830
- // src/domains/ai_services/types.ts
77831
- function getResponseType(response) {
77832
- if (response.generic_response) return "generic_response";
77833
- if (response.explain_log) return "explain_log";
77834
- if (response.gen_dashboard_filter) return "gen_dashboard_filter";
77835
- if (response.list_response) return "list_response";
77836
- if (response.site_analysis_response) return "site_analysis_response";
77837
- if (response.widget_response) return "widget_response";
77838
- return null;
77839
- }
77840
- var FEEDBACK_TYPE_MAP = {
77841
- other: "OTHER",
77842
- inaccurate: "INACCURATE_DATA",
77843
- irrelevant: "IRRELEVANT_CONTENT",
77844
- poor_format: "POOR_FORMAT",
77845
- slow: "SLOW_RESPONSE"
77846
- };
77847
- function getValidFeedbackTypes() {
77848
- return Object.keys(FEEDBACK_TYPE_MAP);
77849
- }
77850
-
77851
- // src/domains/ai_services/response-renderer.ts
77852
- function renderResponse(response) {
77853
- const lines = [];
77854
- const responseType = getResponseType(response);
77855
- switch (responseType) {
77856
- case "generic_response":
77857
- lines.push(...renderGenericResponse(response.generic_response));
77858
- break;
77859
- case "explain_log":
77860
- lines.push(...renderExplainLog(response.explain_log));
77861
- break;
77862
- case "gen_dashboard_filter":
77863
- lines.push(
77864
- ...renderDashboardFilter(response.gen_dashboard_filter)
77865
- );
77866
- break;
77867
- case "list_response":
77868
- lines.push(...renderListResponse(response.list_response));
77869
- break;
77870
- case "site_analysis_response":
77871
- lines.push(...renderSiteAnalysis(response.site_analysis_response));
77872
- break;
77873
- case "widget_response":
77874
- lines.push(...renderWidgetResponse(response.widget_response));
77875
- break;
77876
- default:
77877
- lines.push("No response content.");
77878
- }
77879
- if (response.follow_up_queries && response.follow_up_queries.length > 0) {
77880
- lines.push("");
77881
- lines.push("Suggested follow-up questions:");
77882
- response.follow_up_queries.forEach((q, i) => {
77883
- lines.push(` ${i + 1}. ${q}`);
77884
- });
77885
- }
77886
- return lines;
77887
- }
77888
- function stripHtml(html) {
77889
- return html.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n\n").replace(/<\/li>/gi, "\n").replace(/<\/h[1-6]>/gi, "\n\n").replace(/<hr\s*\/?>/gi, "\n---\n").replace(/<a[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, "$2 ($1)").replace(/<code>([^<]*)<\/code>/gi, "`$1`").replace(/<li[^>]*>/gi, " \u2022 ").replace(/<h3[^>]*>/gi, "\n### ").replace(/<h[1-6][^>]*>/gi, "\n").replace(/<ol[^>]*>/gi, "").replace(/<\/ol>/gi, "").replace(/<ul[^>]*>/gi, "").replace(/<\/ul>/gi, "").replace(/<strong>([^<]*)<\/strong>/gi, "**$1**").replace(/<b>([^<]*)<\/b>/gi, "**$1**").replace(/<em>([^<]*)<\/em>/gi, "*$1*").replace(/<i>([^<]*)<\/i>/gi, "*$1*").replace(/<[^>]+>/g, "").replace(/\n{3,}/g, "\n\n").trim();
77890
- }
77891
- function renderGenericResponse(response) {
77892
- const lines = [];
77893
- if (response.is_error || response.error && response.error !== null) {
77894
- lines.push(`Error: ${response.error ?? "Unknown error"}`);
77895
- return lines;
77896
- }
77897
- const content = response.summary ?? response.text;
77898
- if (content) {
77899
- const plainText = stripHtml(content);
77900
- lines.push(...plainText.split("\n"));
77901
- }
77902
- if (response.links && response.links.length > 0) {
77903
- lines.push("");
77904
- lines.push("Related links:");
77905
- for (const link3 of response.links) {
77906
- lines.push(` - ${link3.title}: ${link3.url}`);
77907
- }
77908
- }
77909
- return lines;
77910
- }
77911
- function renderExplainLog(response) {
77912
- const lines = [];
77913
- lines.push("=== Security Event Analysis ===");
77914
- lines.push("");
77915
- if (response.summary) {
77916
- lines.push("Summary:");
77917
- lines.push(` ${response.summary}`);
77918
- lines.push("");
77919
- }
77920
- if (response.action) {
77921
- lines.push(`Action Taken: ${response.action}`);
77922
- }
77923
- if (response.accuracy) {
77924
- lines.push(`Accuracy: ${response.accuracy}`);
77925
- }
77926
- if (response.violations && response.violations.length > 0) {
77927
- lines.push("");
77928
- lines.push("Violations Detected:");
77929
- for (const v of response.violations) {
77930
- lines.push(` - ${v.name}: ${v.description}`);
77931
- }
77932
- }
77933
- if (response.threat_campaigns && response.threat_campaigns.length > 0) {
77934
- lines.push("");
77935
- lines.push("Threat Campaigns:");
77936
- for (const campaign of response.threat_campaigns) {
77937
- lines.push(` - ${campaign}`);
77938
- }
77939
- }
77940
- if (response.request_details) {
77941
- lines.push("");
77942
- lines.push("Request Details:");
77943
- lines.push(` ${JSON.stringify(response.request_details, null, 2)}`);
77944
- }
77945
- return lines;
77946
- }
77947
- function renderDashboardFilter(response) {
77948
- const lines = [];
77949
- lines.push("=== Dashboard Filter ===");
77950
- lines.push("");
77951
- if (response.filter_expression) {
77952
- lines.push("Filter Expression:");
77953
- lines.push(` ${response.filter_expression}`);
77954
- }
77955
- if (response.dashboard_context) {
77956
- lines.push("");
77957
- lines.push("Dashboard Context:");
77958
- lines.push(` ${response.dashboard_context}`);
77959
- }
77960
- return lines;
77961
- }
77962
- function renderListResponse(response) {
77963
- const lines = [];
77964
- if (response.formatted_list) {
77965
- lines.push(response.formatted_list);
77966
- return lines;
77967
- }
77968
- if (response.items && response.items.length > 0) {
77969
- if (response.total_count !== void 0) {
77970
- lines.push(`Total: ${response.total_count} items`);
77971
- lines.push("");
77972
- }
77973
- for (const item of response.items) {
77974
- lines.push(JSON.stringify(item, null, 2));
77975
- lines.push("");
77976
- }
77977
- } else {
77978
- lines.push("No items found.");
77979
- }
77980
- return lines;
79864
+ # Third+ word: flags
79865
+ if [[ "\${cur}" == -* ]]; then
79866
+ local action_flags="--name -n --namespace -ns --output -o --json --yaml --limit --label --spec"
79867
+ COMPREPLY=($(compgen -W "\${action_flags}" -- "\${cur}"))
79868
+ fi
79869
+ return 0
79870
+ ;;
79871
+ esac
77981
79872
  }
77982
- function renderSiteAnalysis(response) {
77983
- const lines = [];
77984
- lines.push("=== Site Analysis ===");
77985
- lines.push("");
77986
- if (response.site_name) {
77987
- lines.push(`Site: ${response.site_name}`);
77988
- }
77989
- if (response.health_status) {
77990
- lines.push(`Health: ${response.health_status}`);
77991
- }
77992
- if (response.metrics) {
77993
- lines.push("");
77994
- lines.push("Metrics:");
77995
- for (const [key, value] of Object.entries(response.metrics)) {
77996
- lines.push(` ${key}: ${JSON.stringify(value)}`);
77997
- }
77998
- }
77999
- if (response.recommendations && response.recommendations.length > 0) {
78000
- lines.push("");
78001
- lines.push("Recommendations:");
78002
- for (const rec of response.recommendations) {
78003
- lines.push(` - ${rec}`);
78004
- }
78005
- }
78006
- return lines;
79873
+
79874
+ complete -F _xcsh_completions xcsh
79875
+ `;
78007
79876
  }
78008
- function renderWidgetResponse(response) {
78009
- const lines = [];
78010
- if (response.display_type) {
78011
- lines.push(`Widget Type: ${response.display_type}`);
78012
- lines.push("");
78013
- }
78014
- if (response.table) {
78015
- for (const row of response.table.rows) {
78016
- const cells = row.cells.map((cell) => {
78017
- let value = cell.value;
78018
- if (cell.properties?.status_style) {
78019
- value = `[${cell.properties.status_style}] ${value}`;
78020
- }
78021
- return value;
78022
- });
78023
- lines.push(cells.join(" | "));
79877
+ function generateZshCompletion() {
79878
+ const domains = completionRegistry.getDomains();
79879
+ const domainDescriptions = domains.map((d) => {
79880
+ const escaped = escapeForZsh(d.description);
79881
+ return `'${d.name}:${escaped}'`;
79882
+ }).join("\n ");
79883
+ const aliasDescriptions = domains.filter((d) => d.aliases && d.aliases.length > 0).flatMap((d) => d.aliases.map((a) => `'${a}:Alias for ${d.name}'`)).join("\n ");
79884
+ const actionDescriptions2 = getActionDescriptions();
79885
+ const actionDescArray = Object.entries(actionDescriptions2).map(([action, desc]) => {
79886
+ const escaped = escapeForZsh(desc);
79887
+ return `'${action}:${escaped}'`;
79888
+ }).join("\n ");
79889
+ const customDomainCompletions = [];
79890
+ for (const domain of domains) {
79891
+ if (domain.source !== "custom" || !domain.children) continue;
79892
+ const childDescriptions = [];
79893
+ for (const child of domain.children.values()) {
79894
+ const escaped = escapeForZsh(child.description);
79895
+ childDescriptions.push(`'${child.name}:${escaped}'`);
78024
79896
  }
78025
- }
78026
- if (response.links && response.links.length > 0) {
78027
- lines.push("");
78028
- lines.push("Links:");
78029
- for (const link3 of response.links) {
78030
- lines.push(` - ${link3.title}: ${link3.url}`);
79897
+ if (childDescriptions.length > 0) {
79898
+ customDomainCompletions.push(
79899
+ ` (${domain.name})`,
79900
+ ` _values 'command' ${childDescriptions.join(" ")}`,
79901
+ ` ;;`
79902
+ );
78031
79903
  }
78032
79904
  }
78033
- return lines;
78034
- }
79905
+ return `#compdef xcsh
79906
+ # zsh completion for xcsh
79907
+ # Generated by xcsh completion zsh
78035
79908
 
78036
- // src/domains/ai_services/query.ts
78037
- var lastQueryState = {
78038
- namespace: "",
78039
- lastQueryId: null,
78040
- lastQuery: null,
78041
- followUpQueries: [],
78042
- isActive: false
78043
- };
78044
- function getLastQueryState() {
78045
- return lastQueryState;
79909
+ _xcsh() {
79910
+ local curcontext="$curcontext" state line
79911
+ typeset -A opt_args
79912
+
79913
+ local -a global_opts
79914
+ global_opts=(
79915
+ '(-h --help)'{-h,--help}'[Show help information]'
79916
+ '(-v --version)'{-v,--version}'[Show version number]'
79917
+ '--no-color[Disable color output]'
79918
+ '(-o --output)'{-o,--output}'[Output format]:format:(${ALL_OUTPUT_FORMATS.join(" ")})'
79919
+ '(-ns --namespace)'{-ns,--namespace}'[Namespace]:namespace:_xcsh_namespaces'
79920
+ '--spec[Output command specification as JSON for AI assistants]'
79921
+ )
79922
+
79923
+ _arguments -C \\
79924
+ "\${global_opts[@]}" \\
79925
+ '1: :->domain' \\
79926
+ '2: :->action' \\
79927
+ '*: :->args'
79928
+
79929
+ case $state in
79930
+ (domain)
79931
+ local -a domains builtins
79932
+ domains=(
79933
+ ${domainDescriptions}
79934
+ ${aliasDescriptions}
79935
+ )
79936
+ builtins=(
79937
+ 'help:Show help information'
79938
+ 'quit:Exit the shell'
79939
+ 'exit:Exit the shell'
79940
+ 'clear:Clear the screen'
79941
+ 'history:Show command history'
79942
+ 'refresh:Refresh git status in statusline'
79943
+ 'context:Show current navigation context'
79944
+ 'ctx:Show current navigation context'
79945
+ )
79946
+ _describe -t domains 'domain' domains
79947
+ _describe -t builtins 'builtin' builtins
79948
+ ;;
79949
+ (action)
79950
+ case \${line[1]} in
79951
+ ${customDomainCompletions.join("\n")}
79952
+ (help|quit|exit|clear|history|refresh|context|ctx)
79953
+ ;;
79954
+ (*)
79955
+ local -a actions
79956
+ actions=(
79957
+ ${actionDescArray}
79958
+ )
79959
+ _describe -t actions 'action' actions
79960
+ ;;
79961
+ esac
79962
+ ;;
79963
+ (args)
79964
+ local -a action_opts
79965
+ action_opts=(
79966
+ '(-n --name)'{-n,--name}'[Resource name]:name:'
79967
+ '(-ns --namespace)'{-ns,--namespace}'[Namespace]:namespace:_xcsh_namespaces'
79968
+ '(-o --output)'{-o,--output}'[Output format]:format:(${ALL_OUTPUT_FORMATS.join(" ")})'
79969
+ '--limit[Maximum results]:limit:'
79970
+ '--label[Filter by label]:label:'
79971
+ '(-f --file)'{-f,--file}'[Configuration file]:file:_files'
79972
+ '--spec[Output command specification as JSON for AI assistants]'
79973
+ )
79974
+ _arguments "\${action_opts[@]}"
79975
+ ;;
79976
+ esac
78046
79977
  }
78047
- function updateLastQueryState(partial) {
78048
- lastQueryState = { ...lastQueryState, ...partial };
79978
+
79979
+ _xcsh_namespaces() {
79980
+ local -a namespaces
79981
+ namespaces=('default' 'system' 'shared')
79982
+ _describe -t namespaces 'namespace' namespaces
78049
79983
  }
78050
- function clearLastQueryState() {
78051
- lastQueryState = {
78052
- namespace: "",
78053
- lastQueryId: null,
78054
- lastQuery: null,
78055
- followUpQueries: [],
78056
- isActive: false
78057
- };
79984
+
79985
+ _xcsh "$@"
79986
+ `;
78058
79987
  }
78059
- function parseQueryArgs(args, session) {
78060
- const { options, remainingArgs } = parseDomainOutputFlags(
78061
- args,
78062
- session.getOutputFormat()
78063
- );
78064
- let spec = false;
78065
- let namespace = session.getNamespace();
78066
- const questionParts = [];
78067
- let i = 0;
78068
- while (i < remainingArgs.length) {
78069
- const arg = remainingArgs[i];
78070
- if (arg === "--spec") {
78071
- spec = true;
78072
- } else if (arg === "--namespace" || arg === "-ns") {
78073
- if (i + 1 < remainingArgs.length) {
78074
- namespace = remainingArgs[i + 1] ?? namespace;
78075
- i++;
79988
+ function generateFishCompletion() {
79989
+ const domains = completionRegistry.getDomains();
79990
+ const actionDescriptions2 = getActionDescriptions();
79991
+ const domainCompletions = domains.map((d) => {
79992
+ const escaped = escapeForFish(d.description);
79993
+ return `complete -c xcsh -n "__fish_use_subcommand" -a "${d.name}" -d '${escaped}'`;
79994
+ }).join("\n");
79995
+ const aliasCompletions = domains.filter((d) => d.aliases && d.aliases.length > 0).flatMap(
79996
+ (d) => d.aliases.map(
79997
+ (a) => `complete -c xcsh -n "__fish_use_subcommand" -a "${a}" -d 'Alias for ${d.name}'`
79998
+ )
79999
+ ).join("\n");
80000
+ const customDomainCompletions = [];
80001
+ for (const domain of domains) {
80002
+ if (domain.source !== "custom" || !domain.children) continue;
80003
+ for (const child of domain.children.values()) {
80004
+ const escaped = escapeForFish(child.description);
80005
+ customDomainCompletions.push(
80006
+ `complete -c xcsh -n "__fish_seen_subcommand_from ${domain.name}" -a "${child.name}" -d '${escaped}'`
80007
+ );
80008
+ if (child.children) {
80009
+ for (const nested of child.children.values()) {
80010
+ const nestedEscaped = escapeForFish(nested.description);
80011
+ customDomainCompletions.push(
80012
+ `complete -c xcsh -n "__fish_seen_subcommand_from ${domain.name}; and __fish_seen_subcommand_from ${child.name}" -a "${nested.name}" -d '${nestedEscaped}'`
80013
+ );
80014
+ }
78076
80015
  }
78077
- } else {
78078
- questionParts.push(arg ?? "");
78079
80016
  }
78080
- i++;
78081
80017
  }
78082
- return {
78083
- format: options.format,
78084
- noColor: options.noColor,
78085
- spec,
78086
- namespace,
78087
- question: questionParts.join(" ")
78088
- };
80018
+ const apiDomains = domains.filter((d) => d.source === "api");
80019
+ const actionCompletions = apiDomains.map(
80020
+ (d) => Object.entries(actionDescriptions2).map(
80021
+ ([action, desc]) => `complete -c xcsh -n "__fish_seen_subcommand_from ${d.name}" -a "${action}" -d '${escapeForFish(desc)}'`
80022
+ ).join("\n")
80023
+ ).join("\n");
80024
+ return `# fish completion for xcsh
80025
+ # Generated by xcsh completion fish
80026
+
80027
+ # Disable file completions for xcsh
80028
+ complete -c xcsh -f
80029
+
80030
+ # Global options
80031
+ complete -c xcsh -s h -l help -d 'Show help information'
80032
+ complete -c xcsh -s v -l version -d 'Show version number'
80033
+ complete -c xcsh -l no-color -d 'Disable color output'
80034
+ complete -c xcsh -s o -l output -d 'Output format' -xa '${ALL_OUTPUT_FORMATS.join(" ")}'
80035
+ complete -c xcsh -l namespace -s ns -d 'Namespace' -xa 'default system shared'
80036
+ complete -c xcsh -l spec -d 'Output command specification as JSON for AI assistants'
80037
+
80038
+ # Builtin commands
80039
+ complete -c xcsh -n "__fish_use_subcommand" -a "help" -d 'Show help information'
80040
+ complete -c xcsh -n "__fish_use_subcommand" -a "quit" -d 'Exit the shell'
80041
+ complete -c xcsh -n "__fish_use_subcommand" -a "exit" -d 'Exit the shell'
80042
+ complete -c xcsh -n "__fish_use_subcommand" -a "clear" -d 'Clear the screen'
80043
+ complete -c xcsh -n "__fish_use_subcommand" -a "history" -d 'Show command history'
80044
+ complete -c xcsh -n "__fish_use_subcommand" -a "refresh" -d 'Refresh git status in statusline'
80045
+ complete -c xcsh -n "__fish_use_subcommand" -a "context" -d 'Show current navigation context'
80046
+ complete -c xcsh -n "__fish_use_subcommand" -a "ctx" -d 'Show current navigation context'
80047
+
80048
+ # Domain completions
80049
+ ${domainCompletions}
80050
+
80051
+ # Alias completions
80052
+ ${aliasCompletions}
80053
+
80054
+ # Custom domain subcommands
80055
+ ${customDomainCompletions.join("\n")}
80056
+
80057
+ # Action completions for API domains
80058
+ ${actionCompletions}
80059
+
80060
+ # Action-specific flags
80061
+ complete -c xcsh -l name -s n -d 'Resource name'
80062
+ complete -c xcsh -l limit -d 'Maximum results'
80063
+ complete -c xcsh -l label -d 'Filter by label'
80064
+ complete -c xcsh -s f -l file -d 'Configuration file' -r
80065
+ complete -c xcsh -l force -d 'Force deletion'
80066
+ complete -c xcsh -l cascade -d 'Cascade delete'
80067
+ complete -c xcsh -l spec -d 'Output command specification as JSON for AI assistants'
80068
+ `;
78089
80069
  }
78090
- var queryCommand = {
78091
- name: "query",
78092
- description: "Send a natural language query to the F5 Distributed Cloud AI assistant. Ask about load balancers, WAF configurations, site status, security events, or any platform topic. Returns AI-generated responses with optional follow-up suggestions. Use --namespace to specify the context for namespace-scoped resources.",
78093
- descriptionShort: "Query the AI assistant",
78094
- descriptionMedium: "Send natural language queries to the AI assistant for help with F5 XC platform operations, configurations, and troubleshooting.",
78095
- usage: "<question> [--namespace <ns>]",
78096
- aliases: ["ask", "q"],
78097
- async execute(args, session) {
78098
- const { format, noColor, spec, namespace, question } = parseQueryArgs(
78099
- args,
78100
- session
78101
- );
78102
- if (spec) {
78103
- const cmdSpec = getCommandSpec("ai_services query");
78104
- if (cmdSpec) {
78105
- return successResult([formatSpec(cmdSpec)]);
78106
- }
78107
- }
78108
- if (!question.trim()) {
78109
- return errorResult(
78110
- "Please provide a question. Usage: ai query <question>"
78111
- );
78112
- }
78113
- const apiClient = session.getAPIClient();
78114
- if (!apiClient) {
80070
+
80071
+ // src/domains/completion/index.ts
80072
+ var bashCommand = {
80073
+ name: "bash",
80074
+ description: "Generate a bash shell completion script for xcsh. Output the script to stdout for manual installation or pipe to a file. Enables tab-completion for commands, domains, actions, and option flags.",
80075
+ descriptionShort: "Generate bash completion script",
80076
+ descriptionMedium: "Output bash completion script for tab-completion of commands, domains, and flags.",
80077
+ async execute() {
80078
+ try {
80079
+ const script = generateBashCompletion();
80080
+ return successResult([script]);
80081
+ } catch (error) {
78115
80082
  return errorResult(
78116
- "Not connected to API. Please configure connection first."
80083
+ `Failed to generate bash completion: ${error instanceof Error ? error.message : "Unknown error"}`
78117
80084
  );
78118
80085
  }
78119
- if (!session.isTokenValidated()) {
80086
+ }
80087
+ };
80088
+ var zshCommand = {
80089
+ name: "zsh",
80090
+ description: "Generate a zsh shell completion script for xcsh. Output the script to stdout for manual installation or add to your fpath. Provides rich tab-completion with descriptions for commands, domains, and options.",
80091
+ descriptionShort: "Generate zsh completion script",
80092
+ descriptionMedium: "Output zsh completion script with rich descriptions for commands and options.",
80093
+ async execute() {
80094
+ try {
80095
+ const script = generateZshCompletion();
80096
+ return successResult([script]);
80097
+ } catch (error) {
78120
80098
  return errorResult(
78121
- "Not authenticated. Please check your API token."
80099
+ `Failed to generate zsh completion: ${error instanceof Error ? error.message : "Unknown error"}`
78122
80100
  );
78123
80101
  }
80102
+ }
80103
+ };
80104
+ var fishCommand = {
80105
+ name: "fish",
80106
+ description: "Generate a fish shell completion script for xcsh. Output the script to stdout for manual installation or save to your fish completions directory. Enables intelligent tab-completion with inline descriptions.",
80107
+ descriptionShort: "Generate fish completion script",
80108
+ descriptionMedium: "Output fish completion script with inline descriptions for commands and options.",
80109
+ async execute() {
78124
80110
  try {
78125
- const client = getGenAIClient(apiClient);
78126
- const response = await client.query(namespace, question);
78127
- updateLastQueryState({
78128
- namespace,
78129
- lastQueryId: response.query_id,
78130
- lastQuery: question,
78131
- followUpQueries: response.follow_up_queries ?? [],
78132
- isActive: true
78133
- });
78134
- if (format === "none") {
78135
- return successResult([]);
78136
- }
78137
- if (format === "json" || format === "yaml" || format === "tsv") {
78138
- return successResult(
78139
- formatDomainOutput(response, { format, noColor })
78140
- );
78141
- }
78142
- const lines = renderResponse(response);
78143
- return successResult(lines);
80111
+ const script = generateFishCompletion();
80112
+ return successResult([script]);
78144
80113
  } catch (error) {
78145
- const message = error instanceof Error ? error.message : String(error);
78146
- return errorResult(`Query failed: ${message}`);
80114
+ return errorResult(
80115
+ `Failed to generate fish completion: ${error instanceof Error ? error.message : "Unknown error"}`
80116
+ );
78147
80117
  }
78148
80118
  }
78149
80119
  };
80120
+ var completionDomain = {
80121
+ name: "completion",
80122
+ description: "Generate shell completion scripts for bash, zsh, and fish shells. Enables tab-completion for xcsh commands, domains, actions, and flags in your preferred shell environment.",
80123
+ descriptionShort: "Shell completion script generation",
80124
+ descriptionMedium: "Generate tab-completion scripts for bash, zsh, and fish shells to enhance the xcsh command-line experience.",
80125
+ commands: /* @__PURE__ */ new Map([
80126
+ ["bash", bashCommand],
80127
+ ["zsh", zshCommand],
80128
+ ["fish", fishCommand]
80129
+ ]),
80130
+ subcommands: /* @__PURE__ */ new Map()
80131
+ };
78150
80132
 
78151
80133
  // src/domains/ai_services/chat.ts
78152
- import * as readline from "readline";
78153
80134
  function parseChatArgs(args, session) {
78154
80135
  const { options, remainingArgs } = parseDomainOutputFlags(
78155
80136
  args,
@@ -78176,218 +80157,12 @@ function parseChatArgs(args, session) {
78176
80157
  suppressOutput: options.format === "none"
78177
80158
  };
78178
80159
  }
78179
- function showChatHelp() {
78180
- return [
78181
- "",
78182
- "=== AI Chat Commands ===",
78183
- "",
78184
- " /exit, /quit, /q - Exit chat mode",
78185
- " /help, /h - Show this help",
78186
- " /clear, /c - Clear conversation context",
78187
- " /feedback <type> - Submit feedback for last response",
78188
- " Types: positive, negative",
78189
- " 1, 2, 3... - Select a follow-up question by number",
78190
- "",
78191
- "Just type your question to query the AI assistant.",
78192
- ""
78193
- ];
78194
- }
78195
- async function handleFeedback(input, session) {
78196
- const state = getLastQueryState();
78197
- if (!state.lastQueryId || !state.lastQuery) {
78198
- return ["No previous query to provide feedback for."];
78199
- }
78200
- const parts = input.split(/\s+/);
78201
- const feedbackType = parts[1]?.toLowerCase();
78202
- if (!feedbackType) {
78203
- return [
78204
- "Usage: /feedback <positive|negative>",
78205
- " Optional: /feedback negative <type> [comment]",
78206
- " Types: other, inaccurate, irrelevant, poor_format, slow"
78207
- ];
78208
- }
78209
- const apiClient = session.getAPIClient();
78210
- if (!apiClient) {
78211
- return ["Not connected to API."];
78212
- }
78213
- try {
78214
- const client = getGenAIClient(apiClient);
78215
- if (feedbackType === "positive" || feedbackType === "+") {
78216
- await client.feedback({
78217
- query: state.lastQuery,
78218
- query_id: state.lastQueryId,
78219
- namespace: state.namespace,
78220
- positive_feedback: {}
78221
- });
78222
- return ["Positive feedback submitted. Thank you!"];
78223
- }
78224
- if (feedbackType === "negative" || feedbackType === "-") {
78225
- const negType = parts[2]?.toLowerCase();
78226
- const mappedType = negType ? FEEDBACK_TYPE_MAP[negType] : void 0;
78227
- const comment = parts.slice(3).join(" ") || void 0;
78228
- await client.feedback({
78229
- query: state.lastQuery,
78230
- query_id: state.lastQueryId,
78231
- namespace: state.namespace,
78232
- negative_feedback: {
78233
- remarks: mappedType ? [mappedType] : ["OTHER"]
78234
- },
78235
- comment
78236
- });
78237
- return [
78238
- "Negative feedback submitted. Thank you for helping improve the AI."
78239
- ];
78240
- }
78241
- return [
78242
- `Unknown feedback type: ${feedbackType}`,
78243
- "Use 'positive' or 'negative'."
78244
- ];
78245
- } catch (error) {
78246
- const message = error instanceof Error ? error.message : String(error);
78247
- return [`Feedback failed: ${message}`];
78248
- }
78249
- }
78250
- async function runChatLoop(session, namespace) {
78251
- const apiClient = session.getAPIClient();
78252
- if (!apiClient) {
78253
- return ["Not connected to API. Please configure connection first."];
78254
- }
78255
- if (!session.isTokenValidated()) {
78256
- return ["Not authenticated. Please check your API token."];
78257
- }
78258
- const client = getGenAIClient(apiClient);
78259
- const output = [];
78260
- output.push("");
78261
- output.push("=== F5 XC AI Assistant Chat ===");
78262
- output.push(`Namespace: ${namespace}`);
78263
- output.push("Type /help for commands, /exit to quit.");
78264
- output.push("");
78265
- const rl = readline.createInterface({
78266
- input: process.stdin,
78267
- output: process.stdout,
78268
- terminal: process.stdin.isTTY ?? false
78269
- });
78270
- let interrupted = false;
78271
- rl.on("SIGINT", () => {
78272
- interrupted = true;
78273
- console.log("\n(Use /exit to leave chat mode)");
78274
- rl.prompt();
78275
- });
78276
- const askQuestion = (prompt) => {
78277
- return new Promise((resolve) => {
78278
- rl.question(prompt, (answer) => {
78279
- resolve(answer);
78280
- });
78281
- });
78282
- };
78283
- for (const line of output) {
78284
- console.log(line);
78285
- }
78286
- let running = true;
78287
- while (running && !interrupted) {
78288
- const input = await askQuestion("ai> ");
78289
- if (interrupted) {
78290
- break;
78291
- }
78292
- const trimmed = input.trim();
78293
- if (!trimmed) {
78294
- continue;
78295
- }
78296
- if (trimmed === "/exit" || trimmed === "/quit" || trimmed === "/q") {
78297
- console.log("Exiting chat mode.");
78298
- running = false;
78299
- break;
78300
- }
78301
- if (trimmed === "/help" || trimmed === "/h") {
78302
- for (const line of showChatHelp()) {
78303
- console.log(line);
78304
- }
78305
- continue;
78306
- }
78307
- if (trimmed === "/clear" || trimmed === "/c") {
78308
- clearLastQueryState();
78309
- console.log("Conversation context cleared.");
78310
- continue;
78311
- }
78312
- if (trimmed.startsWith("/feedback")) {
78313
- const feedbackLines = await handleFeedback(trimmed, session);
78314
- for (const line of feedbackLines) {
78315
- console.log(line);
78316
- }
78317
- continue;
78318
- }
78319
- if (/^\d+$/.test(trimmed)) {
78320
- const num = parseInt(trimmed, 10);
78321
- const state = getLastQueryState();
78322
- if (state.followUpQueries.length > 0 && num >= 1 && num <= state.followUpQueries.length) {
78323
- const followUp = state.followUpQueries[num - 1];
78324
- if (followUp) {
78325
- console.log(`
78326
- Following up: ${followUp}
78327
- `);
78328
- try {
78329
- const response = await client.query(
78330
- namespace,
78331
- followUp
78332
- );
78333
- updateLastQueryState({
78334
- namespace,
78335
- lastQueryId: response.query_id,
78336
- lastQuery: followUp,
78337
- followUpQueries: response.follow_up_queries ?? []
78338
- });
78339
- const lines = renderResponse(response);
78340
- for (const line of lines) {
78341
- console.log(line);
78342
- }
78343
- console.log("");
78344
- } catch (error) {
78345
- const message = error instanceof Error ? error.message : String(error);
78346
- console.log(`Query failed: ${message}`);
78347
- }
78348
- continue;
78349
- }
78350
- }
78351
- console.log(
78352
- `Invalid selection. Choose 1-${state.followUpQueries.length} from suggested follow-ups.`
78353
- );
78354
- continue;
78355
- }
78356
- if (trimmed.startsWith("/")) {
78357
- console.log(
78358
- `Unknown command: ${trimmed}. Type /help for commands.`
78359
- );
78360
- continue;
78361
- }
78362
- try {
78363
- const response = await client.query(namespace, trimmed);
78364
- updateLastQueryState({
78365
- namespace,
78366
- lastQueryId: response.query_id,
78367
- lastQuery: trimmed,
78368
- followUpQueries: response.follow_up_queries ?? []
78369
- });
78370
- console.log("");
78371
- const lines = renderResponse(response);
78372
- for (const line of lines) {
78373
- console.log(line);
78374
- }
78375
- console.log("");
78376
- } catch (error) {
78377
- const message = error instanceof Error ? error.message : String(error);
78378
- console.log(`Query failed: ${message}`);
78379
- }
78380
- }
78381
- rl.close();
78382
- return ["Chat session ended."];
78383
- }
78384
80160
  var chatCommand = {
78385
80161
  name: "chat",
78386
80162
  description: "Start an interactive conversation with the F5 XC AI assistant. Enter a multi-turn dialog where you can ask questions, receive responses with follow-up suggestions, and navigate through topics naturally. Use numbered responses to quickly select suggested follow-up questions. Supports in-chat feedback submission. Type /exit to return to the main CLI.",
78387
80163
  descriptionShort: "Interactive AI chat mode",
78388
80164
  descriptionMedium: "Start an interactive multi-turn conversation with the AI assistant. Supports follow-up suggestions and in-chat commands.",
78389
80165
  usage: "[--namespace <ns>]",
78390
- aliases: ["interactive", "i"],
78391
80166
  async execute(args, session) {
78392
80167
  const { spec, namespace, suppressOutput } = parseChatArgs(
78393
80168
  args,
@@ -78404,16 +80179,30 @@ var chatCommand = {
78404
80179
  }
78405
80180
  if (!process.stdin.isTTY) {
78406
80181
  return errorResult(
78407
- "Chat mode requires an interactive terminal. Use 'ai query' for non-interactive queries."
80182
+ "Chat mode requires an interactive terminal. Use 'ai_services query' for non-interactive queries."
78408
80183
  );
78409
80184
  }
78410
- try {
78411
- const result = await runChatLoop(session, namespace);
78412
- return successResult(result);
78413
- } catch (error) {
78414
- const message = error instanceof Error ? error.message : String(error);
78415
- return errorResult(`Chat session failed: ${message}`);
80185
+ const apiClient = session.getAPIClient();
80186
+ if (!apiClient) {
80187
+ return errorResult(
80188
+ "Not connected to API. Please configure connection first."
80189
+ );
80190
+ }
80191
+ if (!session.isTokenValidated()) {
80192
+ return errorResult(
80193
+ "Not authenticated. Please check your API token."
80194
+ );
78416
80195
  }
80196
+ return {
80197
+ output: [],
80198
+ shouldExit: false,
80199
+ shouldClear: false,
80200
+ contextChanged: false,
80201
+ enterChatMode: true,
80202
+ chatConfig: {
80203
+ namespace
80204
+ }
80205
+ };
78417
80206
  }
78418
80207
  };
78419
80208
 
@@ -78932,15 +80721,7 @@ var aiServicesDomain = {
78932
80721
  ]),
78933
80722
  subcommands: /* @__PURE__ */ new Map([["eval", evalSubcommands]])
78934
80723
  };
78935
- var aiServicesAliases = [
78936
- "ai",
78937
- "genai",
78938
- "assistant",
78939
- "query",
78940
- "ask",
78941
- "q",
78942
- "chat"
78943
- ];
80724
+ var aiServicesAliases = [];
78944
80725
 
78945
80726
  // src/domains/subscription/client.ts
78946
80727
  var SubscriptionClient = class {
@@ -79416,7 +81197,6 @@ var showCommand3 = {
79416
81197
  descriptionShort: "Display subscription overview",
79417
81198
  descriptionMedium: "Show subscription tier, active addons, quota usage summary, and current billing status.",
79418
81199
  usage: "",
79419
- aliases: ["overview", "info"],
79420
81200
  async execute(args, session) {
79421
81201
  const { format, noColor, spec } = parseOutputArgs2(args, session);
79422
81202
  if (spec) {
@@ -79639,7 +81419,6 @@ var addonListCommand = {
79639
81419
  descriptionShort: "List addon services",
79640
81420
  descriptionMedium: "Display all addon services with status and access information. Use --subscribed for active only.",
79641
81421
  usage: "[--subscribed]",
79642
- aliases: ["ls"],
79643
81422
  async execute(args, session) {
79644
81423
  const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
79645
81424
  args,
@@ -80304,7 +82083,6 @@ var reportSummaryCommand = {
80304
82083
  descriptionShort: "Generate subscription report",
80305
82084
  descriptionMedium: "Create comprehensive report with plan, addons, quotas, usage, and billing data.",
80306
82085
  usage: "",
80307
- aliases: ["full"],
80308
82086
  async execute(args, session) {
80309
82087
  const { format, noColor, spec } = parseOutputArgs2(args, session);
80310
82088
  if (spec) {
@@ -80476,7 +82254,7 @@ var subscriptionDomain = {
80476
82254
  ["report", reportSubcommands]
80477
82255
  ])
80478
82256
  };
80479
- var subscriptionAliases = ["sub", "billing", "quota"];
82257
+ var subscriptionAliases = [];
80480
82258
 
80481
82259
  // src/domains/index.ts
80482
82260
  customDomains.register(loginDomain);
@@ -81782,27 +83560,27 @@ var Completer = class {
81782
83560
  // src/repl/hooks/useCompletion.ts
81783
83561
  function useCompletion(options) {
81784
83562
  const { session } = options;
81785
- const [completer] = (0, import_react27.useState)(() => {
83563
+ const [completer] = (0, import_react29.useState)(() => {
81786
83564
  const c = new Completer();
81787
83565
  if (session) {
81788
83566
  c.setSession(session);
81789
83567
  }
81790
83568
  return c;
81791
83569
  });
81792
- const [suggestions, setSuggestions] = (0, import_react27.useState)([]);
81793
- const [selectedIndex, setSelectedIndex] = (0, import_react27.useState)(0);
81794
- const [isShowing, setIsShowing] = (0, import_react27.useState)(false);
81795
- (0, import_react27.useEffect)(() => {
83570
+ const [suggestions, setSuggestions] = (0, import_react29.useState)([]);
83571
+ const [selectedIndex, setSelectedIndex] = (0, import_react29.useState)(0);
83572
+ const [isShowing, setIsShowing] = (0, import_react29.useState)(false);
83573
+ (0, import_react29.useEffect)(() => {
81796
83574
  if (session) {
81797
83575
  completer.setSession(session);
81798
83576
  }
81799
83577
  }, [session, completer]);
81800
- const hide = (0, import_react27.useCallback)(() => {
83578
+ const hide = (0, import_react29.useCallback)(() => {
81801
83579
  setIsShowing(false);
81802
83580
  setSuggestions([]);
81803
83581
  setSelectedIndex(0);
81804
83582
  }, []);
81805
- const triggerCompletion = (0, import_react27.useCallback)(
83583
+ const triggerCompletion = (0, import_react29.useCallback)(
81806
83584
  async (input) => {
81807
83585
  const newSuggestions = await completer.complete(input);
81808
83586
  if (newSuggestions.length === 1) {
@@ -81820,7 +83598,7 @@ function useCompletion(options) {
81820
83598
  },
81821
83599
  [completer, hide]
81822
83600
  );
81823
- const filterSuggestions = (0, import_react27.useCallback)(
83601
+ const filterSuggestions = (0, import_react29.useCallback)(
81824
83602
  async (input) => {
81825
83603
  if (!isShowing) return;
81826
83604
  const newSuggestions = await completer.complete(input);
@@ -81833,19 +83611,19 @@ function useCompletion(options) {
81833
83611
  },
81834
83612
  [completer, isShowing, hide]
81835
83613
  );
81836
- const navigateUp = (0, import_react27.useCallback)(() => {
83614
+ const navigateUp = (0, import_react29.useCallback)(() => {
81837
83615
  if (!isShowing || suggestions.length === 0) return;
81838
83616
  setSelectedIndex(
81839
83617
  (current) => current > 0 ? current - 1 : suggestions.length - 1
81840
83618
  );
81841
83619
  }, [isShowing, suggestions.length]);
81842
- const navigateDown = (0, import_react27.useCallback)(() => {
83620
+ const navigateDown = (0, import_react29.useCallback)(() => {
81843
83621
  if (!isShowing || suggestions.length === 0) return;
81844
83622
  setSelectedIndex(
81845
83623
  (current) => current < suggestions.length - 1 ? current + 1 : 0
81846
83624
  );
81847
83625
  }, [isShowing, suggestions.length]);
81848
- const selectCurrent = (0, import_react27.useCallback)(() => {
83626
+ const selectCurrent = (0, import_react29.useCallback)(() => {
81849
83627
  if (!isShowing || suggestions.length === 0) return null;
81850
83628
  const selected = suggestions.at(selectedIndex);
81851
83629
  hide();
@@ -81865,7 +83643,7 @@ function useCompletion(options) {
81865
83643
  }
81866
83644
 
81867
83645
  // src/repl/hooks/useGitStatus.ts
81868
- var import_react28 = __toESM(require_react(), 1);
83646
+ var import_react30 = __toESM(require_react(), 1);
81869
83647
  var DEFAULT_POLL_INTERVAL_MS = 3e4;
81870
83648
  var MIN_POLL_INTERVAL_MS = 5e3;
81871
83649
  function getPollInterval() {
@@ -81879,20 +83657,20 @@ function getPollInterval() {
81879
83657
  function useGitStatus(options = {}) {
81880
83658
  const { enabled = true } = options;
81881
83659
  const pollIntervalMs = options.pollIntervalMs ?? getPollInterval();
81882
- const [gitInfo, setGitInfo] = (0, import_react28.useState)(void 0);
81883
- const [lastRefresh, setLastRefresh] = (0, import_react28.useState)(0);
81884
- const intervalRef = (0, import_react28.useRef)(null);
81885
- const refresh = (0, import_react28.useCallback)(() => {
83660
+ const [gitInfo, setGitInfo] = (0, import_react30.useState)(void 0);
83661
+ const [lastRefresh, setLastRefresh] = (0, import_react30.useState)(0);
83662
+ const intervalRef = (0, import_react30.useRef)(null);
83663
+ const refresh = (0, import_react30.useCallback)(() => {
81886
83664
  const info = getGitInfo();
81887
83665
  setGitInfo(info);
81888
83666
  setLastRefresh(Date.now());
81889
83667
  }, []);
81890
- (0, import_react28.useEffect)(() => {
83668
+ (0, import_react30.useEffect)(() => {
81891
83669
  if (enabled) {
81892
83670
  refresh();
81893
83671
  }
81894
83672
  }, [enabled, refresh]);
81895
- (0, import_react28.useEffect)(() => {
83673
+ (0, import_react30.useEffect)(() => {
81896
83674
  if (!enabled || pollIntervalMs === 0) {
81897
83675
  return;
81898
83676
  }
@@ -82987,7 +84765,7 @@ function getBuiltinDescription(cmd) {
82987
84765
  }
82988
84766
 
82989
84767
  // src/repl/App.tsx
82990
- var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
84768
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
82991
84769
  function isValidDomain2(word) {
82992
84770
  const lowerWord = word.toLowerCase();
82993
84771
  if (isCustomDomain(lowerWord)) return true;
@@ -83007,11 +84785,11 @@ function toUISuggestions(suggestions) {
83007
84785
  function App2({ initialSession } = {}) {
83008
84786
  const { exit } = use_app_default();
83009
84787
  const { stdout } = use_stdout_default();
83010
- const [session] = (0, import_react29.useState)(() => initialSession ?? new REPLSession());
83011
- const [isInitialized, setIsInitialized] = (0, import_react29.useState)(!!initialSession);
83012
- const [input, setInputState] = (0, import_react29.useState)("");
83013
- const inputRef = (0, import_react29.useRef)("");
83014
- const setInput = (0, import_react29.useCallback)(
84788
+ const [session] = (0, import_react31.useState)(() => initialSession ?? new REPLSession());
84789
+ const [isInitialized, setIsInitialized] = (0, import_react31.useState)(!!initialSession);
84790
+ const [input, setInputState] = (0, import_react31.useState)("");
84791
+ const inputRef = (0, import_react31.useRef)("");
84792
+ const setInput = (0, import_react31.useCallback)(
83015
84793
  (value) => {
83016
84794
  setInputState((prev) => {
83017
84795
  const newValue = typeof value === "function" ? value(prev) : value;
@@ -83021,18 +84799,20 @@ function App2({ initialSession } = {}) {
83021
84799
  },
83022
84800
  []
83023
84801
  );
83024
- const [outputItems, setOutputItems] = (0, import_react29.useState)([]);
83025
- const outputIdRef = (0, import_react29.useRef)(0);
83026
- const [prompt, setPrompt] = (0, import_react29.useState)("> ");
83027
- const [width, setWidth] = (0, import_react29.useState)(stdout?.columns ?? 80);
83028
- const [statusHint, setStatusHint] = (0, import_react29.useState)("Ctrl+C twice to exit");
83029
- const [historyArray, setHistoryArray] = (0, import_react29.useState)([]);
83030
- const [inputKey, setInputKey] = (0, import_react29.useState)(0);
83031
- const [hideStatusBar, setHideStatusBar] = (0, import_react29.useState)(false);
83032
- const [pendingRawStdout, setPendingRawStdout] = (0, import_react29.useState)(
84802
+ const [outputItems, setOutputItems] = (0, import_react31.useState)([]);
84803
+ const outputIdRef = (0, import_react31.useRef)(0);
84804
+ const [prompt, setPrompt] = (0, import_react31.useState)("> ");
84805
+ const [width, setWidth] = (0, import_react31.useState)(stdout?.columns ?? 80);
84806
+ const [statusHint, setStatusHint] = (0, import_react31.useState)("Ctrl+C twice to exit");
84807
+ const [historyArray, setHistoryArray] = (0, import_react31.useState)([]);
84808
+ const [inputKey, setInputKey] = (0, import_react31.useState)(0);
84809
+ const [hideStatusBar, setHideStatusBar] = (0, import_react31.useState)(false);
84810
+ const [pendingRawStdout, setPendingRawStdout] = (0, import_react31.useState)(
83033
84811
  null
83034
84812
  );
83035
- (0, import_react29.useEffect)(() => {
84813
+ const [mode, setMode] = (0, import_react31.useState)("repl");
84814
+ const [chatConfig, setChatConfig] = (0, import_react31.useState)(null);
84815
+ (0, import_react31.useEffect)(() => {
83036
84816
  if (hideStatusBar && pendingRawStdout) {
83037
84817
  process.stdout.write(pendingRawStdout);
83038
84818
  process.stdout.write("\n\n\n");
@@ -83061,7 +84841,7 @@ function App2({ initialSession } = {}) {
83061
84841
  session.saveHistory().finally(() => exit());
83062
84842
  }
83063
84843
  });
83064
- (0, import_react29.useEffect)(() => {
84844
+ (0, import_react31.useEffect)(() => {
83065
84845
  const init = async () => {
83066
84846
  if (!isInitialized) {
83067
84847
  await session.initialize();
@@ -83075,7 +84855,7 @@ function App2({ initialSession } = {}) {
83075
84855
  };
83076
84856
  init();
83077
84857
  }, [session]);
83078
- (0, import_react29.useEffect)(() => {
84858
+ (0, import_react31.useEffect)(() => {
83079
84859
  const handleResize = () => {
83080
84860
  if (stdout) {
83081
84861
  const newWidth = stdout.columns ?? 80;
@@ -83091,7 +84871,7 @@ function App2({ initialSession } = {}) {
83091
84871
  stdout?.off("resize", handleResize);
83092
84872
  };
83093
84873
  }, [stdout]);
83094
- const addOutput = (0, import_react29.useCallback)((line) => {
84874
+ const addOutput = (0, import_react31.useCallback)((line) => {
83095
84875
  const lines = line.split("\n");
83096
84876
  const newItems = lines.map((content) => ({
83097
84877
  id: outputIdRef.current++,
@@ -83105,7 +84885,7 @@ function App2({ initialSession } = {}) {
83105
84885
  return combined;
83106
84886
  });
83107
84887
  }, []);
83108
- const applyCompletion = (0, import_react29.useCallback)(
84888
+ const applyCompletion = (0, import_react31.useCallback)(
83109
84889
  (suggestion) => {
83110
84890
  const currentInput = inputRef.current;
83111
84891
  let newValue;
@@ -83133,19 +84913,24 @@ function App2({ initialSession } = {}) {
83133
84913
  []
83134
84914
  // No dependencies needed since we use inputRef
83135
84915
  );
83136
- const refreshHistory = (0, import_react29.useCallback)(() => {
84916
+ const refreshHistory = (0, import_react31.useCallback)(() => {
83137
84917
  const histMgr = session.getHistory();
83138
84918
  if (histMgr) {
83139
84919
  setHistoryArray(histMgr.getHistory());
83140
84920
  }
83141
84921
  }, [session]);
83142
- const runCommand = (0, import_react29.useCallback)(
84922
+ const runCommand = (0, import_react31.useCallback)(
83143
84923
  async (cmd) => {
83144
84924
  const trimmed = cmd.trim();
83145
84925
  if (!trimmed) return;
83146
84926
  const scrollbackCommand = `${colorBlue("\u23FA")} ${colorBoldWhite(prompt + trimmed)}`;
83147
84927
  addOutput(scrollbackCommand);
83148
84928
  const result = await executeCommand(trimmed, session);
84929
+ if (result.enterChatMode && result.chatConfig) {
84930
+ setMode("chat");
84931
+ setChatConfig(result.chatConfig);
84932
+ return;
84933
+ }
83149
84934
  if (result.rawStdout) {
83150
84935
  setHideStatusBar(true);
83151
84936
  setPendingRawStdout(result.rawStdout);
@@ -83171,7 +84956,7 @@ function App2({ initialSession } = {}) {
83171
84956
  },
83172
84957
  [session, prompt, addOutput, exit, refreshHistory, gitStatus]
83173
84958
  );
83174
- const handleInputChange = (0, import_react29.useCallback)(
84959
+ const handleInputChange = (0, import_react31.useCallback)(
83175
84960
  (newValue) => {
83176
84961
  const oldValue = input;
83177
84962
  setInput(newValue);
@@ -83199,7 +84984,7 @@ function App2({ initialSession } = {}) {
83199
84984
  },
83200
84985
  [input, completion]
83201
84986
  );
83202
- const handleSubmit = (0, import_react29.useCallback)(
84987
+ const handleSubmit = (0, import_react31.useCallback)(
83203
84988
  async (value) => {
83204
84989
  if (completion.isShowing && completion.suggestions.length > 0) {
83205
84990
  const selected = completion.selectCurrent();
@@ -83297,7 +85082,7 @@ function App2({ initialSession } = {}) {
83297
85082
  return;
83298
85083
  }
83299
85084
  });
83300
- const handleSuggestionNavigate = (0, import_react29.useCallback)(
85085
+ const handleSuggestionNavigate = (0, import_react31.useCallback)(
83301
85086
  (direction) => {
83302
85087
  if (direction === "up") {
83303
85088
  completion.navigateUp();
@@ -83307,17 +85092,33 @@ function App2({ initialSession } = {}) {
83307
85092
  },
83308
85093
  [completion]
83309
85094
  );
83310
- const handleSuggestionSelect = (0, import_react29.useCallback)(
85095
+ const handleSuggestionSelect = (0, import_react31.useCallback)(
83311
85096
  (suggestion) => {
83312
85097
  applyCompletion(suggestion);
83313
85098
  completion.hide();
83314
85099
  },
83315
85100
  [applyCompletion, completion]
83316
85101
  );
83317
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", width, children: [
83318
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Static, { items: outputItems, children: (item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: item.content }, item.id) }),
83319
- isInitialized && !hideStatusBar ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
83320
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
85102
+ const handleChatExit = (0, import_react31.useCallback)(
85103
+ (chatMessages) => {
85104
+ chatMessages.forEach((msg) => addOutput(msg));
85105
+ setMode("repl");
85106
+ setChatConfig(null);
85107
+ },
85108
+ [addOutput]
85109
+ );
85110
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", width, children: [
85111
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Static, { items: outputItems, children: (item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: item.content }, item.id) }),
85112
+ isInitialized && !hideStatusBar ? mode === "chat" && chatConfig ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
85113
+ ChatMode,
85114
+ {
85115
+ session,
85116
+ namespace: chatConfig.namespace,
85117
+ width,
85118
+ onExit: handleChatExit
85119
+ }
85120
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
85121
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
83321
85122
  InputBox,
83322
85123
  {
83323
85124
  prompt,
@@ -83329,7 +85130,7 @@ function App2({ initialSession } = {}) {
83329
85130
  inputKey
83330
85131
  }
83331
85132
  ),
83332
- completion.isShowing && completion.suggestions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
85133
+ completion.isShowing && completion.suggestions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
83333
85134
  Suggestions,
83334
85135
  {
83335
85136
  suggestions: toUISuggestions(
@@ -83342,7 +85143,7 @@ function App2({ initialSession } = {}) {
83342
85143
  maxVisible: 20,
83343
85144
  isActive: false
83344
85145
  }
83345
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
85146
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
83346
85147
  StatusBar,
83347
85148
  {
83348
85149
  gitInfo: gitStatus.gitInfo,
@@ -83350,12 +85151,12 @@ function App2({ initialSession } = {}) {
83350
85151
  hint: statusHint
83351
85152
  }
83352
85153
  )
83353
- ] }) : !isInitialized ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: "Initializing..." }) : null
85154
+ ] }) : !isInitialized ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: "Initializing..." }) : null
83354
85155
  ] });
83355
85156
  }
83356
85157
 
83357
85158
  // src/headless/controller.ts
83358
- import * as readline2 from "readline";
85159
+ import * as readline from "readline";
83359
85160
 
83360
85161
  // src/headless/protocol.ts
83361
85162
  function parseInput2(line) {
@@ -83630,7 +85431,7 @@ var HeadlessController = class {
83630
85431
  */
83631
85432
  async run() {
83632
85433
  await this.initialize();
83633
- this.rl = readline2.createInterface({
85434
+ this.rl = readline.createInterface({
83634
85435
  input: process.stdin,
83635
85436
  output: process.stdout,
83636
85437
  terminal: false
@@ -83663,7 +85464,7 @@ var HeadlessController = class {
83663
85464
  };
83664
85465
 
83665
85466
  // src/index.tsx
83666
- var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
85467
+ var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
83667
85468
  var program2 = new Command();
83668
85469
  program2.configureHelp({
83669
85470
  formatHelp: () => formatRootHelp().join("\n")
@@ -83773,7 +85574,7 @@ program2.name(CLI_NAME).description("F5 Distributed Cloud Shell - Interactive CL
83773
85574
  }
83774
85575
  process.stdin.resume();
83775
85576
  const appProps = { initialSession: session };
83776
- render_default(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(App2, { ...appProps }), { exitOnCtrlC: false });
85577
+ render_default(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(App2, { ...appProps }), { exitOnCtrlC: false });
83777
85578
  return;
83778
85579
  }
83779
85580
  await executeNonInteractive(commandArgs);