@vm0/cli 5.1.3 → 5.2.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/index.js +771 -38
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,8 +6,8 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { Command as
|
|
10
|
-
import
|
|
9
|
+
import { Command as Command34 } from "commander";
|
|
10
|
+
import chalk35 from "chalk";
|
|
11
11
|
|
|
12
12
|
// src/lib/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -2760,7 +2760,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
|
|
|
2760
2760
|
function isValidBase64URL(data) {
|
|
2761
2761
|
if (!base64url.test(data))
|
|
2762
2762
|
return false;
|
|
2763
|
-
const base643 = data.replace(/[-_]/g, (
|
|
2763
|
+
const base643 = data.replace(/[-_]/g, (c16) => c16 === "-" ? "+" : "/");
|
|
2764
2764
|
const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "=");
|
|
2765
2765
|
return isValidBase64(padded);
|
|
2766
2766
|
}
|
|
@@ -11672,9 +11672,9 @@ var ZodDate = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
|
|
|
11672
11672
|
ZodType.init(inst, def);
|
|
11673
11673
|
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
11674
11674
|
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
11675
|
-
const
|
|
11676
|
-
inst.minDate =
|
|
11677
|
-
inst.maxDate =
|
|
11675
|
+
const c16 = inst._zod.bag;
|
|
11676
|
+
inst.minDate = c16.minimum ? new Date(c16.minimum) : null;
|
|
11677
|
+
inst.maxDate = c16.maximum ? new Date(c16.maximum) : null;
|
|
11678
11678
|
});
|
|
11679
11679
|
function date3(params) {
|
|
11680
11680
|
return _date(ZodDate, params);
|
|
@@ -13679,6 +13679,203 @@ var checkpointsByIdContract = c10.router({
|
|
|
13679
13679
|
}
|
|
13680
13680
|
});
|
|
13681
13681
|
|
|
13682
|
+
// ../../packages/core/src/contracts/schedules.ts
|
|
13683
|
+
var c11 = initContract();
|
|
13684
|
+
var scheduleTriggerSchema = external_exports.object({
|
|
13685
|
+
cron: external_exports.string().optional(),
|
|
13686
|
+
at: external_exports.string().optional(),
|
|
13687
|
+
timezone: external_exports.string().default("UTC")
|
|
13688
|
+
}).refine((data) => data.cron && !data.at || !data.cron && data.at, {
|
|
13689
|
+
message: "Exactly one of 'cron' or 'at' must be specified"
|
|
13690
|
+
});
|
|
13691
|
+
var scheduleRunConfigSchema = external_exports.object({
|
|
13692
|
+
agent: external_exports.string().min(1, "Agent reference required"),
|
|
13693
|
+
prompt: external_exports.string().min(1, "Prompt required"),
|
|
13694
|
+
vars: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
13695
|
+
secrets: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
13696
|
+
artifactName: external_exports.string().optional(),
|
|
13697
|
+
artifactVersion: external_exports.string().optional(),
|
|
13698
|
+
volumeVersions: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
13699
|
+
});
|
|
13700
|
+
var scheduleDefinitionSchema = external_exports.object({
|
|
13701
|
+
on: scheduleTriggerSchema,
|
|
13702
|
+
run: scheduleRunConfigSchema
|
|
13703
|
+
});
|
|
13704
|
+
var scheduleYamlSchema = external_exports.object({
|
|
13705
|
+
version: external_exports.literal("1.0"),
|
|
13706
|
+
schedules: external_exports.record(external_exports.string(), scheduleDefinitionSchema)
|
|
13707
|
+
});
|
|
13708
|
+
var deployScheduleRequestSchema = external_exports.object({
|
|
13709
|
+
name: external_exports.string().min(1).max(64, "Schedule name max 64 chars"),
|
|
13710
|
+
cronExpression: external_exports.string().optional(),
|
|
13711
|
+
atTime: external_exports.string().optional(),
|
|
13712
|
+
timezone: external_exports.string().default("UTC"),
|
|
13713
|
+
prompt: external_exports.string().min(1, "Prompt required"),
|
|
13714
|
+
vars: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
13715
|
+
secrets: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
13716
|
+
artifactName: external_exports.string().optional(),
|
|
13717
|
+
artifactVersion: external_exports.string().optional(),
|
|
13718
|
+
volumeVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
13719
|
+
// Resolved agent compose ID (CLI resolves scope/name:version → composeId)
|
|
13720
|
+
composeId: external_exports.string().uuid("Invalid compose ID")
|
|
13721
|
+
}).refine(
|
|
13722
|
+
(data) => data.cronExpression && !data.atTime || !data.cronExpression && data.atTime,
|
|
13723
|
+
{
|
|
13724
|
+
message: "Exactly one of 'cronExpression' or 'atTime' must be specified"
|
|
13725
|
+
}
|
|
13726
|
+
);
|
|
13727
|
+
var scheduleResponseSchema = external_exports.object({
|
|
13728
|
+
id: external_exports.string().uuid(),
|
|
13729
|
+
composeId: external_exports.string().uuid(),
|
|
13730
|
+
composeName: external_exports.string(),
|
|
13731
|
+
scopeSlug: external_exports.string(),
|
|
13732
|
+
name: external_exports.string(),
|
|
13733
|
+
cronExpression: external_exports.string().nullable(),
|
|
13734
|
+
atTime: external_exports.string().nullable(),
|
|
13735
|
+
timezone: external_exports.string(),
|
|
13736
|
+
prompt: external_exports.string(),
|
|
13737
|
+
vars: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
|
|
13738
|
+
// Secret names only (values are never returned)
|
|
13739
|
+
secretNames: external_exports.array(external_exports.string()).nullable(),
|
|
13740
|
+
artifactName: external_exports.string().nullable(),
|
|
13741
|
+
artifactVersion: external_exports.string().nullable(),
|
|
13742
|
+
volumeVersions: external_exports.record(external_exports.string(), external_exports.string()).nullable(),
|
|
13743
|
+
enabled: external_exports.boolean(),
|
|
13744
|
+
nextRunAt: external_exports.string().nullable(),
|
|
13745
|
+
lastRunAt: external_exports.string().nullable(),
|
|
13746
|
+
lastRunId: external_exports.string().nullable(),
|
|
13747
|
+
createdAt: external_exports.string(),
|
|
13748
|
+
updatedAt: external_exports.string()
|
|
13749
|
+
});
|
|
13750
|
+
var scheduleListResponseSchema = external_exports.object({
|
|
13751
|
+
schedules: external_exports.array(scheduleResponseSchema)
|
|
13752
|
+
});
|
|
13753
|
+
var deployScheduleResponseSchema = external_exports.object({
|
|
13754
|
+
schedule: scheduleResponseSchema,
|
|
13755
|
+
created: external_exports.boolean()
|
|
13756
|
+
// true if created, false if updated
|
|
13757
|
+
});
|
|
13758
|
+
var schedulesMainContract = c11.router({
|
|
13759
|
+
/**
|
|
13760
|
+
* POST /api/agent/schedules
|
|
13761
|
+
* Deploy (create or update) a schedule
|
|
13762
|
+
*/
|
|
13763
|
+
deploy: {
|
|
13764
|
+
method: "POST",
|
|
13765
|
+
path: "/api/agent/schedules",
|
|
13766
|
+
body: deployScheduleRequestSchema,
|
|
13767
|
+
responses: {
|
|
13768
|
+
200: deployScheduleResponseSchema,
|
|
13769
|
+
// Updated
|
|
13770
|
+
201: deployScheduleResponseSchema,
|
|
13771
|
+
// Created
|
|
13772
|
+
400: apiErrorSchema,
|
|
13773
|
+
401: apiErrorSchema,
|
|
13774
|
+
404: apiErrorSchema,
|
|
13775
|
+
409: apiErrorSchema
|
|
13776
|
+
// Schedule limit reached
|
|
13777
|
+
},
|
|
13778
|
+
summary: "Deploy schedule (create or update)"
|
|
13779
|
+
},
|
|
13780
|
+
/**
|
|
13781
|
+
* GET /api/agent/schedules
|
|
13782
|
+
* List all schedules for the user
|
|
13783
|
+
*/
|
|
13784
|
+
list: {
|
|
13785
|
+
method: "GET",
|
|
13786
|
+
path: "/api/agent/schedules",
|
|
13787
|
+
responses: {
|
|
13788
|
+
200: scheduleListResponseSchema,
|
|
13789
|
+
401: apiErrorSchema
|
|
13790
|
+
},
|
|
13791
|
+
summary: "List all schedules"
|
|
13792
|
+
}
|
|
13793
|
+
});
|
|
13794
|
+
var schedulesByNameContract = c11.router({
|
|
13795
|
+
/**
|
|
13796
|
+
* GET /api/agent/schedules/:name
|
|
13797
|
+
* Get schedule by name
|
|
13798
|
+
*/
|
|
13799
|
+
getByName: {
|
|
13800
|
+
method: "GET",
|
|
13801
|
+
path: "/api/agent/schedules/:name",
|
|
13802
|
+
pathParams: external_exports.object({
|
|
13803
|
+
name: external_exports.string().min(1, "Schedule name required")
|
|
13804
|
+
}),
|
|
13805
|
+
query: external_exports.object({
|
|
13806
|
+
composeId: external_exports.string().uuid("Compose ID required")
|
|
13807
|
+
}),
|
|
13808
|
+
responses: {
|
|
13809
|
+
200: scheduleResponseSchema,
|
|
13810
|
+
401: apiErrorSchema,
|
|
13811
|
+
404: apiErrorSchema
|
|
13812
|
+
},
|
|
13813
|
+
summary: "Get schedule by name"
|
|
13814
|
+
},
|
|
13815
|
+
/**
|
|
13816
|
+
* DELETE /api/agent/schedules/:name
|
|
13817
|
+
* Delete schedule by name
|
|
13818
|
+
*/
|
|
13819
|
+
delete: {
|
|
13820
|
+
method: "DELETE",
|
|
13821
|
+
path: "/api/agent/schedules/:name",
|
|
13822
|
+
pathParams: external_exports.object({
|
|
13823
|
+
name: external_exports.string().min(1, "Schedule name required")
|
|
13824
|
+
}),
|
|
13825
|
+
query: external_exports.object({
|
|
13826
|
+
composeId: external_exports.string().uuid("Compose ID required")
|
|
13827
|
+
}),
|
|
13828
|
+
responses: {
|
|
13829
|
+
204: external_exports.undefined(),
|
|
13830
|
+
401: apiErrorSchema,
|
|
13831
|
+
404: apiErrorSchema
|
|
13832
|
+
},
|
|
13833
|
+
summary: "Delete schedule"
|
|
13834
|
+
}
|
|
13835
|
+
});
|
|
13836
|
+
var schedulesEnableContract = c11.router({
|
|
13837
|
+
/**
|
|
13838
|
+
* POST /api/agent/schedules/:name/enable
|
|
13839
|
+
* Enable a disabled schedule
|
|
13840
|
+
*/
|
|
13841
|
+
enable: {
|
|
13842
|
+
method: "POST",
|
|
13843
|
+
path: "/api/agent/schedules/:name/enable",
|
|
13844
|
+
pathParams: external_exports.object({
|
|
13845
|
+
name: external_exports.string().min(1, "Schedule name required")
|
|
13846
|
+
}),
|
|
13847
|
+
body: external_exports.object({
|
|
13848
|
+
composeId: external_exports.string().uuid("Compose ID required")
|
|
13849
|
+
}),
|
|
13850
|
+
responses: {
|
|
13851
|
+
200: scheduleResponseSchema,
|
|
13852
|
+
401: apiErrorSchema,
|
|
13853
|
+
404: apiErrorSchema
|
|
13854
|
+
},
|
|
13855
|
+
summary: "Enable schedule"
|
|
13856
|
+
},
|
|
13857
|
+
/**
|
|
13858
|
+
* POST /api/agent/schedules/:name/disable
|
|
13859
|
+
* Disable an enabled schedule
|
|
13860
|
+
*/
|
|
13861
|
+
disable: {
|
|
13862
|
+
method: "POST",
|
|
13863
|
+
path: "/api/agent/schedules/:name/disable",
|
|
13864
|
+
pathParams: external_exports.object({
|
|
13865
|
+
name: external_exports.string().min(1, "Schedule name required")
|
|
13866
|
+
}),
|
|
13867
|
+
body: external_exports.object({
|
|
13868
|
+
composeId: external_exports.string().uuid("Compose ID required")
|
|
13869
|
+
}),
|
|
13870
|
+
responses: {
|
|
13871
|
+
200: scheduleResponseSchema,
|
|
13872
|
+
401: apiErrorSchema,
|
|
13873
|
+
404: apiErrorSchema
|
|
13874
|
+
},
|
|
13875
|
+
summary: "Disable schedule"
|
|
13876
|
+
}
|
|
13877
|
+
});
|
|
13878
|
+
|
|
13682
13879
|
// ../../packages/core/src/contracts/public/common.ts
|
|
13683
13880
|
var publicApiErrorTypeSchema = external_exports.enum([
|
|
13684
13881
|
"api_error",
|
|
@@ -13719,7 +13916,7 @@ var requestIdSchema = external_exports.string().uuid();
|
|
|
13719
13916
|
var timestampSchema = external_exports.string().datetime();
|
|
13720
13917
|
|
|
13721
13918
|
// ../../packages/core/src/contracts/public/agents.ts
|
|
13722
|
-
var
|
|
13919
|
+
var c12 = initContract();
|
|
13723
13920
|
var publicAgentSchema = external_exports.object({
|
|
13724
13921
|
id: external_exports.string(),
|
|
13725
13922
|
name: external_exports.string(),
|
|
@@ -13739,7 +13936,7 @@ var paginatedAgentVersionsSchema = createPaginatedResponseSchema(agentVersionSch
|
|
|
13739
13936
|
var agentListQuerySchema = listQuerySchema.extend({
|
|
13740
13937
|
name: external_exports.string().optional()
|
|
13741
13938
|
});
|
|
13742
|
-
var publicAgentsListContract =
|
|
13939
|
+
var publicAgentsListContract = c12.router({
|
|
13743
13940
|
list: {
|
|
13744
13941
|
method: "GET",
|
|
13745
13942
|
path: "/v1/agents",
|
|
@@ -13753,7 +13950,7 @@ var publicAgentsListContract = c11.router({
|
|
|
13753
13950
|
description: "List all agents in the current scope with pagination. Use the `name` query parameter to filter by agent name."
|
|
13754
13951
|
}
|
|
13755
13952
|
});
|
|
13756
|
-
var publicAgentByIdContract =
|
|
13953
|
+
var publicAgentByIdContract = c12.router({
|
|
13757
13954
|
get: {
|
|
13758
13955
|
method: "GET",
|
|
13759
13956
|
path: "/v1/agents/:id",
|
|
@@ -13770,7 +13967,7 @@ var publicAgentByIdContract = c11.router({
|
|
|
13770
13967
|
description: "Get agent details by ID"
|
|
13771
13968
|
}
|
|
13772
13969
|
});
|
|
13773
|
-
var publicAgentVersionsContract =
|
|
13970
|
+
var publicAgentVersionsContract = c12.router({
|
|
13774
13971
|
list: {
|
|
13775
13972
|
method: "GET",
|
|
13776
13973
|
path: "/v1/agents/:id/versions",
|
|
@@ -13790,7 +13987,7 @@ var publicAgentVersionsContract = c11.router({
|
|
|
13790
13987
|
});
|
|
13791
13988
|
|
|
13792
13989
|
// ../../packages/core/src/contracts/public/runs.ts
|
|
13793
|
-
var
|
|
13990
|
+
var c13 = initContract();
|
|
13794
13991
|
var publicRunStatusSchema = external_exports.enum([
|
|
13795
13992
|
"pending",
|
|
13796
13993
|
"running",
|
|
@@ -13848,7 +14045,7 @@ var runListQuerySchema = listQuerySchema.extend({
|
|
|
13848
14045
|
status: publicRunStatusSchema.optional(),
|
|
13849
14046
|
since: timestampSchema.optional()
|
|
13850
14047
|
});
|
|
13851
|
-
var publicRunsListContract =
|
|
14048
|
+
var publicRunsListContract = c13.router({
|
|
13852
14049
|
list: {
|
|
13853
14050
|
method: "GET",
|
|
13854
14051
|
path: "/v1/runs",
|
|
@@ -13877,7 +14074,7 @@ var publicRunsListContract = c12.router({
|
|
|
13877
14074
|
description: "Create and execute a new agent run. Returns 202 Accepted as runs execute asynchronously."
|
|
13878
14075
|
}
|
|
13879
14076
|
});
|
|
13880
|
-
var publicRunByIdContract =
|
|
14077
|
+
var publicRunByIdContract = c13.router({
|
|
13881
14078
|
get: {
|
|
13882
14079
|
method: "GET",
|
|
13883
14080
|
path: "/v1/runs/:id",
|
|
@@ -13894,7 +14091,7 @@ var publicRunByIdContract = c12.router({
|
|
|
13894
14091
|
description: "Get run details by ID"
|
|
13895
14092
|
}
|
|
13896
14093
|
});
|
|
13897
|
-
var publicRunCancelContract =
|
|
14094
|
+
var publicRunCancelContract = c13.router({
|
|
13898
14095
|
cancel: {
|
|
13899
14096
|
method: "POST",
|
|
13900
14097
|
path: "/v1/runs/:id/cancel",
|
|
@@ -13928,7 +14125,7 @@ var logsQuerySchema = listQuerySchema.extend({
|
|
|
13928
14125
|
until: timestampSchema.optional(),
|
|
13929
14126
|
order: external_exports.enum(["asc", "desc"]).default("asc")
|
|
13930
14127
|
});
|
|
13931
|
-
var publicRunLogsContract =
|
|
14128
|
+
var publicRunLogsContract = c13.router({
|
|
13932
14129
|
getLogs: {
|
|
13933
14130
|
method: "GET",
|
|
13934
14131
|
path: "/v1/runs/:id/logs",
|
|
@@ -13963,7 +14160,7 @@ var metricsResponseSchema2 = external_exports.object({
|
|
|
13963
14160
|
data: external_exports.array(metricPointSchema),
|
|
13964
14161
|
summary: metricsSummarySchema
|
|
13965
14162
|
});
|
|
13966
|
-
var publicRunMetricsContract =
|
|
14163
|
+
var publicRunMetricsContract = c13.router({
|
|
13967
14164
|
getMetrics: {
|
|
13968
14165
|
method: "GET",
|
|
13969
14166
|
path: "/v1/runs/:id/metrics",
|
|
@@ -13998,7 +14195,7 @@ var sseEventSchema = external_exports.object({
|
|
|
13998
14195
|
id: external_exports.string().optional()
|
|
13999
14196
|
// For Last-Event-ID reconnection
|
|
14000
14197
|
});
|
|
14001
|
-
var publicRunEventsContract =
|
|
14198
|
+
var publicRunEventsContract = c13.router({
|
|
14002
14199
|
streamEvents: {
|
|
14003
14200
|
method: "GET",
|
|
14004
14201
|
path: "/v1/runs/:id/events",
|
|
@@ -14022,7 +14219,7 @@ var publicRunEventsContract = c12.router({
|
|
|
14022
14219
|
});
|
|
14023
14220
|
|
|
14024
14221
|
// ../../packages/core/src/contracts/public/artifacts.ts
|
|
14025
|
-
var
|
|
14222
|
+
var c14 = initContract();
|
|
14026
14223
|
var publicArtifactSchema = external_exports.object({
|
|
14027
14224
|
id: external_exports.string(),
|
|
14028
14225
|
name: external_exports.string(),
|
|
@@ -14052,7 +14249,7 @@ var paginatedArtifactsSchema = createPaginatedResponseSchema(publicArtifactSchem
|
|
|
14052
14249
|
var paginatedArtifactVersionsSchema = createPaginatedResponseSchema(
|
|
14053
14250
|
artifactVersionSchema
|
|
14054
14251
|
);
|
|
14055
|
-
var publicArtifactsListContract =
|
|
14252
|
+
var publicArtifactsListContract = c14.router({
|
|
14056
14253
|
list: {
|
|
14057
14254
|
method: "GET",
|
|
14058
14255
|
path: "/v1/artifacts",
|
|
@@ -14066,7 +14263,7 @@ var publicArtifactsListContract = c13.router({
|
|
|
14066
14263
|
description: "List all artifacts in the current scope with pagination"
|
|
14067
14264
|
}
|
|
14068
14265
|
});
|
|
14069
|
-
var publicArtifactByIdContract =
|
|
14266
|
+
var publicArtifactByIdContract = c14.router({
|
|
14070
14267
|
get: {
|
|
14071
14268
|
method: "GET",
|
|
14072
14269
|
path: "/v1/artifacts/:id",
|
|
@@ -14083,7 +14280,7 @@ var publicArtifactByIdContract = c13.router({
|
|
|
14083
14280
|
description: "Get artifact details by ID"
|
|
14084
14281
|
}
|
|
14085
14282
|
});
|
|
14086
|
-
var publicArtifactVersionsContract =
|
|
14283
|
+
var publicArtifactVersionsContract = c14.router({
|
|
14087
14284
|
list: {
|
|
14088
14285
|
method: "GET",
|
|
14089
14286
|
path: "/v1/artifacts/:id/versions",
|
|
@@ -14101,7 +14298,7 @@ var publicArtifactVersionsContract = c13.router({
|
|
|
14101
14298
|
description: "List all versions of an artifact with pagination"
|
|
14102
14299
|
}
|
|
14103
14300
|
});
|
|
14104
|
-
var publicArtifactDownloadContract =
|
|
14301
|
+
var publicArtifactDownloadContract = c14.router({
|
|
14105
14302
|
download: {
|
|
14106
14303
|
method: "GET",
|
|
14107
14304
|
path: "/v1/artifacts/:id/download",
|
|
@@ -14125,7 +14322,7 @@ var publicArtifactDownloadContract = c13.router({
|
|
|
14125
14322
|
});
|
|
14126
14323
|
|
|
14127
14324
|
// ../../packages/core/src/contracts/public/volumes.ts
|
|
14128
|
-
var
|
|
14325
|
+
var c15 = initContract();
|
|
14129
14326
|
var publicVolumeSchema = external_exports.object({
|
|
14130
14327
|
id: external_exports.string(),
|
|
14131
14328
|
name: external_exports.string(),
|
|
@@ -14153,7 +14350,7 @@ var publicVolumeDetailSchema = publicVolumeSchema.extend({
|
|
|
14153
14350
|
});
|
|
14154
14351
|
var paginatedVolumesSchema = createPaginatedResponseSchema(publicVolumeSchema);
|
|
14155
14352
|
var paginatedVolumeVersionsSchema = createPaginatedResponseSchema(volumeVersionSchema);
|
|
14156
|
-
var publicVolumesListContract =
|
|
14353
|
+
var publicVolumesListContract = c15.router({
|
|
14157
14354
|
list: {
|
|
14158
14355
|
method: "GET",
|
|
14159
14356
|
path: "/v1/volumes",
|
|
@@ -14167,7 +14364,7 @@ var publicVolumesListContract = c14.router({
|
|
|
14167
14364
|
description: "List all volumes in the current scope with pagination"
|
|
14168
14365
|
}
|
|
14169
14366
|
});
|
|
14170
|
-
var publicVolumeByIdContract =
|
|
14367
|
+
var publicVolumeByIdContract = c15.router({
|
|
14171
14368
|
get: {
|
|
14172
14369
|
method: "GET",
|
|
14173
14370
|
path: "/v1/volumes/:id",
|
|
@@ -14184,7 +14381,7 @@ var publicVolumeByIdContract = c14.router({
|
|
|
14184
14381
|
description: "Get volume details by ID"
|
|
14185
14382
|
}
|
|
14186
14383
|
});
|
|
14187
|
-
var publicVolumeVersionsContract =
|
|
14384
|
+
var publicVolumeVersionsContract = c15.router({
|
|
14188
14385
|
list: {
|
|
14189
14386
|
method: "GET",
|
|
14190
14387
|
path: "/v1/volumes/:id/versions",
|
|
@@ -14202,7 +14399,7 @@ var publicVolumeVersionsContract = c14.router({
|
|
|
14202
14399
|
description: "List all versions of a volume with pagination"
|
|
14203
14400
|
}
|
|
14204
14401
|
});
|
|
14205
|
-
var publicVolumeDownloadContract =
|
|
14402
|
+
var publicVolumeDownloadContract = c15.router({
|
|
14206
14403
|
download: {
|
|
14207
14404
|
method: "GET",
|
|
14208
14405
|
path: "/v1/volumes/:id/download",
|
|
@@ -16061,9 +16258,9 @@ var CodexEventParser = class {
|
|
|
16061
16258
|
}
|
|
16062
16259
|
}
|
|
16063
16260
|
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
16064
|
-
const changes = item.changes.map((
|
|
16065
|
-
const action =
|
|
16066
|
-
return `${action}: ${
|
|
16261
|
+
const changes = item.changes.map((c16) => {
|
|
16262
|
+
const action = c16.kind === "add" ? "Created" : c16.kind === "modify" ? "Modified" : "Deleted";
|
|
16263
|
+
return `${action}: ${c16.path}`;
|
|
16067
16264
|
}).join("\n");
|
|
16068
16265
|
return {
|
|
16069
16266
|
type: "text",
|
|
@@ -16404,9 +16601,9 @@ var CodexEventRenderer = class {
|
|
|
16404
16601
|
return;
|
|
16405
16602
|
}
|
|
16406
16603
|
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
16407
|
-
const summary = item.changes.map((
|
|
16408
|
-
const icon =
|
|
16409
|
-
return `${icon}${
|
|
16604
|
+
const summary = item.changes.map((c16) => {
|
|
16605
|
+
const icon = c16.kind === "add" ? "+" : c16.kind === "delete" ? "-" : "~";
|
|
16606
|
+
return `${icon}${c16.path}`;
|
|
16410
16607
|
}).join(", ");
|
|
16411
16608
|
console.log(chalk4.green("[files]") + ` ${summary}`);
|
|
16412
16609
|
return;
|
|
@@ -18298,7 +18495,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
18298
18495
|
}
|
|
18299
18496
|
var cookCmd = new Command17().name("cook").description("One-click agent preparation and execution from vm0.yaml");
|
|
18300
18497
|
cookCmd.argument("[prompt]", "Prompt for the agent").option("-y, --yes", "Skip confirmation prompts").action(async (prompt, options) => {
|
|
18301
|
-
const shouldExit = await checkAndUpgrade("5.
|
|
18498
|
+
const shouldExit = await checkAndUpgrade("5.2.0", prompt);
|
|
18302
18499
|
if (shouldExit) {
|
|
18303
18500
|
process.exit(0);
|
|
18304
18501
|
}
|
|
@@ -18982,7 +19179,7 @@ var listCommand3 = new Command22().name("list").alias("ls").description("List al
|
|
|
18982
19179
|
);
|
|
18983
19180
|
return;
|
|
18984
19181
|
}
|
|
18985
|
-
const nameWidth = Math.max(4, ...data.composes.map((
|
|
19182
|
+
const nameWidth = Math.max(4, ...data.composes.map((c16) => c16.name.length));
|
|
18986
19183
|
const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
|
|
18987
19184
|
" "
|
|
18988
19185
|
);
|
|
@@ -19861,11 +20058,546 @@ var setupGithubCommand = new Command26().name("setup-github").description("Initi
|
|
|
19861
20058
|
}
|
|
19862
20059
|
);
|
|
19863
20060
|
|
|
20061
|
+
// src/commands/schedule/index.ts
|
|
20062
|
+
import { Command as Command33 } from "commander";
|
|
20063
|
+
|
|
20064
|
+
// src/commands/schedule/deploy.ts
|
|
20065
|
+
import { Command as Command27 } from "commander";
|
|
20066
|
+
import chalk29 from "chalk";
|
|
20067
|
+
import { existsSync as existsSync11, readFileSync as readFileSync2 } from "fs";
|
|
20068
|
+
import { parse as parseYaml6 } from "yaml";
|
|
20069
|
+
function expandEnvVars(value) {
|
|
20070
|
+
return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
20071
|
+
const envValue = process.env[varName];
|
|
20072
|
+
if (envValue === void 0) {
|
|
20073
|
+
console.warn(
|
|
20074
|
+
chalk29.yellow(` Warning: Environment variable ${varName} not set`)
|
|
20075
|
+
);
|
|
20076
|
+
return match;
|
|
20077
|
+
}
|
|
20078
|
+
return envValue;
|
|
20079
|
+
});
|
|
20080
|
+
}
|
|
20081
|
+
function expandEnvVarsInObject(obj) {
|
|
20082
|
+
if (!obj) return void 0;
|
|
20083
|
+
const result = {};
|
|
20084
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
20085
|
+
result[key] = expandEnvVars(value);
|
|
20086
|
+
}
|
|
20087
|
+
return result;
|
|
20088
|
+
}
|
|
20089
|
+
var deployCommand = new Command27().name("deploy").description("Deploy a schedule from schedule.yaml (create or update)").argument("[file]", "Path to schedule.yaml", "schedule.yaml").action(async (file2) => {
|
|
20090
|
+
try {
|
|
20091
|
+
if (!existsSync11(file2)) {
|
|
20092
|
+
console.error(chalk29.red(`\u2717 File not found: ${file2}`));
|
|
20093
|
+
console.error(chalk29.dim(" Create a schedule.yaml file first"));
|
|
20094
|
+
process.exit(1);
|
|
20095
|
+
}
|
|
20096
|
+
const content = readFileSync2(file2, "utf-8");
|
|
20097
|
+
let parsed;
|
|
20098
|
+
try {
|
|
20099
|
+
parsed = parseYaml6(content);
|
|
20100
|
+
} catch (err) {
|
|
20101
|
+
console.error(chalk29.red("\u2717 Invalid YAML syntax"));
|
|
20102
|
+
if (err instanceof Error) {
|
|
20103
|
+
console.error(chalk29.dim(` ${err.message}`));
|
|
20104
|
+
}
|
|
20105
|
+
process.exit(1);
|
|
20106
|
+
}
|
|
20107
|
+
const result = scheduleYamlSchema.safeParse(parsed);
|
|
20108
|
+
if (!result.success) {
|
|
20109
|
+
console.error(chalk29.red("\u2717 Invalid schedule.yaml format"));
|
|
20110
|
+
for (const issue2 of result.error.issues) {
|
|
20111
|
+
console.error(
|
|
20112
|
+
chalk29.dim(` ${issue2.path.join(".")}: ${issue2.message}`)
|
|
20113
|
+
);
|
|
20114
|
+
}
|
|
20115
|
+
process.exit(1);
|
|
20116
|
+
}
|
|
20117
|
+
const scheduleYaml = result.data;
|
|
20118
|
+
const scheduleEntries = Object.entries(scheduleYaml.schedules);
|
|
20119
|
+
if (scheduleEntries.length === 0) {
|
|
20120
|
+
console.error(chalk29.red("\u2717 No schedules defined in file"));
|
|
20121
|
+
process.exit(1);
|
|
20122
|
+
}
|
|
20123
|
+
if (scheduleEntries.length > 1) {
|
|
20124
|
+
console.error(
|
|
20125
|
+
chalk29.red("\u2717 Multiple schedules per file not supported yet")
|
|
20126
|
+
);
|
|
20127
|
+
console.error(chalk29.dim(" Please use one schedule per file"));
|
|
20128
|
+
process.exit(1);
|
|
20129
|
+
}
|
|
20130
|
+
const [scheduleName, schedule] = scheduleEntries[0];
|
|
20131
|
+
console.log(`Deploying schedule ${chalk29.cyan(scheduleName)}...`);
|
|
20132
|
+
const agentRef = schedule.run.agent;
|
|
20133
|
+
let composeId;
|
|
20134
|
+
try {
|
|
20135
|
+
const namePart = agentRef.includes("/") ? agentRef.split("/").pop() : agentRef;
|
|
20136
|
+
const agentName = namePart.includes(":") ? namePart.split(":")[0] : namePart;
|
|
20137
|
+
const compose = await apiClient.getComposeByName(agentName);
|
|
20138
|
+
composeId = compose.id;
|
|
20139
|
+
} catch {
|
|
20140
|
+
console.error(chalk29.red(`\u2717 Agent not found: ${agentRef}`));
|
|
20141
|
+
console.error(chalk29.dim(" Make sure the agent is pushed first"));
|
|
20142
|
+
process.exit(1);
|
|
20143
|
+
}
|
|
20144
|
+
const expandedVars = expandEnvVarsInObject(schedule.run.vars);
|
|
20145
|
+
const expandedSecrets = expandEnvVarsInObject(schedule.run.secrets);
|
|
20146
|
+
const body = {
|
|
20147
|
+
name: scheduleName,
|
|
20148
|
+
composeId,
|
|
20149
|
+
cronExpression: schedule.on.cron,
|
|
20150
|
+
atTime: schedule.on.at,
|
|
20151
|
+
timezone: schedule.on.timezone || "UTC",
|
|
20152
|
+
prompt: schedule.run.prompt,
|
|
20153
|
+
vars: expandedVars,
|
|
20154
|
+
secrets: expandedSecrets,
|
|
20155
|
+
artifactName: schedule.run.artifactName,
|
|
20156
|
+
artifactVersion: schedule.run.artifactVersion,
|
|
20157
|
+
volumeVersions: schedule.run.volumeVersions
|
|
20158
|
+
};
|
|
20159
|
+
const response = await apiClient.post("/api/agent/schedules", {
|
|
20160
|
+
body: JSON.stringify(body)
|
|
20161
|
+
});
|
|
20162
|
+
if (!response.ok) {
|
|
20163
|
+
const error43 = await response.json();
|
|
20164
|
+
throw new Error(error43.error?.message || "Deploy failed");
|
|
20165
|
+
}
|
|
20166
|
+
const deployResult = await response.json();
|
|
20167
|
+
if (deployResult.created) {
|
|
20168
|
+
console.log(
|
|
20169
|
+
chalk29.green(`\u2713 Created schedule ${chalk29.cyan(scheduleName)}`)
|
|
20170
|
+
);
|
|
20171
|
+
} else {
|
|
20172
|
+
console.log(
|
|
20173
|
+
chalk29.green(`\u2713 Updated schedule ${chalk29.cyan(scheduleName)}`)
|
|
20174
|
+
);
|
|
20175
|
+
}
|
|
20176
|
+
if (deployResult.schedule.nextRunAt) {
|
|
20177
|
+
const nextRun = new Date(deployResult.schedule.nextRunAt);
|
|
20178
|
+
console.log(chalk29.dim(` Next run: ${nextRun.toLocaleString()}`));
|
|
20179
|
+
}
|
|
20180
|
+
if (deployResult.schedule.cronExpression) {
|
|
20181
|
+
console.log(
|
|
20182
|
+
chalk29.dim(
|
|
20183
|
+
` Cron: ${deployResult.schedule.cronExpression} (${deployResult.schedule.timezone})`
|
|
20184
|
+
)
|
|
20185
|
+
);
|
|
20186
|
+
} else if (deployResult.schedule.atTime) {
|
|
20187
|
+
console.log(chalk29.dim(` At: ${deployResult.schedule.atTime}`));
|
|
20188
|
+
}
|
|
20189
|
+
} catch (error43) {
|
|
20190
|
+
console.error(chalk29.red("\u2717 Failed to deploy schedule"));
|
|
20191
|
+
if (error43 instanceof Error) {
|
|
20192
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20193
|
+
console.error(chalk29.dim(" Run: vm0 auth login"));
|
|
20194
|
+
} else {
|
|
20195
|
+
console.error(chalk29.dim(` ${error43.message}`));
|
|
20196
|
+
}
|
|
20197
|
+
}
|
|
20198
|
+
process.exit(1);
|
|
20199
|
+
}
|
|
20200
|
+
});
|
|
20201
|
+
|
|
20202
|
+
// src/commands/schedule/list.ts
|
|
20203
|
+
import { Command as Command28 } from "commander";
|
|
20204
|
+
import chalk30 from "chalk";
|
|
20205
|
+
|
|
20206
|
+
// src/lib/schedule-utils.ts
|
|
20207
|
+
import { existsSync as existsSync12, readFileSync as readFileSync3 } from "fs";
|
|
20208
|
+
import { parse as parseYaml7 } from "yaml";
|
|
20209
|
+
var CONFIG_FILE4 = "vm0.yaml";
|
|
20210
|
+
function loadAgentName() {
|
|
20211
|
+
if (!existsSync12(CONFIG_FILE4)) {
|
|
20212
|
+
return { agentName: null };
|
|
20213
|
+
}
|
|
20214
|
+
try {
|
|
20215
|
+
const content = readFileSync3(CONFIG_FILE4, "utf8");
|
|
20216
|
+
const config2 = parseYaml7(content);
|
|
20217
|
+
const agentNames = Object.keys(config2.agents || {});
|
|
20218
|
+
return { agentName: agentNames[0] || null };
|
|
20219
|
+
} catch (err) {
|
|
20220
|
+
return {
|
|
20221
|
+
agentName: null,
|
|
20222
|
+
error: err instanceof Error ? err.message : "Failed to parse vm0.yaml"
|
|
20223
|
+
};
|
|
20224
|
+
}
|
|
20225
|
+
}
|
|
20226
|
+
function formatRelativeTime2(dateStr) {
|
|
20227
|
+
if (!dateStr) return "-";
|
|
20228
|
+
const date5 = new Date(dateStr);
|
|
20229
|
+
const now = /* @__PURE__ */ new Date();
|
|
20230
|
+
const diffMs = date5.getTime() - now.getTime();
|
|
20231
|
+
const diffAbs = Math.abs(diffMs);
|
|
20232
|
+
const minutes = Math.floor(diffAbs / (1e3 * 60));
|
|
20233
|
+
const hours = Math.floor(diffAbs / (1e3 * 60 * 60));
|
|
20234
|
+
const days = Math.floor(diffAbs / (1e3 * 60 * 60 * 24));
|
|
20235
|
+
const isPast = diffMs < 0;
|
|
20236
|
+
if (days > 0) {
|
|
20237
|
+
return isPast ? `${days}d ago` : `in ${days}d`;
|
|
20238
|
+
} else if (hours > 0) {
|
|
20239
|
+
return isPast ? `${hours}h ago` : `in ${hours}h`;
|
|
20240
|
+
} else if (minutes > 0) {
|
|
20241
|
+
return isPast ? `${minutes}m ago` : `in ${minutes}m`;
|
|
20242
|
+
} else {
|
|
20243
|
+
return isPast ? "just now" : "soon";
|
|
20244
|
+
}
|
|
20245
|
+
}
|
|
20246
|
+
function formatDateTime(dateStr) {
|
|
20247
|
+
if (!dateStr) return "-";
|
|
20248
|
+
const date5 = new Date(dateStr);
|
|
20249
|
+
const formatted = date5.toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC");
|
|
20250
|
+
const relative2 = formatRelativeTime2(dateStr);
|
|
20251
|
+
return `${formatted} (${relative2})`;
|
|
20252
|
+
}
|
|
20253
|
+
|
|
20254
|
+
// src/commands/schedule/list.ts
|
|
20255
|
+
var listCommand4 = new Command28().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
20256
|
+
try {
|
|
20257
|
+
const response = await apiClient.get("/api/agent/schedules");
|
|
20258
|
+
if (!response.ok) {
|
|
20259
|
+
const error43 = await response.json();
|
|
20260
|
+
throw new Error(error43.error?.message || "List failed");
|
|
20261
|
+
}
|
|
20262
|
+
const result = await response.json();
|
|
20263
|
+
if (result.schedules.length === 0) {
|
|
20264
|
+
console.log(chalk30.dim("No schedules found"));
|
|
20265
|
+
console.log(
|
|
20266
|
+
chalk30.dim(" Create one with: vm0 schedule deploy schedule.yaml")
|
|
20267
|
+
);
|
|
20268
|
+
return;
|
|
20269
|
+
}
|
|
20270
|
+
const nameWidth = Math.max(
|
|
20271
|
+
4,
|
|
20272
|
+
...result.schedules.map((s) => s.name.length)
|
|
20273
|
+
);
|
|
20274
|
+
const agentWidth = Math.max(
|
|
20275
|
+
5,
|
|
20276
|
+
...result.schedules.map((s) => s.composeName.length)
|
|
20277
|
+
);
|
|
20278
|
+
const triggerWidth = Math.max(
|
|
20279
|
+
7,
|
|
20280
|
+
...result.schedules.map(
|
|
20281
|
+
(s) => s.cronExpression ? s.cronExpression.length + s.timezone.length + 3 : s.atTime?.length || 0
|
|
20282
|
+
)
|
|
20283
|
+
);
|
|
20284
|
+
const header = [
|
|
20285
|
+
"NAME".padEnd(nameWidth),
|
|
20286
|
+
"AGENT".padEnd(agentWidth),
|
|
20287
|
+
"TRIGGER".padEnd(triggerWidth),
|
|
20288
|
+
"STATUS".padEnd(8),
|
|
20289
|
+
"NEXT RUN"
|
|
20290
|
+
].join(" ");
|
|
20291
|
+
console.log(chalk30.dim(header));
|
|
20292
|
+
for (const schedule of result.schedules) {
|
|
20293
|
+
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
20294
|
+
const status = schedule.enabled ? chalk30.green("enabled") : chalk30.yellow("disabled");
|
|
20295
|
+
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
20296
|
+
const row = [
|
|
20297
|
+
schedule.name.padEnd(nameWidth),
|
|
20298
|
+
schedule.composeName.padEnd(agentWidth),
|
|
20299
|
+
trigger.padEnd(triggerWidth),
|
|
20300
|
+
status.padEnd(8 + (schedule.enabled ? 0 : 2)),
|
|
20301
|
+
// Account for chalk chars
|
|
20302
|
+
nextRun
|
|
20303
|
+
].join(" ");
|
|
20304
|
+
console.log(row);
|
|
20305
|
+
}
|
|
20306
|
+
} catch (error43) {
|
|
20307
|
+
console.error(chalk30.red("\u2717 Failed to list schedules"));
|
|
20308
|
+
if (error43 instanceof Error) {
|
|
20309
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20310
|
+
console.error(chalk30.dim(" Run: vm0 auth login"));
|
|
20311
|
+
} else {
|
|
20312
|
+
console.error(chalk30.dim(` ${error43.message}`));
|
|
20313
|
+
}
|
|
20314
|
+
}
|
|
20315
|
+
process.exit(1);
|
|
20316
|
+
}
|
|
20317
|
+
});
|
|
20318
|
+
|
|
20319
|
+
// src/commands/schedule/status.ts
|
|
20320
|
+
import { Command as Command29 } from "commander";
|
|
20321
|
+
import chalk31 from "chalk";
|
|
20322
|
+
function formatDateTimeStyled(dateStr) {
|
|
20323
|
+
if (!dateStr) return chalk31.dim("-");
|
|
20324
|
+
const formatted = formatDateTime(dateStr);
|
|
20325
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk31.dim("($1)"));
|
|
20326
|
+
}
|
|
20327
|
+
function formatTrigger(schedule) {
|
|
20328
|
+
if (schedule.cronExpression) {
|
|
20329
|
+
return `${schedule.cronExpression} ${chalk31.dim(`(${schedule.timezone})`)}`;
|
|
20330
|
+
}
|
|
20331
|
+
if (schedule.atTime) {
|
|
20332
|
+
return `${schedule.atTime} ${chalk31.dim("(one-time)")}`;
|
|
20333
|
+
}
|
|
20334
|
+
return chalk31.dim("-");
|
|
20335
|
+
}
|
|
20336
|
+
var statusCommand4 = new Command29().name("status").description("Show detailed status of a schedule").argument("<name>", "Schedule name").action(async (name) => {
|
|
20337
|
+
try {
|
|
20338
|
+
const result = loadAgentName();
|
|
20339
|
+
if (result.error) {
|
|
20340
|
+
console.error(chalk31.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20341
|
+
process.exit(1);
|
|
20342
|
+
}
|
|
20343
|
+
if (!result.agentName) {
|
|
20344
|
+
console.error(chalk31.red("\u2717 No vm0.yaml found in current directory"));
|
|
20345
|
+
console.error(chalk31.dim(" Run this command from the agent directory"));
|
|
20346
|
+
process.exit(1);
|
|
20347
|
+
}
|
|
20348
|
+
const agentName = result.agentName;
|
|
20349
|
+
let composeId;
|
|
20350
|
+
try {
|
|
20351
|
+
const compose = await apiClient.getComposeByName(agentName);
|
|
20352
|
+
composeId = compose.id;
|
|
20353
|
+
} catch {
|
|
20354
|
+
console.error(chalk31.red(`\u2717 Agent not found: ${agentName}`));
|
|
20355
|
+
console.error(chalk31.dim(" Make sure the agent is pushed first"));
|
|
20356
|
+
process.exit(1);
|
|
20357
|
+
}
|
|
20358
|
+
const response = await apiClient.get(
|
|
20359
|
+
`/api/agent/schedules/${encodeURIComponent(name)}?composeId=${encodeURIComponent(composeId)}`
|
|
20360
|
+
);
|
|
20361
|
+
if (!response.ok) {
|
|
20362
|
+
const error43 = await response.json();
|
|
20363
|
+
throw new Error(error43.error?.message || "Failed to get schedule");
|
|
20364
|
+
}
|
|
20365
|
+
const schedule = await response.json();
|
|
20366
|
+
console.log();
|
|
20367
|
+
console.log(`Schedule: ${chalk31.cyan(schedule.name)}`);
|
|
20368
|
+
console.log(chalk31.dim("\u2501".repeat(50)));
|
|
20369
|
+
const statusText = schedule.enabled ? chalk31.green("enabled") : chalk31.yellow("disabled");
|
|
20370
|
+
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
20371
|
+
console.log(
|
|
20372
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk31.dim(`(${schedule.scopeSlug})`)}`
|
|
20373
|
+
);
|
|
20374
|
+
console.log(`${"Trigger:".padEnd(16)}${formatTrigger(schedule)}`);
|
|
20375
|
+
if (schedule.enabled) {
|
|
20376
|
+
console.log(
|
|
20377
|
+
`${"Next Run:".padEnd(16)}${formatDateTimeStyled(schedule.nextRunAt)}`
|
|
20378
|
+
);
|
|
20379
|
+
}
|
|
20380
|
+
if (schedule.lastRunAt) {
|
|
20381
|
+
const lastRunInfo = schedule.lastRunId ? `${formatDateTimeStyled(schedule.lastRunAt)} ${chalk31.dim(`[${schedule.lastRunId.slice(0, 8)}]`)}` : formatDateTimeStyled(schedule.lastRunAt);
|
|
20382
|
+
console.log(`${"Last Run:".padEnd(16)}${lastRunInfo}`);
|
|
20383
|
+
}
|
|
20384
|
+
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
20385
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk31.dim(promptPreview)}`);
|
|
20386
|
+
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
20387
|
+
console.log(
|
|
20388
|
+
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
20389
|
+
);
|
|
20390
|
+
}
|
|
20391
|
+
if (schedule.secretNames && schedule.secretNames.length > 0) {
|
|
20392
|
+
console.log(
|
|
20393
|
+
`${"Secrets:".padEnd(16)}${schedule.secretNames.join(", ")}`
|
|
20394
|
+
);
|
|
20395
|
+
}
|
|
20396
|
+
if (schedule.artifactName) {
|
|
20397
|
+
const artifactInfo = schedule.artifactVersion ? `${schedule.artifactName}:${schedule.artifactVersion}` : schedule.artifactName;
|
|
20398
|
+
console.log(`${"Artifact:".padEnd(16)}${artifactInfo}`);
|
|
20399
|
+
}
|
|
20400
|
+
if (schedule.volumeVersions && Object.keys(schedule.volumeVersions).length > 0) {
|
|
20401
|
+
console.log(
|
|
20402
|
+
`${"Volumes:".padEnd(16)}${Object.keys(schedule.volumeVersions).join(", ")}`
|
|
20403
|
+
);
|
|
20404
|
+
}
|
|
20405
|
+
console.log();
|
|
20406
|
+
console.log(
|
|
20407
|
+
chalk31.dim(
|
|
20408
|
+
`Created: ${new Date(schedule.createdAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20409
|
+
)
|
|
20410
|
+
);
|
|
20411
|
+
console.log(
|
|
20412
|
+
chalk31.dim(
|
|
20413
|
+
`Updated: ${new Date(schedule.updatedAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20414
|
+
)
|
|
20415
|
+
);
|
|
20416
|
+
console.log(chalk31.dim(`ID: ${schedule.id}`));
|
|
20417
|
+
console.log();
|
|
20418
|
+
} catch (error43) {
|
|
20419
|
+
console.error(chalk31.red("\u2717 Failed to get schedule status"));
|
|
20420
|
+
if (error43 instanceof Error) {
|
|
20421
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20422
|
+
console.error(chalk31.dim(" Run: vm0 auth login"));
|
|
20423
|
+
} else if (error43.message.includes("not found") || error43.message.includes("Not found")) {
|
|
20424
|
+
console.error(chalk31.dim(` Schedule "${name}" not found`));
|
|
20425
|
+
} else {
|
|
20426
|
+
console.error(chalk31.dim(` ${error43.message}`));
|
|
20427
|
+
}
|
|
20428
|
+
}
|
|
20429
|
+
process.exit(1);
|
|
20430
|
+
}
|
|
20431
|
+
});
|
|
20432
|
+
|
|
20433
|
+
// src/commands/schedule/delete.ts
|
|
20434
|
+
import { Command as Command30 } from "commander";
|
|
20435
|
+
import chalk32 from "chalk";
|
|
20436
|
+
import * as readline from "readline";
|
|
20437
|
+
async function confirm(message) {
|
|
20438
|
+
const rl = readline.createInterface({
|
|
20439
|
+
input: process.stdin,
|
|
20440
|
+
output: process.stdout
|
|
20441
|
+
});
|
|
20442
|
+
return new Promise((resolve2) => {
|
|
20443
|
+
rl.question(`${message} (y/N) `, (answer) => {
|
|
20444
|
+
rl.close();
|
|
20445
|
+
resolve2(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
20446
|
+
});
|
|
20447
|
+
});
|
|
20448
|
+
}
|
|
20449
|
+
var deleteCommand = new Command30().name("delete").alias("rm").description("Delete a schedule").argument("<name>", "Schedule name to delete").option("-f, --force", "Skip confirmation prompt").action(async (name, options) => {
|
|
20450
|
+
try {
|
|
20451
|
+
const result = loadAgentName();
|
|
20452
|
+
if (result.error) {
|
|
20453
|
+
console.error(chalk32.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20454
|
+
process.exit(1);
|
|
20455
|
+
}
|
|
20456
|
+
if (!result.agentName) {
|
|
20457
|
+
console.error(chalk32.red("\u2717 No vm0.yaml found in current directory"));
|
|
20458
|
+
console.error(chalk32.dim(" Run this command from the agent directory"));
|
|
20459
|
+
process.exit(1);
|
|
20460
|
+
}
|
|
20461
|
+
const agentName = result.agentName;
|
|
20462
|
+
let composeId;
|
|
20463
|
+
try {
|
|
20464
|
+
const compose = await apiClient.getComposeByName(agentName);
|
|
20465
|
+
composeId = compose.id;
|
|
20466
|
+
} catch {
|
|
20467
|
+
console.error(chalk32.red(`\u2717 Agent not found: ${agentName}`));
|
|
20468
|
+
console.error(chalk32.dim(" Make sure the agent is pushed first"));
|
|
20469
|
+
process.exit(1);
|
|
20470
|
+
}
|
|
20471
|
+
if (!options.force) {
|
|
20472
|
+
const confirmed = await confirm(`Delete schedule ${chalk32.cyan(name)}?`);
|
|
20473
|
+
if (!confirmed) {
|
|
20474
|
+
console.log(chalk32.dim("Cancelled"));
|
|
20475
|
+
return;
|
|
20476
|
+
}
|
|
20477
|
+
}
|
|
20478
|
+
const response = await apiClient.delete(
|
|
20479
|
+
`/api/agent/schedules/${encodeURIComponent(name)}?composeId=${encodeURIComponent(composeId)}`
|
|
20480
|
+
);
|
|
20481
|
+
if (!response.ok) {
|
|
20482
|
+
const error43 = await response.json();
|
|
20483
|
+
throw new Error(error43.error?.message || "Delete failed");
|
|
20484
|
+
}
|
|
20485
|
+
console.log(chalk32.green(`\u2713 Deleted schedule ${chalk32.cyan(name)}`));
|
|
20486
|
+
} catch (error43) {
|
|
20487
|
+
console.error(chalk32.red("\u2717 Failed to delete schedule"));
|
|
20488
|
+
if (error43 instanceof Error) {
|
|
20489
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20490
|
+
console.error(chalk32.dim(" Run: vm0 auth login"));
|
|
20491
|
+
} else {
|
|
20492
|
+
console.error(chalk32.dim(` ${error43.message}`));
|
|
20493
|
+
}
|
|
20494
|
+
}
|
|
20495
|
+
process.exit(1);
|
|
20496
|
+
}
|
|
20497
|
+
});
|
|
20498
|
+
|
|
20499
|
+
// src/commands/schedule/enable.ts
|
|
20500
|
+
import { Command as Command31 } from "commander";
|
|
20501
|
+
import chalk33 from "chalk";
|
|
20502
|
+
var enableCommand = new Command31().name("enable").description("Enable a schedule").argument("<name>", "Schedule name to enable").action(async (name) => {
|
|
20503
|
+
try {
|
|
20504
|
+
const result = loadAgentName();
|
|
20505
|
+
if (result.error) {
|
|
20506
|
+
console.error(chalk33.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20507
|
+
process.exit(1);
|
|
20508
|
+
}
|
|
20509
|
+
if (!result.agentName) {
|
|
20510
|
+
console.error(chalk33.red("\u2717 No vm0.yaml found in current directory"));
|
|
20511
|
+
console.error(chalk33.dim(" Run this command from the agent directory"));
|
|
20512
|
+
process.exit(1);
|
|
20513
|
+
}
|
|
20514
|
+
const agentName = result.agentName;
|
|
20515
|
+
let composeId;
|
|
20516
|
+
try {
|
|
20517
|
+
const compose = await apiClient.getComposeByName(agentName);
|
|
20518
|
+
composeId = compose.id;
|
|
20519
|
+
} catch {
|
|
20520
|
+
console.error(chalk33.red(`\u2717 Agent not found: ${agentName}`));
|
|
20521
|
+
console.error(chalk33.dim(" Make sure the agent is pushed first"));
|
|
20522
|
+
process.exit(1);
|
|
20523
|
+
}
|
|
20524
|
+
const response = await apiClient.post(
|
|
20525
|
+
`/api/agent/schedules/${encodeURIComponent(name)}/enable`,
|
|
20526
|
+
{ body: JSON.stringify({ composeId }) }
|
|
20527
|
+
);
|
|
20528
|
+
if (!response.ok) {
|
|
20529
|
+
const error43 = await response.json();
|
|
20530
|
+
throw new Error(error43.error?.message || "Enable failed");
|
|
20531
|
+
}
|
|
20532
|
+
console.log(chalk33.green(`\u2713 Enabled schedule ${chalk33.cyan(name)}`));
|
|
20533
|
+
} catch (error43) {
|
|
20534
|
+
console.error(chalk33.red("\u2717 Failed to enable schedule"));
|
|
20535
|
+
if (error43 instanceof Error) {
|
|
20536
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20537
|
+
console.error(chalk33.dim(" Run: vm0 auth login"));
|
|
20538
|
+
} else {
|
|
20539
|
+
console.error(chalk33.dim(` ${error43.message}`));
|
|
20540
|
+
}
|
|
20541
|
+
}
|
|
20542
|
+
process.exit(1);
|
|
20543
|
+
}
|
|
20544
|
+
});
|
|
20545
|
+
|
|
20546
|
+
// src/commands/schedule/disable.ts
|
|
20547
|
+
import { Command as Command32 } from "commander";
|
|
20548
|
+
import chalk34 from "chalk";
|
|
20549
|
+
var disableCommand = new Command32().name("disable").description("Disable a schedule").argument("<name>", "Schedule name to disable").action(async (name) => {
|
|
20550
|
+
try {
|
|
20551
|
+
const result = loadAgentName();
|
|
20552
|
+
if (result.error) {
|
|
20553
|
+
console.error(chalk34.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20554
|
+
process.exit(1);
|
|
20555
|
+
}
|
|
20556
|
+
if (!result.agentName) {
|
|
20557
|
+
console.error(chalk34.red("\u2717 No vm0.yaml found in current directory"));
|
|
20558
|
+
console.error(chalk34.dim(" Run this command from the agent directory"));
|
|
20559
|
+
process.exit(1);
|
|
20560
|
+
}
|
|
20561
|
+
const agentName = result.agentName;
|
|
20562
|
+
let composeId;
|
|
20563
|
+
try {
|
|
20564
|
+
const compose = await apiClient.getComposeByName(agentName);
|
|
20565
|
+
composeId = compose.id;
|
|
20566
|
+
} catch {
|
|
20567
|
+
console.error(chalk34.red(`\u2717 Agent not found: ${agentName}`));
|
|
20568
|
+
console.error(chalk34.dim(" Make sure the agent is pushed first"));
|
|
20569
|
+
process.exit(1);
|
|
20570
|
+
}
|
|
20571
|
+
const response = await apiClient.post(
|
|
20572
|
+
`/api/agent/schedules/${encodeURIComponent(name)}/disable`,
|
|
20573
|
+
{ body: JSON.stringify({ composeId }) }
|
|
20574
|
+
);
|
|
20575
|
+
if (!response.ok) {
|
|
20576
|
+
const error43 = await response.json();
|
|
20577
|
+
throw new Error(error43.error?.message || "Disable failed");
|
|
20578
|
+
}
|
|
20579
|
+
console.log(chalk34.green(`\u2713 Disabled schedule ${chalk34.cyan(name)}`));
|
|
20580
|
+
} catch (error43) {
|
|
20581
|
+
console.error(chalk34.red("\u2717 Failed to disable schedule"));
|
|
20582
|
+
if (error43 instanceof Error) {
|
|
20583
|
+
if (error43.message.includes("Not authenticated")) {
|
|
20584
|
+
console.error(chalk34.dim(" Run: vm0 auth login"));
|
|
20585
|
+
} else {
|
|
20586
|
+
console.error(chalk34.dim(` ${error43.message}`));
|
|
20587
|
+
}
|
|
20588
|
+
}
|
|
20589
|
+
process.exit(1);
|
|
20590
|
+
}
|
|
20591
|
+
});
|
|
20592
|
+
|
|
20593
|
+
// src/commands/schedule/index.ts
|
|
20594
|
+
var scheduleCommand = new Command33().name("schedule").description("Manage agent schedules").addCommand(deployCommand).addCommand(listCommand4).addCommand(statusCommand4).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
|
|
20595
|
+
|
|
19864
20596
|
// src/index.ts
|
|
19865
|
-
var program = new
|
|
19866
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.
|
|
20597
|
+
var program = new Command34();
|
|
20598
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.2.0");
|
|
19867
20599
|
program.command("info").description("Display environment information").action(async () => {
|
|
19868
|
-
console.log(
|
|
20600
|
+
console.log(chalk35.bold("System Information:"));
|
|
19869
20601
|
console.log(`Node Version: ${process.version}`);
|
|
19870
20602
|
console.log(`Platform: ${process.platform}`);
|
|
19871
20603
|
console.log(`Architecture: ${process.arch}`);
|
|
@@ -19895,6 +20627,7 @@ program.addCommand(scopeCommand);
|
|
|
19895
20627
|
program.addCommand(agentsCommand);
|
|
19896
20628
|
program.addCommand(initCommand3);
|
|
19897
20629
|
program.addCommand(setupGithubCommand);
|
|
20630
|
+
program.addCommand(scheduleCommand);
|
|
19898
20631
|
if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
|
|
19899
20632
|
program.parse();
|
|
19900
20633
|
}
|