@vm0/cli 5.7.0 → 5.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +612 -388
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2595,8 +2595,7 @@ var ApiClient = class {
2595
2595
  throw new Error("Not authenticated. Run: vm0 auth login");
2596
2596
  }
2597
2597
  const headers = {
2598
- Authorization: `Bearer ${token}`,
2599
- "Content-Type": "application/json"
2598
+ Authorization: `Bearer ${token}`
2600
2599
  };
2601
2600
  const bypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
2602
2601
  if (bypassSecret) {
@@ -2614,35 +2613,41 @@ var ApiClient = class {
2614
2613
  async getComposeByName(name, scope) {
2615
2614
  const baseUrl = await this.getBaseUrl();
2616
2615
  const headers = await this.getHeaders();
2617
- const params = new URLSearchParams({ name });
2618
- if (scope) {
2619
- params.append("scope", scope);
2620
- }
2621
- const response = await fetch(
2622
- `${baseUrl}/api/agent/composes?${params.toString()}`,
2623
- {
2624
- method: "GET",
2625
- headers
2616
+ const client = initClient(composesMainContract, {
2617
+ baseUrl,
2618
+ baseHeaders: headers,
2619
+ jsonQuery: true
2620
+ });
2621
+ const result = await client.getByName({
2622
+ query: {
2623
+ name,
2624
+ scope
2626
2625
  }
2627
- );
2628
- if (!response.ok) {
2629
- const error = await response.json();
2630
- throw new Error(error.error?.message || `Compose not found: ${name}`);
2626
+ });
2627
+ if (result.status === 200) {
2628
+ return result.body;
2631
2629
  }
2632
- return await response.json();
2630
+ const errorBody = result.body;
2631
+ const message = errorBody.error?.message || `Compose not found: ${name}`;
2632
+ throw new Error(message);
2633
2633
  }
2634
2634
  async getComposeById(id) {
2635
2635
  const baseUrl = await this.getBaseUrl();
2636
2636
  const headers = await this.getHeaders();
2637
- const response = await fetch(`${baseUrl}/api/agent/composes/${id}`, {
2638
- method: "GET",
2639
- headers
2637
+ const client = initClient(composesByIdContract, {
2638
+ baseUrl,
2639
+ baseHeaders: headers,
2640
+ jsonQuery: true
2640
2641
  });
2641
- if (!response.ok) {
2642
- const error = await response.json();
2643
- throw new Error(error.error?.message || `Compose not found: ${id}`);
2642
+ const result = await client.getById({
2643
+ params: { id }
2644
+ });
2645
+ if (result.status === 200) {
2646
+ return result.body;
2644
2647
  }
2645
- return await response.json();
2648
+ const errorBody = result.body;
2649
+ const message = errorBody.error?.message || `Compose not found: ${id}`;
2650
+ throw new Error(message);
2646
2651
  }
2647
2652
  /**
2648
2653
  * Resolve a version specifier to a full version ID
@@ -2651,33 +2656,41 @@ var ApiClient = class {
2651
2656
  async getComposeVersion(composeId, version) {
2652
2657
  const baseUrl = await this.getBaseUrl();
2653
2658
  const headers = await this.getHeaders();
2654
- const quotedVersion = JSON.stringify(version);
2655
- const response = await fetch(
2656
- `${baseUrl}/api/agent/composes/versions?composeId=${encodeURIComponent(composeId)}&version=${encodeURIComponent(quotedVersion)}`,
2657
- {
2658
- method: "GET",
2659
- headers
2659
+ const client = initClient(composesVersionsContract, {
2660
+ baseUrl,
2661
+ baseHeaders: headers,
2662
+ jsonQuery: true
2663
+ });
2664
+ const result = await client.resolveVersion({
2665
+ query: {
2666
+ composeId,
2667
+ version
2660
2668
  }
2661
- );
2662
- if (!response.ok) {
2663
- const error = await response.json();
2664
- throw new Error(error.error?.message || `Version not found: ${version}`);
2669
+ });
2670
+ if (result.status === 200) {
2671
+ return result.body;
2665
2672
  }
2666
- return await response.json();
2673
+ const errorBody = result.body;
2674
+ const message = errorBody.error?.message || `Version not found: ${version}`;
2675
+ throw new Error(message);
2667
2676
  }
2668
2677
  async createOrUpdateCompose(body) {
2669
2678
  const baseUrl = await this.getBaseUrl();
2670
2679
  const headers = await this.getHeaders();
2671
- const response = await fetch(`${baseUrl}/api/agent/composes`, {
2672
- method: "POST",
2673
- headers,
2674
- body: JSON.stringify(body)
2680
+ const client = initClient(composesMainContract, {
2681
+ baseUrl,
2682
+ baseHeaders: headers,
2683
+ jsonQuery: true
2675
2684
  });
2676
- if (!response.ok) {
2677
- const error = await response.json();
2678
- throw new Error(error.error?.message || "Failed to create compose");
2685
+ const result = await client.create({
2686
+ body
2687
+ });
2688
+ if (result.status === 200 || result.status === 201) {
2689
+ return result.body;
2679
2690
  }
2680
- return await response.json();
2691
+ const errorBody = result.body;
2692
+ const message = errorBody.error?.message || "Failed to create compose";
2693
+ throw new Error(message);
2681
2694
  }
2682
2695
  /**
2683
2696
  * Create a run with unified request format
@@ -2703,120 +2716,116 @@ var ApiClient = class {
2703
2716
  async getEvents(runId, options) {
2704
2717
  const baseUrl = await this.getBaseUrl();
2705
2718
  const headers = await this.getHeaders();
2706
- const since = options?.since ?? 0;
2707
- const limit = options?.limit ?? 100;
2708
- const response = await fetch(
2709
- `${baseUrl}/api/agent/runs/${runId}/events?since=${since}&limit=${limit}`,
2710
- {
2711
- method: "GET",
2712
- headers
2719
+ const client = initClient(runEventsContract, {
2720
+ baseUrl,
2721
+ baseHeaders: headers,
2722
+ jsonQuery: true
2723
+ });
2724
+ const result = await client.getEvents({
2725
+ params: { id: runId },
2726
+ query: {
2727
+ since: options?.since ?? 0,
2728
+ limit: options?.limit ?? 100
2713
2729
  }
2714
- );
2715
- if (!response.ok) {
2716
- const error = await response.json();
2717
- throw new Error(error.error?.message || "Failed to fetch events");
2730
+ });
2731
+ if (result.status === 200) {
2732
+ return result.body;
2718
2733
  }
2719
- return await response.json();
2734
+ const errorBody = result.body;
2735
+ const message = errorBody.error?.message || "Failed to fetch events";
2736
+ throw new Error(message);
2720
2737
  }
2721
2738
  async getSystemLog(runId, options) {
2722
2739
  const baseUrl = await this.getBaseUrl();
2723
2740
  const headers = await this.getHeaders();
2724
- const params = new URLSearchParams();
2725
- if (options?.since !== void 0) {
2726
- params.set("since", String(options.since));
2727
- }
2728
- if (options?.limit !== void 0) {
2729
- params.set("limit", String(options.limit));
2730
- }
2731
- if (options?.order !== void 0) {
2732
- params.set("order", options.order);
2733
- }
2734
- const queryString = params.toString();
2735
- const url = `${baseUrl}/api/agent/runs/${runId}/telemetry/system-log${queryString ? `?${queryString}` : ""}`;
2736
- const response = await fetch(url, {
2737
- method: "GET",
2738
- headers
2741
+ const client = initClient(runSystemLogContract, {
2742
+ baseUrl,
2743
+ baseHeaders: headers,
2744
+ jsonQuery: true
2739
2745
  });
2740
- if (!response.ok) {
2741
- const error = await response.json();
2742
- throw new Error(error.error?.message || "Failed to fetch system log");
2746
+ const result = await client.getSystemLog({
2747
+ params: { id: runId },
2748
+ query: {
2749
+ since: options?.since,
2750
+ limit: options?.limit,
2751
+ order: options?.order
2752
+ }
2753
+ });
2754
+ if (result.status === 200) {
2755
+ return result.body;
2743
2756
  }
2744
- return await response.json();
2757
+ const errorBody = result.body;
2758
+ const message = errorBody.error?.message || "Failed to fetch system log";
2759
+ throw new Error(message);
2745
2760
  }
2746
2761
  async getMetrics(runId, options) {
2747
2762
  const baseUrl = await this.getBaseUrl();
2748
2763
  const headers = await this.getHeaders();
2749
- const params = new URLSearchParams();
2750
- if (options?.since !== void 0) {
2751
- params.set("since", String(options.since));
2752
- }
2753
- if (options?.limit !== void 0) {
2754
- params.set("limit", String(options.limit));
2755
- }
2756
- if (options?.order !== void 0) {
2757
- params.set("order", options.order);
2758
- }
2759
- const queryString = params.toString();
2760
- const url = `${baseUrl}/api/agent/runs/${runId}/telemetry/metrics${queryString ? `?${queryString}` : ""}`;
2761
- const response = await fetch(url, {
2762
- method: "GET",
2763
- headers
2764
+ const client = initClient(runMetricsContract, {
2765
+ baseUrl,
2766
+ baseHeaders: headers,
2767
+ jsonQuery: true
2764
2768
  });
2765
- if (!response.ok) {
2766
- const error = await response.json();
2767
- throw new Error(error.error?.message || "Failed to fetch metrics");
2769
+ const result = await client.getMetrics({
2770
+ params: { id: runId },
2771
+ query: {
2772
+ since: options?.since,
2773
+ limit: options?.limit,
2774
+ order: options?.order
2775
+ }
2776
+ });
2777
+ if (result.status === 200) {
2778
+ return result.body;
2768
2779
  }
2769
- return await response.json();
2780
+ const errorBody = result.body;
2781
+ const message = errorBody.error?.message || "Failed to fetch metrics";
2782
+ throw new Error(message);
2770
2783
  }
2771
2784
  async getAgentEvents(runId, options) {
2772
2785
  const baseUrl = await this.getBaseUrl();
2773
2786
  const headers = await this.getHeaders();
2774
- const params = new URLSearchParams();
2775
- if (options?.since !== void 0) {
2776
- params.set("since", String(options.since));
2777
- }
2778
- if (options?.limit !== void 0) {
2779
- params.set("limit", String(options.limit));
2780
- }
2781
- if (options?.order !== void 0) {
2782
- params.set("order", options.order);
2783
- }
2784
- const queryString = params.toString();
2785
- const url = `${baseUrl}/api/agent/runs/${runId}/telemetry/agent${queryString ? `?${queryString}` : ""}`;
2786
- const response = await fetch(url, {
2787
- method: "GET",
2788
- headers
2787
+ const client = initClient(runAgentEventsContract, {
2788
+ baseUrl,
2789
+ baseHeaders: headers,
2790
+ jsonQuery: true
2789
2791
  });
2790
- if (!response.ok) {
2791
- const error = await response.json();
2792
- throw new Error(error.error?.message || "Failed to fetch agent events");
2792
+ const result = await client.getAgentEvents({
2793
+ params: { id: runId },
2794
+ query: {
2795
+ since: options?.since,
2796
+ limit: options?.limit,
2797
+ order: options?.order
2798
+ }
2799
+ });
2800
+ if (result.status === 200) {
2801
+ return result.body;
2793
2802
  }
2794
- return await response.json();
2803
+ const errorBody = result.body;
2804
+ const message = errorBody.error?.message || "Failed to fetch agent events";
2805
+ throw new Error(message);
2795
2806
  }
2796
2807
  async getNetworkLogs(runId, options) {
2797
2808
  const baseUrl = await this.getBaseUrl();
2798
2809
  const headers = await this.getHeaders();
2799
- const params = new URLSearchParams();
2800
- if (options?.since !== void 0) {
2801
- params.set("since", String(options.since));
2802
- }
2803
- if (options?.limit !== void 0) {
2804
- params.set("limit", String(options.limit));
2805
- }
2806
- if (options?.order !== void 0) {
2807
- params.set("order", options.order);
2808
- }
2809
- const queryString = params.toString();
2810
- const url = `${baseUrl}/api/agent/runs/${runId}/telemetry/network${queryString ? `?${queryString}` : ""}`;
2811
- const response = await fetch(url, {
2812
- method: "GET",
2813
- headers
2810
+ const client = initClient(runNetworkLogsContract, {
2811
+ baseUrl,
2812
+ baseHeaders: headers,
2813
+ jsonQuery: true
2814
2814
  });
2815
- if (!response.ok) {
2816
- const error = await response.json();
2817
- throw new Error(error.error?.message || "Failed to fetch network logs");
2815
+ const result = await client.getNetworkLogs({
2816
+ params: { id: runId },
2817
+ query: {
2818
+ since: options?.since,
2819
+ limit: options?.limit,
2820
+ order: options?.order
2821
+ }
2822
+ });
2823
+ if (result.status === 200) {
2824
+ return result.body;
2818
2825
  }
2819
- return await response.json();
2826
+ const errorBody = result.body;
2827
+ const message = errorBody.error?.message || "Failed to fetch network logs";
2828
+ throw new Error(message);
2820
2829
  }
2821
2830
  /**
2822
2831
  * Get current user's scope
@@ -2824,15 +2833,18 @@ var ApiClient = class {
2824
2833
  async getScope() {
2825
2834
  const baseUrl = await this.getBaseUrl();
2826
2835
  const headers = await this.getHeaders();
2827
- const response = await fetch(`${baseUrl}/api/scope`, {
2828
- method: "GET",
2829
- headers
2836
+ const client = initClient(scopeContract, {
2837
+ baseUrl,
2838
+ baseHeaders: headers,
2839
+ jsonQuery: true
2830
2840
  });
2831
- if (!response.ok) {
2832
- const error = await response.json();
2833
- throw new Error(error.error?.message || "Failed to get scope");
2841
+ const result = await client.get();
2842
+ if (result.status === 200) {
2843
+ return result.body;
2834
2844
  }
2835
- return await response.json();
2845
+ const errorBody = result.body;
2846
+ const message = errorBody.error?.message || "Failed to get scope";
2847
+ throw new Error(message);
2836
2848
  }
2837
2849
  /**
2838
2850
  * Create user's scope
@@ -2840,16 +2852,18 @@ var ApiClient = class {
2840
2852
  async createScope(body) {
2841
2853
  const baseUrl = await this.getBaseUrl();
2842
2854
  const headers = await this.getHeaders();
2843
- const response = await fetch(`${baseUrl}/api/scope`, {
2844
- method: "POST",
2845
- headers,
2846
- body: JSON.stringify(body)
2855
+ const client = initClient(scopeContract, {
2856
+ baseUrl,
2857
+ baseHeaders: headers,
2858
+ jsonQuery: true
2847
2859
  });
2848
- if (!response.ok) {
2849
- const error = await response.json();
2850
- throw new Error(error.error?.message || "Failed to create scope");
2860
+ const result = await client.create({ body });
2861
+ if (result.status === 201) {
2862
+ return result.body;
2851
2863
  }
2852
- return await response.json();
2864
+ const errorBody = result.body;
2865
+ const message = errorBody.error?.message || "Failed to create scope";
2866
+ throw new Error(message);
2853
2867
  }
2854
2868
  /**
2855
2869
  * Update user's scope slug
@@ -2857,16 +2871,18 @@ var ApiClient = class {
2857
2871
  async updateScope(body) {
2858
2872
  const baseUrl = await this.getBaseUrl();
2859
2873
  const headers = await this.getHeaders();
2860
- const response = await fetch(`${baseUrl}/api/scope`, {
2861
- method: "PUT",
2862
- headers,
2863
- body: JSON.stringify(body)
2874
+ const client = initClient(scopeContract, {
2875
+ baseUrl,
2876
+ baseHeaders: headers,
2877
+ jsonQuery: true
2864
2878
  });
2865
- if (!response.ok) {
2866
- const error = await response.json();
2867
- throw new Error(error.error?.message || "Failed to update scope");
2879
+ const result = await client.update({ body });
2880
+ if (result.status === 200) {
2881
+ return result.body;
2868
2882
  }
2869
- return await response.json();
2883
+ const errorBody = result.body;
2884
+ const message = errorBody.error?.message || "Failed to update scope";
2885
+ throw new Error(message);
2870
2886
  }
2871
2887
  /**
2872
2888
  * Get session by ID
@@ -2875,17 +2891,20 @@ var ApiClient = class {
2875
2891
  async getSession(sessionId) {
2876
2892
  const baseUrl = await this.getBaseUrl();
2877
2893
  const headers = await this.getHeaders();
2878
- const response = await fetch(`${baseUrl}/api/agent/sessions/${sessionId}`, {
2879
- method: "GET",
2880
- headers
2894
+ const client = initClient(sessionsByIdContract, {
2895
+ baseUrl,
2896
+ baseHeaders: headers,
2897
+ jsonQuery: true
2881
2898
  });
2882
- if (!response.ok) {
2883
- const error = await response.json();
2884
- throw new Error(
2885
- error.error?.message || `Session not found: ${sessionId}`
2886
- );
2899
+ const result = await client.getById({
2900
+ params: { id: sessionId }
2901
+ });
2902
+ if (result.status === 200) {
2903
+ return result.body;
2887
2904
  }
2888
- return await response.json();
2905
+ const errorBody = result.body;
2906
+ const message = errorBody.error?.message || `Session not found: ${sessionId}`;
2907
+ throw new Error(message);
2889
2908
  }
2890
2909
  /**
2891
2910
  * Get checkpoint by ID
@@ -2894,20 +2913,348 @@ var ApiClient = class {
2894
2913
  async getCheckpoint(checkpointId) {
2895
2914
  const baseUrl = await this.getBaseUrl();
2896
2915
  const headers = await this.getHeaders();
2897
- const response = await fetch(
2898
- `${baseUrl}/api/agent/checkpoints/${checkpointId}`,
2899
- {
2900
- method: "GET",
2901
- headers
2916
+ const client = initClient(checkpointsByIdContract, {
2917
+ baseUrl,
2918
+ baseHeaders: headers,
2919
+ jsonQuery: true
2920
+ });
2921
+ const result = await client.getById({
2922
+ params: { id: checkpointId }
2923
+ });
2924
+ if (result.status === 200) {
2925
+ return result.body;
2926
+ }
2927
+ const errorBody = result.body;
2928
+ const message = errorBody.error?.message || `Checkpoint not found: ${checkpointId}`;
2929
+ throw new Error(message);
2930
+ }
2931
+ /**
2932
+ * Prepare storage for direct S3 upload
2933
+ */
2934
+ async prepareStorage(body) {
2935
+ const baseUrl = await this.getBaseUrl();
2936
+ const headers = await this.getHeaders();
2937
+ const client = initClient(storagesPrepareContract, {
2938
+ baseUrl,
2939
+ baseHeaders: headers,
2940
+ jsonQuery: true
2941
+ });
2942
+ const result = await client.prepare({ body });
2943
+ if (result.status === 200) {
2944
+ return result.body;
2945
+ }
2946
+ const errorBody = result.body;
2947
+ const message = errorBody.error?.message || "Failed to prepare storage";
2948
+ throw new Error(message);
2949
+ }
2950
+ /**
2951
+ * Commit storage after S3 upload
2952
+ */
2953
+ async commitStorage(body) {
2954
+ const baseUrl = await this.getBaseUrl();
2955
+ const headers = await this.getHeaders();
2956
+ const client = initClient(storagesCommitContract, {
2957
+ baseUrl,
2958
+ baseHeaders: headers,
2959
+ jsonQuery: true
2960
+ });
2961
+ const result = await client.commit({ body });
2962
+ if (result.status === 200) {
2963
+ return result.body;
2964
+ }
2965
+ const errorBody = result.body;
2966
+ const message = errorBody.error?.message || "Failed to commit storage";
2967
+ throw new Error(message);
2968
+ }
2969
+ /**
2970
+ * Get download URL for storage (volume or artifact)
2971
+ */
2972
+ async getStorageDownload(query) {
2973
+ const baseUrl = await this.getBaseUrl();
2974
+ const headers = await this.getHeaders();
2975
+ const client = initClient(storagesDownloadContract, {
2976
+ baseUrl,
2977
+ baseHeaders: headers,
2978
+ jsonQuery: true
2979
+ });
2980
+ const result = await client.download({
2981
+ query: {
2982
+ name: query.name,
2983
+ type: query.type,
2984
+ version: query.version
2902
2985
  }
2903
- );
2904
- if (!response.ok) {
2905
- const error = await response.json();
2906
- throw new Error(
2907
- error.error?.message || `Checkpoint not found: ${checkpointId}`
2908
- );
2986
+ });
2987
+ if (result.status === 200) {
2988
+ return result.body;
2989
+ }
2990
+ const errorBody = result.body;
2991
+ const message = errorBody.error?.message || `Storage "${query.name}" not found`;
2992
+ throw new Error(message);
2993
+ }
2994
+ /**
2995
+ * List storages (volumes or artifacts)
2996
+ */
2997
+ async listStorages(query) {
2998
+ const baseUrl = await this.getBaseUrl();
2999
+ const headers = await this.getHeaders();
3000
+ const client = initClient(storagesListContract, {
3001
+ baseUrl,
3002
+ baseHeaders: headers,
3003
+ jsonQuery: true
3004
+ });
3005
+ const result = await client.list({ query });
3006
+ if (result.status === 200) {
3007
+ return result.body;
3008
+ }
3009
+ const errorBody = result.body;
3010
+ const message = errorBody.error?.message || `Failed to list ${query.type}s`;
3011
+ throw new Error(message);
3012
+ }
3013
+ /**
3014
+ * Deploy schedule (create or update)
3015
+ */
3016
+ async deploySchedule(body) {
3017
+ const baseUrl = await this.getBaseUrl();
3018
+ const headers = await this.getHeaders();
3019
+ const client = initClient(schedulesMainContract, {
3020
+ baseUrl,
3021
+ baseHeaders: headers,
3022
+ jsonQuery: true
3023
+ });
3024
+ const result = await client.deploy({ body });
3025
+ if (result.status === 200 || result.status === 201) {
3026
+ return result.body;
3027
+ }
3028
+ const errorBody = result.body;
3029
+ const message = errorBody.error?.message || "Failed to deploy schedule";
3030
+ throw new Error(message);
3031
+ }
3032
+ /**
3033
+ * List all schedules
3034
+ */
3035
+ async listSchedules() {
3036
+ const baseUrl = await this.getBaseUrl();
3037
+ const headers = await this.getHeaders();
3038
+ const client = initClient(schedulesMainContract, {
3039
+ baseUrl,
3040
+ baseHeaders: headers,
3041
+ jsonQuery: true
3042
+ });
3043
+ const result = await client.list();
3044
+ if (result.status === 200) {
3045
+ return result.body;
3046
+ }
3047
+ const errorBody = result.body;
3048
+ const message = errorBody.error?.message || "Failed to list schedules";
3049
+ throw new Error(message);
3050
+ }
3051
+ /**
3052
+ * Get schedule by name
3053
+ */
3054
+ async getScheduleByName(params) {
3055
+ const baseUrl = await this.getBaseUrl();
3056
+ const headers = await this.getHeaders();
3057
+ const client = initClient(schedulesByNameContract, {
3058
+ baseUrl,
3059
+ baseHeaders: headers,
3060
+ jsonQuery: true
3061
+ });
3062
+ const result = await client.getByName({
3063
+ params: { name: params.name },
3064
+ query: { composeId: params.composeId }
3065
+ });
3066
+ if (result.status === 200) {
3067
+ return result.body;
3068
+ }
3069
+ const errorBody = result.body;
3070
+ const message = errorBody.error?.message || `Schedule "${params.name}" not found`;
3071
+ throw new Error(message);
3072
+ }
3073
+ /**
3074
+ * Delete schedule by name
3075
+ */
3076
+ async deleteSchedule(params) {
3077
+ const baseUrl = await this.getBaseUrl();
3078
+ const headers = await this.getHeaders();
3079
+ const client = initClient(schedulesByNameContract, {
3080
+ baseUrl,
3081
+ baseHeaders: headers,
3082
+ jsonQuery: true
3083
+ });
3084
+ const result = await client.delete({
3085
+ params: { name: params.name },
3086
+ query: { composeId: params.composeId }
3087
+ });
3088
+ if (result.status === 204) {
3089
+ return;
3090
+ }
3091
+ const errorBody = result.body;
3092
+ const message = errorBody.error?.message || `Schedule "${params.name}" not found on remote`;
3093
+ throw new Error(message);
3094
+ }
3095
+ /**
3096
+ * Enable schedule
3097
+ */
3098
+ async enableSchedule(params) {
3099
+ const baseUrl = await this.getBaseUrl();
3100
+ const headers = await this.getHeaders();
3101
+ const client = initClient(schedulesEnableContract, {
3102
+ baseUrl,
3103
+ baseHeaders: headers,
3104
+ jsonQuery: true
3105
+ });
3106
+ const result = await client.enable({
3107
+ params: { name: params.name },
3108
+ body: { composeId: params.composeId }
3109
+ });
3110
+ if (result.status === 200) {
3111
+ return result.body;
3112
+ }
3113
+ const errorBody = result.body;
3114
+ const message = errorBody.error?.message || `Failed to enable schedule "${params.name}"`;
3115
+ throw new Error(message);
3116
+ }
3117
+ /**
3118
+ * Disable schedule
3119
+ */
3120
+ async disableSchedule(params) {
3121
+ const baseUrl = await this.getBaseUrl();
3122
+ const headers = await this.getHeaders();
3123
+ const client = initClient(schedulesEnableContract, {
3124
+ baseUrl,
3125
+ baseHeaders: headers,
3126
+ jsonQuery: true
3127
+ });
3128
+ const result = await client.disable({
3129
+ params: { name: params.name },
3130
+ body: { composeId: params.composeId }
3131
+ });
3132
+ if (result.status === 200) {
3133
+ return result.body;
3134
+ }
3135
+ const errorBody = result.body;
3136
+ const message = errorBody.error?.message || `Failed to disable schedule "${params.name}"`;
3137
+ throw new Error(message);
3138
+ }
3139
+ /**
3140
+ * List recent runs for a schedule
3141
+ */
3142
+ async listScheduleRuns(params) {
3143
+ const baseUrl = await this.getBaseUrl();
3144
+ const headers = await this.getHeaders();
3145
+ const client = initClient(scheduleRunsContract, {
3146
+ baseUrl,
3147
+ baseHeaders: headers,
3148
+ jsonQuery: true
3149
+ });
3150
+ const result = await client.listRuns({
3151
+ params: { name: params.name },
3152
+ query: {
3153
+ composeId: params.composeId,
3154
+ limit: params.limit ?? 5
3155
+ }
3156
+ });
3157
+ if (result.status === 200) {
3158
+ return result.body;
3159
+ }
3160
+ const errorBody = result.body;
3161
+ const message = errorBody.error?.message || `Failed to list runs for schedule "${params.name}"`;
3162
+ throw new Error(message);
3163
+ }
3164
+ /**
3165
+ * List public agents
3166
+ */
3167
+ async listPublicAgents(query) {
3168
+ const baseUrl = await this.getBaseUrl();
3169
+ const headers = await this.getHeaders();
3170
+ const client = initClient(publicAgentsListContract, {
3171
+ baseUrl,
3172
+ baseHeaders: headers,
3173
+ jsonQuery: true
3174
+ });
3175
+ const result = await client.list({ query: query ?? {} });
3176
+ if (result.status === 200) {
3177
+ return result.body;
2909
3178
  }
2910
- return await response.json();
3179
+ const errorBody = result.body;
3180
+ const message = errorBody.error?.message || "Failed to list agents";
3181
+ throw new Error(message);
3182
+ }
3183
+ /**
3184
+ * List public artifacts
3185
+ */
3186
+ async listPublicArtifacts(query) {
3187
+ const baseUrl = await this.getBaseUrl();
3188
+ const headers = await this.getHeaders();
3189
+ const client = initClient(publicArtifactsListContract, {
3190
+ baseUrl,
3191
+ baseHeaders: headers,
3192
+ jsonQuery: true
3193
+ });
3194
+ const result = await client.list({ query: query ?? {} });
3195
+ if (result.status === 200) {
3196
+ return result.body;
3197
+ }
3198
+ const errorBody = result.body;
3199
+ const message = errorBody.error?.message || "Failed to list artifacts";
3200
+ throw new Error(message);
3201
+ }
3202
+ /**
3203
+ * Get public artifact by ID
3204
+ */
3205
+ async getPublicArtifact(id) {
3206
+ const baseUrl = await this.getBaseUrl();
3207
+ const headers = await this.getHeaders();
3208
+ const client = initClient(publicArtifactByIdContract, {
3209
+ baseUrl,
3210
+ baseHeaders: headers,
3211
+ jsonQuery: true
3212
+ });
3213
+ const result = await client.get({ params: { id } });
3214
+ if (result.status === 200) {
3215
+ return result.body;
3216
+ }
3217
+ const errorBody = result.body;
3218
+ const message = errorBody.error?.message || `Artifact "${id}" not found`;
3219
+ throw new Error(message);
3220
+ }
3221
+ /**
3222
+ * List public volumes
3223
+ */
3224
+ async listPublicVolumes(query) {
3225
+ const baseUrl = await this.getBaseUrl();
3226
+ const headers = await this.getHeaders();
3227
+ const client = initClient(publicVolumesListContract, {
3228
+ baseUrl,
3229
+ baseHeaders: headers,
3230
+ jsonQuery: true
3231
+ });
3232
+ const result = await client.list({ query: query ?? {} });
3233
+ if (result.status === 200) {
3234
+ return result.body;
3235
+ }
3236
+ const errorBody = result.body;
3237
+ const message = errorBody.error?.message || "Failed to list volumes";
3238
+ throw new Error(message);
3239
+ }
3240
+ /**
3241
+ * Get public volume by ID
3242
+ */
3243
+ async getPublicVolume(id) {
3244
+ const baseUrl = await this.getBaseUrl();
3245
+ const headers = await this.getHeaders();
3246
+ const client = initClient(publicVolumeByIdContract, {
3247
+ baseUrl,
3248
+ baseHeaders: headers,
3249
+ jsonQuery: true
3250
+ });
3251
+ const result = await client.get({ params: { id } });
3252
+ if (result.status === 200) {
3253
+ return result.body;
3254
+ }
3255
+ const errorBody = result.body;
3256
+ const message = errorBody.error?.message || `Volume "${id}" not found`;
3257
+ throw new Error(message);
2911
3258
  }
2912
3259
  /**
2913
3260
  * Generic GET request
@@ -3549,34 +3896,20 @@ async function directUpload(storageName, storageType, cwd, options) {
3549
3896
  onProgress?.("Computing file hashes...");
3550
3897
  const fileEntries = await collectFileMetadata(cwd, files, onProgress);
3551
3898
  onProgress?.("Preparing upload...");
3552
- const prepareResponse = await apiClient.post("/api/storages/prepare", {
3553
- body: JSON.stringify({
3554
- storageName,
3555
- storageType,
3556
- files: fileEntries,
3557
- force
3558
- })
3899
+ const prepareResult = await apiClient.prepareStorage({
3900
+ storageName,
3901
+ storageType,
3902
+ files: fileEntries,
3903
+ force
3559
3904
  });
3560
- if (!prepareResponse.ok) {
3561
- const error = await prepareResponse.json();
3562
- throw new Error(error.error?.message || "Prepare failed");
3563
- }
3564
- const prepareResult = await prepareResponse.json();
3565
3905
  if (prepareResult.existing) {
3566
3906
  onProgress?.("Version exists, updating HEAD...");
3567
- const commitResponse2 = await apiClient.post("/api/storages/commit", {
3568
- body: JSON.stringify({
3569
- storageName,
3570
- storageType,
3571
- versionId: prepareResult.versionId,
3572
- files: fileEntries
3573
- })
3907
+ const commitResult2 = await apiClient.commitStorage({
3908
+ storageName,
3909
+ storageType,
3910
+ versionId: prepareResult.versionId,
3911
+ files: fileEntries
3574
3912
  });
3575
- if (!commitResponse2.ok) {
3576
- const error = await commitResponse2.json();
3577
- throw new Error(error.error?.message || "Commit failed");
3578
- }
3579
- const commitResult2 = await commitResponse2.json();
3580
3913
  return {
3581
3914
  versionId: commitResult2.versionId,
3582
3915
  size: commitResult2.size,
@@ -3609,19 +3942,12 @@ async function directUpload(storageName, storageType, cwd, options) {
3609
3942
  "application/json"
3610
3943
  );
3611
3944
  onProgress?.("Committing...");
3612
- const commitResponse = await apiClient.post("/api/storages/commit", {
3613
- body: JSON.stringify({
3614
- storageName,
3615
- storageType,
3616
- versionId: prepareResult.versionId,
3617
- files: fileEntries
3618
- })
3945
+ const commitResult = await apiClient.commitStorage({
3946
+ storageName,
3947
+ storageType,
3948
+ versionId: prepareResult.versionId,
3949
+ files: fileEntries
3619
3950
  });
3620
- if (!commitResponse.ok) {
3621
- const error = await commitResponse.json();
3622
- throw new Error(error.error?.message || "Commit failed");
3623
- }
3624
- const commitResult = await commitResponse.json();
3625
3951
  return {
3626
3952
  versionId: commitResult.versionId,
3627
3953
  size: commitResult.size,
@@ -5415,39 +5741,21 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
5415
5741
  console.log(`Pulling volume: ${config.name}`);
5416
5742
  }
5417
5743
  console.log(chalk9.dim("Getting download URL..."));
5418
- let url = `/api/storages/download?name=${encodeURIComponent(config.name)}&type=volume`;
5419
- if (versionId) {
5420
- const quotedVersion = JSON.stringify(versionId);
5421
- url += `&version=${encodeURIComponent(quotedVersion)}`;
5422
- }
5423
- const response = await apiClient.get(url);
5424
- if (!response.ok) {
5425
- if (response.status === 404) {
5426
- console.error(chalk9.red(`\u2717 Volume "${config.name}" not found`));
5427
- console.error(
5428
- chalk9.dim(
5429
- " Make sure the volume name is correct in .vm0/storage.yaml"
5430
- )
5431
- );
5432
- console.error(
5433
- chalk9.dim(" Or push the volume first with: vm0 volume push")
5434
- );
5435
- } else {
5436
- const error = await response.json();
5437
- throw new Error(error.error?.message || "Download failed");
5438
- }
5439
- process.exit(1);
5440
- }
5441
- const downloadInfo = await response.json();
5442
- if (downloadInfo.empty) {
5744
+ const downloadInfo = await apiClient.getStorageDownload({
5745
+ name: config.name,
5746
+ type: "volume",
5747
+ version: versionId
5748
+ });
5749
+ if ("empty" in downloadInfo) {
5443
5750
  await handleEmptyStorageResponse(cwd);
5444
5751
  return;
5445
5752
  }
5446
- if (!downloadInfo.url) {
5753
+ const downloadUrl = downloadInfo.url;
5754
+ if (!downloadUrl) {
5447
5755
  throw new Error("No download URL returned");
5448
5756
  }
5449
5757
  console.log(chalk9.dim("Downloading from S3..."));
5450
- const s3Response = await fetch(downloadInfo.url);
5758
+ const s3Response = await fetch(downloadUrl);
5451
5759
  if (!s3Response.ok) {
5452
5760
  throw new Error(`S3 download failed: ${s3Response.status}`);
5453
5761
  }
@@ -5519,21 +5827,12 @@ var statusCommand = new Command6().name("status").description("Show status of cl
5519
5827
  process.exit(1);
5520
5828
  }
5521
5829
  console.log(`Checking volume: ${config.name}`);
5522
- const url = `/api/storages/download?name=${encodeURIComponent(config.name)}&type=volume`;
5523
- const response = await apiClient.get(url);
5524
- if (!response.ok) {
5525
- if (response.status === 404) {
5526
- console.error(chalk10.red("\u2717 Not found on remote"));
5527
- console.error(chalk10.dim(" Run: vm0 volume push"));
5528
- } else {
5529
- const error = await response.json();
5530
- throw new Error(error.error?.message || "Status check failed");
5531
- }
5532
- process.exit(1);
5533
- }
5534
- const info = await response.json();
5830
+ const info = await apiClient.getStorageDownload({
5831
+ name: config.name,
5832
+ type: "volume"
5833
+ });
5535
5834
  const shortVersion = info.versionId.slice(0, 8);
5536
- if (info.empty) {
5835
+ if ("empty" in info) {
5537
5836
  console.log(chalk10.green("\u2713 Found (empty)"));
5538
5837
  console.log(chalk10.dim(` Version: ${shortVersion}`));
5539
5838
  } else {
@@ -5543,12 +5842,17 @@ var statusCommand = new Command6().name("status").description("Show status of cl
5543
5842
  console.log(chalk10.dim(` Size: ${formatBytes4(info.size)}`));
5544
5843
  }
5545
5844
  } catch (error) {
5546
- console.error(chalk10.red("\u2717 Status check failed"));
5547
- if (error instanceof Error) {
5548
- if (error.message.includes("Not authenticated")) {
5549
- console.error(chalk10.dim(" Run: vm0 auth login"));
5550
- } else {
5551
- console.error(chalk10.dim(` ${error.message}`));
5845
+ if (error instanceof Error && error.message.includes("not found")) {
5846
+ console.error(chalk10.red("\u2717 Not found on remote"));
5847
+ console.error(chalk10.dim(" Run: vm0 volume push"));
5848
+ } else {
5849
+ console.error(chalk10.red("\u2717 Status check failed"));
5850
+ if (error instanceof Error) {
5851
+ if (error.message.includes("Not authenticated")) {
5852
+ console.error(chalk10.dim(" Run: vm0 auth login"));
5853
+ } else {
5854
+ console.error(chalk10.dim(` ${error.message}`));
5855
+ }
5552
5856
  }
5553
5857
  }
5554
5858
  process.exit(1);
@@ -5560,13 +5864,7 @@ import { Command as Command7 } from "commander";
5560
5864
  import chalk11 from "chalk";
5561
5865
  var listCommand = new Command7().name("list").alias("ls").description("List all remote volumes").action(async () => {
5562
5866
  try {
5563
- const url = "/api/storages/list?type=volume";
5564
- const response = await apiClient.get(url);
5565
- if (!response.ok) {
5566
- const error = await response.json();
5567
- throw new Error(error.error?.message || "List failed");
5568
- }
5569
- const items = await response.json();
5867
+ const items = await apiClient.listStorages({ type: "volume" });
5570
5868
  if (items.length === 0) {
5571
5869
  console.log(chalk11.dim("No volumes found"));
5572
5870
  console.log(
@@ -5628,25 +5926,14 @@ async function cloneStorage(name, type, destination, options = {}) {
5628
5926
  throw new Error(`Directory "${destination}" already exists`);
5629
5927
  }
5630
5928
  console.log(chalk12.dim(`Checking remote ${typeLabel}...`));
5631
- let url = `/api/storages/download?name=${encodeURIComponent(name)}&type=${type}`;
5632
- if (options.version) {
5633
- const quotedVersion = JSON.stringify(options.version);
5634
- url += `&version=${encodeURIComponent(quotedVersion)}`;
5635
- }
5636
- const response = await apiClient.get(url);
5637
- if (!response.ok) {
5638
- if (response.status === 404) {
5639
- throw new Error(
5640
- `${typeLabel.charAt(0).toUpperCase() + typeLabel.slice(1)} "${name}" not found`
5641
- );
5642
- }
5643
- const error = await response.json();
5644
- throw new Error(error.error?.message || "Clone failed");
5645
- }
5646
- const downloadInfo = await response.json();
5929
+ const downloadInfo = await apiClient.getStorageDownload({
5930
+ name,
5931
+ type,
5932
+ version: options.version
5933
+ });
5647
5934
  console.log(chalk12.dim(`Creating directory: ${destination}/`));
5648
5935
  await fs7.promises.mkdir(destination, { recursive: true });
5649
- if (downloadInfo.empty) {
5936
+ if ("empty" in downloadInfo) {
5650
5937
  await writeStorageConfig(name, destination, type);
5651
5938
  console.log(chalk12.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
5652
5939
  console.log(chalk12.dim(`\u2713 Initialized .vm0/storage.yaml`));
@@ -5657,11 +5944,12 @@ async function cloneStorage(name, type, destination, options = {}) {
5657
5944
  versionId: downloadInfo.versionId
5658
5945
  };
5659
5946
  }
5660
- if (!downloadInfo.url) {
5947
+ const downloadUrl = downloadInfo.url;
5948
+ if (!downloadUrl) {
5661
5949
  throw new Error("No download URL returned");
5662
5950
  }
5663
5951
  console.log(chalk12.dim("Downloading from S3..."));
5664
- const s3Response = await fetch(downloadInfo.url);
5952
+ const s3Response = await fetch(downloadUrl);
5665
5953
  if (!s3Response.ok) {
5666
5954
  await fs7.promises.rm(destination, { recursive: true, force: true });
5667
5955
  throw new Error(`S3 download failed: ${s3Response.status}`);
@@ -5910,39 +6198,21 @@ var pullCommand2 = new Command12().name("pull").description("Pull cloud artifact
5910
6198
  console.log(`Pulling artifact: ${config.name}`);
5911
6199
  }
5912
6200
  console.log(chalk16.dim("Getting download URL..."));
5913
- let url = `/api/storages/download?name=${encodeURIComponent(config.name)}&type=artifact`;
5914
- if (versionId) {
5915
- const quotedVersion = JSON.stringify(versionId);
5916
- url += `&version=${encodeURIComponent(quotedVersion)}`;
5917
- }
5918
- const response = await apiClient.get(url);
5919
- if (!response.ok) {
5920
- if (response.status === 404) {
5921
- console.error(chalk16.red(`\u2717 Artifact "${config.name}" not found`));
5922
- console.error(
5923
- chalk16.dim(
5924
- " Make sure the artifact name is correct in .vm0/storage.yaml"
5925
- )
5926
- );
5927
- console.error(
5928
- chalk16.dim(" Or push the artifact first with: vm0 artifact push")
5929
- );
5930
- } else {
5931
- const error = await response.json();
5932
- throw new Error(error.error?.message || "Download failed");
5933
- }
5934
- process.exit(1);
5935
- }
5936
- const downloadInfo = await response.json();
5937
- if (downloadInfo.empty) {
6201
+ const downloadInfo = await apiClient.getStorageDownload({
6202
+ name: config.name,
6203
+ type: "artifact",
6204
+ version: versionId
6205
+ });
6206
+ if ("empty" in downloadInfo) {
5938
6207
  await handleEmptyStorageResponse(cwd);
5939
6208
  return;
5940
6209
  }
5941
- if (!downloadInfo.url) {
6210
+ const downloadUrl = downloadInfo.url;
6211
+ if (!downloadUrl) {
5942
6212
  throw new Error("No download URL returned");
5943
6213
  }
5944
6214
  console.log(chalk16.dim("Downloading from S3..."));
5945
- const s3Response = await fetch(downloadInfo.url);
6215
+ const s3Response = await fetch(downloadUrl);
5946
6216
  if (!s3Response.ok) {
5947
6217
  throw new Error(`S3 download failed: ${s3Response.status}`);
5948
6218
  }
@@ -6010,21 +6280,12 @@ var statusCommand2 = new Command13().name("status").description("Show status of
6010
6280
  process.exit(1);
6011
6281
  }
6012
6282
  console.log(`Checking artifact: ${config.name}`);
6013
- const url = `/api/storages/download?name=${encodeURIComponent(config.name)}&type=artifact`;
6014
- const response = await apiClient.get(url);
6015
- if (!response.ok) {
6016
- if (response.status === 404) {
6017
- console.error(chalk17.red("\u2717 Not found on remote"));
6018
- console.error(chalk17.dim(" Run: vm0 artifact push"));
6019
- } else {
6020
- const error = await response.json();
6021
- throw new Error(error.error?.message || "Status check failed");
6022
- }
6023
- process.exit(1);
6024
- }
6025
- const info = await response.json();
6283
+ const info = await apiClient.getStorageDownload({
6284
+ name: config.name,
6285
+ type: "artifact"
6286
+ });
6026
6287
  const shortVersion = info.versionId.slice(0, 8);
6027
- if (info.empty) {
6288
+ if ("empty" in info) {
6028
6289
  console.log(chalk17.green("\u2713 Found (empty)"));
6029
6290
  console.log(chalk17.dim(` Version: ${shortVersion}`));
6030
6291
  } else {
@@ -6034,9 +6295,14 @@ var statusCommand2 = new Command13().name("status").description("Show status of
6034
6295
  console.log(chalk17.dim(` Size: ${formatBytes7(info.size)}`));
6035
6296
  }
6036
6297
  } catch (error) {
6037
- console.error(chalk17.red("\u2717 Status check failed"));
6038
- if (error instanceof Error) {
6039
- console.error(chalk17.dim(` ${error.message}`));
6298
+ if (error instanceof Error && error.message.includes("not found")) {
6299
+ console.error(chalk17.red("\u2717 Not found on remote"));
6300
+ console.error(chalk17.dim(" Run: vm0 artifact push"));
6301
+ } else {
6302
+ console.error(chalk17.red("\u2717 Status check failed"));
6303
+ if (error instanceof Error) {
6304
+ console.error(chalk17.dim(` ${error.message}`));
6305
+ }
6040
6306
  }
6041
6307
  process.exit(1);
6042
6308
  }
@@ -6047,13 +6313,7 @@ import { Command as Command14 } from "commander";
6047
6313
  import chalk18 from "chalk";
6048
6314
  var listCommand2 = new Command14().name("list").alias("ls").description("List all remote artifacts").action(async () => {
6049
6315
  try {
6050
- const url = "/api/storages/list?type=artifact";
6051
- const response = await apiClient.get(url);
6052
- if (!response.ok) {
6053
- const error = await response.json();
6054
- throw new Error(error.error?.message || "List failed");
6055
- }
6056
- const items = await response.json();
6316
+ const items = await apiClient.listStorages({ type: "artifact" });
6057
6317
  if (items.length === 0) {
6058
6318
  console.log(chalk18.dim("No artifacts found"));
6059
6319
  console.log(
@@ -6472,7 +6732,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
6472
6732
  }
6473
6733
  var cookCmd = new Command17().name("cook").description("One-click agent preparation and execution from vm0.yaml");
6474
6734
  cookCmd.argument("[prompt]", "Prompt for the agent").option("-y, --yes", "Skip confirmation prompts").action(async (prompt, options) => {
6475
- const shouldExit = await checkAndUpgrade("5.7.0", prompt);
6735
+ const shouldExit = await checkAndUpgrade("5.7.2", prompt);
6476
6736
  if (shouldExit) {
6477
6737
  process.exit(0);
6478
6738
  }
@@ -8660,14 +8920,7 @@ var deployCommand = new Command28().name("deploy").description("Deploy a schedul
8660
8920
  artifactVersion: schedule.run.artifactVersion,
8661
8921
  volumeVersions: schedule.run.volumeVersions
8662
8922
  };
8663
- const response = await apiClient.post("/api/agent/schedules", {
8664
- body: JSON.stringify(body)
8665
- });
8666
- if (!response.ok) {
8667
- const error = await response.json();
8668
- throw new Error(error.error?.message || "Deploy failed");
8669
- }
8670
- const deployResult = await response.json();
8923
+ const deployResult = await apiClient.deploySchedule(body);
8671
8924
  if (deployResult.created) {
8672
8925
  console.log(
8673
8926
  chalk30.green(`\u2713 Created schedule ${chalk30.cyan(scheduleName)}`)
@@ -8714,12 +8967,7 @@ import { Command as Command29 } from "commander";
8714
8967
  import chalk31 from "chalk";
8715
8968
  var listCommand4 = new Command29().name("list").alias("ls").description("List all schedules").action(async () => {
8716
8969
  try {
8717
- const response = await apiClient.get("/api/agent/schedules");
8718
- if (!response.ok) {
8719
- const error = await response.json();
8720
- throw new Error(error.error?.message || "List failed");
8721
- }
8722
- const result = await response.json();
8970
+ const result = await apiClient.listSchedules();
8723
8971
  if (result.schedules.length === 0) {
8724
8972
  console.log(chalk31.dim("No schedules found"));
8725
8973
  console.log(
@@ -8855,14 +9103,7 @@ var statusCommand4 = new Command30().name("status").description("Show detailed s
8855
9103
  console.error(chalk32.dim(" Make sure the agent is pushed first"));
8856
9104
  process.exit(1);
8857
9105
  }
8858
- const response = await apiClient.get(
8859
- `/api/agent/schedules/${encodeURIComponent(name)}?composeId=${encodeURIComponent(composeId)}`
8860
- );
8861
- if (!response.ok) {
8862
- const error = await response.json();
8863
- throw new Error(error.error?.message || "Failed to get schedule");
8864
- }
8865
- const schedule = await response.json();
9106
+ const schedule = await apiClient.getScheduleByName({ name, composeId });
8866
9107
  console.log();
8867
9108
  console.log(`Schedule: ${chalk32.cyan(schedule.name)}`);
8868
9109
  console.log(chalk32.dim("\u2501".repeat(50)));
@@ -8905,11 +9146,12 @@ var statusCommand4 = new Command30().name("status").description("Show detailed s
8905
9146
  100
8906
9147
  );
8907
9148
  if (limit > 0) {
8908
- const runsResponse = await apiClient.get(
8909
- `/api/agent/schedules/${encodeURIComponent(name)}/runs?composeId=${encodeURIComponent(composeId)}&limit=${limit}`
8910
- );
8911
- if (runsResponse.ok) {
8912
- const { runs } = await runsResponse.json();
9149
+ try {
9150
+ const { runs } = await apiClient.listScheduleRuns({
9151
+ name,
9152
+ composeId,
9153
+ limit
9154
+ });
8913
9155
  if (runs.length > 0) {
8914
9156
  console.log();
8915
9157
  console.log("Recent Runs:");
@@ -8925,7 +9167,7 @@ var statusCommand4 = new Command30().name("status").description("Show detailed s
8925
9167
  console.log(`${id} ${status} ${created}`);
8926
9168
  }
8927
9169
  }
8928
- } else {
9170
+ } catch {
8929
9171
  console.log();
8930
9172
  console.log(chalk32.dim("Recent Runs: (unable to fetch)"));
8931
9173
  }
@@ -8968,8 +9210,8 @@ var deleteCommand = new Command31().name("delete").alias("rm").description("Dele
8968
9210
  "[name]",
8969
9211
  "Schedule name (auto-detected from schedule.yaml if omitted)"
8970
9212
  ).option("-f, --force", "Skip confirmation prompt").action(async (nameArg, options) => {
9213
+ let name = nameArg;
8971
9214
  try {
8972
- let name = nameArg;
8973
9215
  if (!name) {
8974
9216
  const scheduleResult = loadScheduleName();
8975
9217
  if (scheduleResult.error) {
@@ -9014,19 +9256,15 @@ var deleteCommand = new Command31().name("delete").alias("rm").description("Dele
9014
9256
  return;
9015
9257
  }
9016
9258
  }
9017
- const response = await apiClient.delete(
9018
- `/api/agent/schedules/${encodeURIComponent(name)}?composeId=${encodeURIComponent(composeId)}`
9019
- );
9020
- if (!response.ok) {
9021
- const error = await response.json();
9022
- throw new Error(error.error?.message || "Delete failed");
9023
- }
9259
+ await apiClient.deleteSchedule({ name, composeId });
9024
9260
  console.log(chalk33.green(`\u2713 Deleted schedule ${chalk33.cyan(name)}`));
9025
9261
  } catch (error) {
9026
9262
  console.error(chalk33.red("\u2717 Failed to delete schedule"));
9027
9263
  if (error instanceof Error) {
9028
9264
  if (error.message.includes("Not authenticated")) {
9029
9265
  console.error(chalk33.dim(" Run: vm0 auth login"));
9266
+ } else if (error.message.toLowerCase().includes("not found")) {
9267
+ console.error(chalk33.dim(` Schedule "${name}" not found`));
9030
9268
  } else {
9031
9269
  console.error(chalk33.dim(` ${error.message}`));
9032
9270
  }
@@ -9081,14 +9319,7 @@ var enableCommand = new Command32().name("enable").description("Enable a schedul
9081
9319
  console.error(chalk34.dim(" Make sure the agent is pushed first"));
9082
9320
  process.exit(1);
9083
9321
  }
9084
- const response = await apiClient.post(
9085
- `/api/agent/schedules/${encodeURIComponent(name)}/enable`,
9086
- { body: JSON.stringify({ composeId }) }
9087
- );
9088
- if (!response.ok) {
9089
- const error = await response.json();
9090
- throw new Error(error.error?.message || "Enable failed");
9091
- }
9322
+ await apiClient.enableSchedule({ name, composeId });
9092
9323
  console.log(chalk34.green(`\u2713 Enabled schedule ${chalk34.cyan(name)}`));
9093
9324
  } catch (error) {
9094
9325
  console.error(chalk34.red("\u2717 Failed to enable schedule"));
@@ -9149,14 +9380,7 @@ var disableCommand = new Command33().name("disable").description("Disable a sche
9149
9380
  console.error(chalk35.dim(" Make sure the agent is pushed first"));
9150
9381
  process.exit(1);
9151
9382
  }
9152
- const response = await apiClient.post(
9153
- `/api/agent/schedules/${encodeURIComponent(name)}/disable`,
9154
- { body: JSON.stringify({ composeId }) }
9155
- );
9156
- if (!response.ok) {
9157
- const error = await response.json();
9158
- throw new Error(error.error?.message || "Disable failed");
9159
- }
9383
+ await apiClient.disableSchedule({ name, composeId });
9160
9384
  console.log(chalk35.green(`\u2713 Disabled schedule ${chalk35.cyan(name)}`));
9161
9385
  } catch (error) {
9162
9386
  console.error(chalk35.red("\u2717 Failed to disable schedule"));
@@ -9176,7 +9400,7 @@ var scheduleCommand = new Command34().name("schedule").description("Manage agent
9176
9400
 
9177
9401
  // src/index.ts
9178
9402
  var program = new Command35();
9179
- program.name("vm0").description("VM0 CLI - A modern build tool").version("5.7.0");
9403
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("5.7.2");
9180
9404
  program.command("info").description("Display environment information").action(async () => {
9181
9405
  console.log(chalk36.bold("System Information:"));
9182
9406
  console.log(`Node Version: ${process.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "5.7.0",
3
+ "version": "5.7.2",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",