@alva-ai/toolkit 0.4.3 → 0.7.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -219,6 +219,25 @@ var DeployResource = class {
219
219
  `/api/v1/deploy/cronjob/${params.id}/resume`
220
220
  );
221
221
  }
222
+ /**
223
+ * Fire the cronjob workflow once, immediately, bypassing the schedule.
224
+ * Async — returns the Hatchet workflow run id at enqueue. The
225
+ * `cronjob_runs` row appears only after the worker finishes the run;
226
+ * callers verify completion by polling `listRuns({cronjob_id})` and
227
+ * matching `runs[].workflow_run_id` against the returned id.
228
+ *
229
+ * Surfaces backend status as HTTP errors (handled by AlvaClient):
230
+ * - 404 not found / cross-user
231
+ * - 412 cronjob is paused (resume before triggering)
232
+ * - 503 worker workflow handle not yet connected (startup race)
233
+ */
234
+ async trigger(params) {
235
+ this.client._requireAuth();
236
+ return this.client._request(
237
+ "POST",
238
+ `/api/v1/deploy/cronjob/${params.id}/trigger`
239
+ );
240
+ }
222
241
  async listRuns(params) {
223
242
  this.client._requireAuth();
224
243
  return this.client._request(
@@ -265,7 +284,8 @@ var ReleaseResource = class {
265
284
  display_name: params.display_name,
266
285
  description: params.description,
267
286
  feeds: params.feeds,
268
- trading_symbols: params.trading_symbols
287
+ trading_symbols: params.trading_symbols,
288
+ template_id: params.template_id
269
289
  }
270
290
  });
271
291
  }
@@ -276,7 +296,8 @@ var ReleaseResource = class {
276
296
  name: params.name,
277
297
  version: params.version,
278
298
  feeds: params.feeds,
279
- changelog: params.changelog
299
+ changelog: params.changelog,
300
+ readme_url: params.readme_url
280
301
  }
281
302
  });
282
303
  }
@@ -349,8 +370,1060 @@ var SdkDocsResource = class {
349
370
  }
350
371
  };
351
372
 
