@calebmabry/wami 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +124 -0
  2. package/dist/cli.js +3180 -0
  3. package/package.json +55 -0
package/dist/cli.js ADDED
@@ -0,0 +1,3180 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+
20
+ // node_modules/cli-spinners/spinners.json
21
+ var require_spinners = __commonJS((exports, module) => {
22
+ module.exports = {
23
+ dots: {
24
+ interval: 80,
25
+ frames: [
26
+ "⠋",
27
+ "⠙",
28
+ "⠹",
29
+ "⠸",
30
+ "⠼",
31
+ "⠴",
32
+ "⠦",
33
+ "⠧",
34
+ "⠇",
35
+ "⠏"
36
+ ]
37
+ },
38
+ dots2: {
39
+ interval: 80,
40
+ frames: [
41
+ "⣾",
42
+ "⣽",
43
+ "⣻",
44
+ "⢿",
45
+ "⡿",
46
+ "⣟",
47
+ "⣯",
48
+ "⣷"
49
+ ]
50
+ },
51
+ dots3: {
52
+ interval: 80,
53
+ frames: [
54
+ "⠋",
55
+ "⠙",
56
+ "⠚",
57
+ "⠞",
58
+ "⠖",
59
+ "⠦",
60
+ "⠴",
61
+ "⠲",
62
+ "⠳",
63
+ "⠓"
64
+ ]
65
+ },
66
+ dots4: {
67
+ interval: 80,
68
+ frames: [
69
+ "⠄",
70
+ "⠆",
71
+ "⠇",
72
+ "⠋",
73
+ "⠙",
74
+ "⠸",
75
+ "⠰",
76
+ "⠠",
77
+ "⠰",
78
+ "⠸",
79
+ "⠙",
80
+ "⠋",
81
+ "⠇",
82
+ "⠆"
83
+ ]
84
+ },
85
+ dots5: {
86
+ interval: 80,
87
+ frames: [
88
+ "⠋",
89
+ "⠙",
90
+ "⠚",
91
+ "⠒",
92
+ "⠂",
93
+ "⠂",
94
+ "⠒",
95
+ "⠲",
96
+ "⠴",
97
+ "⠦",
98
+ "⠖",
99
+ "⠒",
100
+ "⠐",
101
+ "⠐",
102
+ "⠒",
103
+ "⠓",
104
+ "⠋"
105
+ ]
106
+ },
107
+ dots6: {
108
+ interval: 80,
109
+ frames: [
110
+ "⠁",
111
+ "⠉",
112
+ "⠙",
113
+ "⠚",
114
+ "⠒",
115
+ "⠂",
116
+ "⠂",
117
+ "⠒",
118
+ "⠲",
119
+ "⠴",
120
+ "⠤",
121
+ "⠄",
122
+ "⠄",
123
+ "⠤",
124
+ "⠴",
125
+ "⠲",
126
+ "⠒",
127
+ "⠂",
128
+ "⠂",
129
+ "⠒",
130
+ "⠚",
131
+ "⠙",
132
+ "⠉",
133
+ "⠁"
134
+ ]
135
+ },
136
+ dots7: {
137
+ interval: 80,
138
+ frames: [
139
+ "⠈",
140
+ "⠉",
141
+ "⠋",
142
+ "⠓",
143
+ "⠒",
144
+ "⠐",
145
+ "⠐",
146
+ "⠒",
147
+ "⠖",
148
+ "⠦",
149
+ "⠤",
150
+ "⠠",
151
+ "⠠",
152
+ "⠤",
153
+ "⠦",
154
+ "⠖",
155
+ "⠒",
156
+ "⠐",
157
+ "⠐",
158
+ "⠒",
159
+ "⠓",
160
+ "⠋",
161
+ "⠉",
162
+ "⠈"
163
+ ]
164
+ },
165
+ dots8: {
166
+ interval: 80,
167
+ frames: [
168
+ "⠁",
169
+ "⠁",
170
+ "⠉",
171
+ "⠙",
172
+ "⠚",
173
+ "⠒",
174
+ "⠂",
175
+ "⠂",
176
+ "⠒",
177
+ "⠲",
178
+ "⠴",
179
+ "⠤",
180
+ "⠄",
181
+ "⠄",
182
+ "⠤",
183
+ "⠠",
184
+ "⠠",
185
+ "⠤",
186
+ "⠦",
187
+ "⠖",
188
+ "⠒",
189
+ "⠐",
190
+ "⠐",
191
+ "⠒",
192
+ "⠓",
193
+ "⠋",
194
+ "⠉",
195
+ "⠈",
196
+ "⠈"
197
+ ]
198
+ },
199
+ dots9: {
200
+ interval: 80,
201
+ frames: [
202
+ "⢹",
203
+ "⢺",
204
+ "⢼",
205
+ "⣸",
206
+ "⣇",
207
+ "⡧",
208
+ "⡗",
209
+ "⡏"
210
+ ]
211
+ },
212
+ dots10: {
213
+ interval: 80,
214
+ frames: [
215
+ "⢄",
216
+ "⢂",
217
+ "⢁",
218
+ "⡁",
219
+ "⡈",
220
+ "⡐",
221
+ "⡠"
222
+ ]
223
+ },
224
+ dots11: {
225
+ interval: 100,
226
+ frames: [
227
+ "⠁",
228
+ "⠂",
229
+ "⠄",
230
+ "⡀",
231
+ "⢀",
232
+ "⠠",
233
+ "⠐",
234
+ "⠈"
235
+ ]
236
+ },
237
+ dots12: {
238
+ interval: 80,
239
+ frames: [
240
+ "⢀⠀",
241
+ "⡀⠀",
242
+ "⠄⠀",
243
+ "⢂⠀",
244
+ "⡂⠀",
245
+ "⠅⠀",
246
+ "⢃⠀",
247
+ "⡃⠀",
248
+ "⠍⠀",
249
+ "⢋⠀",
250
+ "⡋⠀",
251
+ "⠍⠁",
252
+ "⢋⠁",
253
+ "⡋⠁",
254
+ "⠍⠉",
255
+ "⠋⠉",
256
+ "⠋⠉",
257
+ "⠉⠙",
258
+ "⠉⠙",
259
+ "⠉⠩",
260
+ "⠈⢙",
261
+ "⠈⡙",
262
+ "⢈⠩",
263
+ "⡀⢙",
264
+ "⠄⡙",
265
+ "⢂⠩",
266
+ "⡂⢘",
267
+ "⠅⡘",
268
+ "⢃⠨",
269
+ "⡃⢐",
270
+ "⠍⡐",
271
+ "⢋⠠",
272
+ "⡋⢀",
273
+ "⠍⡁",
274
+ "⢋⠁",
275
+ "⡋⠁",
276
+ "⠍⠉",
277
+ "⠋⠉",
278
+ "⠋⠉",
279
+ "⠉⠙",
280
+ "⠉⠙",
281
+ "⠉⠩",
282
+ "⠈⢙",
283
+ "⠈⡙",
284
+ "⠈⠩",
285
+ "⠀⢙",
286
+ "⠀⡙",
287
+ "⠀⠩",
288
+ "⠀⢘",
289
+ "⠀⡘",
290
+ "⠀⠨",
291
+ "⠀⢐",
292
+ "⠀⡐",
293
+ "⠀⠠",
294
+ "⠀⢀",
295
+ "⠀⡀"
296
+ ]
297
+ },
298
+ dots13: {
299
+ interval: 80,
300
+ frames: [
301
+ "⣼",
302
+ "⣹",
303
+ "⢻",
304
+ "⠿",
305
+ "⡟",
306
+ "⣏",
307
+ "⣧",
308
+ "⣶"
309
+ ]
310
+ },
311
+ dots8Bit: {
312
+ interval: 80,
313
+ frames: [
314
+ "⠀",
315
+ "⠁",
316
+ "⠂",
317
+ "⠃",
318
+ "⠄",
319
+ "⠅",
320
+ "⠆",
321
+ "⠇",
322
+ "⡀",
323
+ "⡁",
324
+ "⡂",
325
+ "⡃",
326
+ "⡄",
327
+ "⡅",
328
+ "⡆",
329
+ "⡇",
330
+ "⠈",
331
+ "⠉",
332
+ "⠊",
333
+ "⠋",
334
+ "⠌",
335
+ "⠍",
336
+ "⠎",
337
+ "⠏",
338
+ "⡈",
339
+ "⡉",
340
+ "⡊",
341
+ "⡋",
342
+ "⡌",
343
+ "⡍",
344
+ "⡎",
345
+ "⡏",
346
+ "⠐",
347
+ "⠑",
348
+ "⠒",
349
+ "⠓",
350
+ "⠔",
351
+ "⠕",
352
+ "⠖",
353
+ "⠗",
354
+ "⡐",
355
+ "⡑",
356
+ "⡒",
357
+ "⡓",
358
+ "⡔",
359
+ "⡕",
360
+ "⡖",
361
+ "⡗",
362
+ "⠘",
363
+ "⠙",
364
+ "⠚",
365
+ "⠛",
366
+ "⠜",
367
+ "⠝",
368
+ "⠞",
369
+ "⠟",
370
+ "⡘",
371
+ "⡙",
372
+ "⡚",
373
+ "⡛",
374
+ "⡜",
375
+ "⡝",
376
+ "⡞",
377
+ "⡟",
378
+ "⠠",
379
+ "⠡",
380
+ "⠢",
381
+ "⠣",
382
+ "⠤",
383
+ "⠥",
384
+ "⠦",
385
+ "⠧",
386
+ "⡠",
387
+ "⡡",
388
+ "⡢",
389
+ "⡣",
390
+ "⡤",
391
+ "⡥",
392
+ "⡦",
393
+ "⡧",
394
+ "⠨",
395
+ "⠩",
396
+ "⠪",
397
+ "⠫",
398
+ "⠬",
399
+ "⠭",
400
+ "⠮",
401
+ "⠯",
402
+ "⡨",
403
+ "⡩",
404
+ "⡪",
405
+ "⡫",
406
+ "⡬",
407
+ "⡭",
408
+ "⡮",
409
+ "⡯",
410
+ "⠰",
411
+ "⠱",
412
+ "⠲",
413
+ "⠳",
414
+ "⠴",
415
+ "⠵",
416
+ "⠶",
417
+ "⠷",
418
+ "⡰",
419
+ "⡱",
420
+ "⡲",
421
+ "⡳",
422
+ "⡴",
423
+ "⡵",
424
+ "⡶",
425
+ "⡷",
426
+ "⠸",
427
+ "⠹",
428
+ "⠺",
429
+ "⠻",
430
+ "⠼",
431
+ "⠽",
432
+ "⠾",
433
+ "⠿",
434
+ "⡸",
435
+ "⡹",
436
+ "⡺",
437
+ "⡻",
438
+ "⡼",
439
+ "⡽",
440
+ "⡾",
441
+ "⡿",
442
+ "⢀",
443
+ "⢁",
444
+ "⢂",
445
+ "⢃",
446
+ "⢄",
447
+ "⢅",
448
+ "⢆",
449
+ "⢇",
450
+ "⣀",
451
+ "⣁",
452
+ "⣂",
453
+ "⣃",
454
+ "⣄",
455
+ "⣅",
456
+ "⣆",
457
+ "⣇",
458
+ "⢈",
459
+ "⢉",
460
+ "⢊",
461
+ "⢋",
462
+ "⢌",
463
+ "⢍",
464
+ "⢎",
465
+ "⢏",
466
+ "⣈",
467
+ "⣉",
468
+ "⣊",
469
+ "⣋",
470
+ "⣌",
471
+ "⣍",
472
+ "⣎",
473
+ "⣏",
474
+ "⢐",
475
+ "⢑",
476
+ "⢒",
477
+ "⢓",
478
+ "⢔",
479
+ "⢕",
480
+ "⢖",
481
+ "⢗",
482
+ "⣐",
483
+ "⣑",
484
+ "⣒",
485
+ "⣓",
486
+ "⣔",
487
+ "⣕",
488
+ "⣖",
489
+ "⣗",
490
+ "⢘",
491
+ "⢙",
492
+ "⢚",
493
+ "⢛",
494
+ "⢜",
495
+ "⢝",
496
+ "⢞",
497
+ "⢟",
498
+ "⣘",
499
+ "⣙",
500
+ "⣚",
501
+ "⣛",
502
+ "⣜",
503
+ "⣝",
504
+ "⣞",
505
+ "⣟",
506
+ "⢠",
507
+ "⢡",
508
+ "⢢",
509
+ "⢣",
510
+ "⢤",
511
+ "⢥",
512
+ "⢦",
513
+ "⢧",
514
+ "⣠",
515
+ "⣡",
516
+ "⣢",
517
+ "⣣",
518
+ "⣤",
519
+ "⣥",
520
+ "⣦",
521
+ "⣧",
522
+ "⢨",
523
+ "⢩",
524
+ "⢪",
525
+ "⢫",
526
+ "⢬",
527
+ "⢭",
528
+ "⢮",
529
+ "⢯",
530
+ "⣨",
531
+ "⣩",
532
+ "⣪",
533
+ "⣫",
534
+ "⣬",
535
+ "⣭",
536
+ "⣮",
537
+ "⣯",
538
+ "⢰",
539
+ "⢱",
540
+ "⢲",
541
+ "⢳",
542
+ "⢴",
543
+ "⢵",
544
+ "⢶",
545
+ "⢷",
546
+ "⣰",
547
+ "⣱",
548
+ "⣲",
549
+ "⣳",
550
+ "⣴",
551
+ "⣵",
552
+ "⣶",
553
+ "⣷",
554
+ "⢸",
555
+ "⢹",
556
+ "⢺",
557
+ "⢻",
558
+ "⢼",
559
+ "⢽",
560
+ "⢾",
561
+ "⢿",
562
+ "⣸",
563
+ "⣹",
564
+ "⣺",
565
+ "⣻",
566
+ "⣼",
567
+ "⣽",
568
+ "⣾",
569
+ "⣿"
570
+ ]
571
+ },
572
+ sand: {
573
+ interval: 80,
574
+ frames: [
575
+ "⠁",
576
+ "⠂",
577
+ "⠄",
578
+ "⡀",
579
+ "⡈",
580
+ "⡐",
581
+ "⡠",
582
+ "⣀",
583
+ "⣁",
584
+ "⣂",
585
+ "⣄",
586
+ "⣌",
587
+ "⣔",
588
+ "⣤",
589
+ "⣥",
590
+ "⣦",
591
+ "⣮",
592
+ "⣶",
593
+ "⣷",
594
+ "⣿",
595
+ "⡿",
596
+ "⠿",
597
+ "⢟",
598
+ "⠟",
599
+ "⡛",
600
+ "⠛",
601
+ "⠫",
602
+ "⢋",
603
+ "⠋",
604
+ "⠍",
605
+ "⡉",
606
+ "⠉",
607
+ "⠑",
608
+ "⠡",
609
+ "⢁"
610
+ ]
611
+ },
612
+ line: {
613
+ interval: 130,
614
+ frames: [
615
+ "-",
616
+ "\\",
617
+ "|",
618
+ "/"
619
+ ]
620
+ },
621
+ line2: {
622
+ interval: 100,
623
+ frames: [
624
+ "⠂",
625
+ "-",
626
+ "–",
627
+ "—",
628
+ "–",
629
+ "-"
630
+ ]
631
+ },
632
+ pipe: {
633
+ interval: 100,
634
+ frames: [
635
+ "┤",
636
+ "┘",
637
+ "┴",
638
+ "└",
639
+ "├",
640
+ "┌",
641
+ "┬",
642
+ "┐"
643
+ ]
644
+ },
645
+ simpleDots: {
646
+ interval: 400,
647
+ frames: [
648
+ ". ",
649
+ ".. ",
650
+ "...",
651
+ " "
652
+ ]
653
+ },
654
+ simpleDotsScrolling: {
655
+ interval: 200,
656
+ frames: [
657
+ ". ",
658
+ ".. ",
659
+ "...",
660
+ " ..",
661
+ " .",
662
+ " "
663
+ ]
664
+ },
665
+ star: {
666
+ interval: 70,
667
+ frames: [
668
+ "✶",
669
+ "✸",
670
+ "✹",
671
+ "✺",
672
+ "✹",
673
+ "✷"
674
+ ]
675
+ },
676
+ star2: {
677
+ interval: 80,
678
+ frames: [
679
+ "+",
680
+ "x",
681
+ "*"
682
+ ]
683
+ },
684
+ flip: {
685
+ interval: 70,
686
+ frames: [
687
+ "_",
688
+ "_",
689
+ "_",
690
+ "-",
691
+ "`",
692
+ "`",
693
+ "'",
694
+ "´",
695
+ "-",
696
+ "_",
697
+ "_",
698
+ "_"
699
+ ]
700
+ },
701
+ hamburger: {
702
+ interval: 100,
703
+ frames: [
704
+ "☱",
705
+ "☲",
706
+ "☴"
707
+ ]
708
+ },
709
+ growVertical: {
710
+ interval: 120,
711
+ frames: [
712
+ "▁",
713
+ "▃",
714
+ "▄",
715
+ "▅",
716
+ "▆",
717
+ "▇",
718
+ "▆",
719
+ "▅",
720
+ "▄",
721
+ "▃"
722
+ ]
723
+ },
724
+ growHorizontal: {
725
+ interval: 120,
726
+ frames: [
727
+ "▏",
728
+ "▎",
729
+ "▍",
730
+ "▌",
731
+ "▋",
732
+ "▊",
733
+ "▉",
734
+ "▊",
735
+ "▋",
736
+ "▌",
737
+ "▍",
738
+ "▎"
739
+ ]
740
+ },
741
+ balloon: {
742
+ interval: 140,
743
+ frames: [
744
+ " ",
745
+ ".",
746
+ "o",
747
+ "O",
748
+ "@",
749
+ "*",
750
+ " "
751
+ ]
752
+ },
753
+ balloon2: {
754
+ interval: 120,
755
+ frames: [
756
+ ".",
757
+ "o",
758
+ "O",
759
+ "°",
760
+ "O",
761
+ "o",
762
+ "."
763
+ ]
764
+ },
765
+ noise: {
766
+ interval: 100,
767
+ frames: [
768
+ "▓",
769
+ "▒",
770
+ "░"
771
+ ]
772
+ },
773
+ bounce: {
774
+ interval: 120,
775
+ frames: [
776
+ "⠁",
777
+ "⠂",
778
+ "⠄",
779
+ "⠂"
780
+ ]
781
+ },
782
+ boxBounce: {
783
+ interval: 120,
784
+ frames: [
785
+ "▖",
786
+ "▘",
787
+ "▝",
788
+ "▗"
789
+ ]
790
+ },
791
+ boxBounce2: {
792
+ interval: 100,
793
+ frames: [
794
+ "▌",
795
+ "▀",
796
+ "▐",
797
+ "▄"
798
+ ]
799
+ },
800
+ triangle: {
801
+ interval: 50,
802
+ frames: [
803
+ "◢",
804
+ "◣",
805
+ "◤",
806
+ "◥"
807
+ ]
808
+ },
809
+ binary: {
810
+ interval: 80,
811
+ frames: [
812
+ "010010",
813
+ "001100",
814
+ "100101",
815
+ "111010",
816
+ "111101",
817
+ "010111",
818
+ "101011",
819
+ "111000",
820
+ "110011",
821
+ "110101"
822
+ ]
823
+ },
824
+ arc: {
825
+ interval: 100,
826
+ frames: [
827
+ "◜",
828
+ "◠",
829
+ "◝",
830
+ "◞",
831
+ "◡",
832
+ "◟"
833
+ ]
834
+ },
835
+ circle: {
836
+ interval: 120,
837
+ frames: [
838
+ "◡",
839
+ "⊙",
840
+ "◠"
841
+ ]
842
+ },
843
+ squareCorners: {
844
+ interval: 180,
845
+ frames: [
846
+ "◰",
847
+ "◳",
848
+ "◲",
849
+ "◱"
850
+ ]
851
+ },
852
+ circleQuarters: {
853
+ interval: 120,
854
+ frames: [
855
+ "◴",
856
+ "◷",
857
+ "◶",
858
+ "◵"
859
+ ]
860
+ },
861
+ circleHalves: {
862
+ interval: 50,
863
+ frames: [
864
+ "◐",
865
+ "◓",
866
+ "◑",
867
+ "◒"
868
+ ]
869
+ },
870
+ squish: {
871
+ interval: 100,
872
+ frames: [
873
+ "╫",
874
+ "╪"
875
+ ]
876
+ },
877
+ toggle: {
878
+ interval: 250,
879
+ frames: [
880
+ "⊶",
881
+ "⊷"
882
+ ]
883
+ },
884
+ toggle2: {
885
+ interval: 80,
886
+ frames: [
887
+ "▫",
888
+ "▪"
889
+ ]
890
+ },
891
+ toggle3: {
892
+ interval: 120,
893
+ frames: [
894
+ "□",
895
+ "■"
896
+ ]
897
+ },
898
+ toggle4: {
899
+ interval: 100,
900
+ frames: [
901
+ "■",
902
+ "□",
903
+ "▪",
904
+ "▫"
905
+ ]
906
+ },
907
+ toggle5: {
908
+ interval: 100,
909
+ frames: [
910
+ "▮",
911
+ "▯"
912
+ ]
913
+ },
914
+ toggle6: {
915
+ interval: 300,
916
+ frames: [
917
+ "ဝ",
918
+ "၀"
919
+ ]
920
+ },
921
+ toggle7: {
922
+ interval: 80,
923
+ frames: [
924
+ "⦾",
925
+ "⦿"
926
+ ]
927
+ },
928
+ toggle8: {
929
+ interval: 100,
930
+ frames: [
931
+ "◍",
932
+ "◌"
933
+ ]
934
+ },
935
+ toggle9: {
936
+ interval: 100,
937
+ frames: [
938
+ "◉",
939
+ "◎"
940
+ ]
941
+ },
942
+ toggle10: {
943
+ interval: 100,
944
+ frames: [
945
+ "㊂",
946
+ "㊀",
947
+ "㊁"
948
+ ]
949
+ },
950
+ toggle11: {
951
+ interval: 50,
952
+ frames: [
953
+ "⧇",
954
+ "⧆"
955
+ ]
956
+ },
957
+ toggle12: {
958
+ interval: 120,
959
+ frames: [
960
+ "☗",
961
+ "☖"
962
+ ]
963
+ },
964
+ toggle13: {
965
+ interval: 80,
966
+ frames: [
967
+ "=",
968
+ "*",
969
+ "-"
970
+ ]
971
+ },
972
+ arrow: {
973
+ interval: 100,
974
+ frames: [
975
+ "←",
976
+ "↖",
977
+ "↑",
978
+ "↗",
979
+ "→",
980
+ "↘",
981
+ "↓",
982
+ "↙"
983
+ ]
984
+ },
985
+ arrow2: {
986
+ interval: 80,
987
+ frames: [
988
+ "⬆️ ",
989
+ "↗️ ",
990
+ "➡️ ",
991
+ "↘️ ",
992
+ "⬇️ ",
993
+ "↙️ ",
994
+ "⬅️ ",
995
+ "↖️ "
996
+ ]
997
+ },
998
+ arrow3: {
999
+ interval: 120,
1000
+ frames: [
1001
+ "▹▹▹▹▹",
1002
+ "▸▹▹▹▹",
1003
+ "▹▸▹▹▹",
1004
+ "▹▹▸▹▹",
1005
+ "▹▹▹▸▹",
1006
+ "▹▹▹▹▸"
1007
+ ]
1008
+ },
1009
+ bouncingBar: {
1010
+ interval: 80,
1011
+ frames: [
1012
+ "[ ]",
1013
+ "[= ]",
1014
+ "[== ]",
1015
+ "[=== ]",
1016
+ "[====]",
1017
+ "[ ===]",
1018
+ "[ ==]",
1019
+ "[ =]",
1020
+ "[ ]",
1021
+ "[ =]",
1022
+ "[ ==]",
1023
+ "[ ===]",
1024
+ "[====]",
1025
+ "[=== ]",
1026
+ "[== ]",
1027
+ "[= ]"
1028
+ ]
1029
+ },
1030
+ bouncingBall: {
1031
+ interval: 80,
1032
+ frames: [
1033
+ "( ● )",
1034
+ "( ● )",
1035
+ "( ● )",
1036
+ "( ● )",
1037
+ "( ●)",
1038
+ "( ● )",
1039
+ "( ● )",
1040
+ "( ● )",
1041
+ "( ● )",
1042
+ "(● )"
1043
+ ]
1044
+ },
1045
+ smiley: {
1046
+ interval: 200,
1047
+ frames: [
1048
+ "😄 ",
1049
+ "😝 "
1050
+ ]
1051
+ },
1052
+ monkey: {
1053
+ interval: 300,
1054
+ frames: [
1055
+ "🙈 ",
1056
+ "🙈 ",
1057
+ "🙉 ",
1058
+ "🙊 "
1059
+ ]
1060
+ },
1061
+ hearts: {
1062
+ interval: 100,
1063
+ frames: [
1064
+ "💛 ",
1065
+ "💙 ",
1066
+ "💜 ",
1067
+ "💚 ",
1068
+ "❤️ "
1069
+ ]
1070
+ },
1071
+ clock: {
1072
+ interval: 100,
1073
+ frames: [
1074
+ "🕛 ",
1075
+ "🕐 ",
1076
+ "🕑 ",
1077
+ "🕒 ",
1078
+ "🕓 ",
1079
+ "🕔 ",
1080
+ "🕕 ",
1081
+ "🕖 ",
1082
+ "🕗 ",
1083
+ "🕘 ",
1084
+ "🕙 ",
1085
+ "🕚 "
1086
+ ]
1087
+ },
1088
+ earth: {
1089
+ interval: 180,
1090
+ frames: [
1091
+ "🌍 ",
1092
+ "🌎 ",
1093
+ "🌏 "
1094
+ ]
1095
+ },
1096
+ material: {
1097
+ interval: 17,
1098
+ frames: [
1099
+ "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1100
+ "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1101
+ "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1102
+ "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1103
+ "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1104
+ "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1105
+ "███████▁▁▁▁▁▁▁▁▁▁▁▁▁",
1106
+ "████████▁▁▁▁▁▁▁▁▁▁▁▁",
1107
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1108
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1109
+ "██████████▁▁▁▁▁▁▁▁▁▁",
1110
+ "███████████▁▁▁▁▁▁▁▁▁",
1111
+ "█████████████▁▁▁▁▁▁▁",
1112
+ "██████████████▁▁▁▁▁▁",
1113
+ "██████████████▁▁▁▁▁▁",
1114
+ "▁██████████████▁▁▁▁▁",
1115
+ "▁██████████████▁▁▁▁▁",
1116
+ "▁██████████████▁▁▁▁▁",
1117
+ "▁▁██████████████▁▁▁▁",
1118
+ "▁▁▁██████████████▁▁▁",
1119
+ "▁▁▁▁█████████████▁▁▁",
1120
+ "▁▁▁▁██████████████▁▁",
1121
+ "▁▁▁▁██████████████▁▁",
1122
+ "▁▁▁▁▁██████████████▁",
1123
+ "▁▁▁▁▁██████████████▁",
1124
+ "▁▁▁▁▁██████████████▁",
1125
+ "▁▁▁▁▁▁██████████████",
1126
+ "▁▁▁▁▁▁██████████████",
1127
+ "▁▁▁▁▁▁▁█████████████",
1128
+ "▁▁▁▁▁▁▁█████████████",
1129
+ "▁▁▁▁▁▁▁▁████████████",
1130
+ "▁▁▁▁▁▁▁▁████████████",
1131
+ "▁▁▁▁▁▁▁▁▁███████████",
1132
+ "▁▁▁▁▁▁▁▁▁███████████",
1133
+ "▁▁▁▁▁▁▁▁▁▁██████████",
1134
+ "▁▁▁▁▁▁▁▁▁▁██████████",
1135
+ "▁▁▁▁▁▁▁▁▁▁▁▁████████",
1136
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
1137
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████",
1138
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
1139
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
1140
+ "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
1141
+ "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
1142
+ "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
1143
+ "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
1144
+ "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
1145
+ "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1146
+ "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1147
+ "██████▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1148
+ "████████▁▁▁▁▁▁▁▁▁▁▁▁",
1149
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1150
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1151
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1152
+ "█████████▁▁▁▁▁▁▁▁▁▁▁",
1153
+ "███████████▁▁▁▁▁▁▁▁▁",
1154
+ "████████████▁▁▁▁▁▁▁▁",
1155
+ "████████████▁▁▁▁▁▁▁▁",
1156
+ "██████████████▁▁▁▁▁▁",
1157
+ "██████████████▁▁▁▁▁▁",
1158
+ "▁██████████████▁▁▁▁▁",
1159
+ "▁██████████████▁▁▁▁▁",
1160
+ "▁▁▁█████████████▁▁▁▁",
1161
+ "▁▁▁▁▁████████████▁▁▁",
1162
+ "▁▁▁▁▁████████████▁▁▁",
1163
+ "▁▁▁▁▁▁███████████▁▁▁",
1164
+ "▁▁▁▁▁▁▁▁█████████▁▁▁",
1165
+ "▁▁▁▁▁▁▁▁█████████▁▁▁",
1166
+ "▁▁▁▁▁▁▁▁▁█████████▁▁",
1167
+ "▁▁▁▁▁▁▁▁▁█████████▁▁",
1168
+ "▁▁▁▁▁▁▁▁▁▁█████████▁",
1169
+ "▁▁▁▁▁▁▁▁▁▁▁████████▁",
1170
+ "▁▁▁▁▁▁▁▁▁▁▁████████▁",
1171
+ "▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
1172
+ "▁▁▁▁▁▁▁▁▁▁▁▁███████▁",
1173
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
1174
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
1175
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
1176
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
1177
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
1178
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
1179
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
1180
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
1181
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
1182
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
1183
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
1184
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1185
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1186
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
1187
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1188
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1189
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
1190
+ "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁"
1191
+ ]
1192
+ },
1193
+ moon: {
1194
+ interval: 80,
1195
+ frames: [
1196
+ "🌑 ",
1197
+ "🌒 ",
1198
+ "🌓 ",
1199
+ "🌔 ",
1200
+ "🌕 ",
1201
+ "🌖 ",
1202
+ "🌗 ",
1203
+ "🌘 "
1204
+ ]
1205
+ },
1206
+ runner: {
1207
+ interval: 140,
1208
+ frames: [
1209
+ "🚶 ",
1210
+ "🏃 "
1211
+ ]
1212
+ },
1213
+ pong: {
1214
+ interval: 80,
1215
+ frames: [
1216
+ "▐⠂ ▌",
1217
+ "▐⠈ ▌",
1218
+ "▐ ⠂ ▌",
1219
+ "▐ ⠠ ▌",
1220
+ "▐ ⡀ ▌",
1221
+ "▐ ⠠ ▌",
1222
+ "▐ ⠂ ▌",
1223
+ "▐ ⠈ ▌",
1224
+ "▐ ⠂ ▌",
1225
+ "▐ ⠠ ▌",
1226
+ "▐ ⡀ ▌",
1227
+ "▐ ⠠ ▌",
1228
+ "▐ ⠂ ▌",
1229
+ "▐ ⠈ ▌",
1230
+ "▐ ⠂▌",
1231
+ "▐ ⠠▌",
1232
+ "▐ ⡀▌",
1233
+ "▐ ⠠ ▌",
1234
+ "▐ ⠂ ▌",
1235
+ "▐ ⠈ ▌",
1236
+ "▐ ⠂ ▌",
1237
+ "▐ ⠠ ▌",
1238
+ "▐ ⡀ ▌",
1239
+ "▐ ⠠ ▌",
1240
+ "▐ ⠂ ▌",
1241
+ "▐ ⠈ ▌",
1242
+ "▐ ⠂ ▌",
1243
+ "▐ ⠠ ▌",
1244
+ "▐ ⡀ ▌",
1245
+ "▐⠠ ▌"
1246
+ ]
1247
+ },
1248
+ shark: {
1249
+ interval: 120,
1250
+ frames: [
1251
+ "▐|\\____________▌",
1252
+ "▐_|\\___________▌",
1253
+ "▐__|\\__________▌",
1254
+ "▐___|\\_________▌",
1255
+ "▐____|\\________▌",
1256
+ "▐_____|\\_______▌",
1257
+ "▐______|\\______▌",
1258
+ "▐_______|\\_____▌",
1259
+ "▐________|\\____▌",
1260
+ "▐_________|\\___▌",
1261
+ "▐__________|\\__▌",
1262
+ "▐___________|\\_▌",
1263
+ "▐____________|\\▌",
1264
+ "▐____________/|▌",
1265
+ "▐___________/|_▌",
1266
+ "▐__________/|__▌",
1267
+ "▐_________/|___▌",
1268
+ "▐________/|____▌",
1269
+ "▐_______/|_____▌",
1270
+ "▐______/|______▌",
1271
+ "▐_____/|_______▌",
1272
+ "▐____/|________▌",
1273
+ "▐___/|_________▌",
1274
+ "▐__/|__________▌",
1275
+ "▐_/|___________▌",
1276
+ "▐/|____________▌"
1277
+ ]
1278
+ },
1279
+ dqpb: {
1280
+ interval: 100,
1281
+ frames: [
1282
+ "d",
1283
+ "q",
1284
+ "p",
1285
+ "b"
1286
+ ]
1287
+ },
1288
+ weather: {
1289
+ interval: 100,
1290
+ frames: [
1291
+ "☀️ ",
1292
+ "☀️ ",
1293
+ "☀️ ",
1294
+ "🌤 ",
1295
+ "⛅️ ",
1296
+ "🌥 ",
1297
+ "☁️ ",
1298
+ "🌧 ",
1299
+ "🌨 ",
1300
+ "🌧 ",
1301
+ "🌨 ",
1302
+ "🌧 ",
1303
+ "🌨 ",
1304
+ "⛈ ",
1305
+ "🌨 ",
1306
+ "🌧 ",
1307
+ "🌨 ",
1308
+ "☁️ ",
1309
+ "🌥 ",
1310
+ "⛅️ ",
1311
+ "🌤 ",
1312
+ "☀️ ",
1313
+ "☀️ "
1314
+ ]
1315
+ },
1316
+ christmas: {
1317
+ interval: 400,
1318
+ frames: [
1319
+ "🌲",
1320
+ "🎄"
1321
+ ]
1322
+ },
1323
+ grenade: {
1324
+ interval: 80,
1325
+ frames: [
1326
+ "، ",
1327
+ "′ ",
1328
+ " ´ ",
1329
+ " ‾ ",
1330
+ " ⸌",
1331
+ " ⸊",
1332
+ " |",
1333
+ " ⁎",
1334
+ " ⁕",
1335
+ " ෴ ",
1336
+ " ⁓",
1337
+ " ",
1338
+ " ",
1339
+ " "
1340
+ ]
1341
+ },
1342
+ point: {
1343
+ interval: 125,
1344
+ frames: [
1345
+ "∙∙∙",
1346
+ "●∙∙",
1347
+ "∙●∙",
1348
+ "∙∙●",
1349
+ "∙∙∙"
1350
+ ]
1351
+ },
1352
+ layer: {
1353
+ interval: 150,
1354
+ frames: [
1355
+ "-",
1356
+ "=",
1357
+ "≡"
1358
+ ]
1359
+ },
1360
+ betaWave: {
1361
+ interval: 80,
1362
+ frames: [
1363
+ "ρββββββ",
1364
+ "βρβββββ",
1365
+ "ββρββββ",
1366
+ "βββρβββ",
1367
+ "ββββρββ",
1368
+ "βββββρβ",
1369
+ "ββββββρ"
1370
+ ]
1371
+ },
1372
+ fingerDance: {
1373
+ interval: 160,
1374
+ frames: [
1375
+ "🤘 ",
1376
+ "🤟 ",
1377
+ "🖖 ",
1378
+ "✋ ",
1379
+ "🤚 ",
1380
+ "👆 "
1381
+ ]
1382
+ },
1383
+ fistBump: {
1384
+ interval: 80,
1385
+ frames: [
1386
+ "🤜    🤛 ",
1387
+ "🤜    🤛 ",
1388
+ "🤜    🤛 ",
1389
+ " 🤜  🤛  ",
1390
+ "  🤜🤛   ",
1391
+ " 🤜✨🤛   ",
1392
+ "🤜 ✨ 🤛  "
1393
+ ]
1394
+ },
1395
+ soccerHeader: {
1396
+ interval: 80,
1397
+ frames: [
1398
+ " 🧑⚽️ 🧑 ",
1399
+ "🧑 ⚽️ 🧑 ",
1400
+ "🧑 ⚽️ 🧑 ",
1401
+ "🧑 ⚽️ 🧑 ",
1402
+ "🧑 ⚽️ 🧑 ",
1403
+ "🧑 ⚽️ 🧑 ",
1404
+ "🧑 ⚽️🧑 ",
1405
+ "🧑 ⚽️ 🧑 ",
1406
+ "🧑 ⚽️ 🧑 ",
1407
+ "🧑 ⚽️ 🧑 ",
1408
+ "🧑 ⚽️ 🧑 ",
1409
+ "🧑 ⚽️ 🧑 "
1410
+ ]
1411
+ },
1412
+ mindblown: {
1413
+ interval: 160,
1414
+ frames: [
1415
+ "😐 ",
1416
+ "😐 ",
1417
+ "😮 ",
1418
+ "😮 ",
1419
+ "😦 ",
1420
+ "😦 ",
1421
+ "😧 ",
1422
+ "😧 ",
1423
+ "🤯 ",
1424
+ "💥 ",
1425
+ "✨ ",
1426
+ "  ",
1427
+ "  ",
1428
+ "  "
1429
+ ]
1430
+ },
1431
+ speaker: {
1432
+ interval: 160,
1433
+ frames: [
1434
+ "🔈 ",
1435
+ "🔉 ",
1436
+ "🔊 ",
1437
+ "🔉 "
1438
+ ]
1439
+ },
1440
+ orangePulse: {
1441
+ interval: 100,
1442
+ frames: [
1443
+ "🔸 ",
1444
+ "🔶 ",
1445
+ "🟠 ",
1446
+ "🟠 ",
1447
+ "🔶 "
1448
+ ]
1449
+ },
1450
+ bluePulse: {
1451
+ interval: 100,
1452
+ frames: [
1453
+ "🔹 ",
1454
+ "🔷 ",
1455
+ "🔵 ",
1456
+ "🔵 ",
1457
+ "🔷 "
1458
+ ]
1459
+ },
1460
+ orangeBluePulse: {
1461
+ interval: 100,
1462
+ frames: [
1463
+ "🔸 ",
1464
+ "🔶 ",
1465
+ "🟠 ",
1466
+ "🟠 ",
1467
+ "🔶 ",
1468
+ "🔹 ",
1469
+ "🔷 ",
1470
+ "🔵 ",
1471
+ "🔵 ",
1472
+ "🔷 "
1473
+ ]
1474
+ },
1475
+ timeTravel: {
1476
+ interval: 100,
1477
+ frames: [
1478
+ "🕛 ",
1479
+ "🕚 ",
1480
+ "🕙 ",
1481
+ "🕘 ",
1482
+ "🕗 ",
1483
+ "🕖 ",
1484
+ "🕕 ",
1485
+ "🕔 ",
1486
+ "🕓 ",
1487
+ "🕒 ",
1488
+ "🕑 ",
1489
+ "🕐 "
1490
+ ]
1491
+ },
1492
+ aesthetic: {
1493
+ interval: 80,
1494
+ frames: [
1495
+ "▰▱▱▱▱▱▱",
1496
+ "▰▰▱▱▱▱▱",
1497
+ "▰▰▰▱▱▱▱",
1498
+ "▰▰▰▰▱▱▱",
1499
+ "▰▰▰▰▰▱▱",
1500
+ "▰▰▰▰▰▰▱",
1501
+ "▰▰▰▰▰▰▰",
1502
+ "▰▱▱▱▱▱▱"
1503
+ ]
1504
+ },
1505
+ dwarfFortress: {
1506
+ interval: 80,
1507
+ frames: [
1508
+ " ██████£££ ",
1509
+ "☺██████£££ ",
1510
+ "☺██████£££ ",
1511
+ "☺▓█████£££ ",
1512
+ "☺▓█████£££ ",
1513
+ "☺▒█████£££ ",
1514
+ "☺▒█████£££ ",
1515
+ "☺░█████£££ ",
1516
+ "☺░█████£££ ",
1517
+ "☺ █████£££ ",
1518
+ " ☺█████£££ ",
1519
+ " ☺█████£££ ",
1520
+ " ☺▓████£££ ",
1521
+ " ☺▓████£££ ",
1522
+ " ☺▒████£££ ",
1523
+ " ☺▒████£££ ",
1524
+ " ☺░████£££ ",
1525
+ " ☺░████£££ ",
1526
+ " ☺ ████£££ ",
1527
+ " ☺████£££ ",
1528
+ " ☺████£££ ",
1529
+ " ☺▓███£££ ",
1530
+ " ☺▓███£££ ",
1531
+ " ☺▒███£££ ",
1532
+ " ☺▒███£££ ",
1533
+ " ☺░███£££ ",
1534
+ " ☺░███£££ ",
1535
+ " ☺ ███£££ ",
1536
+ " ☺███£££ ",
1537
+ " ☺███£££ ",
1538
+ " ☺▓██£££ ",
1539
+ " ☺▓██£££ ",
1540
+ " ☺▒██£££ ",
1541
+ " ☺▒██£££ ",
1542
+ " ☺░██£££ ",
1543
+ " ☺░██£££ ",
1544
+ " ☺ ██£££ ",
1545
+ " ☺██£££ ",
1546
+ " ☺██£££ ",
1547
+ " ☺▓█£££ ",
1548
+ " ☺▓█£££ ",
1549
+ " ☺▒█£££ ",
1550
+ " ☺▒█£££ ",
1551
+ " ☺░█£££ ",
1552
+ " ☺░█£££ ",
1553
+ " ☺ █£££ ",
1554
+ " ☺█£££ ",
1555
+ " ☺█£££ ",
1556
+ " ☺▓£££ ",
1557
+ " ☺▓£££ ",
1558
+ " ☺▒£££ ",
1559
+ " ☺▒£££ ",
1560
+ " ☺░£££ ",
1561
+ " ☺░£££ ",
1562
+ " ☺ £££ ",
1563
+ " ☺£££ ",
1564
+ " ☺£££ ",
1565
+ " ☺▓££ ",
1566
+ " ☺▓££ ",
1567
+ " ☺▒££ ",
1568
+ " ☺▒££ ",
1569
+ " ☺░££ ",
1570
+ " ☺░££ ",
1571
+ " ☺ ££ ",
1572
+ " ☺££ ",
1573
+ " ☺££ ",
1574
+ " ☺▓£ ",
1575
+ " ☺▓£ ",
1576
+ " ☺▒£ ",
1577
+ " ☺▒£ ",
1578
+ " ☺░£ ",
1579
+ " ☺░£ ",
1580
+ " ☺ £ ",
1581
+ " ☺£ ",
1582
+ " ☺£ ",
1583
+ " ☺▓ ",
1584
+ " ☺▓ ",
1585
+ " ☺▒ ",
1586
+ " ☺▒ ",
1587
+ " ☺░ ",
1588
+ " ☺░ ",
1589
+ " ☺ ",
1590
+ " ☺ &",
1591
+ " ☺ ☼&",
1592
+ " ☺ ☼ &",
1593
+ " ☺☼ &",
1594
+ " ☺☼ & ",
1595
+ " ‼ & ",
1596
+ " ☺ & ",
1597
+ " ‼ & ",
1598
+ " ☺ & ",
1599
+ " ‼ & ",
1600
+ " ☺ & ",
1601
+ "‼ & ",
1602
+ " & ",
1603
+ " & ",
1604
+ " & ░ ",
1605
+ " & ▒ ",
1606
+ " & ▓ ",
1607
+ " & £ ",
1608
+ " & ░£ ",
1609
+ " & ▒£ ",
1610
+ " & ▓£ ",
1611
+ " & ££ ",
1612
+ " & ░££ ",
1613
+ " & ▒££ ",
1614
+ "& ▓££ ",
1615
+ "& £££ ",
1616
+ " ░£££ ",
1617
+ " ▒£££ ",
1618
+ " ▓£££ ",
1619
+ " █£££ ",
1620
+ " ░█£££ ",
1621
+ " ▒█£££ ",
1622
+ " ▓█£££ ",
1623
+ " ██£££ ",
1624
+ " ░██£££ ",
1625
+ " ▒██£££ ",
1626
+ " ▓██£££ ",
1627
+ " ███£££ ",
1628
+ " ░███£££ ",
1629
+ " ▒███£££ ",
1630
+ " ▓███£££ ",
1631
+ " ████£££ ",
1632
+ " ░████£££ ",
1633
+ " ▒████£££ ",
1634
+ " ▓████£££ ",
1635
+ " █████£££ ",
1636
+ " ░█████£££ ",
1637
+ " ▒█████£££ ",
1638
+ " ▓█████£££ ",
1639
+ " ██████£££ ",
1640
+ " ██████£££ "
1641
+ ]
1642
+ }
1643
+ };
1644
+ });
1645
+
1646
+ // node_modules/cli-spinners/index.js
1647
+ var require_cli_spinners = __commonJS((exports, module) => {
1648
+ var spinners = Object.assign({}, require_spinners());
1649
+ var spinnersList = Object.keys(spinners);
1650
+ Object.defineProperty(spinners, "random", {
1651
+ get() {
1652
+ const randomIndex = Math.floor(Math.random() * spinnersList.length);
1653
+ const spinnerName = spinnersList[randomIndex];
1654
+ return spinners[spinnerName];
1655
+ }
1656
+ });
1657
+ module.exports = spinners;
1658
+ });
1659
+
1660
+ // src/cli.tsx
1661
+ import { render } from "ink";
1662
+
1663
+ // src/app.tsx
1664
+ import { useEffect as useEffect3, useState as useState5 } from "react";
1665
+ import { Text as Text7, Box as Box6 } from "ink";
1666
+
1667
+ // node_modules/ink-spinner/build/index.js
1668
+ var import_cli_spinners = __toESM(require_cli_spinners(), 1);
1669
+ import React, { useState, useEffect } from "react";
1670
+ import { Text } from "ink";
1671
+ function Spinner({ type = "dots" }) {
1672
+ const [frame, setFrame] = useState(0);
1673
+ const spinner = import_cli_spinners.default[type];
1674
+ useEffect(() => {
1675
+ const timer = setInterval(() => {
1676
+ setFrame((previousFrame) => {
1677
+ const isLastFrame = previousFrame === spinner.frames.length - 1;
1678
+ return isLastFrame ? 0 : previousFrame + 1;
1679
+ });
1680
+ }, spinner.interval);
1681
+ return () => {
1682
+ clearInterval(timer);
1683
+ };
1684
+ }, [spinner]);
1685
+ return React.createElement(Text, null, spinner.frames[frame]);
1686
+ }
1687
+ var build_default = Spinner;
1688
+
1689
+ // src/core/nodejs-detector.ts
1690
+ import * as path2 from "path";
1691
+
1692
+ // src/core/detector.ts
1693
+ class EcosystemDetector {
1694
+ }
1695
+
1696
+ // src/utils/fs.ts
1697
+ import { promises as fs } from "fs";
1698
+ import * as path from "path";
1699
+ async function findFileUpwards(cwd, fileName) {
1700
+ let currentDir = path.resolve(cwd);
1701
+ const root = path.parse(currentDir).root;
1702
+ while (true) {
1703
+ const filePath = path.join(currentDir, fileName);
1704
+ try {
1705
+ await fs.access(filePath);
1706
+ return currentDir;
1707
+ } catch {}
1708
+ if (currentDir === root) {
1709
+ return null;
1710
+ }
1711
+ currentDir = path.dirname(currentDir);
1712
+ }
1713
+ }
1714
+ async function findAllFilesUpwards(cwd, fileName) {
1715
+ const results = [];
1716
+ let currentDir = path.resolve(cwd);
1717
+ const root = path.parse(currentDir).root;
1718
+ while (true) {
1719
+ const filePath = path.join(currentDir, fileName);
1720
+ try {
1721
+ await fs.access(filePath);
1722
+ results.push(currentDir);
1723
+ } catch {}
1724
+ if (currentDir === root) {
1725
+ break;
1726
+ }
1727
+ currentDir = path.dirname(currentDir);
1728
+ }
1729
+ return results;
1730
+ }
1731
+ async function fileExists(filePath) {
1732
+ try {
1733
+ await fs.access(filePath);
1734
+ return true;
1735
+ } catch {
1736
+ return false;
1737
+ }
1738
+ }
1739
+ async function readJsonFile(filePath) {
1740
+ const content = await fs.readFile(filePath, "utf-8");
1741
+ return JSON.parse(content);
1742
+ }
1743
+
1744
+ // src/core/nodejs-detector.ts
1745
+ class NodeJSDetector extends EcosystemDetector {
1746
+ name = "Node.js";
1747
+ markerFiles = ["package.json"];
1748
+ async detect(cwd) {
1749
+ return await findFileUpwards(cwd, "package.json");
1750
+ }
1751
+ async parse(projectRoot) {
1752
+ const packageJsonPath = path2.join(projectRoot, "package.json");
1753
+ const packageJson = await readJsonFile(packageJsonPath);
1754
+ const name = packageJson.name || path2.basename(projectRoot);
1755
+ const packageManager = await this.detectPackageManager(projectRoot);
1756
+ const scripts = this.extractScripts(packageJson);
1757
+ const workspace = await this.detectWorkspace(projectRoot);
1758
+ return {
1759
+ path: packageJsonPath,
1760
+ name,
1761
+ packageManager,
1762
+ scripts,
1763
+ workspace
1764
+ };
1765
+ }
1766
+ async detectPackageManager(projectRoot) {
1767
+ const lockFiles = [
1768
+ ["bun.lockb", "bun"],
1769
+ ["bun.lock", "bun"],
1770
+ ["pnpm-lock.yaml", "pnpm"],
1771
+ ["yarn.lock", "yarn"],
1772
+ ["package-lock.json", "npm"]
1773
+ ];
1774
+ for (const [lockFile, manager] of lockFiles) {
1775
+ const lockPath = path2.join(projectRoot, lockFile);
1776
+ if (await fileExists(lockPath)) {
1777
+ return manager;
1778
+ }
1779
+ }
1780
+ return "npm";
1781
+ }
1782
+ extractScripts(packageJson) {
1783
+ if (!packageJson.scripts) {
1784
+ return [];
1785
+ }
1786
+ return Object.entries(packageJson.scripts).map(([name, command]) => ({
1787
+ name,
1788
+ command
1789
+ }));
1790
+ }
1791
+ async detectWorkspace(projectRoot) {
1792
+ const allPackageRoots = await findAllFilesUpwards(projectRoot, "package.json");
1793
+ if (allPackageRoots.length <= 1) {
1794
+ return;
1795
+ }
1796
+ const currentPackageRoot = allPackageRoots[0];
1797
+ if (!currentPackageRoot) {
1798
+ return;
1799
+ }
1800
+ for (let i = 1;i < allPackageRoots.length; i++) {
1801
+ const parentRoot = allPackageRoots[i];
1802
+ if (!parentRoot) {
1803
+ continue;
1804
+ }
1805
+ const parentPackageJsonPath = path2.join(parentRoot, "package.json");
1806
+ const parentPackageJson = await readJsonFile(parentPackageJsonPath);
1807
+ if (parentPackageJson.workspaces) {
1808
+ const relativePath = path2.relative(parentRoot, currentPackageRoot);
1809
+ return {
1810
+ isWorkspace: true,
1811
+ workspaceRoot: parentRoot,
1812
+ workspaceName: parentPackageJson.name || path2.basename(parentRoot),
1813
+ relativePath
1814
+ };
1815
+ }
1816
+ }
1817
+ return;
1818
+ }
1819
+ buildCommand(packageInfo, scriptName) {
1820
+ const { packageManager } = packageInfo;
1821
+ if (packageManager === "npm" || packageManager === "yarn") {
1822
+ return `${packageManager} run ${scriptName}`;
1823
+ }
1824
+ return `${packageManager} ${scriptName}`;
1825
+ }
1826
+ }
1827
+
1828
+ // src/core/python-detector.ts
1829
+ import * as path4 from "path";
1830
+
1831
+ // src/utils/config.ts
1832
+ import * as path3 from "path";
1833
+ async function loadConfig(projectRoot) {
1834
+ const configPaths = [
1835
+ path3.join(projectRoot, ".wami.json"),
1836
+ path3.join(projectRoot, "wami.json")
1837
+ ];
1838
+ for (const configPath of configPaths) {
1839
+ if (await fileExists(configPath)) {
1840
+ try {
1841
+ return await readJsonFile(configPath);
1842
+ } catch (error) {
1843
+ console.error(`Failed to parse ${configPath}:`, error);
1844
+ return null;
1845
+ }
1846
+ }
1847
+ }
1848
+ return null;
1849
+ }
1850
+ async function detectVenv(projectRoot) {
1851
+ const venvPaths = [
1852
+ path3.join(projectRoot, ".venv"),
1853
+ path3.join(projectRoot, "venv"),
1854
+ path3.join(projectRoot, "env")
1855
+ ];
1856
+ for (const venvPath of venvPaths) {
1857
+ if (await fileExists(venvPath)) {
1858
+ return venvPath;
1859
+ }
1860
+ }
1861
+ return null;
1862
+ }
1863
+
1864
+ // src/core/python-detector.ts
1865
+ import { promises as fs2 } from "fs";
1866
+
1867
+ class PythonDetector extends EcosystemDetector {
1868
+ name = "Python";
1869
+ markerFiles = ["pyproject.toml", "requirements.txt", "Pipfile"];
1870
+ async detect(cwd) {
1871
+ const pyprojectRoot = await findFileUpwards(cwd, "pyproject.toml");
1872
+ if (pyprojectRoot) {
1873
+ return pyprojectRoot;
1874
+ }
1875
+ const pipfileRoot = await findFileUpwards(cwd, "Pipfile");
1876
+ if (pipfileRoot) {
1877
+ return pipfileRoot;
1878
+ }
1879
+ const reqRoot = await findFileUpwards(cwd, "requirements.txt");
1880
+ if (reqRoot) {
1881
+ return reqRoot;
1882
+ }
1883
+ return null;
1884
+ }
1885
+ async parse(projectRoot) {
1886
+ const pyprojectPath = path4.join(projectRoot, "pyproject.toml");
1887
+ const pipfilePath = path4.join(projectRoot, "Pipfile");
1888
+ const requirementsPath = path4.join(projectRoot, "requirements.txt");
1889
+ let name = path4.basename(projectRoot);
1890
+ let scripts = [];
1891
+ let packageManager = "pip";
1892
+ if (await fileExists(pyprojectPath)) {
1893
+ const result = await this.parsePyProject(pyprojectPath, projectRoot);
1894
+ name = result.name;
1895
+ scripts = result.scripts;
1896
+ packageManager = result.packageManager;
1897
+ } else if (await fileExists(pipfilePath)) {
1898
+ const result = await this.parsePipfile(pipfilePath);
1899
+ name = result.name || name;
1900
+ scripts = result.scripts;
1901
+ packageManager = "pipenv";
1902
+ } else if (await fileExists(requirementsPath)) {
1903
+ packageManager = "pip";
1904
+ scripts = this.getDefaultPipScripts();
1905
+ }
1906
+ const venvPath = await detectVenv(projectRoot);
1907
+ const config = await loadConfig(projectRoot);
1908
+ if (config) {
1909
+ scripts = this.applyConfig(scripts, config);
1910
+ }
1911
+ return {
1912
+ path: pyprojectPath || pipfilePath || requirementsPath,
1913
+ name,
1914
+ packageManager,
1915
+ scripts,
1916
+ hasVenv: !!venvPath,
1917
+ venvPath: venvPath || undefined
1918
+ };
1919
+ }
1920
+ async parsePyProject(pyprojectPath, projectRoot) {
1921
+ const content = await fs2.readFile(pyprojectPath, "utf-8");
1922
+ const toml = this.parseToml(content);
1923
+ let name = path4.basename(projectRoot);
1924
+ let scripts = [];
1925
+ let packageManager = "pip";
1926
+ const hasUvLock = await fileExists(path4.join(projectRoot, "uv.lock"));
1927
+ const hasPoetryLock = await fileExists(path4.join(projectRoot, "poetry.lock"));
1928
+ const hasPdmLock = await fileExists(path4.join(projectRoot, "pdm.lock"));
1929
+ if (toml.tool?.poetry || hasPoetryLock) {
1930
+ packageManager = "poetry";
1931
+ name = toml.tool?.poetry?.name || name;
1932
+ if (toml.tool?.poetry?.scripts) {
1933
+ scripts = Object.entries(toml.tool.poetry.scripts).map(([key, value]) => ({
1934
+ name: key,
1935
+ command: value
1936
+ }));
1937
+ }
1938
+ scripts.push({ name: "install", command: "poetry install" }, { name: "shell", command: "poetry shell" }, { name: "run", command: "poetry run python" });
1939
+ } else if (toml.tool?.pdm || hasPdmLock) {
1940
+ packageManager = "pdm";
1941
+ name = toml.tool?.pdm?.name || toml.project?.name || name;
1942
+ if (toml.tool?.pdm?.scripts) {
1943
+ scripts = Object.entries(toml.tool.pdm.scripts).map(([key, value]) => {
1944
+ let command;
1945
+ if (typeof value === "string") {
1946
+ command = value;
1947
+ } else {
1948
+ command = value.cmd || "";
1949
+ }
1950
+ return { name: key, command };
1951
+ });
1952
+ }
1953
+ scripts.push({ name: "install", command: "pdm install" }, { name: "run", command: "pdm run" });
1954
+ } else if (hasUvLock) {
1955
+ packageManager = "uv";
1956
+ name = toml.project?.name || name;
1957
+ if (toml.project?.scripts) {
1958
+ scripts = Object.entries(toml.project.scripts).map(([key, value]) => ({
1959
+ name: key,
1960
+ command: `uv run ${key}`
1961
+ }));
1962
+ }
1963
+ scripts.push({ name: "sync", command: "uv sync", description: "Install and sync dependencies" }, { name: "python", command: "uv run python", description: "Run Python interpreter" });
1964
+ } else if (toml.project?.scripts) {
1965
+ packageManager = "pip";
1966
+ name = toml.project.name || name;
1967
+ scripts = Object.entries(toml.project.scripts).map(([key, value]) => ({
1968
+ name: key,
1969
+ command: `python -m ${key}`
1970
+ }));
1971
+ scripts.push({ name: "install", command: "pip install -e ." });
1972
+ }
1973
+ return { name, scripts, packageManager };
1974
+ }
1975
+ async parsePipfile(pipfilePath) {
1976
+ const content = await fs2.readFile(pipfilePath, "utf-8");
1977
+ const pipfile = this.parseToml(content);
1978
+ const scripts = [];
1979
+ if (pipfile.scripts) {
1980
+ Object.entries(pipfile.scripts).forEach(([key, value]) => {
1981
+ scripts.push({ name: key, command: value });
1982
+ });
1983
+ }
1984
+ scripts.push({ name: "install", command: "pipenv install" }, { name: "shell", command: "pipenv shell" }, { name: "run", command: "pipenv run" });
1985
+ return { name: null, scripts };
1986
+ }
1987
+ getDefaultPipScripts() {
1988
+ return [
1989
+ { name: "install", command: "pip install -r requirements.txt" },
1990
+ { name: "freeze", command: "pip freeze > requirements.txt" }
1991
+ ];
1992
+ }
1993
+ parseToml(content) {
1994
+ const result = {};
1995
+ let currentSection = result;
1996
+ const sectionPath = [];
1997
+ const lines = content.split(`
1998
+ `);
1999
+ for (const line of lines) {
2000
+ const trimmed = line.trim();
2001
+ if (!trimmed || trimmed.startsWith("#")) {
2002
+ continue;
2003
+ }
2004
+ if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
2005
+ const section = trimmed.slice(1, -1);
2006
+ const parts = section.split(".");
2007
+ currentSection = result;
2008
+ sectionPath.length = 0;
2009
+ for (const part of parts) {
2010
+ sectionPath.push(part);
2011
+ if (!currentSection[part]) {
2012
+ currentSection[part] = {};
2013
+ }
2014
+ currentSection = currentSection[part];
2015
+ }
2016
+ continue;
2017
+ }
2018
+ const match = trimmed.match(/^([^=]+)=(.+)$/);
2019
+ if (match && match[1] && match[2]) {
2020
+ const key = match[1].trim();
2021
+ let value = match[2].trim();
2022
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
2023
+ value = value.slice(1, -1);
2024
+ }
2025
+ currentSection[key] = value;
2026
+ }
2027
+ }
2028
+ return result;
2029
+ }
2030
+ applyConfig(scripts, config) {
2031
+ const configCommands = config.commands || {};
2032
+ const ignoreList = config.ignore || [];
2033
+ let filteredScripts = scripts.filter((script) => !ignoreList.includes(script.name));
2034
+ for (const [name, cmdConfig] of Object.entries(configCommands)) {
2035
+ const existingIndex = filteredScripts.findIndex((s) => s.name === name);
2036
+ let script;
2037
+ if (typeof cmdConfig === "string") {
2038
+ script = { name, command: cmdConfig };
2039
+ } else {
2040
+ const config2 = cmdConfig;
2041
+ script = {
2042
+ name,
2043
+ command: config2.command,
2044
+ description: config2.description
2045
+ };
2046
+ }
2047
+ if (existingIndex >= 0) {
2048
+ filteredScripts[existingIndex] = script;
2049
+ } else {
2050
+ filteredScripts.push(script);
2051
+ }
2052
+ }
2053
+ return filteredScripts;
2054
+ }
2055
+ buildCommand(packageInfo, scriptName) {
2056
+ const manager = packageInfo.packageManager;
2057
+ const script = packageInfo.scripts.find((s) => s.name === scriptName);
2058
+ if (script) {
2059
+ if (script.command.includes(manager) || script.command.includes("uv run")) {
2060
+ return script.command;
2061
+ }
2062
+ }
2063
+ switch (manager) {
2064
+ case "uv":
2065
+ return `uv run ${scriptName}`;
2066
+ case "poetry":
2067
+ return `poetry run ${scriptName}`;
2068
+ case "pdm":
2069
+ return `pdm run ${scriptName}`;
2070
+ case "pipenv":
2071
+ return `pipenv run ${scriptName}`;
2072
+ case "pip":
2073
+ default:
2074
+ return `python ${scriptName}`;
2075
+ }
2076
+ }
2077
+ }
2078
+
2079
+ // src/core/registry.ts
2080
+ class DetectorRegistry {
2081
+ detectors = [];
2082
+ constructor() {
2083
+ this.register(new PythonDetector);
2084
+ this.register(new NodeJSDetector);
2085
+ }
2086
+ register(detector) {
2087
+ this.detectors.push(detector);
2088
+ }
2089
+ async detect(cwd) {
2090
+ for (const detector of this.detectors) {
2091
+ try {
2092
+ const projectRoot = await detector.detect(cwd);
2093
+ if (projectRoot) {
2094
+ const packageInfo = await detector.parse(projectRoot);
2095
+ return {
2096
+ found: true,
2097
+ packageInfo,
2098
+ detector
2099
+ };
2100
+ }
2101
+ } catch (error) {
2102
+ console.error(`Detector ${detector.name} failed:`, error instanceof Error ? error.message : error);
2103
+ }
2104
+ }
2105
+ return {
2106
+ found: false,
2107
+ error: "No supported project found in current directory or parent directories"
2108
+ };
2109
+ }
2110
+ getSupportedEcosystems() {
2111
+ return this.detectors.map((d) => d.name);
2112
+ }
2113
+ }
2114
+ var registry = new DetectorRegistry;
2115
+
2116
+ // src/components/Header.tsx
2117
+ import { Text as Text2, Box } from "ink";
2118
+ import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
2119
+ function Header({ packageInfo, ecosystemName }) {
2120
+ const workspace = packageInfo.workspace;
2121
+ const isInWorkspace = workspace?.isWorkspace && workspace.workspaceRoot;
2122
+ return /* @__PURE__ */ jsxDEV(Box, {
2123
+ flexDirection: "column",
2124
+ children: [
2125
+ /* @__PURE__ */ jsxDEV(Box, {
2126
+ borderStyle: "round",
2127
+ borderColor: "cyan",
2128
+ padding: 1,
2129
+ children: /* @__PURE__ */ jsxDEV(Text2, {
2130
+ bold: true,
2131
+ color: "cyan",
2132
+ children: "Where Am I? \uD83D\uDDFA️"
2133
+ }, undefined, false, undefined, this)
2134
+ }, undefined, false, undefined, this),
2135
+ /* @__PURE__ */ jsxDEV(Box, {
2136
+ marginTop: 1,
2137
+ flexDirection: "column",
2138
+ children: [
2139
+ isInWorkspace && workspace && /* @__PURE__ */ jsxDEV(Fragment, {
2140
+ children: [
2141
+ /* @__PURE__ */ jsxDEV(Box, {
2142
+ children: [
2143
+ /* @__PURE__ */ jsxDEV(Text2, {
2144
+ bold: true,
2145
+ children: "Workspace: "
2146
+ }, undefined, false, undefined, this),
2147
+ /* @__PURE__ */ jsxDEV(Text2, {
2148
+ color: "yellow",
2149
+ children: workspace.workspaceName || "Unknown"
2150
+ }, undefined, false, undefined, this),
2151
+ /* @__PURE__ */ jsxDEV(Text2, {
2152
+ dimColor: true,
2153
+ children: " (mono-repo)"
2154
+ }, undefined, false, undefined, this)
2155
+ ]
2156
+ }, undefined, true, undefined, this),
2157
+ /* @__PURE__ */ jsxDEV(Box, {
2158
+ marginLeft: 2,
2159
+ children: /* @__PURE__ */ jsxDEV(Text2, {
2160
+ dimColor: true,
2161
+ children: [
2162
+ "Root: ",
2163
+ workspace.workspaceRoot
2164
+ ]
2165
+ }, undefined, true, undefined, this)
2166
+ }, undefined, false, undefined, this)
2167
+ ]
2168
+ }, undefined, true, undefined, this),
2169
+ /* @__PURE__ */ jsxDEV(Box, {
2170
+ children: [
2171
+ /* @__PURE__ */ jsxDEV(Text2, {
2172
+ bold: true,
2173
+ children: isInWorkspace ? "Package: " : "Repository: "
2174
+ }, undefined, false, undefined, this),
2175
+ /* @__PURE__ */ jsxDEV(Text2, {
2176
+ color: "green",
2177
+ children: packageInfo.name
2178
+ }, undefined, false, undefined, this)
2179
+ ]
2180
+ }, undefined, true, undefined, this),
2181
+ /* @__PURE__ */ jsxDEV(Box, {
2182
+ marginLeft: isInWorkspace ? 2 : 0,
2183
+ children: /* @__PURE__ */ jsxDEV(Text2, {
2184
+ dimColor: true,
2185
+ children: [
2186
+ isInWorkspace && "↳ ",
2187
+ packageInfo.path.replace("/package.json", "")
2188
+ ]
2189
+ }, undefined, true, undefined, this)
2190
+ }, undefined, false, undefined, this),
2191
+ isInWorkspace && workspace?.relativePath && /* @__PURE__ */ jsxDEV(Box, {
2192
+ marginLeft: 2,
2193
+ children: /* @__PURE__ */ jsxDEV(Text2, {
2194
+ dimColor: true,
2195
+ children: [
2196
+ "Relative: ",
2197
+ workspace.relativePath
2198
+ ]
2199
+ }, undefined, true, undefined, this)
2200
+ }, undefined, false, undefined, this),
2201
+ /* @__PURE__ */ jsxDEV(Box, {
2202
+ children: [
2203
+ /* @__PURE__ */ jsxDEV(Text2, {
2204
+ bold: true,
2205
+ children: "Ecosystem: "
2206
+ }, undefined, false, undefined, this),
2207
+ /* @__PURE__ */ jsxDEV(Text2, {
2208
+ color: "blue",
2209
+ children: ecosystemName
2210
+ }, undefined, false, undefined, this)
2211
+ ]
2212
+ }, undefined, true, undefined, this),
2213
+ /* @__PURE__ */ jsxDEV(Box, {
2214
+ children: [
2215
+ /* @__PURE__ */ jsxDEV(Text2, {
2216
+ bold: true,
2217
+ children: "Package Manager: "
2218
+ }, undefined, false, undefined, this),
2219
+ /* @__PURE__ */ jsxDEV(Text2, {
2220
+ color: "magenta",
2221
+ children: packageInfo.packageManager
2222
+ }, undefined, false, undefined, this)
2223
+ ]
2224
+ }, undefined, true, undefined, this)
2225
+ ]
2226
+ }, undefined, true, undefined, this)
2227
+ ]
2228
+ }, undefined, true, undefined, this);
2229
+ }
2230
+
2231
+ // src/components/ScriptList.tsx
2232
+ import { useState as useState4, useEffect as useEffect2 } from "react";
2233
+ import { Text as Text5, Box as Box4, useInput as useInput3, useApp } from "ink";
2234
+
2235
+ // src/utils/command.ts
2236
+ import { spawn } from "child_process";
2237
+
2238
+ // src/utils/history.ts
2239
+ import { promises as fs3 } from "fs";
2240
+ import * as path5 from "path";
2241
+ import * as os from "os";
2242
+ var HISTORY_FILE = path5.join(os.homedir(), ".wami", "history.json");
2243
+ var MAX_HISTORY_PER_PROJECT = 10;
2244
+ async function ensureWamiDir() {
2245
+ const wamiDir = path5.dirname(HISTORY_FILE);
2246
+ try {
2247
+ await fs3.mkdir(wamiDir, { recursive: true });
2248
+ } catch (error) {}
2249
+ }
2250
+ async function loadHistory() {
2251
+ await ensureWamiDir();
2252
+ if (!await fileExists(HISTORY_FILE)) {
2253
+ return {};
2254
+ }
2255
+ try {
2256
+ const content = await fs3.readFile(HISTORY_FILE, "utf-8");
2257
+ return JSON.parse(content);
2258
+ } catch (error) {
2259
+ console.error("Failed to load history:", error);
2260
+ return {};
2261
+ }
2262
+ }
2263
+ async function saveHistory(history) {
2264
+ await ensureWamiDir();
2265
+ try {
2266
+ await fs3.writeFile(HISTORY_FILE, JSON.stringify(history, null, 2), "utf-8");
2267
+ } catch (error) {
2268
+ console.error("Failed to save history:", error);
2269
+ }
2270
+ }
2271
+ async function addToHistory(projectPath, scriptName, command) {
2272
+ const history = await loadHistory();
2273
+ if (!history[projectPath]) {
2274
+ history[projectPath] = { history: [] };
2275
+ }
2276
+ const projectHistory = history[projectPath].history;
2277
+ const existingIndex = projectHistory.findIndex((entry) => entry.command === command);
2278
+ if (existingIndex >= 0) {
2279
+ const existingEntry = projectHistory[existingIndex];
2280
+ if (existingEntry) {
2281
+ existingEntry.count++;
2282
+ existingEntry.timestamp = new Date().toISOString();
2283
+ projectHistory.splice(existingIndex, 1);
2284
+ projectHistory.unshift(existingEntry);
2285
+ }
2286
+ } else {
2287
+ projectHistory.unshift({
2288
+ script: scriptName,
2289
+ command,
2290
+ timestamp: new Date().toISOString(),
2291
+ count: 1
2292
+ });
2293
+ if (projectHistory.length > MAX_HISTORY_PER_PROJECT) {
2294
+ projectHistory.pop();
2295
+ }
2296
+ }
2297
+ await saveHistory(history);
2298
+ }
2299
+ async function getHistory(projectPath) {
2300
+ const history = await loadHistory();
2301
+ if (!history[projectPath]) {
2302
+ return [];
2303
+ }
2304
+ return history[projectPath].history.map((entry) => ({
2305
+ name: entry.script,
2306
+ command: entry.command,
2307
+ description: `Run ${entry.count} time${entry.count > 1 ? "s" : ""} before`
2308
+ }));
2309
+ }
2310
+ async function deleteFromHistory(projectPath, command) {
2311
+ const history = await loadHistory();
2312
+ if (!history[projectPath]) {
2313
+ return;
2314
+ }
2315
+ const projectHistory = history[projectPath].history;
2316
+ const index = projectHistory.findIndex((entry) => entry.command === command);
2317
+ if (index >= 0) {
2318
+ projectHistory.splice(index, 1);
2319
+ await saveHistory(history);
2320
+ }
2321
+ }
2322
+
2323
+ // src/utils/command.ts
2324
+ function executeCommand(command, exitFn, projectPath, scriptName, saveToHistory = false) {
2325
+ exitFn();
2326
+ process.nextTick(async () => {
2327
+ if (saveToHistory && projectPath && scriptName) {
2328
+ await addToHistory(projectPath, scriptName, command);
2329
+ }
2330
+ await new Promise((resolve2) => setTimeout(resolve2, 50));
2331
+ console.clear();
2332
+ console.log("─".repeat(process.stdout.columns || 80));
2333
+ console.log(`Running: ${command}`);
2334
+ console.log("─".repeat(process.stdout.columns || 80));
2335
+ console.log("");
2336
+ const child = spawn(command, {
2337
+ shell: true,
2338
+ stdio: "inherit",
2339
+ cwd: process.cwd(),
2340
+ detached: false
2341
+ });
2342
+ child.on("exit", (code) => {
2343
+ process.exit(code || 0);
2344
+ });
2345
+ child.on("error", (err) => {
2346
+ console.error(`
2347
+ Failed to execute command:`, err);
2348
+ process.exit(1);
2349
+ });
2350
+ });
2351
+ }
2352
+
2353
+ // src/components/ArgumentInput.tsx
2354
+ import { useState as useState2 } from "react";
2355
+ import { Text as Text3, Box as Box2, useInput } from "ink";
2356
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
2357
+ function ArgumentInput({
2358
+ scriptName,
2359
+ baseCommand,
2360
+ onSubmit,
2361
+ onCancel
2362
+ }) {
2363
+ const [input, setInput] = useState2("");
2364
+ const [cursorPosition, setCursorPosition] = useState2(0);
2365
+ useInput((char, key) => {
2366
+ if (key.return) {
2367
+ onSubmit(input);
2368
+ } else if (key.escape) {
2369
+ onCancel();
2370
+ } else if (key.backspace || key.delete) {
2371
+ if (cursorPosition > 0) {
2372
+ setInput((prev) => prev.slice(0, cursorPosition - 1) + prev.slice(cursorPosition));
2373
+ setCursorPosition((prev) => prev - 1);
2374
+ }
2375
+ } else if (key.leftArrow) {
2376
+ setCursorPosition((prev) => Math.max(0, prev - 1));
2377
+ } else if (key.rightArrow) {
2378
+ setCursorPosition((prev) => Math.min(input.length, prev + 1));
2379
+ } else if (!key.ctrl && !key.meta && char) {
2380
+ setInput((prev) => prev.slice(0, cursorPosition) + char + prev.slice(cursorPosition));
2381
+ setCursorPosition((prev) => prev + 1);
2382
+ }
2383
+ });
2384
+ let displayCommand = baseCommand;
2385
+ const maxLength = 60;
2386
+ if (displayCommand.length > maxLength) {
2387
+ displayCommand = displayCommand.substring(0, maxLength) + "...";
2388
+ }
2389
+ const beforeCursor = input.slice(0, cursorPosition);
2390
+ const atCursor = input[cursorPosition] || " ";
2391
+ const afterCursor = input.slice(cursorPosition + 1);
2392
+ return /* @__PURE__ */ jsxDEV2(Box2, {
2393
+ flexDirection: "column",
2394
+ padding: 1,
2395
+ width: "100%",
2396
+ children: [
2397
+ /* @__PURE__ */ jsxDEV2(Box2, {
2398
+ marginBottom: 1,
2399
+ borderStyle: "round",
2400
+ borderColor: "cyan",
2401
+ paddingX: 1,
2402
+ children: /* @__PURE__ */ jsxDEV2(Text3, {
2403
+ bold: true,
2404
+ color: "cyan",
2405
+ children: [
2406
+ "✏️ Add arguments to: ",
2407
+ scriptName
2408
+ ]
2409
+ }, undefined, true, undefined, this)
2410
+ }, undefined, false, undefined, this),
2411
+ /* @__PURE__ */ jsxDEV2(Box2, {
2412
+ marginBottom: 1,
2413
+ flexDirection: "column",
2414
+ children: /* @__PURE__ */ jsxDEV2(Text3, {
2415
+ dimColor: true,
2416
+ children: [
2417
+ "Base: ",
2418
+ displayCommand
2419
+ ]
2420
+ }, undefined, true, undefined, this)
2421
+ }, undefined, false, undefined, this),
2422
+ /* @__PURE__ */ jsxDEV2(Box2, {
2423
+ flexDirection: "column",
2424
+ children: [
2425
+ /* @__PURE__ */ jsxDEV2(Box2, {
2426
+ children: [
2427
+ /* @__PURE__ */ jsxDEV2(Text3, {
2428
+ bold: true,
2429
+ children: "Arguments: "
2430
+ }, undefined, false, undefined, this),
2431
+ /* @__PURE__ */ jsxDEV2(Text3, {
2432
+ color: "green",
2433
+ children: [
2434
+ beforeCursor,
2435
+ /* @__PURE__ */ jsxDEV2(Text3, {
2436
+ inverse: true,
2437
+ children: atCursor
2438
+ }, undefined, false, undefined, this),
2439
+ afterCursor
2440
+ ]
2441
+ }, undefined, true, undefined, this)
2442
+ ]
2443
+ }, undefined, true, undefined, this),
2444
+ input.length > 50 && /* @__PURE__ */ jsxDEV2(Box2, {
2445
+ paddingLeft: 11,
2446
+ children: /* @__PURE__ */ jsxDEV2(Text3, {
2447
+ dimColor: true,
2448
+ wrap: "wrap",
2449
+ children: input
2450
+ }, undefined, false, undefined, this)
2451
+ }, undefined, false, undefined, this)
2452
+ ]
2453
+ }, undefined, true, undefined, this),
2454
+ /* @__PURE__ */ jsxDEV2(Box2, {
2455
+ marginTop: 1,
2456
+ children: /* @__PURE__ */ jsxDEV2(Text3, {
2457
+ dimColor: true,
2458
+ children: [
2459
+ /* @__PURE__ */ jsxDEV2(Text3, {
2460
+ bold: true,
2461
+ children: "Enter"
2462
+ }, undefined, false, undefined, this),
2463
+ " run ",
2464
+ /* @__PURE__ */ jsxDEV2(Text3, {
2465
+ bold: true,
2466
+ children: "Esc"
2467
+ }, undefined, false, undefined, this),
2468
+ " cancel ",
2469
+ /* @__PURE__ */ jsxDEV2(Text3, {
2470
+ bold: true,
2471
+ children: "←/→"
2472
+ }, undefined, false, undefined, this),
2473
+ " move cursor"
2474
+ ]
2475
+ }, undefined, true, undefined, this)
2476
+ }, undefined, false, undefined, this)
2477
+ ]
2478
+ }, undefined, true, undefined, this);
2479
+ }
2480
+
2481
+ // src/components/CommandEditor.tsx
2482
+ import { useState as useState3 } from "react";
2483
+ import { Text as Text4, Box as Box3, useInput as useInput2 } from "ink";
2484
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
2485
+ function CommandEditor({
2486
+ scriptName,
2487
+ initialCommand,
2488
+ onSubmit,
2489
+ onCancel
2490
+ }) {
2491
+ const [command, setCommand] = useState3(initialCommand);
2492
+ const [cursorPosition, setCursorPosition] = useState3(initialCommand.length);
2493
+ useInput2((char, key) => {
2494
+ if (key.return) {
2495
+ onSubmit(command);
2496
+ } else if (key.escape) {
2497
+ onCancel();
2498
+ } else if (key.backspace || key.delete) {
2499
+ if (cursorPosition > 0) {
2500
+ setCommand((prev) => prev.slice(0, cursorPosition - 1) + prev.slice(cursorPosition));
2501
+ setCursorPosition((prev) => prev - 1);
2502
+ }
2503
+ } else if (key.leftArrow) {
2504
+ setCursorPosition((prev) => Math.max(0, prev - 1));
2505
+ } else if (key.rightArrow) {
2506
+ setCursorPosition((prev) => Math.min(command.length, prev + 1));
2507
+ } else if (!key.ctrl && !key.meta && char) {
2508
+ setCommand((prev) => prev.slice(0, cursorPosition) + char + prev.slice(cursorPosition));
2509
+ setCursorPosition((prev) => prev + 1);
2510
+ }
2511
+ });
2512
+ const beforeCursor = command.slice(0, cursorPosition);
2513
+ const atCursor = command[cursorPosition] || " ";
2514
+ const afterCursor = command.slice(cursorPosition + 1);
2515
+ return /* @__PURE__ */ jsxDEV3(Box3, {
2516
+ flexDirection: "column",
2517
+ padding: 1,
2518
+ width: "100%",
2519
+ children: [
2520
+ /* @__PURE__ */ jsxDEV3(Box3, {
2521
+ marginBottom: 1,
2522
+ borderStyle: "round",
2523
+ borderColor: "cyan",
2524
+ paddingX: 1,
2525
+ children: /* @__PURE__ */ jsxDEV3(Text4, {
2526
+ bold: true,
2527
+ color: "cyan",
2528
+ children: [
2529
+ "✏️ Edit command: ",
2530
+ scriptName
2531
+ ]
2532
+ }, undefined, true, undefined, this)
2533
+ }, undefined, false, undefined, this),
2534
+ /* @__PURE__ */ jsxDEV3(Box3, {
2535
+ marginBottom: 1,
2536
+ flexDirection: "column",
2537
+ children: [
2538
+ /* @__PURE__ */ jsxDEV3(Text4, {
2539
+ dimColor: true,
2540
+ children: [
2541
+ "Command (",
2542
+ command.length,
2543
+ " chars):"
2544
+ ]
2545
+ }, undefined, true, undefined, this),
2546
+ /* @__PURE__ */ jsxDEV3(Box3, {
2547
+ flexDirection: "column",
2548
+ paddingLeft: 2,
2549
+ children: /* @__PURE__ */ jsxDEV3(Text4, {
2550
+ color: "green",
2551
+ wrap: "wrap",
2552
+ children: [
2553
+ beforeCursor,
2554
+ /* @__PURE__ */ jsxDEV3(Text4, {
2555
+ inverse: true,
2556
+ children: atCursor
2557
+ }, undefined, false, undefined, this),
2558
+ afterCursor
2559
+ ]
2560
+ }, undefined, true, undefined, this)
2561
+ }, undefined, false, undefined, this)
2562
+ ]
2563
+ }, undefined, true, undefined, this),
2564
+ /* @__PURE__ */ jsxDEV3(Box3, {
2565
+ marginTop: 1,
2566
+ children: /* @__PURE__ */ jsxDEV3(Text4, {
2567
+ dimColor: true,
2568
+ children: [
2569
+ /* @__PURE__ */ jsxDEV3(Text4, {
2570
+ bold: true,
2571
+ children: "Enter"
2572
+ }, undefined, false, undefined, this),
2573
+ " run ",
2574
+ /* @__PURE__ */ jsxDEV3(Text4, {
2575
+ bold: true,
2576
+ children: "Esc"
2577
+ }, undefined, false, undefined, this),
2578
+ " cancel ",
2579
+ /* @__PURE__ */ jsxDEV3(Text4, {
2580
+ bold: true,
2581
+ children: "←/→"
2582
+ }, undefined, false, undefined, this),
2583
+ " move ",
2584
+ /* @__PURE__ */ jsxDEV3(Text4, {
2585
+ bold: true,
2586
+ children: "Backspace"
2587
+ }, undefined, false, undefined, this),
2588
+ " delete"
2589
+ ]
2590
+ }, undefined, true, undefined, this)
2591
+ }, undefined, false, undefined, this)
2592
+ ]
2593
+ }, undefined, true, undefined, this);
2594
+ }
2595
+
2596
+ // src/components/ScriptList.tsx
2597
+ import { jsxDEV as jsxDEV4, Fragment as Fragment2 } from "react/jsx-dev-runtime";
2598
+ function ScriptList({
2599
+ packageInfo,
2600
+ detector,
2601
+ history: initialHistory,
2602
+ projectPath
2603
+ }) {
2604
+ const [selectedIndex, setSelectedIndex] = useState4(0);
2605
+ const [showArgInput, setShowArgInput] = useState4(false);
2606
+ const [showEditor, setShowEditor] = useState4(false);
2607
+ const [history, setHistory] = useState4(initialHistory);
2608
+ const [isSearching, setIsSearching] = useState4(false);
2609
+ const [searchQuery, setSearchQuery] = useState4("");
2610
+ const { exit } = useApp();
2611
+ const allScriptsUnfiltered = [...history, ...packageInfo.scripts];
2612
+ const historyCount = history.length;
2613
+ const allScripts = searchQuery ? allScriptsUnfiltered.filter((script) => {
2614
+ const searchLower = searchQuery.toLowerCase();
2615
+ const nameMatch = script.name.toLowerCase().includes(searchLower);
2616
+ const commandMatch = script.command.toLowerCase().includes(searchLower);
2617
+ const descMatch = script.description?.toLowerCase().includes(searchLower);
2618
+ return nameMatch || commandMatch || descMatch;
2619
+ }) : allScriptsUnfiltered;
2620
+ useEffect2(() => {
2621
+ setHistory(initialHistory);
2622
+ }, [initialHistory]);
2623
+ useEffect2(() => {
2624
+ if (selectedIndex >= allScripts.length) {
2625
+ setSelectedIndex(Math.max(0, allScripts.length - 1));
2626
+ }
2627
+ }, [allScripts.length, selectedIndex]);
2628
+ useInput3((input, key) => {
2629
+ if (showArgInput || showEditor) {
2630
+ return;
2631
+ }
2632
+ if (isSearching) {
2633
+ if (key.escape) {
2634
+ setIsSearching(false);
2635
+ setSearchQuery("");
2636
+ setSelectedIndex(0);
2637
+ } else if (key.backspace || key.delete) {
2638
+ setSearchQuery((prev) => prev.slice(0, -1));
2639
+ } else if (key.return) {
2640
+ setIsSearching(false);
2641
+ } else if (!key.ctrl && !key.meta && !key.upArrow && !key.downArrow && input) {
2642
+ setSearchQuery((prev) => prev + input);
2643
+ } else if (key.upArrow) {
2644
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
2645
+ } else if (key.downArrow) {
2646
+ setSelectedIndex((prev) => Math.min(allScripts.length - 1, prev + 1));
2647
+ }
2648
+ return;
2649
+ }
2650
+ if (key.upArrow) {
2651
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
2652
+ } else if (key.downArrow) {
2653
+ setSelectedIndex((prev) => Math.min(allScripts.length - 1, prev + 1));
2654
+ } else if (key.return) {
2655
+ const selectedScript = allScripts[selectedIndex];
2656
+ if (selectedScript) {
2657
+ const isHistory = selectedIndex < historyCount;
2658
+ const command = isHistory ? selectedScript.command : detector.buildCommand(packageInfo, selectedScript.name);
2659
+ executeCommand(command, exit);
2660
+ }
2661
+ } else if (input === "a") {
2662
+ setShowArgInput(true);
2663
+ } else if (input === "e") {
2664
+ setShowEditor(true);
2665
+ } else if (input === "/" || input === "s") {
2666
+ setIsSearching(true);
2667
+ setSearchQuery("");
2668
+ } else if (input === "c" && searchQuery) {
2669
+ setSearchQuery("");
2670
+ setSelectedIndex(0);
2671
+ } else if (input === "d" || key.delete) {
2672
+ const isHistory = selectedIndex < historyCount;
2673
+ if (isHistory) {
2674
+ const scriptToDelete = history[selectedIndex];
2675
+ if (scriptToDelete) {
2676
+ deleteFromHistory(projectPath, scriptToDelete.command);
2677
+ const newHistory = [...history];
2678
+ newHistory.splice(selectedIndex, 1);
2679
+ setHistory(newHistory);
2680
+ if (selectedIndex >= newHistory.length + packageInfo.scripts.length) {
2681
+ setSelectedIndex((prev) => Math.max(0, prev - 1));
2682
+ }
2683
+ }
2684
+ }
2685
+ } else if (key.escape || input === "q") {
2686
+ exit();
2687
+ }
2688
+ });
2689
+ const handleArgumentSubmit = (args) => {
2690
+ const selectedScript = allScripts[selectedIndex];
2691
+ if (selectedScript) {
2692
+ const isHistory = selectedIndex < historyCount;
2693
+ const baseCommand = isHistory ? selectedScript.command : detector.buildCommand(packageInfo, selectedScript.name);
2694
+ const fullCommand = args.trim() ? `${baseCommand} ${args.trim()}` : baseCommand;
2695
+ const saveToHistory = args.trim().length > 0;
2696
+ executeCommand(fullCommand, exit, projectPath, selectedScript.name, saveToHistory);
2697
+ }
2698
+ };
2699
+ const handleArgumentCancel = () => {
2700
+ setShowArgInput(false);
2701
+ };
2702
+ const handleEditorSubmit = async (editedCommand) => {
2703
+ const selectedScript = allScripts[selectedIndex];
2704
+ if (selectedScript) {
2705
+ const isHistory = selectedIndex < historyCount;
2706
+ const originalCommand = isHistory ? selectedScript.command : detector.buildCommand(packageInfo, selectedScript.name);
2707
+ if (isHistory && editedCommand !== originalCommand) {
2708
+ await deleteFromHistory(projectPath, originalCommand);
2709
+ }
2710
+ const saveToHistory = editedCommand !== originalCommand;
2711
+ executeCommand(editedCommand, exit, projectPath, selectedScript.name, saveToHistory);
2712
+ }
2713
+ };
2714
+ const handleEditorCancel = () => {
2715
+ setShowEditor(false);
2716
+ };
2717
+ if (showArgInput) {
2718
+ const selectedScript = allScripts[selectedIndex];
2719
+ if (selectedScript) {
2720
+ const isHistory = selectedIndex < historyCount;
2721
+ const baseCommand = isHistory ? selectedScript.command : detector.buildCommand(packageInfo, selectedScript.name);
2722
+ return /* @__PURE__ */ jsxDEV4(ArgumentInput, {
2723
+ scriptName: selectedScript.name,
2724
+ baseCommand,
2725
+ onSubmit: handleArgumentSubmit,
2726
+ onCancel: handleArgumentCancel
2727
+ }, undefined, false, undefined, this);
2728
+ }
2729
+ }
2730
+ if (showEditor) {
2731
+ const selectedScript = allScripts[selectedIndex];
2732
+ if (selectedScript) {
2733
+ const isHistory = selectedIndex < historyCount;
2734
+ const fullCommand = isHistory ? selectedScript.command : detector.buildCommand(packageInfo, selectedScript.name);
2735
+ return /* @__PURE__ */ jsxDEV4(CommandEditor, {
2736
+ scriptName: selectedScript.name,
2737
+ initialCommand: fullCommand,
2738
+ onSubmit: handleEditorSubmit,
2739
+ onCancel: handleEditorCancel
2740
+ }, undefined, false, undefined, this);
2741
+ }
2742
+ }
2743
+ if (allScripts.length === 0) {
2744
+ return /* @__PURE__ */ jsxDEV4(Box4, {
2745
+ flexDirection: "column",
2746
+ children: searchQuery ? /* @__PURE__ */ jsxDEV4(Fragment2, {
2747
+ children: [
2748
+ /* @__PURE__ */ jsxDEV4(Box4, {
2749
+ marginBottom: 1,
2750
+ children: [
2751
+ /* @__PURE__ */ jsxDEV4(Text5, {
2752
+ bold: true,
2753
+ color: "cyan",
2754
+ children: "Search: "
2755
+ }, undefined, false, undefined, this),
2756
+ /* @__PURE__ */ jsxDEV4(Text5, {
2757
+ color: "yellow",
2758
+ children: searchQuery
2759
+ }, undefined, false, undefined, this)
2760
+ ]
2761
+ }, undefined, true, undefined, this),
2762
+ /* @__PURE__ */ jsxDEV4(Text5, {
2763
+ dimColor: true,
2764
+ children: [
2765
+ "No matches found. Press ",
2766
+ /* @__PURE__ */ jsxDEV4(Text5, {
2767
+ bold: true,
2768
+ children: "Esc"
2769
+ }, undefined, false, undefined, this),
2770
+ " to clear search."
2771
+ ]
2772
+ }, undefined, true, undefined, this)
2773
+ ]
2774
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Fragment2, {
2775
+ children: [
2776
+ /* @__PURE__ */ jsxDEV4(Text5, {
2777
+ bold: true,
2778
+ color: "yellow",
2779
+ children: "Available Scripts:"
2780
+ }, undefined, false, undefined, this),
2781
+ /* @__PURE__ */ jsxDEV4(Box4, {
2782
+ marginLeft: 2,
2783
+ children: /* @__PURE__ */ jsxDEV4(Text5, {
2784
+ dimColor: true,
2785
+ children: "No scripts found"
2786
+ }, undefined, false, undefined, this)
2787
+ }, undefined, false, undefined, this)
2788
+ ]
2789
+ }, undefined, true, undefined, this)
2790
+ }, undefined, false, undefined, this);
2791
+ }
2792
+ const MAX_VISIBLE_ITEMS = 15;
2793
+ const totalItems = allScripts.length;
2794
+ let startIndex = 0;
2795
+ let endIndex = Math.min(MAX_VISIBLE_ITEMS, totalItems);
2796
+ if (totalItems > MAX_VISIBLE_ITEMS) {
2797
+ const halfWindow = Math.floor(MAX_VISIBLE_ITEMS / 2);
2798
+ startIndex = Math.max(0, selectedIndex - halfWindow);
2799
+ endIndex = Math.min(totalItems, startIndex + MAX_VISIBLE_ITEMS);
2800
+ if (endIndex === totalItems) {
2801
+ startIndex = Math.max(0, endIndex - MAX_VISIBLE_ITEMS);
2802
+ }
2803
+ }
2804
+ const visibleScripts = allScripts.slice(startIndex, endIndex);
2805
+ const hasMoreAbove = startIndex > 0;
2806
+ const hasMoreBelow = endIndex < totalItems;
2807
+ return /* @__PURE__ */ jsxDEV4(Box4, {
2808
+ flexDirection: "column",
2809
+ children: [
2810
+ (isSearching || searchQuery) && /* @__PURE__ */ jsxDEV4(Box4, {
2811
+ marginBottom: 1,
2812
+ borderStyle: "round",
2813
+ borderColor: "cyan",
2814
+ paddingX: 1,
2815
+ children: [
2816
+ /* @__PURE__ */ jsxDEV4(Text5, {
2817
+ bold: true,
2818
+ color: "cyan",
2819
+ children: [
2820
+ isSearching && /* @__PURE__ */ jsxDEV4(build_default, {
2821
+ type: "dots"
2822
+ }, undefined, false, undefined, this),
2823
+ " Search:"
2824
+ ]
2825
+ }, undefined, true, undefined, this),
2826
+ /* @__PURE__ */ jsxDEV4(Text5, {
2827
+ color: "yellow",
2828
+ children: searchQuery
2829
+ }, undefined, false, undefined, this),
2830
+ isSearching && /* @__PURE__ */ jsxDEV4(Text5, {
2831
+ inverse: true,
2832
+ children: " "
2833
+ }, undefined, false, undefined, this),
2834
+ searchQuery && !isSearching && /* @__PURE__ */ jsxDEV4(Text5, {
2835
+ dimColor: true,
2836
+ children: [
2837
+ " (press ",
2838
+ /* @__PURE__ */ jsxDEV4(Text5, {
2839
+ bold: true,
2840
+ children: "c"
2841
+ }, undefined, false, undefined, this),
2842
+ " to clear)"
2843
+ ]
2844
+ }, undefined, true, undefined, this)
2845
+ ]
2846
+ }, undefined, true, undefined, this),
2847
+ searchQuery && allScripts.length > 0 && /* @__PURE__ */ jsxDEV4(Box4, {
2848
+ marginBottom: 1,
2849
+ children: [
2850
+ /* @__PURE__ */ jsxDEV4(Text5, {
2851
+ color: "green",
2852
+ children: "✓ "
2853
+ }, undefined, false, undefined, this),
2854
+ /* @__PURE__ */ jsxDEV4(Text5, {
2855
+ dimColor: true,
2856
+ children: [
2857
+ allScripts.length,
2858
+ " match",
2859
+ allScripts.length !== 1 ? "es" : "",
2860
+ " found"
2861
+ ]
2862
+ }, undefined, true, undefined, this)
2863
+ ]
2864
+ }, undefined, true, undefined, this),
2865
+ hasMoreAbove && /* @__PURE__ */ jsxDEV4(Box4, {
2866
+ marginBottom: 1,
2867
+ children: /* @__PURE__ */ jsxDEV4(Text5, {
2868
+ dimColor: true,
2869
+ children: [
2870
+ "↑ ",
2871
+ startIndex,
2872
+ " more above"
2873
+ ]
2874
+ }, undefined, true, undefined, this)
2875
+ }, undefined, false, undefined, this),
2876
+ historyCount > 0 && startIndex < historyCount && /* @__PURE__ */ jsxDEV4(Fragment2, {
2877
+ children: [
2878
+ /* @__PURE__ */ jsxDEV4(Text5, {
2879
+ bold: true,
2880
+ color: "green",
2881
+ children: "⚡ Recent Commands:"
2882
+ }, undefined, false, undefined, this),
2883
+ visibleScripts.map((script, visibleIndex) => {
2884
+ const actualIndex = startIndex + visibleIndex;
2885
+ if (actualIndex >= historyCount)
2886
+ return null;
2887
+ const isSelected = actualIndex === selectedIndex;
2888
+ let displayText = script.description || script.command;
2889
+ const maxLength = 60;
2890
+ if (displayText.length > maxLength) {
2891
+ displayText = displayText.substring(0, maxLength) + "... (" + displayText.length + " chars)";
2892
+ }
2893
+ return /* @__PURE__ */ jsxDEV4(Box4, {
2894
+ marginLeft: 2,
2895
+ flexDirection: "column",
2896
+ children: /* @__PURE__ */ jsxDEV4(Box4, {
2897
+ children: [
2898
+ isSelected ? /* @__PURE__ */ jsxDEV4(Text5, {
2899
+ color: "cyan",
2900
+ bold: true,
2901
+ children: [
2902
+ /* @__PURE__ */ jsxDEV4(Text5, {
2903
+ children: "▶ "
2904
+ }, undefined, false, undefined, this),
2905
+ script.name
2906
+ ]
2907
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Text5, {
2908
+ children: [
2909
+ " ",
2910
+ script.name
2911
+ ]
2912
+ }, undefined, true, undefined, this),
2913
+ /* @__PURE__ */ jsxDEV4(Text5, {
2914
+ dimColor: true,
2915
+ children: [
2916
+ " - ",
2917
+ displayText
2918
+ ]
2919
+ }, undefined, true, undefined, this)
2920
+ ]
2921
+ }, undefined, true, undefined, this)
2922
+ }, `history-${actualIndex}`, false, undefined, this);
2923
+ }),
2924
+ /* @__PURE__ */ jsxDEV4(Box4, {
2925
+ marginTop: 1
2926
+ }, undefined, false, undefined, this)
2927
+ ]
2928
+ }, undefined, true, undefined, this),
2929
+ endIndex > historyCount && /* @__PURE__ */ jsxDEV4(Fragment2, {
2930
+ children: [
2931
+ /* @__PURE__ */ jsxDEV4(Text5, {
2932
+ bold: true,
2933
+ color: "yellow",
2934
+ children: "\uD83D\uDCDC Available Scripts:"
2935
+ }, undefined, false, undefined, this),
2936
+ visibleScripts.map((script, visibleIndex) => {
2937
+ const actualIndex = startIndex + visibleIndex;
2938
+ if (actualIndex < historyCount)
2939
+ return null;
2940
+ const isSelected = actualIndex === selectedIndex;
2941
+ let displayText = script.description || script.command;
2942
+ const maxLength = 60;
2943
+ if (displayText.length > maxLength) {
2944
+ displayText = displayText.substring(0, maxLength) + "...";
2945
+ }
2946
+ return /* @__PURE__ */ jsxDEV4(Box4, {
2947
+ marginLeft: 2,
2948
+ flexDirection: "column",
2949
+ children: /* @__PURE__ */ jsxDEV4(Box4, {
2950
+ children: [
2951
+ isSelected ? /* @__PURE__ */ jsxDEV4(Text5, {
2952
+ color: "cyan",
2953
+ bold: true,
2954
+ children: [
2955
+ /* @__PURE__ */ jsxDEV4(Text5, {
2956
+ children: "▶ "
2957
+ }, undefined, false, undefined, this),
2958
+ script.name
2959
+ ]
2960
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Text5, {
2961
+ children: [
2962
+ " ",
2963
+ script.name
2964
+ ]
2965
+ }, undefined, true, undefined, this),
2966
+ /* @__PURE__ */ jsxDEV4(Text5, {
2967
+ dimColor: true,
2968
+ children: [
2969
+ " - ",
2970
+ displayText
2971
+ ]
2972
+ }, undefined, true, undefined, this)
2973
+ ]
2974
+ }, undefined, true, undefined, this)
2975
+ }, script.name, false, undefined, this);
2976
+ })
2977
+ ]
2978
+ }, undefined, true, undefined, this),
2979
+ hasMoreBelow && /* @__PURE__ */ jsxDEV4(Box4, {
2980
+ marginTop: 1,
2981
+ children: /* @__PURE__ */ jsxDEV4(Text5, {
2982
+ dimColor: true,
2983
+ children: [
2984
+ "↓ ",
2985
+ totalItems - endIndex,
2986
+ " more below"
2987
+ ]
2988
+ }, undefined, true, undefined, this)
2989
+ }, undefined, false, undefined, this),
2990
+ /* @__PURE__ */ jsxDEV4(Box4, {
2991
+ marginTop: 1,
2992
+ marginLeft: 2,
2993
+ children: /* @__PURE__ */ jsxDEV4(Text5, {
2994
+ dimColor: true,
2995
+ children: isSearching ? /* @__PURE__ */ jsxDEV4(Fragment2, {
2996
+ children: [
2997
+ /* @__PURE__ */ jsxDEV4(Text5, {
2998
+ bold: true,
2999
+ children: "Type"
3000
+ }, undefined, false, undefined, this),
3001
+ " to search ",
3002
+ /* @__PURE__ */ jsxDEV4(Text5, {
3003
+ bold: true,
3004
+ children: "↑/↓"
3005
+ }, undefined, false, undefined, this),
3006
+ " navigate ",
3007
+ /* @__PURE__ */ jsxDEV4(Text5, {
3008
+ bold: true,
3009
+ children: "Enter"
3010
+ }, undefined, false, undefined, this),
3011
+ " done ",
3012
+ /* @__PURE__ */ jsxDEV4(Text5, {
3013
+ bold: true,
3014
+ children: "Esc"
3015
+ }, undefined, false, undefined, this),
3016
+ " cancel"
3017
+ ]
3018
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV4(Fragment2, {
3019
+ children: [
3020
+ /* @__PURE__ */ jsxDEV4(Text5, {
3021
+ bold: true,
3022
+ children: "↑/↓"
3023
+ }, undefined, false, undefined, this),
3024
+ " navigate ",
3025
+ /* @__PURE__ */ jsxDEV4(Text5, {
3026
+ bold: true,
3027
+ children: "Enter"
3028
+ }, undefined, false, undefined, this),
3029
+ " run ",
3030
+ /* @__PURE__ */ jsxDEV4(Text5, {
3031
+ bold: true,
3032
+ children: "a"
3033
+ }, undefined, false, undefined, this),
3034
+ " add args ",
3035
+ /* @__PURE__ */ jsxDEV4(Text5, {
3036
+ bold: true,
3037
+ children: "e"
3038
+ }, undefined, false, undefined, this),
3039
+ " edit ",
3040
+ /* @__PURE__ */ jsxDEV4(Text5, {
3041
+ bold: true,
3042
+ children: "/"
3043
+ }, undefined, false, undefined, this),
3044
+ " search ",
3045
+ historyCount > 0 && /* @__PURE__ */ jsxDEV4(Fragment2, {
3046
+ children: [
3047
+ /* @__PURE__ */ jsxDEV4(Text5, {
3048
+ bold: true,
3049
+ children: "d"
3050
+ }, undefined, false, undefined, this),
3051
+ " delete "
3052
+ ]
3053
+ }, undefined, true, undefined, this),
3054
+ /* @__PURE__ */ jsxDEV4(Text5, {
3055
+ bold: true,
3056
+ children: "q"
3057
+ }, undefined, false, undefined, this),
3058
+ " quit"
3059
+ ]
3060
+ }, undefined, true, undefined, this)
3061
+ }, undefined, false, undefined, this)
3062
+ }, undefined, false, undefined, this)
3063
+ ]
3064
+ }, undefined, true, undefined, this);
3065
+ }
3066
+
3067
+ // src/components/ErrorMessage.tsx
3068
+ import { Text as Text6, Box as Box5 } from "ink";
3069
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
3070
+ function ErrorMessage({ error, supportedEcosystems }) {
3071
+ return /* @__PURE__ */ jsxDEV5(Box5, {
3072
+ flexDirection: "column",
3073
+ padding: 1,
3074
+ children: [
3075
+ /* @__PURE__ */ jsxDEV5(Box5, {
3076
+ borderStyle: "double",
3077
+ borderColor: "red",
3078
+ padding: 1,
3079
+ children: /* @__PURE__ */ jsxDEV5(Text6, {
3080
+ bold: true,
3081
+ color: "red",
3082
+ children: "❌ No Project Found"
3083
+ }, undefined, false, undefined, this)
3084
+ }, undefined, false, undefined, this),
3085
+ /* @__PURE__ */ jsxDEV5(Box5, {
3086
+ marginTop: 1,
3087
+ children: /* @__PURE__ */ jsxDEV5(Text6, {
3088
+ children: error
3089
+ }, undefined, false, undefined, this)
3090
+ }, undefined, false, undefined, this),
3091
+ /* @__PURE__ */ jsxDEV5(Box5, {
3092
+ marginTop: 1,
3093
+ children: /* @__PURE__ */ jsxDEV5(Text6, {
3094
+ dimColor: true,
3095
+ children: [
3096
+ "Supported ecosystems: ",
3097
+ supportedEcosystems.join(", ")
3098
+ ]
3099
+ }, undefined, true, undefined, this)
3100
+ }, undefined, false, undefined, this)
3101
+ ]
3102
+ }, undefined, true, undefined, this);
3103
+ }
3104
+
3105
+ // src/app.tsx
3106
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
3107
+ function App() {
3108
+ const [result, setResult] = useState5(null);
3109
+ const [history, setHistory] = useState5([]);
3110
+ const [loading, setLoading] = useState5(true);
3111
+ useEffect3(() => {
3112
+ const detectProject = async () => {
3113
+ const cwd = process.cwd();
3114
+ const detectionResult = await registry.detect(cwd);
3115
+ setResult(detectionResult);
3116
+ if (detectionResult.found && detectionResult.packageInfo) {
3117
+ const projectPath2 = detectionResult.packageInfo.path.replace(/\/(package\.json|pyproject\.toml|Pipfile|requirements\.txt)$/, "");
3118
+ const projectHistory = await getHistory(projectPath2);
3119
+ setHistory(projectHistory);
3120
+ }
3121
+ setLoading(false);
3122
+ };
3123
+ detectProject();
3124
+ }, []);
3125
+ if (loading) {
3126
+ return /* @__PURE__ */ jsxDEV6(Box6, {
3127
+ padding: 1,
3128
+ children: [
3129
+ /* @__PURE__ */ jsxDEV6(Text7, {
3130
+ color: "cyan",
3131
+ children: /* @__PURE__ */ jsxDEV6(build_default, {
3132
+ type: "dots"
3133
+ }, undefined, false, undefined, this)
3134
+ }, undefined, false, undefined, this),
3135
+ /* @__PURE__ */ jsxDEV6(Text7, {
3136
+ children: " Detecting project..."
3137
+ }, undefined, false, undefined, this)
3138
+ ]
3139
+ }, undefined, true, undefined, this);
3140
+ }
3141
+ if (!result?.found) {
3142
+ return /* @__PURE__ */ jsxDEV6(ErrorMessage, {
3143
+ error: result?.error || "Unknown error",
3144
+ supportedEcosystems: registry.getSupportedEcosystems()
3145
+ }, undefined, false, undefined, this);
3146
+ }
3147
+ const { packageInfo, detector } = result;
3148
+ const projectPath = packageInfo.path.replace(/\/(package\.json|pyproject\.toml|Pipfile|requirements\.txt)$/, "");
3149
+ return /* @__PURE__ */ jsxDEV6(Box6, {
3150
+ flexDirection: "column",
3151
+ padding: 1,
3152
+ children: [
3153
+ /* @__PURE__ */ jsxDEV6(Header, {
3154
+ packageInfo,
3155
+ ecosystemName: detector.name
3156
+ }, undefined, false, undefined, this),
3157
+ /* @__PURE__ */ jsxDEV6(Box6, {
3158
+ marginTop: 1,
3159
+ borderStyle: "single",
3160
+ borderColor: "gray",
3161
+ padding: 1,
3162
+ children: /* @__PURE__ */ jsxDEV6(ScriptList, {
3163
+ packageInfo,
3164
+ detector,
3165
+ history,
3166
+ projectPath
3167
+ }, undefined, false, undefined, this)
3168
+ }, undefined, false, undefined, this)
3169
+ ]
3170
+ }, undefined, true, undefined, this);
3171
+ }
3172
+
3173
+ // src/cli.tsx
3174
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
3175
+ var { waitUntilExit, clear } = render(/* @__PURE__ */ jsxDEV7(App, {}, undefined, false, undefined, this), {
3176
+ exitOnCtrlC: true,
3177
+ patchConsole: false
3178
+ });
3179
+ await waitUntilExit();
3180
+ clear();