@alva-ai/toolkit 0.4.2 → 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
  }
@@ -698,6 +1880,69 @@ var PushSubscriptionsResource = class {
698
1880
  }
699
1881
  };
700
1882
 
1883
+ // src/resources/channelGroupSubscriptions.ts
1884
+ var ChannelGroupSubscriptionsResource = class {
1885
+ constructor(client) {
1886
+ this.client = client;
1887
+ }
1888
+ client;
1889
+ async context(params) {
1890
+ this.client._requireAuth();
1891
+ return this.client._request(
1892
+ "GET",
1893
+ "/api/v1/channel/group-subscriptions/context",
1894
+ {
1895
+ query: { session_id: params.session_id }
1896
+ }
1897
+ );
1898
+ }
1899
+ async list(params) {
1900
+ this.client._requireAuth();
1901
+ return this.client._request("GET", "/api/v1/channel/group-subscriptions", {
1902
+ query: { session_id: params.session_id }
1903
+ });
1904
+ }
1905
+ async subscribe(params) {
1906
+ this.client._requireAuth();
1907
+ return this.client._request("POST", "/api/v1/channel/group-subscriptions", {
1908
+ jsonBody: mutationBody(params)
1909
+ });
1910
+ }
1911
+ async unsubscribe(params) {
1912
+ this.client._requireAuth();
1913
+ return this.client._request(
1914
+ "DELETE",
1915
+ "/api/v1/channel/group-subscriptions",
1916
+ {
1917
+ jsonBody: mutationBody(params)
1918
+ }
1919
+ );
1920
+ }
1921
+ };
1922
+ function mutationBody(params) {
1923
+ return `{"session_id":${idLiteral(params.session_id)},"target_type":${JSON.stringify(params.target_type)},"target_id":${idLiteral(params.target_id)}}`;
1924
+ }
1925
+ function idLiteral(value) {
1926
+ if (typeof value === "number") {
1927
+ if (!Number.isInteger(value) || value <= 0 || !Number.isSafeInteger(value)) {
1928
+ throw new AlvaError(
1929
+ "INVALID_ARGUMENT",
1930
+ "channel group subscription ids must be positive safe integers; pass large int64 ids as strings",
1931
+ 0
1932
+ );
1933
+ }
1934
+ return String(value);
1935
+ }
1936
+ if (!/^[1-9]\d*$/.test(value)) {
1937
+ throw new AlvaError(
1938
+ "INVALID_ARGUMENT",
1939
+ "channel group subscription ids must be positive integer strings",
1940
+ 0
1941
+ );
1942
+ }
1943
+ return value;
1944
+ }
1945
+
701
1946
  // src/client.ts
702
1947
  var DEFAULT_BASE_URL = "https://api-llm.prd.alva.ai";
703
1948
  var DEFAULT_ARRAYS_BASE_URL = "https://data-tools.prd.space.id";