352
- // src/resources/skills.ts
353
- var SkillsResource = class {
373
+ // src/resources/skillTiers.ts
374
+ var SKILL_ENDPOINT_METADATA = [
375
+ {
376
+ skill: "arrays-data-api-spot-market-price-and-volume",
377
+ file: "crypto-detail",
378
+ method: "GET",
379
+ path: "/api/v1/crypto/detail",
380
+ tier: "public",
381
+ required_subscription_tier: "free",
382
+ access: "free_and_pro",
383
+ pro_required: false
384
+ },
385
+ {
386
+ skill: "arrays-data-api-crypto-metrics-and-screener",
387
+ file: "fear-greed-index",
388
+ method: "GET",
389
+ path: "/api/v1/crypto/fear-greed-index",
390
+ tier: "public",
391
+ required_subscription_tier: "free",
392
+ access: "free_and_pro",
393
+ pro_required: false
394
+ },
395
+ {
396
+ skill: "arrays-data-api-crypto-futures-data",
397
+ file: "funding-rate",
398
+ method: "GET",
399
+ path: "/api/v1/crypto/funding-rate",
400
+ tier: "public",
401
+ required_subscription_tier: "free",
402
+ access: "free_and_pro",
403
+ pro_required: false
404
+ },
405
+ {
406
+ skill: "arrays-data-api-spot-market-price-and-volume",
407
+ file: "crypto-futures-ohlcv",
408
+ method: "GET",
409
+ path: "/api/v1/crypto/futures/ohlcv",
410
+ tier: "public",
411
+ required_subscription_tier: "free",
412
+ access: "free_and_pro",
413
+ pro_required: false
414
+ },
415
+ {
416
+ skill: "arrays-data-api-spot-market-price-and-volume",
417
+ file: "crypto-kline",
418
+ method: "GET",
419
+ path: "/api/v1/crypto/kline",
420
+ tier: "public",
421
+ required_subscription_tier: "free",
422
+ access: "free_and_pro",
423
+ pro_required: false
424
+ },
425
+ {
426
+ skill: "arrays-data-api-crypto-metrics-and-screener",
427
+ file: "list",
428
+ method: "GET",
429
+ path: "/api/v1/crypto/list",
430
+ tier: "public",
431
+ required_subscription_tier: "free",
432
+ access: "free_and_pro",
433
+ pro_required: false
434
+ },
435
+ {
436
+ skill: "arrays-data-api-crypto-futures-data",
437
+ file: "long-short-ratio",
438
+ method: "GET",
439
+ path: "/api/v1/crypto/long-short-ratio",
440
+ tier: "public",
441
+ required_subscription_tier: "free",
442
+ access: "free_and_pro",
443
+ pro_required: false
444
+ },
445
+ {
446
+ skill: "arrays-data-api-crypto-metrics-and-screener",
447
+ file: "crypto-market-cap",
448
+ method: "GET",
449
+ path: "/api/v1/crypto/market-cap",
450
+ tier: "public",
451
+ required_subscription_tier: "free",
452
+ access: "free_and_pro",
453
+ pro_required: false
454
+ },
455
+ {
456
+ skill: "arrays-data-api-crypto-metrics-and-screener",
457
+ file: "market-metrics",
458
+ method: "GET",
459
+ path: "/api/v1/crypto/market-metrics",
460
+ tier: "public",
461
+ required_subscription_tier: "free",
462
+ access: "free_and_pro",
463
+ pro_required: false
464
+ },
465
+ {
466
+ skill: "arrays-data-api-spot-market-price-and-volume",
467
+ file: "crypto-ohlcv",
468
+ method: "GET",
469
+ path: "/api/v1/crypto/ohlcv",
470
+ tier: "public",
471
+ required_subscription_tier: "free",
472
+ access: "free_and_pro",
473
+ pro_required: false
474
+ },
475
+ {
476
+ skill: "arrays-data-api-crypto-futures-data",
477
+ file: "open-interest",
478
+ method: "GET",
479
+ path: "/api/v1/crypto/open-interest",
480
+ tier: "public",
481
+ required_subscription_tier: "free",
482
+ access: "free_and_pro",
483
+ pro_required: false
484
+ },
485
+ {
486
+ skill: "arrays-data-api-crypto-metrics-and-screener",
487
+ file: "screener-metrics",
488
+ method: "GET",
489
+ path: "/api/v1/crypto/screener/metrics",
490
+ tier: "public",
491
+ required_subscription_tier: "free",
492
+ access: "free_and_pro",
493
+ pro_required: false
494
+ },
495
+ {
496
+ skill: "arrays-data-api-crypto-metrics-and-screener",
497
+ file: "screener-metrics-timerange",
498
+ method: "GET",
499
+ path: "/api/v1/crypto/screener/metrics/timerange",
500
+ tier: "public",
501
+ required_subscription_tier: "free",
502
+ access: "free_and_pro",
503
+ pro_required: false
504
+ },
505
+ {
506
+ skill: "arrays-data-api-crypto-metrics-and-screener",
507
+ file: "trading-pair",
508
+ method: "GET",
509
+ path: "/api/v1/crypto/trading-pair",
510
+ tier: "public",
511
+ required_subscription_tier: "free",
512
+ access: "free_and_pro",
513
+ pro_required: false
514
+ },
515
+ {
516
+ skill: "arrays-data-api-etf-fundamentals",
517
+ file: "country-weightings",
518
+ method: "GET",
519
+ path: "/api/v1/etf/country-weightings",
520
+ tier: "public",
521
+ required_subscription_tier: "free",
522
+ access: "free_and_pro",
523
+ pro_required: false
524
+ },
525
+ {
526
+ skill: "arrays-data-api-etf-fundamentals",
527
+ file: "holdings",
528
+ method: "GET",
529
+ path: "/api/v1/etf/holdings",
530
+ tier: "public",
531
+ required_subscription_tier: "free",
532
+ access: "free_and_pro",
533
+ pro_required: false
534
+ },
535
+ {
536
+ skill: "arrays-data-api-etf-fundamentals",
537
+ file: "info",
538
+ method: "GET",
539
+ path: "/api/v1/etf/info",
540
+ tier: "public",
541
+ required_subscription_tier: "free",
542
+ access: "free_and_pro",
543
+ pro_required: false
544
+ },
545
+ {
546
+ skill: "arrays-data-api-etf-fundamentals",
547
+ file: "sector-weightings",
548
+ method: "GET",
549
+ path: "/api/v1/etf/sector-weightings",
550
+ tier: "public",
551
+ required_subscription_tier: "free",
552
+ access: "free_and_pro",
553
+ pro_required: false
554
+ },
555
+ {
556
+ skill: "arrays-data-api-macro-and-economics",
557
+ file: "macro-commodity-historical",
558
+ method: "GET",
559
+ path: "/api/v1/macro/commodity/historical",
560
+ tier: "public",
561
+ required_subscription_tier: "free",
562
+ access: "free_and_pro",
563
+ pro_required: false
564
+ },
565
+ {
566
+ skill: "arrays-data-api-macro-and-economics",
567
+ file: "macro-commodity-real-time",
568
+ method: "GET",
569
+ path: "/api/v1/macro/commodity/real-time",
570
+ tier: "public",
571
+ required_subscription_tier: "free",
572
+ access: "free_and_pro",
573
+ pro_required: false
574
+ },
575
+ {
576
+ skill: "arrays-data-api-macro-and-economics",
577
+ file: "macro-commodity-symbol-list",
578
+ method: "GET",
579
+ path: "/api/v1/macro/commodity/symbols",
580
+ tier: "public",
581
+ required_subscription_tier: "free",
582
+ access: "free_and_pro",
583
+ pro_required: false
584
+ },
585
+ {
586
+ skill: "arrays-data-api-macro-and-economics",
587
+ file: "economic-indicators",
588
+ method: "GET",
589
+ path: "/api/v1/macro/economic-indicators",
590
+ tier: "public",
591
+ required_subscription_tier: "free",
592
+ access: "free_and_pro",
593
+ pro_required: false
594
+ },
595
+ {
596
+ skill: "arrays-data-api-macro-and-economics",
597
+ file: "macro-forex-historical",
598
+ method: "GET",
599
+ path: "/api/v1/macro/forex/historical",
600
+ tier: "public",
601
+ required_subscription_tier: "free",
602
+ access: "free_and_pro",
603
+ pro_required: false
604
+ },
605
+ {
606
+ skill: "arrays-data-api-macro-and-economics",
607
+ file: "macro-forex-real-time",
608
+ method: "GET",
609
+ path: "/api/v1/macro/forex/real-time",
610
+ tier: "public",
611
+ required_subscription_tier: "free",
612
+ access: "free_and_pro",
613
+ pro_required: false
614
+ },
615
+ {
616
+ skill: "arrays-data-api-macro-and-economics",
617
+ file: "macro-forex-symbol-list",
618
+ method: "GET",
619
+ path: "/api/v1/macro/forex/symbols",
620
+ tier: "public",
621
+ required_subscription_tier: "free",
622
+ access: "free_and_pro",
623
+ pro_required: false
624
+ },
625
+ {
626
+ skill: "arrays-data-api-macro-and-economics",
627
+ file: "macro-index-historical",
628
+ method: "GET",
629
+ path: "/api/v1/macro/index/historical",
630
+ tier: "public",
631
+ required_subscription_tier: "free",
632
+ access: "free_and_pro",
633
+ pro_required: false
634
+ },
635
+ {
636
+ skill: "arrays-data-api-macro-and-economics",
637
+ file: "macro-index-real-time",
638
+ method: "GET",
639
+ path: "/api/v1/macro/index/real-time",
640
+ tier: "public",
641
+ required_subscription_tier: "free",
642
+ access: "free_and_pro",
643
+ pro_required: false
644
+ },
645
+ {
646
+ skill: "arrays-data-api-macro-and-economics",
647
+ file: "rates",
648
+ method: "GET",
649
+ path: "/api/v1/macro/treasury-rates",
650
+ tier: "public",
651
+ required_subscription_tier: "free",
652
+ access: "free_and_pro",
653
+ pro_required: false
654
+ },
655
+ {
656
+ skill: "arrays-data-api-equity-fundamentals",
657
+ file: "company-balance-sheets",
658
+ method: "GET",
659
+ path: "/api/v1/stocks/company/balance-sheets",
660
+ tier: "public",
661
+ required_subscription_tier: "free",
662
+ access: "free_and_pro",
663
+ pro_required: false
664
+ },
665
+ {
666
+ skill: "arrays-data-api-equity-fundamentals",
667
+ file: "company-cashflow-statements",
668
+ method: "GET",
669
+ path: "/api/v1/stocks/company/cashflow-statements",
670
+ tier: "public",
671
+ required_subscription_tier: "free",
672
+ access: "free_and_pro",
673
+ pro_required: false
674
+ },
675
+ {
676
+ skill: "arrays-data-api-equity-fundamentals",
677
+ file: "company-detail",
678
+ method: "GET",
679
+ path: "/api/v1/stocks/company/detail",
680
+ tier: "public",
681
+ required_subscription_tier: "free",
682
+ access: "free_and_pro",
683
+ pro_required: false
684
+ },
685
+ {
686
+ skill: "arrays-data-api-equity-fundamentals",
687
+ file: "company-income-statements",
688
+ method: "GET",
689
+ path: "/api/v1/stocks/company/income-statements",
690
+ tier: "public",
691
+ required_subscription_tier: "free",
692
+ access: "free_and_pro",
693
+ pro_required: false
694
+ },
695
+ {
696
+ skill: "arrays-data-api-equity-fundamentals",
697
+ file: "company-kpi",
698
+ method: "GET",
699
+ path: "/api/v1/stocks/company/kpi",
700
+ tier: "public",
701
+ required_subscription_tier: "free",
702
+ access: "free_and_pro",
703
+ pro_required: false
704
+ },
705
+ {
706
+ skill: "arrays-data-api-equity-events",
707
+ file: "crowdfunding-offerings",
708
+ method: "GET",
709
+ path: "/api/v1/stocks/crowdfunding/offerings",
710
+ tier: "public",
711
+ required_subscription_tier: "free",
712
+ access: "free_and_pro",
713
+ pro_required: false
714
+ },
715
+ {
716
+ skill: "arrays-data-api-equity-events",
717
+ file: "dividends",
718
+ method: "GET",
719
+ path: "/api/v1/stocks/dividends",
720
+ tier: "public",
721
+ required_subscription_tier: "free",
722
+ access: "free_and_pro",
723
+ pro_required: false
724
+ },
725
+ {
726
+ skill: "arrays-data-api-equity-events",
727
+ file: "earnings-calendar",
728
+ method: "GET",
729
+ path: "/api/v1/stocks/earnings-calendar",
730
+ tier: "public",
731
+ required_subscription_tier: "free",
732
+ access: "free_and_pro",
733
+ pro_required: false
734
+ },
735
+ {
736
+ skill: "arrays-data-api-equity-events",
737
+ file: "equity-offering",
738
+ method: "GET",
739
+ path: "/api/v1/stocks/equity-offering",
740
+ tier: "public",
741
+ required_subscription_tier: "free",
742
+ access: "free_and_pro",
743
+ pro_required: false
744
+ },
745
+ {
746
+ skill: "arrays-data-api-stock-metrics",
747
+ file: "financial-metrics",
748
+ method: "GET",
749
+ path: "/api/v1/stocks/financial-metrics",
750
+ tier: "public",
751
+ required_subscription_tier: "free",
752
+ access: "free_and_pro",
753
+ pro_required: false
754
+ },
755
+ {
756
+ skill: "arrays-data-api-equity-fundamentals",
757
+ file: "fiscal-dates",
758
+ method: "GET",
759
+ path: "/api/v1/stocks/fiscal-dates",
760
+ tier: "public",
761
+ required_subscription_tier: "free",
762
+ access: "free_and_pro",
763
+ pro_required: false
764
+ },
765
+ {
766
+ skill: "arrays-data-api-equity-fundamentals",
767
+ file: "fiscal-dates-range",
768
+ method: "GET",
769
+ path: "/api/v1/stocks/fiscal-dates/range",
770
+ tier: "public",
771
+ required_subscription_tier: "free",
772
+ access: "free_and_pro",
773
+ pro_required: false
774
+ },
775
+ {
776
+ skill: "arrays-data-api-equity-events",
777
+ file: "ipo-calendar",
778
+ method: "GET",
779
+ path: "/api/v1/stocks/ipo-calendar",
780
+ tier: "public",
781
+ required_subscription_tier: "free",
782
+ access: "free_and_pro",
783
+ pro_required: false
784
+ },
785
+ {
786
+ skill: "arrays-data-api-equity-events",
787
+ file: "ipo-confirmed-calendar",
788
+ method: "GET",
789
+ path: "/api/v1/stocks/ipo-confirmed-calendar",
790
+ tier: "public",
791
+ required_subscription_tier: "free",
792
+ access: "free_and_pro",
793
+ pro_required: false
794
+ },
795
+ {
796
+ skill: "arrays-data-api-spot-market-price-and-volume",
797
+ file: "stocks-kline",
798
+ method: "GET",
799
+ path: "/api/v1/stocks/kline",
800
+ tier: "public",
801
+ required_subscription_tier: "free",
802
+ access: "free_and_pro",
803
+ pro_required: false
804
+ },
805
+ {
806
+ skill: "arrays-data-api-stock-metrics",
807
+ file: "market-metrics",
808
+ method: "GET",
809
+ path: "/api/v1/stocks/market-metrics",
810
+ tier: "public",
811
+ required_subscription_tier: "free",
812
+ access: "free_and_pro",
813
+ pro_required: false
814
+ },
815
+ {
816
+ skill: "arrays-data-api-equity-events",
817
+ file: "mergers-acquisitions",
818
+ method: "GET",
819
+ path: "/api/v1/stocks/mergers-acquisitions",
820
+ tier: "public",
821
+ required_subscription_tier: "free",
822
+ access: "free_and_pro",
823
+ pro_required: false
824
+ },
825
+ {
826
+ skill: "arrays-data-api-equity-fundamentals",
827
+ file: "outstanding-shares",
828
+ method: "GET",
829
+ path: "/api/v1/stocks/outstanding-shares",
830
+ tier: "public",
831
+ required_subscription_tier: "free",
832
+ access: "free_and_pro",
833
+ pro_required: false
834
+ },
835
+ {
836
+ skill: "arrays-data-api-stock-metrics",
837
+ file: "ratings",
838
+ method: "GET",
839
+ path: "/api/v1/stocks/ratings",
840
+ tier: "public",
841
+ required_subscription_tier: "free",
842
+ access: "free_and_pro",
843
+ pro_required: false
844
+ },
845
+ {
846
+ skill: "arrays-data-api-stock-screener",
847
+ file: "basic-info-screener",
848
+ method: "GET",
849
+ path: "/api/v1/stocks/screener/basic-info/{sub}",
850
+ tier: "public",
851
+ required_subscription_tier: "free",
852
+ access: "free_and_pro",
853
+ pro_required: false
854
+ },
855
+ {
856
+ skill: "arrays-data-api-stock-screener",
857
+ file: "event-screener",
858
+ method: "GET",
859
+ path: "/api/v1/stocks/screener/events",
860
+ tier: "public",
861
+ required_subscription_tier: "free",
862
+ access: "free_and_pro",
863
+ pro_required: false
864
+ },
865
+ {
866
+ skill: "arrays-data-api-stock-screener",
867
+ file: "screener-financial-metrics",
868
+ method: "GET",
869
+ path: "/api/v1/stocks/screener/financial-metrics",
870
+ tier: "public",
871
+ required_subscription_tier: "free",
872
+ access: "free_and_pro",
873
+ pro_required: false
874
+ },
875
+ {
876
+ skill: "arrays-data-api-stock-screener",
877
+ file: "screener-financial-metrics-timerange",
878
+ method: "GET",
879
+ path: "/api/v1/stocks/screener/financial-metrics/timerange",
880
+ tier: "public",
881
+ required_subscription_tier: "free",
882
+ access: "free_and_pro",
883
+ pro_required: false
884
+ },
885
+ {
886
+ skill: "arrays-data-api-stock-screener",
887
+ file: "screener-technical-metrics",
888
+ method: "GET",
889
+ path: "/api/v1/stocks/screener/technical-metrics",
890
+ tier: "public",
891
+ required_subscription_tier: "free",
892
+ access: "free_and_pro",
893
+ pro_required: false
894
+ },
895
+ {
896
+ skill: "arrays-data-api-stock-screener",
897
+ file: "screener-technical-metrics-timerange",
898
+ method: "GET",
899
+ path: "/api/v1/stocks/screener/technical-metrics/timerange",
900
+ tier: "public",
901
+ required_subscription_tier: "free",
902
+ access: "free_and_pro",
903
+ pro_required: false
904
+ },
905
+ {
906
+ skill: "arrays-data-api-equity-events",
907
+ file: "sec-earnings-release",
908
+ method: "GET",
909
+ path: "/api/v1/stocks/sec-earnings-release",
910
+ tier: "public",
911
+ required_subscription_tier: "free",
912
+ access: "free_and_pro",
913
+ pro_required: false
914
+ },
915
+ {
916
+ skill: "arrays-data-api-equity-fundamentals",
917
+ file: "shares-float",
918
+ method: "GET",
919
+ path: "/api/v1/stocks/shares-float",
920
+ tier: "public",
921
+ required_subscription_tier: "free",
922
+ access: "free_and_pro",
923
+ pro_required: false
924
+ },
925
+ {
926
+ skill: "arrays-data-api-equity-events",
927
+ file: "splits",
928
+ method: "GET",
929
+ path: "/api/v1/stocks/splits",
930
+ tier: "public",
931
+ required_subscription_tier: "free",
932
+ access: "free_and_pro",
933
+ pro_required: false
934
+ },
935
+ {
936
+ skill: "arrays-data-api-crypto-exchange-flow",
937
+ file: "exchange-flows",
938
+ method: "GET",
939
+ path: "/api/v1/crypto/exchange-flows",
940
+ tier: "alternative",
941
+ required_subscription_tier: "pro",
942
+ access: "pro_only",
943
+ pro_required: true
944
+ },
945
+ {
946
+ skill: "arrays-data-api-company-crypto-holdings",
947
+ file: "crypto-holdings",
948
+ method: "GET",
949
+ path: "/api/v1/crypto/holdings",
950
+ tier: "alternative",
951
+ required_subscription_tier: "pro",
952
+ access: "pro_only",
953
+ pro_required: true
954
+ },
955
+ {
956
+ skill: "arrays-data-api-crypto-metrics-and-screener",
957
+ file: "metrics-inflow-cdd",
958
+ method: "GET",
959
+ path: "/api/v1/crypto/metrics/inflow-cdd",
960
+ tier: "alternative",
961
+ required_subscription_tier: "pro",
962
+ access: "pro_only",
963
+ pro_required: true
964
+ },
965
+ {
966
+ skill: "arrays-data-api-crypto-metrics-and-screener",
967
+ file: "metrics-leverage-ratio",
968
+ method: "GET",
969
+ path: "/api/v1/crypto/metrics/leverage-ratio",
970
+ tier: "alternative",
971
+ required_subscription_tier: "pro",
972
+ access: "pro_only",
973
+ pro_required: true
974
+ },
975
+ {
976
+ skill: "arrays-data-api-crypto-metrics-and-screener",
977
+ file: "metrics-miner-to-exchange",
978
+ method: "GET",
979
+ path: "/api/v1/crypto/metrics/miner-to-exchange",
980
+ tier: "alternative",
981
+ required_subscription_tier: "pro",
982
+ access: "pro_only",
983
+ pro_required: true
984
+ },
985
+ {
986
+ skill: "arrays-data-api-crypto-metrics-and-screener",
987
+ file: "metrics-mvrv",
988
+ method: "GET",
989
+ path: "/api/v1/crypto/metrics/mvrv",
990
+ tier: "alternative",
991
+ required_subscription_tier: "pro",
992
+ access: "pro_only",
993
+ pro_required: true
994
+ },
995
+ {
996
+ skill: "arrays-data-api-crypto-metrics-and-screener",
997
+ file: "metrics-nupl",
998
+ method: "GET",
999
+ path: "/api/v1/crypto/metrics/nupl",
1000
+ tier: "alternative",
1001
+ required_subscription_tier: "pro",
1002
+ access: "pro_only",
1003
+ pro_required: true
1004
+ },
1005
+ {
1006
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1007
+ file: "metrics-puell-multiple",
1008
+ method: "GET",
1009
+ path: "/api/v1/crypto/metrics/puell-multiple",
1010
+ tier: "alternative",
1011
+ required_subscription_tier: "pro",
1012
+ access: "pro_only",
1013
+ pro_required: true
1014
+ },
1015
+ {
1016
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1017
+ file: "metrics-realized-price",
1018
+ method: "GET",
1019
+ path: "/api/v1/crypto/metrics/realized-price",
1020
+ tier: "alternative",
1021
+ required_subscription_tier: "pro",
1022
+ access: "pro_only",
1023
+ pro_required: true
1024
+ },
1025
+ {
1026
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1027
+ file: "metrics-sopr",
1028
+ method: "GET",
1029
+ path: "/api/v1/crypto/metrics/sopr",
1030
+ tier: "alternative",
1031
+ required_subscription_tier: "pro",
1032
+ access: "pro_only",
1033
+ pro_required: true
1034
+ },
1035
+ {
1036
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1037
+ file: "metrics-ssr",
1038
+ method: "GET",
1039
+ path: "/api/v1/crypto/metrics/ssr",
1040
+ tier: "alternative",
1041
+ required_subscription_tier: "pro",
1042
+ access: "pro_only",
1043
+ pro_required: true
1044
+ },
1045
+ {
1046
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1047
+ file: "metrics-whale-ratio",
1048
+ method: "GET",
1049
+ path: "/api/v1/crypto/metrics/whale-ratio",
1050
+ tier: "alternative",
1051
+ required_subscription_tier: "pro",
1052
+ access: "pro_only",
1053
+ pro_required: true
1054
+ },
1055
+ {
1056
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1057
+ file: "crypto-supply",
1058
+ method: "GET",
1059
+ path: "/api/v1/crypto/supply",
1060
+ tier: "alternative",
1061
+ required_subscription_tier: "pro",
1062
+ access: "pro_only",
1063
+ pro_required: true
1064
+ },
1065
+ {
1066
+ skill: "arrays-data-api-crypto-futures-data",
1067
+ file: "taker-buy-sell-volume",
1068
+ method: "GET",
1069
+ path: "/api/v1/crypto/taker-buy-sell-volume",
1070
+ tier: "alternative",
1071
+ required_subscription_tier: "pro",
1072
+ access: "pro_only",
1073
+ pro_required: true
1074
+ },
1075
+ {
1076
+ skill: "arrays-data-api-crypto-metrics-and-screener",
1077
+ file: "unlock-events",
1078
+ method: "GET",
1079
+ path: "/api/v1/crypto/unlock-events",
1080
+ tier: "alternative",
1081
+ required_subscription_tier: "pro",
1082
+ access: "pro_only",
1083
+ pro_required: true
1084
+ },
1085
+ {
1086
+ skill: "arrays-data-api-etf-fundamentals",
1087
+ file: "flow",
1088
+ method: "GET",
1089
+ path: "/api/v1/etf/flow",
1090
+ tier: "alternative",
1091
+ required_subscription_tier: "pro",
1092
+ access: "pro_only",
1093
+ pro_required: true
1094
+ },
1095
+ {
1096
+ skill: "arrays-data-api-options",
1097
+ file: "contracts",
1098
+ method: "GET",
1099
+ path: "/api/v1/options/contracts",
1100
+ tier: "alternative",
1101
+ required_subscription_tier: "pro",
1102
+ access: "pro_only",
1103
+ pro_required: true
1104
+ },
1105
+ {
1106
+ skill: "arrays-data-api-options",
1107
+ file: "kline",
1108
+ method: "GET",
1109
+ path: "/api/v1/options/kline",
1110
+ tier: "alternative",
1111
+ required_subscription_tier: "pro",
1112
+ access: "pro_only",
1113
+ pro_required: true
1114
+ },
1115
+ {
1116
+ skill: "arrays-data-api-equity-fundamentals",
1117
+ file: "company-executives",
1118
+ method: "GET",
1119
+ path: "/api/v1/stocks/company/executives",
1120
+ tier: "alternative",
1121
+ required_subscription_tier: "pro",
1122
+ access: "pro_only",
1123
+ pro_required: true
1124
+ },
1125
+ {
1126
+ skill: "arrays-data-api-equity-estimates-and-targets",
1127
+ file: "company-price-target-consensus",
1128
+ method: "GET",
1129
+ path: "/api/v1/stocks/company/price-target-consensus",
1130
+ tier: "alternative",
1131
+ required_subscription_tier: "pro",
1132
+ access: "pro_only",
1133
+ pro_required: true
1134
+ },
1135
+ {
1136
+ skill: "arrays-data-api-equity-estimates-and-targets",
1137
+ file: "company-price-target-news",
1138
+ method: "GET",
1139
+ path: "/api/v1/stocks/company/price-target-news",
1140
+ tier: "alternative",
1141
+ required_subscription_tier: "pro",
1142
+ access: "pro_only",
1143
+ pro_required: true
1144
+ },
1145
+ {
1146
+ skill: "arrays-data-api-equity-estimates-and-targets",
1147
+ file: "company-price-target-summary",
1148
+ method: "GET",
1149
+ path: "/api/v1/stocks/company/price-target-summary",
1150
+ tier: "alternative",
1151
+ required_subscription_tier: "pro",
1152
+ access: "pro_only",
1153
+ pro_required: true
1154
+ },
1155
+ {
1156
+ skill: "arrays-data-api-equity-ownership-and-flow",
1157
+ file: "congress-recent-trades",
1158
+ method: "GET",
1159
+ path: "/api/v1/stocks/congress/recent-trades",
1160
+ tier: "alternative",
1161
+ required_subscription_tier: "pro",
1162
+ access: "pro_only",
1163
+ pro_required: true
1164
+ },
1165
+ {
1166
+ skill: "arrays-data-api-equity-ownership-and-flow",
1167
+ file: "senate-trade",
1168
+ method: "GET",
1169
+ path: "/api/v1/stocks/company/senate-trade",
1170
+ tier: "alternative",
1171
+ required_subscription_tier: "pro",
1172
+ access: "pro_only",
1173
+ pro_required: true
1174
+ },
1175
+ {
1176
+ skill: "arrays-data-api-stock-metrics",
1177
+ file: "darkpool",
1178
+ method: "GET",
1179
+ path: "/api/v1/stocks/darkpool",
1180
+ tier: "alternative",
1181
+ required_subscription_tier: "pro",
1182
+ access: "pro_only",
1183
+ pro_required: true
1184
+ },
1185
+ {
1186
+ skill: "arrays-data-api-equity-estimates-and-targets",
1187
+ file: "estimates-guidance",
1188
+ method: "GET",
1189
+ path: "/api/v1/stocks/estimates-guidance",
1190
+ tier: "alternative",
1191
+ required_subscription_tier: "pro",
1192
+ access: "pro_only",
1193
+ pro_required: true
1194
+ },
1195
+ {
1196
+ skill: "arrays-data-api-equity-ownership-and-flow",
1197
+ file: "insider-transactions",
1198
+ method: "GET",
1199
+ path: "/api/v1/stocks/insider/transactions",
1200
+ tier: "alternative",
1201
+ required_subscription_tier: "pro",
1202
+ access: "pro_only",
1203
+ pro_required: true
1204
+ },
1205
+ {
1206
+ skill: "arrays-data-api-equity-ownership-and-flow",
1207
+ file: "institution-holder",
1208
+ method: "GET",
1209
+ path: "/api/v1/stocks/institution-holder",
1210
+ tier: "alternative",
1211
+ required_subscription_tier: "pro",
1212
+ access: "pro_only",
1213
+ pro_required: true
1214
+ },
1215
+ {
1216
+ skill: "arrays-data-api-polymarket",
1217
+ file: "activity",
1218
+ method: "GET",
1219
+ path: "polymarket:/activity",
1220
+ tier: "alternative",
1221
+ required_subscription_tier: "pro",
1222
+ access: "pro_only",
1223
+ pro_required: true
1224
+ },
1225
+ {
1226
+ skill: "arrays-data-api-polymarket",
1227
+ file: "book",
1228
+ method: "GET",
1229
+ path: "polymarket:/book",
1230
+ tier: "alternative",
1231
+ required_subscription_tier: "pro",
1232
+ access: "pro_only",
1233
+ pro_required: true
1234
+ },
1235
+ {
1236
+ skill: "arrays-data-api-polymarket",
1237
+ file: "closed-positions",
1238
+ method: "GET",
1239
+ path: "polymarket:/closed-positions",
1240
+ tier: "alternative",
1241
+ required_subscription_tier: "pro",
1242
+ access: "pro_only",
1243
+ pro_required: true
1244
+ },
1245
+ {
1246
+ skill: "arrays-data-api-polymarket",
1247
+ file: "events",
1248
+ method: "GET",
1249
+ path: "polymarket:/events",
1250
+ tier: "alternative",
1251
+ required_subscription_tier: "pro",
1252
+ access: "pro_only",
1253
+ pro_required: true
1254
+ },
1255
+ {
1256
+ skill: "arrays-data-api-polymarket",
1257
+ file: "holders",
1258
+ method: "GET",
1259
+ path: "polymarket:/holders",
1260
+ tier: "alternative",
1261
+ required_subscription_tier: "pro",
1262
+ access: "pro_only",
1263
+ pro_required: true
1264
+ },
1265
+ {
1266
+ skill: "arrays-data-api-polymarket",
1267
+ file: "markets",
1268
+ method: "GET",
1269
+ path: "polymarket:/markets",
1270
+ tier: "alternative",
1271
+ required_subscription_tier: "pro",
1272
+ access: "pro_only",
1273
+ pro_required: true
1274
+ },
1275
+ {
1276
+ skill: "arrays-data-api-polymarket",
1277
+ file: "midpoint",
1278
+ method: "GET",
1279
+ path: "polymarket:/midpoint",
1280
+ tier: "alternative",
1281
+ required_subscription_tier: "pro",
1282
+ access: "pro_only",
1283
+ pro_required: true
1284
+ },
1285
+ {
1286
+ skill: "arrays-data-api-polymarket",
1287
+ file: "oi",
1288
+ method: "GET",
1289
+ path: "polymarket:/oi",
1290
+ tier: "alternative",
1291
+ required_subscription_tier: "pro",
1292
+ access: "pro_only",
1293
+ pro_required: true
1294
+ },
1295
+ {
1296
+ skill: "arrays-data-api-polymarket",
1297
+ file: "positions",
1298
+ method: "GET",
1299
+ path: "polymarket:/positions",
1300
+ tier: "alternative",
1301
+ required_subscription_tier: "pro",
1302
+ access: "pro_only",
1303
+ pro_required: true
1304
+ },
1305
+ {
1306
+ skill: "arrays-data-api-polymarket",
1307
+ file: "price",
1308
+ method: "GET",
1309
+ path: "polymarket:/price",
1310
+ tier: "alternative",
1311
+ required_subscription_tier: "pro",
1312
+ access: "pro_only",
1313
+ pro_required: true
1314
+ },
1315
+ {
1316
+ skill: "arrays-data-api-polymarket",
1317
+ file: "prices-history",
1318
+ method: "GET",
1319
+ path: "polymarket:/prices-history",
1320
+ tier: "alternative",
1321
+ required_subscription_tier: "pro",
1322
+ access: "pro_only",
1323
+ pro_required: true
1324
+ },
1325
+ {
1326
+ skill: "arrays-data-api-polymarket",
1327
+ file: "public-search",
1328
+ method: "GET",
1329
+ path: "polymarket:/public-search",
1330
+ tier: "alternative",
1331
+ required_subscription_tier: "pro",
1332
+ access: "pro_only",
1333
+ pro_required: true
1334
+ },
1335
+ {
1336
+ skill: "arrays-data-api-polymarket",
1337
+ file: "series",
1338
+ method: "GET",
1339
+ path: "polymarket:/series",
1340
+ tier: "alternative",
1341
+ required_subscription_tier: "pro",
1342
+ access: "pro_only",
1343
+ pro_required: true
1344
+ },
1345
+ {
1346
+ skill: "arrays-data-api-polymarket",
1347
+ file: "sports",
1348
+ method: "GET",
1349
+ path: "polymarket:/sports",
1350
+ tier: "alternative",
1351
+ required_subscription_tier: "pro",
1352
+ access: "pro_only",
1353
+ pro_required: true
1354
+ },
1355
+ {
1356
+ skill: "arrays-data-api-polymarket",
1357
+ file: "spread",
1358
+ method: "GET",
1359
+ path: "polymarket:/spread",
1360
+ tier: "alternative",
1361
+ required_subscription_tier: "pro",
1362
+ access: "pro_only",
1363
+ pro_required: true
1364
+ },
1365
+ {
1366
+ skill: "arrays-data-api-polymarket",
1367
+ file: "tags",
1368
+ method: "GET",
1369
+ path: "polymarket:/tags",
1370
+ tier: "alternative",
1371
+ required_subscription_tier: "pro",
1372
+ access: "pro_only",
1373
+ pro_required: true
1374
+ },
1375
+ {
1376
+ skill: "arrays-data-api-polymarket",
1377
+ file: "trades",
1378
+ method: "GET",
1379
+ path: "polymarket:/trades",
1380
+ tier: "alternative",
1381
+ required_subscription_tier: "pro",
1382
+ access: "pro_only",
1383
+ pro_required: true
1384
+ },
1385
+ {
1386
+ skill: "arrays-data-api-polymarket",
1387
+ file: "value",
1388
+ method: "GET",
1389
+ path: "polymarket:/value",
1390
+ tier: "alternative",
1391
+ required_subscription_tier: "pro",
1392
+ access: "pro_only",
1393
+ pro_required: true
1394
+ },
1395
+ {
1396
+ skill: "arrays-data-api-equity-events",
1397
+ file: "earnings-transcript",
1398
+ method: "GET",
1399
+ path: "/api/v1/stocks/earnings-transcript",
1400
+ tier: "unstructured",
1401
+ required_subscription_tier: "pro",
1402
+ access: "pro_only",
1403
+ pro_required: true
1404
+ },
1405
+ {
1406
+ skill: "arrays-data-api-news",
1407
+ file: "market-news",
1408
+ method: "GET",
1409
+ path: "/api/v1/stocks/market-news",
1410
+ tier: "unstructured",
1411
+ required_subscription_tier: "pro",
1412
+ access: "pro_only",
1413
+ pro_required: true
1414
+ }
1415
+ ];
1416
+ function getSkillEndpointMetadata(skill, file) {
1417
+ return SKILL_ENDPOINT_METADATA.find(
1418
+ (item) => item.skill === skill && item.file === file
1419
+ );
1420
+ }
1421
+ function listSkillEndpointMetadata(skill) {
1422
+ return SKILL_ENDPOINT_METADATA.filter((item) => item.skill === skill);
1423
+ }
1424
+
1425
+ // src/resources/dataSkills.ts
1426
+ var DataSkillsResource = class {
354
1427
  constructor(client) {
355
1428
  this.client = client;
356
1429
  }
@@ -360,7 +1433,12 @@ var SkillsResource = class {
360
1433
  baseUrl: this.client.arraysBaseUrl,
361
1434
  noAuth: true
362
1435
  });
363
- return { skills: res.data ?? [] };
1436
+ return {
1437
+ skills: (res.data ?? []).map((skill) => ({
1438
+ ...skill,
1439
+ ...metadataSummaryForSkill(skill.name)
1440
+ }))
1441
+ };
364
1442
  }
365
1443
  async summary(params) {
366
1444
  const encoded = encodeURIComponent(params.name);
@@ -375,7 +1453,12 @@ var SkillsResource = class {
375
1453
  const doc = res.data?.[0];
376
1454
  if (!doc)
377
1455
  throw new Error(`empty skills summary response for "${params.name}"`);
378
- return doc;
1456
+ const endpointMetadata = listSkillEndpointMetadata(params.name);
1457
+ return {
1458
+ ...doc,
1459
+ ...metadataSummaryForSkill(params.name),
1460
+ ...endpointMetadata.length > 0 ? { endpoint_metadata: endpointMetadata } : {}
1461
+ };
379
1462
  }
380
1463
  async endpoint(params) {
381
1464
  const encoded = encodeURIComponent(params.name);
@@ -394,7 +1477,103 @@ var SkillsResource = class {
394
1477
  `empty skills endpoint response for "${params.name}" file "${params.file}"`
395
1478
  );
396
1479
  }
397
- return doc;
1480
+ const metadata = getSkillEndpointMetadata(params.name, params.file);
1481
+ return {
1482
+ ...doc,
1483
+ ...metadata ? { metadata } : {}
1484
+ };
1485
+ }
1486
+ };
1487
+ function metadataSummaryForSkill(skill) {
1488
+ const endpointMetadata = listSkillEndpointMetadata(skill);
1489
+ if (endpointMetadata.length === 0) {
1490
+ return {};
1491
+ }
1492
+ const counts = {};
1493
+ let proCount = 0;
1494
+ for (const endpoint of endpointMetadata) {
1495
+ counts[endpoint.tier] = (counts[endpoint.tier] ?? 0) + 1;
1496
+ if (endpoint.pro_required) proCount += 1;
1497
+ }
1498
+ return {
1499
+ endpoint_tier_counts: counts,
1500
+ metadata: {
1501
+ endpoint_count: endpointMetadata.length,
1502
+ endpoint_tier_counts: counts,
1503
+ pro_count: proCount
1504
+ }
1505
+ };
1506
+ }
1507
+
1508
+ // src/resources/playbookSkills.ts
1509
+ function parsePlaybookSkillId(s) {
1510
+ const parts = s.split("/");
1511
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
1512
+ throw new AlvaError(
1513
+ "INVALID_ARGUMENT",
1514
+ `playbook skill identifier must be "<user>/<name>", got "${s}"`,
1515
+ 0
1516
+ );
1517
+ }
1518
+ return { username: parts[0], name: parts[1] };
1519
+ }
1520
+ var PlaybookSkillsResource = class {
1521
+ constructor(client) {
1522
+ this.client = client;
1523
+ }
1524
+ client;
1525
+ async list(params) {
1526
+ const query = {};
1527
+ if (params?.tag) query.tag = params.tag;
1528
+ if (params?.username) query.username = params.username;
1529
+ const res = await this.client._request("GET", "/api/v1/skills", {
1530
+ query
1531
+ });
1532
+ return { skills: res.data ?? [] };
1533
+ }
1534
+ async tags() {
1535
+ const res = await this.client._request(
1536
+ "GET",
1537
+ "/api/v1/skills/tags"
1538
+ );
1539
+ return { tags: res.data ?? [] };
1540
+ }
1541
+ async get(id) {
1542
+ const { username, name } = parsePlaybookSkillId(id);
1543
+ const u = encodeURIComponent(username);
1544
+ const n = encodeURIComponent(name);
1545
+ const res = await this.client._request(
1546
+ "GET",
1547
+ `/api/v1/skills/${u}/${n}`
1548
+ );
1549
+ const meta = res.data?.[0];
1550
+ if (!meta) {
1551
+ throw new AlvaError(
1552
+ "NOT_FOUND",
1553
+ `empty playbook skills get response for ${id}`,
1554
+ 0
1555
+ );
1556
+ }
1557
+ return meta;
1558
+ }
1559
+ async file(id, path) {
1560
+ const { username, name } = parsePlaybookSkillId(id);
1561
+ const u = encodeURIComponent(username);
1562
+ const n = encodeURIComponent(name);
1563
+ const p = path.split("/").map(encodeURIComponent).join("/");
1564
+ const res = await this.client._request(
1565
+ "GET",
1566
+ `/api/v1/skills/${u}/${n}/files/${p}`
1567
+ );
1568
+ const out = res.data?.[0];
1569
+ if (!out) {
1570
+ throw new AlvaError(
1571
+ "NOT_FOUND",
1572
+ `empty playbook skills file response for ${id} path ${path}`,
1573
+ 0
1574
+ );
1575
+ }
1576
+ return out;
398
1577
  }
399
1578
  };