@@ -712,7 +1957,8 @@ var AlvaClient = class {
712
1957
  _release;
713
1958
  _secrets;
714
1959
  _sdk;
715
- _skills;
1960
+ _dataSkills;
1961
+ _playbookSkills;
716
1962
  _comments;
717
1963
  _remix;
718
1964
  _screenshot;
@@ -721,6 +1967,7 @@ var AlvaClient = class {
721
1967
  _arraysJwt;
722
1968
  _notifications;
723
1969
  _pushSubscriptions;
1970
+ _channelGroupSubscriptions;
724
1971
  constructor(config) {
725
1972
  this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
726
1973
  this.arraysBaseUrl = config.arraysBaseUrl ?? DEFAULT_ARRAYS_BASE_URL;
@@ -745,8 +1992,11 @@ var AlvaClient = class {
745
1992
  get sdk() {
746
1993
  return this._sdk ??= new SdkDocsResource(this);
747
1994
  }
748
- get skills() {
749
- 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);
750
2000
  }
751
2001
  get comments() {
752
2002
  return this._comments ??= new CommentsResource(this);
@@ -772,6 +2022,9 @@ var AlvaClient = class {
772
2022
  get pushSubscriptions() {
773
2023
  return this._pushSubscriptions ??= new PushSubscriptionsResource(this);
774
2024
  }
2025
+ get channelGroupSubscriptions() {
2026
+ return this._channelGroupSubscriptions ??= new ChannelGroupSubscriptionsResource(this);
2027
+ }
775
2028
  _requireAuth() {
776
2029
  if (!this.viewer_token && !this.apiKey) {
777
2030
  throw new AlvaError(
@@ -808,6 +2061,9 @@ var AlvaClient = class {
808
2061
  if (options?.rawBody !== void 0) {
809
2062
  headers["Content-Type"] = "application/octet-stream";
810
2063
  fetchBody = options.rawBody;
2064
+ } else if (options?.jsonBody !== void 0) {
2065
+ headers["Content-Type"] = "application/json";
2066
+ fetchBody = options.jsonBody;
811
2067
  } else if (options?.body !== void 0) {
812
2068
  headers["Content-Type"] = "application/json";
813
2069
  fetchBody = JSON.stringify(options.body);
@@ -1127,11 +2383,168 @@ async function runPostConfigureHooks(client, deps) {
1127
2383
  }
1128
2384
  }
1129
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
+
1130
2543
  // src/cli/index.ts
1131
2544
  import * as fs from "fs";
1132
2545
  import * as os2 from "os";
1133
2546
  import * as fsPromises2 from "fs/promises";
1134
- var CLI_VERSION = true ? "0.4.2" : "dev";
2547
+ var CLI_VERSION = true ? "0.7.0-beta.0" : "dev";
1135
2548
  function isVersionOlderThan(a, b) {
1136
2549
  const parse = (v) => {
1137
2550
  if (!v) return null;
@@ -1161,9 +2574,11 @@ Commands:
1161
2574
  release Feed and playbook releases (feed, playbook-draft, playbook)
1162
2575
  secrets Secret management (create, list, get, update, delete)
1163
2576
  sdk SDK documentation (doc, partitions, partition-summary)
1164
- 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)
1165
2579
  comments Playbook comments (create, pin, unpin)
1166
2580
  push-subscriptions Personal push opt-in (subscribe-playbook, unsubscribe-playbook, subscribe-feed, unsubscribe-feed, list)
2581
+ channel Channel group operations (group-subscriptions context, list, subscribe, unsubscribe)
1167
2582
  remix Save playbook remix lineage
1168
2583
  trading Trading operations (accounts, portfolio, orders, subscriptions, equity-history, risk-rules, subscribe, unsubscribe, execute, update-risk-rules)
1169
2584
  auth Authentication (login)
@@ -1362,7 +2777,7 @@ Examples:
1362
2777
  deploy: `Usage: alva deploy <subcommand> [options]
1363
2778
 
1364
2779
  Manage scheduled cronjobs that run your scripts on a cron schedule.
1365
- Max 20 cronjobs per user. Min interval: 1 minute.
2780
+ Min interval: 1 minute.
1366
2781
 
1367
2782
  Subcommands:
1368
2783
  create Create a new cronjob
@@ -1372,6 +2787,8 @@ Subcommands:
1372
2787
  delete Delete a cronjob
1373
2788
  pause Pause a running cronjob
1374
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)
1375
2792
  runs List runs for a cronjob (cursor-paginated)
1376
2793
  run-logs Get stdout/stderr logs for a single cronjob run
1377
2794
 
@@ -1387,7 +2804,7 @@ List flags:
1387
2804
  --limit <n> Max results per page (default: 20)
1388
2805
  --cursor <cursor> Pagination cursor from previous response
1389
2806
 
1390
- Get/Update/Delete/Pause/Resume flags:
2807
+ Get/Update/Delete/Pause/Resume/Trigger flags:
1391
2808
  --id <id> Cronjob ID (required)
1392
2809
 
1393
2810
  Runs flags:
@@ -1421,7 +2838,17 @@ Examples:
1421
2838
  alva deploy delete --id 42
1422
2839
  alva deploy runs --id 42
1423
2840
  alva deploy runs --id 42 --first 10
1424
- 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)"`,
1425
2852
  release: `Usage: alva release <subcommand> [options]
1426
2853
 
1427
2854
  Publish feeds and playbooks to the Alva platform. The typical workflow:
@@ -1429,7 +2856,8 @@ Publish feeds and playbooks to the Alva platform. The typical workflow:
1429
2856
  2. Register feed (alva release feed)
1430
2857
  3. Create playbook draft (alva release playbook-draft)
1431
2858
  4. Write HTML to ALFS (alva fs write --path ~/playbooks/{name}/index.html)
1432
- 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")
1433
2861
 
1434
2862
  Subcommands:
1435
2863
  feed Register a feed after deploying its cronjob
@@ -1450,12 +2878,19 @@ Playbook-draft flags:
1450
2878
  --feeds <json> JSON array of {feed_id, feed_major?} (required)
1451
2879
  --description <text> Playbook description
1452
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.
1453
2883
 
1454
2884
  Playbook flags:
1455
2885
  --name <name> Playbook name, must already exist as draft (required)
1456
2886
  --version <version> Semantic version, e.g. "v1.0.0" (required)
1457
2887
  --feeds <json> JSON array of {feed_id, feed_major?} (required)
1458
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.
1459
2894
 
1460
2895
  Display name conventions:
1461
2896
  Format: [subject/theme] [analysis angle/strategy logic]
@@ -1467,7 +2902,8 @@ Examples:
1467
2902
  alva release feed --name btc-ema --version 1.0.0 --cronjob-id 42
1468
2903
  alva release feed --name nvda-insiders --version 1.0.0 --cronjob-id 43 --description "NVDA insider trading activity"
1469
2904
  alva release playbook-draft --name btc-dashboard --display-name "BTC Trend Dashboard" --feeds '[{"feed_id":100}]' --trading-symbols '["BTC"]'
1470
- 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"`,
1471
2907
  secrets: `Usage: alva secrets <subcommand> [options]
1472
2908
 
1473
2909
  Manage encrypted secrets for use in Alva scripts. Secrets are stored
@@ -1524,28 +2960,59 @@ Examples:
1524
2960
  alva sdk partition-summary --partition feed_widgets
1525
2961
  alva sdk doc --name "@arrays/data/widget-scrap/twitter:v1.0.0"
1526
2962
  alva sdk doc --name "@arrays/data/search/search-grok-x:v1.0.0"`,
1527
- skills: `Usage: alva skills <subcommand> [options]
2963
+ "data-skills": `Usage: alva data-skills <subcommand> [args]
1528
2964
 
1529
2965
  Browse the Arrays backend's data-skill documentation. These endpoints are
1530
2966
  public \u2014 no Alva credentials required.
1531
2967
 
1532
2968
  Subcommands:
1533
- list List all available data skills
1534
- summary Get the endpoints table for a skill (requires --name)
1535
- 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
1536
2972
 
1537
2973
  Flags:
1538
- --name <name> Skill name (required for summary and endpoint)
1539
- --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.
1540
2979
 
1541
2980
  Global override:
1542
2981
  --arrays-endpoint <url> Arrays backend URL (or ARRAYS_ENDPOINT env)
1543
2982
  Default: https://data-tools.prd.space.id
1544
2983
 
1545
2984
  Examples:
1546
- alva skills list
1547
- alva skills summary --name <skill>
1548
- 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`,
1549
3016
  comments: `Usage: alva comments <subcommand> [options]
1550
3017
 
1551
3018
  Manage comments on Alva playbooks. Supports top-level comments and threaded
@@ -1597,6 +3064,31 @@ Examples:
1597
3064
  alva push-subscriptions subscribe-feed --username alice --name btc-ema-cross
1598
3065
  alva push-subscriptions unsubscribe-feed --username alice --name btc-ema-cross
1599
3066
  alva push-subscriptions list --include-history`,
3067
+ channel: `Usage: alva channel group-subscriptions <subcommand> [options]
3068
+
3069
+ Manage push notifications delivered into the external group chat attached
3070
+ to a channel session. The group can subscribe to public feeds and playbooks.
3071
+ Subscribe/unsubscribe are idempotent no-ops unless the authenticated caller
3072
+ is that group's Alva admin.
3073
+
3074
+ Subcommands:
3075
+ context Show group admin status and current subscriptions
3076
+ list List active subscriptions for the group
3077
+ subscribe Subscribe the group to a public feed or playbook
3078
+ unsubscribe Unsubscribe the group from a feed or playbook
3079
+
3080
+ Common flags:
3081
+ --session-id <id> Channel session id for the group (required)
3082
+
3083
+ Subscribe/unsubscribe flags:
3084
+ --target-type <type> feed or playbook (required)
3085
+ --target-id <id> Numeric feed_id or playbook_id (required)
3086
+
3087
+ Examples:
3088
+ alva channel group-subscriptions context --session-id 123
3089
+ alva channel group-subscriptions list --session-id 123
3090
+ alva channel group-subscriptions subscribe --session-id 123 --target-type feed --target-id 8169
3091
+ alva channel group-subscriptions unsubscribe --session-id 123 --target-type playbook --target-id 42`,
1600
3092
  remix: `Usage: alva remix --child-username <u> --child-name <n> --parents <json>
1601
3093
 
1602
3094
  Record remix lineage when creating a playbook based on existing playbooks.
@@ -1610,22 +3102,26 @@ Required:
1610
3102
 
1611
3103
  Examples:
1612
3104
  alva remix --child-username bob --child-name my-btc --parents '[{"username":"alice","name":"btc-signals"}]'`,
1613
- 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>]
1614
3106
 
1615
3107
  Capture a screenshot of an Alva page and save it as PNG. Useful for verifying
1616
3108
  playbook rendering before release.
1617
3109
 
1618
3110
  Required:
1619
- --url <url> URL or path to capture (e.g. /playbook/alice/dashboard)
1620
- --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
1621
3113
 
1622
3114
  Optional:
1623
- --selector <css> CSS selector to capture a specific element
1624
- --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
1625
3120
 
1626
3121
  Examples:
1627
3122
  alva screenshot --url /playbook/alice/btc-dashboard --out dashboard.png
1628
- 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`,
1629
3125
  trading: `Usage: alva trading <subcommand> [options]
1630
3126
 
1631
3127
  Manage trading accounts, portfolios, orders, subscriptions, and risk rules.
@@ -1751,7 +3247,9 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
1751
3247
  "push-notify",
1752
3248
  "help",
1753
3249
  "execute-latest",
1754
- "dry-run"
3250
+ "dry-run",
3251
+ "json",
3252
+ "compress"
1755
3253
  ]);
1756
3254
  function parseFlags2(argv) {
1757
3255
  const flags = {};
@@ -1798,6 +3296,25 @@ function requireNumericFlag(flags, name, command) {
1798
3296
  }
1799
3297
  return n;
1800
3298
  }
3299
+ function requirePositiveIntegerStringFlag(flags, name, command) {
3300
+ const val = requireFlag(flags, name, command);
3301
+ if (!/^[1-9]\d*$/.test(val)) {
3302
+ const group = command.split(" ")[0];
3303
+ throw new CliUsageError(
3304
+ `--${name} must be a positive integer for '${command}', got '${val}'`,
3305
+ group
3306
+ );
3307
+ }
3308
+ return val;
3309
+ }
3310
+ function requireGroupSubscriptionTargetType(flags, command) {
3311
+ const val = requireFlag(flags, "target-type", command).trim().toLowerCase();
3312
+ if (val === "feed" || val === "playbook") return val;
3313
+ throw new CliUsageError(
3314
+ `--target-type must be feed or playbook for '${command}', got '${val}'`,
3315
+ command.split(" ")[0]
3316
+ );
3317
+ }
1801
3318
  function num(val) {
1802
3319
  if (val === void 0) return void 0;
1803
3320
  const n = Number(val);
@@ -2005,6 +3522,10 @@ async function dispatch(client, args, meta) {
2005
3522
  return client.deploy.resume({
2006
3523
  id: requireNumericFlag(flags, "id", "deploy resume")
2007
3524
  });
3525
+ case "trigger":
3526
+ return client.deploy.trigger({
3527
+ id: requireNumericFlag(flags, "id", "deploy trigger")
3528
+ });
2008
3529
  case "runs":
2009
3530
  return client.deploy.listRuns({
2010
3531
  cronjob_id: requireNumericFlag(flags, "id", "deploy runs"),
@@ -2048,7 +3569,8 @@ async function dispatch(client, args, meta) {
2048
3569
  feeds: jsonParse(
2049
3570
  requireFlag(flags, "feeds", "release playbook-draft")
2050
3571
  ),
2051
- 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"]
2052
3574
  });
2053
3575
  case "playbook":
2054
3576
  return client.release.playbook({
@@ -2057,7 +3579,8 @@ async function dispatch(client, args, meta) {
2057
3579
  feeds: jsonParse(
2058
3580
  requireFlag(flags, "feeds", "release playbook")
2059
3581
  ),
2060
- changelog: requireFlag(flags, "changelog", "release playbook")
3582
+ changelog: requireFlag(flags, "changelog", "release playbook"),
3583
+ readme_url: requireFlag(flags, "readme-url", "release playbook")
2061
3584
  });
2062
3585
  default:
2063
3586
  throw new CliUsageError(
@@ -2118,25 +3641,103 @@ async function dispatch(client, args, meta) {
2118
3641
  );
2119
3642
  }
2120
3643
  }
2121
- case "skills": {
3644
+ case "data-skills": {
2122
3645
  if (!subcommand)
2123
- 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;
2124
3651
  switch (subcommand) {
2125
- case "list":
2126
- return client.skills.list();
2127
- case "summary":
2128
- return client.skills.summary({
2129
- name: requireFlag(flags, "name", "skills summary")
2130
- });
2131
- case "endpoint":
2132
- return client.skills.endpoint({
2133
- name: requireFlag(flags, "name", "skills endpoint"),
2134
- 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"]
2135
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
+ }
2136
3737
  default:
2137
3738
  throw new CliUsageError(
2138
- `Unknown subcommand: skills ${subcommand}`,
2139
- "skills"
3739
+ `Unknown subcommand: skillhub ${subcommand}`,
3740
+ "skillhub"
2140
3741
  );
2141
3742
  }
2142
3743
  }
@@ -2240,6 +3841,80 @@ async function dispatch(client, args, meta) {
2240
3841
  );
2241
3842
  }
2242
3843
  }
3844
+ case "channel": {
3845
+ if (!subcommand || subcommand === "--help" || subcommand === "-h") {
3846
+ return { _help: true, text: COMMAND_HELP.channel };
3847
+ }
3848
+ if (subcommand !== "group-subscriptions") {
3849
+ throw new CliUsageError(
3850
+ `Unknown subcommand: channel ${subcommand}`,
3851
+ "channel"
3852
+ );
3853
+ }
3854
+ const leaf = args[2];
3855
+ if (!leaf || leaf === "--help" || leaf === "-h") {
3856
+ return { _help: true, text: COMMAND_HELP.channel };
3857
+ }
3858
+ const channelFlags = parseFlags2(args.slice(3));
3859
+ const commandName = `channel group-subscriptions ${leaf}`;
3860
+ switch (leaf) {
3861
+ case "context":
3862
+ return client.channelGroupSubscriptions.context({
3863
+ session_id: requirePositiveIntegerStringFlag(
3864
+ channelFlags,
3865
+ "session-id",
3866
+ commandName
3867
+ )
3868
+ });
3869
+ case "list":
3870
+ return client.channelGroupSubscriptions.list({
3871
+ session_id: requirePositiveIntegerStringFlag(
3872
+ channelFlags,
3873
+ "session-id",
3874
+ commandName
3875
+ )
3876
+ });
3877
+ case "subscribe":
3878
+ return client.channelGroupSubscriptions.subscribe({
3879
+ session_id: requirePositiveIntegerStringFlag(
3880
+ channelFlags,
3881
+ "session-id",
3882
+ commandName
3883
+ ),
3884
+ target_type: requireGroupSubscriptionTargetType(
3885
+ channelFlags,
3886
+ commandName
3887
+ ),
3888
+ target_id: requirePositiveIntegerStringFlag(
3889
+ channelFlags,
3890
+ "target-id",
3891
+ commandName
3892
+ )
3893
+ });
3894
+ case "unsubscribe":
3895
+ return client.channelGroupSubscriptions.unsubscribe({
3896
+ session_id: requirePositiveIntegerStringFlag(
3897
+ channelFlags,
3898
+ "session-id",
3899
+ commandName
3900
+ ),
3901
+ target_type: requireGroupSubscriptionTargetType(
3902
+ channelFlags,
3903
+ commandName
3904
+ ),
3905
+ target_id: requirePositiveIntegerStringFlag(
3906
+ channelFlags,
3907
+ "target-id",
3908
+ commandName
3909
+ )
3910
+ });
3911
+ default:
3912
+ throw new CliUsageError(
3913
+ `Unknown subcommand: channel group-subscriptions ${leaf}`,
3914
+ "channel"
3915
+ );
3916
+ }
3917
+ }
2243
3918
  case "remix":
2244
3919
  return client.remix.save({
2245
3920
  child: {
@@ -2274,10 +3949,15 @@ async function dispatch(client, args, meta) {
2274
3949
  }
2275
3950
  case "screenshot": {
2276
3951
  const outFile = requireFlag(flags, "out", "screenshot");
3952
+ const compressQuality = flags["compress-quality"];
3953
+ const compressMaxWidth = flags["compress-max-width"];
2277
3954
  const result = await client.screenshot.capture({
2278
3955
  url: requireFlag(flags, "url", "screenshot"),
2279
3956
  selector: flags["selector"],
2280
- 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
2281
3961
  });
2282
3962
  const buf = Buffer.from(result);
2283
3963
  if (buf.length === 0) {