400
1579
 
@@ -458,7 +1637,10 @@ var ScreenshotResource = class {
458
1637
  query: {
459
1638
  url: params.url,
460
1639
  selector: params.selector,
461
- xpath: params.xpath
1640
+ xpath: params.xpath,
1641
+ compress: params.compress,
1642
+ compress_quality: params.compressQuality,
1643
+ compress_max_width: params.compressMaxWidth
462
1644
  }
463
1645
  });
464
1646
  }
@@ -775,7 +1957,8 @@ var AlvaClient = class {
775
1957
  _release;
776
1958
  _secrets;
777
1959
  _sdk;
778
- _skills;
1960
+ _dataSkills;
1961
+ _playbookSkills;
779
1962
  _comments;
780
1963
  _remix;
781
1964
  _screenshot;
@@ -809,8 +1992,11 @@ var AlvaClient = class {
809
1992
  get sdk() {
810
1993
  return this._sdk ??= new SdkDocsResource(this);
811
1994
  }
812
- get skills() {
813
- return this._skills ??= new SkillsResource(this);
1995
+ get dataSkills() {
1996
+ return this._dataSkills ??= new DataSkillsResource(this);
1997
+ }
1998
+ get playbookSkills() {
1999
+ return this._playbookSkills ??= new PlaybookSkillsResource(this);
814
2000
  }
815
2001
  get comments() {
816
2002
  return this._comments ??= new CommentsResource(this);
@@ -1197,11 +2383,168 @@ async function runPostConfigureHooks(client, deps) {
1197
2383
  }
1198
2384
  }
1199
2385
 
2386
+ // src/cli/dataSkillsFormat.ts
2387
+ var TIER_ORDER = [
2388
+ "public",
2389
+ "alternative",
2390
+ "unstructured"
2391
+ ];
2392
+ function formatTierCounts(counts) {
2393
+ if (!counts) return "";
2394
+ const parts = [];
2395
+ for (const tier of TIER_ORDER) {
2396
+ const n = counts[tier];
2397
+ if (n) parts.push(`${tier}=${n}`);
2398
+ }
2399
+ return parts.join(" ");
2400
+ }
2401
+ function formatSkillsList(payload) {
2402
+ const skills = payload.skills ?? [];
2403
+ if (skills.length === 0) return "(no skills)\n";
2404
+ const lines = [`${skills.length} skill(s):`, ""];
2405
+ for (const s of skills) {
2406
+ const meta = s.metadata;
2407
+ let tag = "";
2408
+ if (meta) {
2409
+ const parts = [`${meta.endpoint_count} endpoints`];
2410
+ const tiers = formatTierCounts(meta.endpoint_tier_counts);
2411
+ if (tiers) parts.push(tiers);
2412
+ if (meta.pro_count > 0) parts.push(`${meta.pro_count} pro`);
2413
+ tag = `[${parts.join("; ")}]`;
2414
+ }
2415
+ lines.push(`\u2022 ${s.name}${tag ? ` ${tag}` : ""}`);
2416
+ if (s.description) lines.push(` ${s.description}`);
2417
+ lines.push("");
2418
+ }
2419
+ return lines.join("\n");
2420
+ }
2421
+ function formatEndpointMetadataTable(endpoints) {
2422
+ if (endpoints.length === 0) return "";
2423
+ const rows = endpoints.map((e) => ({
2424
+ method: e.method,
2425
+ path: e.path,
2426
+ file: e.file,
2427
+ tier: e.tier,
2428
+ access: e.pro_required ? "pro" : "free"
2429
+ }));
2430
+ const headers = ["METHOD", "PATH", "FILE", "TIER", "ACCESS"];
2431
+ const widths = headers.map((h, i) => {
2432
+ const key = ["method", "path", "file", "tier", "access"][i];
2433
+ return Math.max(h.length, ...rows.map((r) => String(r[key]).length));
2434
+ });
2435
+ const pad2 = (s, w) => s + " ".repeat(Math.max(0, w - s.length));
2436
+ const lines = [
2437
+ headers.map((h, i) => pad2(h, widths[i])).join(" "),
2438
+ widths.map((w) => "-".repeat(w)).join(" "),
2439
+ ...rows.map(
2440
+ (r) => [r.method, r.path, r.file, r.tier, r.access].map((v, i) => pad2(String(v), widths[i])).join(" ")
2441
+ )
2442
+ ];
2443
+ return lines.join("\n");
2444
+ }
2445
+ function formatSingleEndpointMetadata(meta) {
2446
+ if (!meta) return "";
2447
+ return [
2448
+ "Endpoint metadata:",
2449
+ ` ${meta.method} ${meta.path}`,
2450
+ ` file: ${meta.file}`,
2451
+ ` tier: ${meta.tier}`,
2452
+ ` access: ${meta.pro_required ? "pro only" : "free and pro"} (requires ${meta.required_subscription_tier})`
2453
+ ].join("\n");
2454
+ }
2455
+ function isEndpointMetadata(m) {
2456
+ return !!m && typeof m === "object" && "path" in m && "method" in m;
2457
+ }
2458
+ function formatSkillSummary(doc) {
2459
+ const sections = [];
2460
+ sections.push(`# ${doc.name}`);
2461
+ if (doc.description) sections.push(doc.description);
2462
+ if (doc.metadata && !isEndpointMetadata(doc.metadata)) {
2463
+ const m = doc.metadata;
2464
+ const parts = [`${m.endpoint_count} endpoints`];
2465
+ const counts = formatTierCounts(m.endpoint_tier_counts);
2466
+ if (counts) parts.push(counts);
2467
+ if (m.pro_count > 0) parts.push(`${m.pro_count} pro`);
2468
+ sections.push(`(${parts.join("; ")})`);
2469
+ }
2470
+ sections.push("---");
2471
+ sections.push((doc.content ?? "").trimEnd());
2472
+ if (doc.endpoint_metadata && doc.endpoint_metadata.length > 0) {
2473
+ sections.push("---");
2474
+ sections.push(formatEndpointMetadataTable(doc.endpoint_metadata));
2475
+ }
2476
+ return sections.join("\n\n") + "\n";
2477
+ }
2478
+ function formatSkillEndpoint(doc) {
2479
+ const sections = [];
2480
+ sections.push(`# ${doc.name}`);
2481
+ if (doc.description) sections.push(doc.description);
2482
+ if (isEndpointMetadata(doc.metadata)) {
2483
+ sections.push(formatSingleEndpointMetadata(doc.metadata));
2484
+ }
2485
+ sections.push("---");
2486
+ sections.push((doc.content ?? "").trimEnd());
2487
+ return sections.join("\n\n") + "\n";
2488
+ }
2489
+
2490
+ // src/cli/playbookSkillsFormat.ts
2491
+ function pad(s, w) {
2492
+ return s + " ".repeat(Math.max(0, w - s.length));
2493
+ }
2494
+ function formatPlaybookSkillsList(result) {
2495
+ const skills = result.skills ?? [];
2496
+ if (skills.length === 0) return "No playbook skills found.\n";
2497
+ const rows = skills.map((s) => ({
2498
+ id: `${s.username}/${s.name}`,
2499
+ description: s.description ?? "",
2500
+ tags: (s.tags ?? []).join(","),
2501
+ updated_at: s.updated_at ?? ""
2502
+ }));
2503
+ const headers = ["USERNAME/NAME", "DESCRIPTION", "TAGS", "UPDATED_AT"];
2504
+ const keys = ["id", "description", "tags", "updated_at"];
2505
+ const widths = headers.map(
2506
+ (h, i) => Math.max(h.length, ...rows.map((r) => r[keys[i]].length))
2507
+ );
2508
+ const lines = [
2509
+ headers.map((h, i) => pad(h, widths[i])).join(" "),
2510
+ widths.map((w) => "-".repeat(w)).join(" "),
2511
+ ...rows.map((r) => keys.map((k, i) => pad(r[k], widths[i])).join(" "))
2512
+ ];
2513
+ return lines.join("\n") + "\n";
2514
+ }
2515
+ function formatPlaybookSkillsTags(result) {
2516
+ const tags = result.tags ?? [];
2517
+ if (tags.length === 0) return "No tags.\n";
2518
+ return tags.map((t) => `\u2022 ${t.name}`).join("\n") + "\n";
2519
+ }
2520
+ function formatPlaybookSkillGet(meta) {
2521
+ const lines = [];
2522
+ lines.push(`${meta.username}/${meta.name}`);
2523
+ if (meta.description) lines.push(meta.description);
2524
+ lines.push(`tags: ${(meta.tags ?? []).join(", ") || "(none)"}`);
2525
+ lines.push(`creator_uid: ${meta.creator_uid}`);
2526
+ lines.push(`updated_at: ${meta.updated_at}`);
2527
+ lines.push("");
2528
+ lines.push("Files:");
2529
+ const files = meta.files ?? [];
2530
+ if (files.length === 0) {
2531
+ lines.push(" (no files)");
2532
+ } else {
2533
+ for (const f of files) {
2534
+ lines.push(` ${f.path} (${f.size_bytes} B)`);
2535
+ }
2536
+ }
2537
+ return lines.join("\n") + "\n";
2538
+ }
2539
+ function formatPlaybookSkillFile(file) {
2540
+ return file.content;
2541
+ }
2542
+
1200
2543
  // src/cli/index.ts
1201
2544
  import * as fs from "fs";
1202
2545
  import * as os2 from "os";
1203
2546
  import * as fsPromises2 from "fs/promises";
1204
- var CLI_VERSION = true ? "0.4.3" : "dev";
2547
+ var CLI_VERSION = true ? "0.7.0-beta.0" : "dev";
1205
2548
  function isVersionOlderThan(a, b) {
1206
2549
  const parse = (v) => {
1207
2550
  if (!v) return null;
@@ -1231,7 +2574,8 @@ Commands:
1231
2574
  release Feed and playbook releases (feed, playbook-draft, playbook)
1232
2575
  secrets Secret management (create, list, get, update, delete)
1233
2576
  sdk SDK documentation (doc, partitions, partition-summary)
1234
- skills Data-skill documentation from the Arrays backend (list, summary, endpoint)
2577
+ skillhub Playbook skills (list, tags, get, file)
2578
+ data-skills Data-skill documentation from the Arrays backend (list, summary, endpoint)
1235
2579
  comments Playbook comments (create, pin, unpin)
1236
2580
  push-subscriptions Personal push opt-in (subscribe-playbook, unsubscribe-playbook, subscribe-feed, unsubscribe-feed, list)
1237
2581
  channel Channel group operations (group-subscriptions context, list, subscribe, unsubscribe)
@@ -1433,7 +2777,7 @@ Examples:
1433
2777
  deploy: `Usage: alva deploy <subcommand> [options]
1434
2778
 
1435
2779
  Manage scheduled cronjobs that run your scripts on a cron schedule.
1436
- Max 20 cronjobs per user. Min interval: 1 minute.
2780
+ Min interval: 1 minute.
1437
2781
 
1438
2782
  Subcommands:
1439
2783
  create Create a new cronjob
@@ -1443,6 +2787,8 @@ Subcommands:
1443
2787
  delete Delete a cronjob
1444
2788
  pause Pause a running cronjob
1445
2789
  resume Resume a paused cronjob
2790
+ trigger Fire the cronjob once, immediately, bypassing the schedule
2791
+ (returns workflow_run_id; poll 'runs' to verify completion)
1446
2792
  runs List runs for a cronjob (cursor-paginated)
1447
2793
  run-logs Get stdout/stderr logs for a single cronjob run
1448
2794
 
@@ -1458,7 +2804,7 @@ List flags:
1458
2804
  --limit <n> Max results per page (default: 20)
1459
2805
  --cursor <cursor> Pagination cursor from previous response
1460
2806
 
1461
- Get/Update/Delete/Pause/Resume flags:
2807
+ Get/Update/Delete/Pause/Resume/Trigger flags:
1462
2808
  --id <id> Cronjob ID (required)
1463
2809
 
1464
2810
  Runs flags:
@@ -1492,7 +2838,17 @@ Examples:
1492
2838
  alva deploy delete --id 42
1493
2839
  alva deploy runs --id 42
1494
2840
  alva deploy runs --id 42 --first 10
1495
- alva deploy run-logs --id 42 --run-id 123`,
2841
+ alva deploy run-logs --id 42 --run-id 123
2842
+
2843
+ Build-time verify (fire once, then poll until your run completes):
2844
+ WF=$(alva deploy trigger --id 42 | jq -r .workflow_run_id)
2845
+ while ! ROW=$(alva deploy runs --id 42 --first 5 \\
2846
+ | jq -e ".runs[] | select(.workflow_run_id==\\"$WF\\")"); do
2847
+ sleep 5
2848
+ done
2849
+ STATUS=$(echo "$ROW" | jq -r .status)
2850
+ [ "$STATUS" = completed ] || alva deploy run-logs --id 42 \\
2851
+ --run-id "$(echo "$ROW" | jq -r .id)"`,
1496
2852
  release: `Usage: alva release <subcommand> [options]
1497
2853
 
1498
2854
  Publish feeds and playbooks to the Alva platform. The typical workflow:
@@ -1500,7 +2856,8 @@ Publish feeds and playbooks to the Alva platform. The typical workflow:
1500
2856
  2. Register feed (alva release feed)
1501
2857
  3. Create playbook draft (alva release playbook-draft)
1502
2858
  4. Write HTML to ALFS (alva fs write --path ~/playbooks/{name}/index.html)
1503
- 5. Release playbook (alva release playbook)
2859
+ 5. Write README to ALFS (alva fs write --path ~/playbooks/{name}/README.md)
2860
+ 6. Release playbook (alva release playbook --readme-url "/alva/home/<username>/playbooks/{name}/README.md")
1504
2861
 
1505
2862
  Subcommands:
1506
2863
  feed Register a feed after deploying its cronjob
@@ -1521,12 +2878,19 @@ Playbook-draft flags:
1521
2878
  --feeds <json> JSON array of {feed_id, feed_major?} (required)
1522
2879
  --description <text> Playbook description
1523
2880
  --trading-symbols <json> JSON array of tickers, e.g. '["BTC","ETH"]' (max 50)
2881
+ --template-id <id> Source-template reference "username/name", e.g.
2882
+ "alva/screener". Persisted set-once on first draft.
1524
2883
 
1525
2884
  Playbook flags:
1526
2885
  --name <name> Playbook name, must already exist as draft (required)
1527
2886
  --version <version> Semantic version, e.g. "v1.0.0" (required)
1528
2887
  --feeds <json> JSON array of {feed_id, feed_major?} (required)
1529
2888
  --changelog <text> Release changelog (required)
2889
+ --readme-url <url> Owner-attested README location (required). Must be
2890
+ the absolute ALFS path
2891
+ "/alva/home/<username>/playbooks/<name>/README.md".
2892
+ The README must already be written to ALFS at that
2893
+ path before publish.
1530
2894
 
1531
2895
  Display name conventions:
1532
2896
  Format: [subject/theme] [analysis angle/strategy logic]
@@ -1538,7 +2902,8 @@ Examples:
1538
2902
  alva release feed --name btc-ema --version 1.0.0 --cronjob-id 42
1539
2903
  alva release feed --name nvda-insiders --version 1.0.0 --cronjob-id 43 --description "NVDA insider trading activity"
1540
2904
  alva release playbook-draft --name btc-dashboard --display-name "BTC Trend Dashboard" --feeds '[{"feed_id":100}]' --trading-symbols '["BTC"]'
1541
- alva release playbook --name btc-dashboard --version v1.0.0 --feeds '[{"feed_id":100}]' --changelog "Initial release"`,
2905
+ alva release playbook-draft --name btc-dashboard --display-name "BTC Trend Dashboard" --feeds '[{"feed_id":100}]' --template-id alva/screener
2906
+ alva release playbook --name btc-dashboard --version v1.0.0 --feeds '[{"feed_id":100}]' --changelog "Initial release" --readme-url "/alva/home/<username>/playbooks/btc-dashboard/README.md"`,
1542
2907
  secrets: `Usage: alva secrets <subcommand> [options]
1543
2908
 
1544
2909
  Manage encrypted secrets for use in Alva scripts. Secrets are stored
@@ -1595,28 +2960,59 @@ Examples:
1595
2960
  alva sdk partition-summary --partition feed_widgets
1596
2961
  alva sdk doc --name "@arrays/data/widget-scrap/twitter:v1.0.0"
1597
2962
  alva sdk doc --name "@arrays/data/search/search-grok-x:v1.0.0"`,
1598
- skills: `Usage: alva skills <subcommand> [options]
2963
+ "data-skills": `Usage: alva data-skills <subcommand> [args]
1599
2964
 
1600
2965
  Browse the Arrays backend's data-skill documentation. These endpoints are
1601
2966
  public \u2014 no Alva credentials required.
1602
2967
 
1603
2968
  Subcommands:
1604
- list List all available data skills
1605
- summary Get the endpoints table for a skill (requires --name)
1606
- endpoint Get full documentation for a specific endpoint (requires --name and --file)
2969
+ list List all available data skills
2970
+ summary <skill> Get the endpoints table for a skill, plus local tier metadata
2971
+ endpoint <skill> <file> Get full documentation and local tier metadata for a specific endpoint
1607
2972
 
1608
2973
  Flags:
1609
- --name <name> Skill name (required for summary and endpoint)
1610
- --file <file> Endpoint file name from the "File" column of 'skills summary' (required for endpoint)
2974
+ --json Emit raw JSON instead of the readable rendering (for scripting / jq)
2975
+
2976
+ Output: by default, summary/endpoint print the skill's markdown content directly,
2977
+ and list prints a name \u2192 description summary. Pass --json to get the raw JSON
2978
+ shape (same as before this CLI version) for piping into jq or other tools.
1611
2979
 
1612
2980
  Global override:
1613
2981
  --arrays-endpoint <url> Arrays backend URL (or ARRAYS_ENDPOINT env)
1614
2982
  Default: https://data-tools.prd.space.id
1615
2983
 
1616
2984
  Examples:
1617
- alva skills list
1618
- alva skills summary --name <skill>
1619
- alva skills endpoint --name <skill> --file <endpoint-file>`,
2985
+ alva data-skills list
2986
+ alva data-skills list --json
2987
+ alva data-skills summary <skill>
2988
+ alva data-skills endpoint <skill> <endpoint-file>
2989
+ alva data-skills summary <skill> --json | jq '.content'`,
2990
+ skillhub: `Usage: alva skillhub <subcommand> [options]
2991
+
2992
+ Browse playbook skills (system templates + user-created) from the
2993
+ alva-gateway public API. Skills are namespaced as "<username>/<name>".
2994
+ The "get" subcommand returns metadata + file listing; use "file" to
2995
+ fetch individual file contents (progressive loading).
2996
+
2997
+ Subcommands:
2998
+ list List skill summaries (filter by --tag and/or --username)
2999
+ tags Distinct tag set used across all skills
3000
+ get Get one skill's metadata + file listing (path + size_bytes only)
3001
+ file Get one file's content from a skill
3002
+
3003
+ Flags:
3004
+ --tag <tag> (list) filter by tag
3005
+ --username <user> (list) filter by owner username
3006
+ --json Return raw envelope instead of pretty output
3007
+
3008
+ Examples:
3009
+ alva skillhub list
3010
+ alva skillhub list --tag research
3011
+ alva skillhub list --username alva
3012
+ alva skillhub tags
3013
+ alva skillhub get alva/ai-digest
3014
+ alva skillhub file alva/ai-digest README.md
3015
+ alva skillhub file alva/ai-digest references/api/example.md > out.md`,
1620
3016
  comments: `Usage: alva comments <subcommand> [options]
1621
3017
 
1622
3018
  Manage comments on Alva playbooks. Supports top-level comments and threaded
@@ -1706,22 +3102,26 @@ Required:
1706
3102
 
1707
3103
  Examples:
1708
3104
  alva remix --child-username bob --child-name my-btc --parents '[{"username":"alice","name":"btc-signals"}]'`,
1709
- screenshot: `Usage: alva screenshot --url <url> --out <file> [--selector <css>] [--xpath <xpath>]
3105
+ screenshot: `Usage: alva screenshot --url <url> --out <file> [--selector <css>] [--xpath <xpath>] [--compress] [--compress-quality <n>] [--compress-max-width <px>]
1710
3106
 
1711
3107
  Capture a screenshot of an Alva page and save it as PNG. Useful for verifying
1712
3108
  playbook rendering before release.
1713
3109
 
1714
3110
  Required:
1715
- --url <url> URL or path to capture (e.g. /playbook/alice/dashboard)
1716
- --out <file> Local file path to write the PNG output
3111
+ --url <url> URL or path to capture (e.g. /playbook/alice/dashboard)
3112
+ --out <file> Local file path to write the PNG output
1717
3113
 
1718
3114
  Optional:
1719
- --selector <css> CSS selector to capture a specific element
1720
- --xpath <xpath> XPath selector to capture a specific element
3115
+ --selector <css> CSS selector to capture a specific element
3116
+ --xpath <xpath> XPath selector to capture a specific element
3117
+ --compress Re-encode the PNG to reduce file size
3118
+ --compress-quality <n> Compression quality 1-100 (gateway default applies if omitted)
3119
+ --compress-max-width <px> Downscale to at most this width in pixels
1721
3120
 
1722
3121
  Examples:
1723
3122
  alva screenshot --url /playbook/alice/btc-dashboard --out dashboard.png
1724
- alva screenshot --url /playbook/alice/btc-dashboard --out chart.png --selector ".chart-container"`,
3123
+ alva screenshot --url /playbook/alice/btc-dashboard --out chart.png --selector ".chart-container"
3124
+ alva screenshot --url /playbook/alice/btc-dashboard --out small.png --compress --compress-quality 70 --compress-max-width 1280`,
1725
3125
  trading: `Usage: alva trading <subcommand> [options]
1726
3126
 
1727
3127
  Manage trading accounts, portfolios, orders, subscriptions, and risk rules.
@@ -1847,7 +3247,9 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
1847
3247
  "push-notify",
1848
3248
  "help",
1849
3249
  "execute-latest",
1850
- "dry-run"
3250
+ "dry-run",
3251
+ "json",
3252
+ "compress"
1851
3253
  ]);
1852
3254
  function parseFlags2(argv) {
1853
3255
  const flags = {};
@@ -2120,6 +3522,10 @@ async function dispatch(client, args, meta) {
2120
3522
  return client.deploy.resume({
2121
3523
  id: requireNumericFlag(flags, "id", "deploy resume")
2122
3524
  });
3525
+ case "trigger":
3526
+ return client.deploy.trigger({
3527
+ id: requireNumericFlag(flags, "id", "deploy trigger")
3528
+ });
2123
3529
  case "runs":
2124
3530
  return client.deploy.listRuns({
2125
3531
  cronjob_id: requireNumericFlag(flags, "id", "deploy runs"),
@@ -2163,7 +3569,8 @@ async function dispatch(client, args, meta) {
2163
3569
  feeds: jsonParse(
2164
3570
  requireFlag(flags, "feeds", "release playbook-draft")
2165
3571
  ),
2166
- trading_symbols: flags["trading-symbols"] ? jsonParse(flags["trading-symbols"]) : void 0
3572
+ trading_symbols: flags["trading-symbols"] ? jsonParse(flags["trading-symbols"]) : void 0,
3573
+ template_id: flags["template-id"]
2167
3574
  });
2168
3575
  case "playbook":
2169
3576
  return client.release.playbook({
@@ -2172,7 +3579,8 @@ async function dispatch(client, args, meta) {
2172
3579
  feeds: jsonParse(
2173
3580
  requireFlag(flags, "feeds", "release playbook")
2174
3581
  ),
2175
- changelog: requireFlag(flags, "changelog", "release playbook")
3582
+ changelog: requireFlag(flags, "changelog", "release playbook"),
3583
+ readme_url: requireFlag(flags, "readme-url", "release playbook")
2176
3584
  });
2177
3585
  default:
2178
3586
  throw new CliUsageError(
@@ -2233,25 +3641,103 @@ async function dispatch(client, args, meta) {
2233
3641
  );
2234
3642
  }
2235
3643
  }
2236
- case "skills": {
3644
+ case "data-skills": {
2237
3645
  if (!subcommand)
2238
- throw new CliUsageError("Missing subcommand for skills", "skills");
3646
+ throw new CliUsageError(
3647
+ "Missing subcommand for data-skills",
3648
+ "data-skills"
3649
+ );
3650
+ const asJson = boolFlag(flags["json"]) ?? false;
2239
3651
  switch (subcommand) {
2240
- case "list":
2241
- return client.skills.list();
2242
- case "summary":
2243
- return client.skills.summary({
2244
- name: requireFlag(flags, "name", "skills summary")
2245
- });
2246
- case "endpoint":
2247
- return client.skills.endpoint({
2248
- name: requireFlag(flags, "name", "skills endpoint"),
2249
- file: requireFlag(flags, "file", "skills endpoint")
3652
+ case "list": {
3653
+ const result = await client.dataSkills.list();
3654
+ return asJson ? result : formatSkillsList(result);
3655
+ }
3656
+ case "summary": {
3657
+ const name = args[2];
3658
+ if (!name || name.startsWith("--")) {
3659
+ throw new CliUsageError(
3660
+ "Missing skill name for data-skills summary",
3661
+ "data-skills"
3662
+ );
3663
+ }
3664
+ const result = await client.dataSkills.summary({ name });
3665
+ return asJson ? result : formatSkillSummary(result);
3666
+ }
3667
+ case "endpoint": {
3668
+ const name = args[2];
3669
+ if (!name || name.startsWith("--")) {
3670
+ throw new CliUsageError(
3671
+ "Missing skill name for data-skills endpoint",
3672
+ "data-skills"
3673
+ );
3674
+ }
3675
+ const file = args[3];
3676
+ if (!file || file.startsWith("--")) {
3677
+ throw new CliUsageError(
3678
+ "Missing endpoint file for data-skills endpoint",
3679
+ "data-skills"
3680
+ );
3681
+ }
3682
+ const result = await client.dataSkills.endpoint({ name, file });
3683
+ return asJson ? result : formatSkillEndpoint(result);
3684
+ }
3685
+ default:
3686
+ throw new CliUsageError(
3687
+ `Unknown subcommand: data-skills ${subcommand}`,
3688
+ "data-skills"
3689
+ );
3690
+ }
3691
+ }
3692
+ case "skillhub": {
3693
+ if (!subcommand)
3694
+ throw new CliUsageError("Missing subcommand for skillhub", "skillhub");
3695
+ const asJson = boolFlag(flags["json"]) ?? false;
3696
+ switch (subcommand) {
3697
+ case "list": {
3698
+ const result = await client.playbookSkills.list({
3699
+ tag: flags["tag"],
3700
+ username: flags["username"]
2250
3701
  });
3702
+ return asJson ? result : formatPlaybookSkillsList(result);
3703
+ }
3704
+ case "tags": {
3705
+ const result = await client.playbookSkills.tags();
3706
+ return asJson ? result : formatPlaybookSkillsTags(result);
3707
+ }
3708
+ case "get": {
3709
+ const id = args[2];
3710
+ if (!id || id.startsWith("--")) {
3711
+ throw new CliUsageError(
3712
+ "Missing playbook skill identifier for skillhub get",
3713
+ "skillhub"
3714
+ );
3715
+ }
3716
+ const result = await client.playbookSkills.get(id);
3717
+ return asJson ? result : formatPlaybookSkillGet(result);
3718
+ }
3719
+ case "file": {
3720
+ const id = args[2];
3721
+ if (!id || id.startsWith("--")) {
3722
+ throw new CliUsageError(
3723
+ "Missing playbook skill identifier for skillhub file",
3724
+ "skillhub"
3725
+ );
3726
+ }
3727
+ const path = args[3];
3728
+ if (!path || path.startsWith("--")) {
3729
+ throw new CliUsageError(
3730
+ "Missing file path for skillhub file",
3731
+ "skillhub"
3732
+ );
3733
+ }
3734
+ const result = await client.playbookSkills.file(id, path);
3735
+ return asJson ? result : formatPlaybookSkillFile(result);
3736
+ }
2251
3737
  default:
2252
3738
  throw new CliUsageError(
2253
- `Unknown subcommand: skills ${subcommand}`,
2254
- "skills"
3739
+ `Unknown subcommand: skillhub ${subcommand}`,
3740
+ "skillhub"
2255
3741
  );
2256
3742
  }
2257
3743
  }
@@ -2463,10 +3949,15 @@ async function dispatch(client, args, meta) {
2463
3949
  }
2464
3950
  case "screenshot": {
2465
3951
  const outFile = requireFlag(flags, "out", "screenshot");
3952
+ const compressQuality = flags["compress-quality"];
3953
+ const compressMaxWidth = flags["compress-max-width"];
2466
3954
  const result = await client.screenshot.capture({
2467
3955
  url: requireFlag(flags, "url", "screenshot"),
2468
3956
  selector: flags["selector"],
2469
- xpath: flags["xpath"]
3957
+ xpath: flags["xpath"],
3958
+ compress: boolFlag(flags["compress"]),
3959
+ compressQuality: compressQuality !== void 0 ? Number(compressQuality) : void 0,
3960
+ compressMaxWidth: compressMaxWidth !== void 0 ? Number(compressMaxWidth) : void 0
2470
3961
  });
2471
3962
  const buf = Buffer.from(result);
2472
3963
  if (buf.length === 0) {