@vm0/cli 5.2.0 → 5.3.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 +571 -213
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,13 +6,13 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { Command as
|
|
10
|
-
import
|
|
9
|
+
import { Command as Command35 } from "commander";
|
|
10
|
+
import chalk36 from "chalk";
|
|
11
11
|
|
|
12
|
-
// src/lib/auth.ts
|
|
12
|
+
// src/lib/api/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
14
14
|
|
|
15
|
-
// src/lib/config.ts
|
|
15
|
+
// src/lib/api/config.ts
|
|
16
16
|
import { homedir } from "os";
|
|
17
17
|
import { join } from "path";
|
|
18
18
|
import { readFile, writeFile, mkdir, unlink } from "fs/promises";
|
|
@@ -53,7 +53,7 @@ async function clearConfig() {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// src/lib/auth.ts
|
|
56
|
+
// src/lib/api/auth.ts
|
|
57
57
|
function buildHeaders() {
|
|
58
58
|
const headers = {
|
|
59
59
|
"Content-Type": "application/json"
|
|
@@ -14511,7 +14511,7 @@ function getProviderDisplayName(provider) {
|
|
|
14511
14511
|
return PROVIDER_DISPLAY_NAMES[provider];
|
|
14512
14512
|
}
|
|
14513
14513
|
|
|
14514
|
-
// src/lib/api-client.ts
|
|
14514
|
+
// src/lib/api/api-client.ts
|
|
14515
14515
|
var ApiClient = class {
|
|
14516
14516
|
async getHeaders() {
|
|
14517
14517
|
const token = await getToken();
|
|
@@ -14641,22 +14641,6 @@ var ApiClient = class {
|
|
|
14641
14641
|
}
|
|
14642
14642
|
return await response.json();
|
|
14643
14643
|
}
|
|
14644
|
-
async getTelemetry(runId) {
|
|
14645
|
-
const baseUrl = await this.getBaseUrl();
|
|
14646
|
-
const headers = await this.getHeaders();
|
|
14647
|
-
const response = await fetch(
|
|
14648
|
-
`${baseUrl}/api/agent/runs/${runId}/telemetry`,
|
|
14649
|
-
{
|
|
14650
|
-
method: "GET",
|
|
14651
|
-
headers
|
|
14652
|
-
}
|
|
14653
|
-
);
|
|
14654
|
-
if (!response.ok) {
|
|
14655
|
-
const error43 = await response.json();
|
|
14656
|
-
throw new Error(error43.error?.message || "Failed to fetch telemetry");
|
|
14657
|
-
}
|
|
14658
|
-
return await response.json();
|
|
14659
|
-
}
|
|
14660
14644
|
async getSystemLog(runId, options) {
|
|
14661
14645
|
const baseUrl = await this.getBaseUrl();
|
|
14662
14646
|
const headers = await this.getHeaders();
|
|
@@ -14757,20 +14741,6 @@ var ApiClient = class {
|
|
|
14757
14741
|
}
|
|
14758
14742
|
return await response.json();
|
|
14759
14743
|
}
|
|
14760
|
-
async createImage(body) {
|
|
14761
|
-
const baseUrl = await this.getBaseUrl();
|
|
14762
|
-
const headers = await this.getHeaders();
|
|
14763
|
-
const response = await fetch(`${baseUrl}/api/images`, {
|
|
14764
|
-
method: "POST",
|
|
14765
|
-
headers,
|
|
14766
|
-
body: JSON.stringify(body)
|
|
14767
|
-
});
|
|
14768
|
-
if (!response.ok) {
|
|
14769
|
-
const error43 = await response.json();
|
|
14770
|
-
throw new Error(error43.error?.message || "Failed to create image");
|
|
14771
|
-
}
|
|
14772
|
-
return await response.json();
|
|
14773
|
-
}
|
|
14774
14744
|
/**
|
|
14775
14745
|
* Get current user's scope
|
|
14776
14746
|
*/
|
|
@@ -14932,7 +14902,7 @@ var ApiClient = class {
|
|
|
14932
14902
|
};
|
|
14933
14903
|
var apiClient = new ApiClient();
|
|
14934
14904
|
|
|
14935
|
-
// src/lib/provider-config.ts
|
|
14905
|
+
// src/lib/domain/provider-config.ts
|
|
14936
14906
|
var PROVIDER_DEFAULTS = {
|
|
14937
14907
|
"claude-code": {
|
|
14938
14908
|
workingDir: "/home/user/workspace",
|
|
@@ -14996,7 +14966,7 @@ function getDefaultImageWithApps(provider, apps) {
|
|
|
14996
14966
|
return isDevelopment ? defaults.image.development : defaults.image.production;
|
|
14997
14967
|
}
|
|
14998
14968
|
|
|
14999
|
-
// src/lib/yaml-validator.ts
|
|
14969
|
+
// src/lib/domain/yaml-validator.ts
|
|
15000
14970
|
function validateAgentName(name) {
|
|
15001
14971
|
const nameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{1,62}[a-zA-Z0-9])?$/;
|
|
15002
14972
|
return nameRegex.test(name);
|
|
@@ -15263,12 +15233,12 @@ function validateAgentCompose(config2) {
|
|
|
15263
15233
|
return { valid: true };
|
|
15264
15234
|
}
|
|
15265
15235
|
|
|
15266
|
-
// src/lib/system-storage.ts
|
|
15236
|
+
// src/lib/storage/system-storage.ts
|
|
15267
15237
|
import * as fs4 from "fs/promises";
|
|
15268
15238
|
import * as path4 from "path";
|
|
15269
15239
|
import * as os3 from "os";
|
|
15270
15240
|
|
|
15271
|
-
// src/lib/github-skills.ts
|
|
15241
|
+
// src/lib/domain/github-skills.ts
|
|
15272
15242
|
import * as fs from "fs/promises";
|
|
15273
15243
|
import * as path from "path";
|
|
15274
15244
|
import * as os from "os";
|
|
@@ -15352,14 +15322,14 @@ async function readSkillFrontmatter(skillDir) {
|
|
|
15352
15322
|
return parseSkillFrontmatter(content);
|
|
15353
15323
|
}
|
|
15354
15324
|
|
|
15355
|
-
// src/lib/direct-upload.ts
|
|
15325
|
+
// src/lib/storage/direct-upload.ts
|
|
15356
15326
|
import { createHash } from "crypto";
|
|
15357
15327
|
import * as fs3 from "fs";
|
|
15358
15328
|
import * as path3 from "path";
|
|
15359
15329
|
import * as os2 from "os";
|
|
15360
15330
|
import * as tar2 from "tar";
|
|
15361
15331
|
|
|
15362
|
-
// src/lib/file-utils.ts
|
|
15332
|
+
// src/lib/utils/file-utils.ts
|
|
15363
15333
|
import * as fs2 from "fs";
|
|
15364
15334
|
import * as path2 from "path";
|
|
15365
15335
|
import * as tar from "tar";
|
|
@@ -15459,7 +15429,7 @@ async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
|
|
|
15459
15429
|
return isEmpty;
|
|
15460
15430
|
}
|
|
15461
15431
|
|
|
15462
|
-
// src/lib/direct-upload.ts
|
|
15432
|
+
// src/lib/storage/direct-upload.ts
|
|
15463
15433
|
async function hashFileStream(filePath) {
|
|
15464
15434
|
return new Promise((resolve2, reject) => {
|
|
15465
15435
|
const hash2 = createHash("sha256");
|
|
@@ -15674,7 +15644,7 @@ async function directUpload(storageName, storageType, cwd, options) {
|
|
|
15674
15644
|
};
|
|
15675
15645
|
}
|
|
15676
15646
|
|
|
15677
|
-
// src/lib/system-storage.ts
|
|
15647
|
+
// src/lib/storage/system-storage.ts
|
|
15678
15648
|
function getInstructionsFilename(provider) {
|
|
15679
15649
|
const validatedProvider = getValidatedProvider(provider);
|
|
15680
15650
|
if (validatedProvider === "codex") {
|
|
@@ -16000,7 +15970,7 @@ import * as fs5 from "fs";
|
|
|
16000
15970
|
import * as path5 from "path";
|
|
16001
15971
|
import { config as dotenvConfig } from "dotenv";
|
|
16002
15972
|
|
|
16003
|
-
// src/lib/claude-event-parser.ts
|
|
15973
|
+
// src/lib/events/claude-event-parser.ts
|
|
16004
15974
|
var ClaudeEventParser = class {
|
|
16005
15975
|
/**
|
|
16006
15976
|
* Parse a raw Claude Code JSONL event into a simplified format
|
|
@@ -16104,7 +16074,7 @@ var ClaudeEventParser = class {
|
|
|
16104
16074
|
}
|
|
16105
16075
|
};
|
|
16106
16076
|
|
|
16107
|
-
// src/lib/codex-event-parser.ts
|
|
16077
|
+
// src/lib/events/codex-event-parser.ts
|
|
16108
16078
|
var CodexEventParser = class {
|
|
16109
16079
|
/**
|
|
16110
16080
|
* Parse a raw Codex CLI JSONL event into a simplified format
|
|
@@ -16294,7 +16264,7 @@ ${changes}` }
|
|
|
16294
16264
|
}
|
|
16295
16265
|
};
|
|
16296
16266
|
|
|
16297
|
-
// src/lib/event-parser-factory.ts
|
|
16267
|
+
// src/lib/events/event-parser-factory.ts
|
|
16298
16268
|
function detectProviderFromEvent(rawEvent) {
|
|
16299
16269
|
if (!rawEvent || typeof rawEvent !== "object") {
|
|
16300
16270
|
return null;
|
|
@@ -16320,7 +16290,7 @@ function parseEvent(rawEvent, provider) {
|
|
|
16320
16290
|
return Parser.parse(rawEvent);
|
|
16321
16291
|
}
|
|
16322
16292
|
|
|
16323
|
-
// src/lib/event-renderer.ts
|
|
16293
|
+
// src/lib/events/event-renderer.ts
|
|
16324
16294
|
import chalk3 from "chalk";
|
|
16325
16295
|
var EventRenderer = class {
|
|
16326
16296
|
/**
|
|
@@ -16508,7 +16478,7 @@ var EventRenderer = class {
|
|
|
16508
16478
|
}
|
|
16509
16479
|
};
|
|
16510
16480
|
|
|
16511
|
-
// src/lib/codex-event-renderer.ts
|
|
16481
|
+
// src/lib/events/codex-event-renderer.ts
|
|
16512
16482
|
import chalk4 from "chalk";
|
|
16513
16483
|
var CodexEventRenderer = class {
|
|
16514
16484
|
/**
|
|
@@ -17178,7 +17148,7 @@ import { Command as Command3 } from "commander";
|
|
|
17178
17148
|
import chalk6 from "chalk";
|
|
17179
17149
|
import path7 from "path";
|
|
17180
17150
|
|
|
17181
|
-
// src/lib/storage-utils.ts
|
|
17151
|
+
// src/lib/storage/storage-utils.ts
|
|
17182
17152
|
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
|
|
17183
17153
|
import { existsSync as existsSync5 } from "fs";
|
|
17184
17154
|
import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
|
|
@@ -17225,7 +17195,7 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type =
|
|
|
17225
17195
|
await writeFile4(configPath, yamlContent, "utf8");
|
|
17226
17196
|
}
|
|
17227
17197
|
|
|
17228
|
-
// src/lib/prompt-utils.ts
|
|
17198
|
+
// src/lib/utils/prompt-utils.ts
|
|
17229
17199
|
import prompts2 from "prompts";
|
|
17230
17200
|
function isInteractive() {
|
|
17231
17201
|
return process.stdout.isTTY === true;
|
|
@@ -17269,6 +17239,26 @@ async function promptConfirm(message, initial = true) {
|
|
|
17269
17239
|
);
|
|
17270
17240
|
return response.value;
|
|
17271
17241
|
}
|
|
17242
|
+
async function promptSelect(message, choices, initial) {
|
|
17243
|
+
if (!isInteractive()) {
|
|
17244
|
+
return void 0;
|
|
17245
|
+
}
|
|
17246
|
+
const response = await prompts2(
|
|
17247
|
+
{
|
|
17248
|
+
type: "select",
|
|
17249
|
+
name: "value",
|
|
17250
|
+
message,
|
|
17251
|
+
choices,
|
|
17252
|
+
initial
|
|
17253
|
+
},
|
|
17254
|
+
{
|
|
17255
|
+
onCancel: () => {
|
|
17256
|
+
return false;
|
|
17257
|
+
}
|
|
17258
|
+
}
|
|
17259
|
+
);
|
|
17260
|
+
return response.value;
|
|
17261
|
+
}
|
|
17272
17262
|
|
|
17273
17263
|
// src/commands/volume/init.ts
|
|
17274
17264
|
var initCommand = new Command3().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
|
|
@@ -17403,7 +17393,7 @@ import * as fs6 from "fs";
|
|
|
17403
17393
|
import * as os4 from "os";
|
|
17404
17394
|
import * as tar3 from "tar";
|
|
17405
17395
|
|
|
17406
|
-
// src/lib/pull-utils.ts
|
|
17396
|
+
// src/lib/storage/pull-utils.ts
|
|
17407
17397
|
import chalk8 from "chalk";
|
|
17408
17398
|
async function handleEmptyStorageResponse(cwd) {
|
|
17409
17399
|
console.log(chalk8.dim("Syncing local files..."));
|
|
@@ -17639,7 +17629,7 @@ var listCommand = new Command7().name("list").alias("ls").description("List all
|
|
|
17639
17629
|
import { Command as Command8 } from "commander";
|
|
17640
17630
|
import chalk13 from "chalk";
|
|
17641
17631
|
|
|
17642
|
-
// src/lib/clone-utils.ts
|
|
17632
|
+
// src/lib/storage/clone-utils.ts
|
|
17643
17633
|
import chalk12 from "chalk";
|
|
17644
17634
|
import path9 from "path";
|
|
17645
17635
|
import * as fs7 from "fs";
|
|
@@ -18162,7 +18152,7 @@ import { spawn as spawn2 } from "child_process";
|
|
|
18162
18152
|
import { parse as parseYaml4 } from "yaml";
|
|
18163
18153
|
import { config as dotenvConfig2 } from "dotenv";
|
|
18164
18154
|
|
|
18165
|
-
// src/lib/update-checker.ts
|
|
18155
|
+
// src/lib/utils/update-checker.ts
|
|
18166
18156
|
import https from "https";
|
|
18167
18157
|
import { spawn } from "child_process";
|
|
18168
18158
|
import chalk20 from "chalk";
|
|
@@ -18270,7 +18260,7 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
18270
18260
|
return true;
|
|
18271
18261
|
}
|
|
18272
18262
|
|
|
18273
|
-
// src/lib/cook-state.ts
|
|
18263
|
+
// src/lib/domain/cook-state.ts
|
|
18274
18264
|
import { homedir as homedir2 } from "os";
|
|
18275
18265
|
import { join as join6 } from "path";
|
|
18276
18266
|
import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
@@ -18495,7 +18485,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
|
|
|
18495
18485
|
}
|
|
18496
18486
|
var cookCmd = new Command17().name("cook").description("One-click agent preparation and execution from vm0.yaml");
|
|
18497
18487
|
cookCmd.argument("[prompt]", "Prompt for the agent").option("-y, --yes", "Skip confirmation prompts").action(async (prompt, options) => {
|
|
18498
|
-
const shouldExit = await checkAndUpgrade("5.
|
|
18488
|
+
const shouldExit = await checkAndUpgrade("5.3.0", prompt);
|
|
18499
18489
|
if (shouldExit) {
|
|
18500
18490
|
process.exit(0);
|
|
18501
18491
|
}
|
|
@@ -18783,7 +18773,7 @@ var cookCommand = cookCmd;
|
|
|
18783
18773
|
import { Command as Command18 } from "commander";
|
|
18784
18774
|
import chalk22 from "chalk";
|
|
18785
18775
|
|
|
18786
|
-
// src/lib/time-parser.ts
|
|
18776
|
+
// src/lib/utils/time-parser.ts
|
|
18787
18777
|
function parseTime(timeStr) {
|
|
18788
18778
|
const relativeMatch = timeStr.match(/^(\d+)([smhdw])$/);
|
|
18789
18779
|
if (relativeMatch) {
|
|
@@ -19210,7 +19200,7 @@ var listCommand3 = new Command22().name("list").alias("ls").description("List al
|
|
|
19210
19200
|
import { Command as Command23 } from "commander";
|
|
19211
19201
|
import chalk26 from "chalk";
|
|
19212
19202
|
|
|
19213
|
-
// src/lib/source-derivation.ts
|
|
19203
|
+
// src/lib/domain/source-derivation.ts
|
|
19214
19204
|
import * as fs9 from "fs/promises";
|
|
19215
19205
|
import * as path13 from "path";
|
|
19216
19206
|
import * as os7 from "os";
|
|
@@ -20059,19 +20049,437 @@ var setupGithubCommand = new Command26().name("setup-github").description("Initi
|
|
|
20059
20049
|
);
|
|
20060
20050
|
|
|
20061
20051
|
// src/commands/schedule/index.ts
|
|
20062
|
-
import { Command as
|
|
20052
|
+
import { Command as Command34 } from "commander";
|
|
20063
20053
|
|
|
20064
|
-
// src/commands/schedule/
|
|
20054
|
+
// src/commands/schedule/init.ts
|
|
20065
20055
|
import { Command as Command27 } from "commander";
|
|
20066
20056
|
import chalk29 from "chalk";
|
|
20057
|
+
import { existsSync as existsSync12, writeFileSync } from "fs";
|
|
20058
|
+
import { stringify as stringifyYaml2 } from "yaml";
|
|
20059
|
+
|
|
20060
|
+
// src/lib/domain/schedule-utils.ts
|
|
20067
20061
|
import { existsSync as existsSync11, readFileSync as readFileSync2 } from "fs";
|
|
20068
20062
|
import { parse as parseYaml6 } from "yaml";
|
|
20063
|
+
var CONFIG_FILE4 = "vm0.yaml";
|
|
20064
|
+
function loadAgentName() {
|
|
20065
|
+
if (!existsSync11(CONFIG_FILE4)) {
|
|
20066
|
+
return { agentName: null };
|
|
20067
|
+
}
|
|
20068
|
+
try {
|
|
20069
|
+
const content = readFileSync2(CONFIG_FILE4, "utf8");
|
|
20070
|
+
const config2 = parseYaml6(content);
|
|
20071
|
+
const agentNames = Object.keys(config2.agents || {});
|
|
20072
|
+
return { agentName: agentNames[0] || null };
|
|
20073
|
+
} catch (err) {
|
|
20074
|
+
return {
|
|
20075
|
+
agentName: null,
|
|
20076
|
+
error: err instanceof Error ? err.message : "Failed to parse vm0.yaml"
|
|
20077
|
+
};
|
|
20078
|
+
}
|
|
20079
|
+
}
|
|
20080
|
+
function formatRelativeTime2(dateStr) {
|
|
20081
|
+
if (!dateStr) return "-";
|
|
20082
|
+
const date5 = new Date(dateStr);
|
|
20083
|
+
const now = /* @__PURE__ */ new Date();
|
|
20084
|
+
const diffMs = date5.getTime() - now.getTime();
|
|
20085
|
+
const diffAbs = Math.abs(diffMs);
|
|
20086
|
+
const minutes = Math.floor(diffAbs / (1e3 * 60));
|
|
20087
|
+
const hours = Math.floor(diffAbs / (1e3 * 60 * 60));
|
|
20088
|
+
const days = Math.floor(diffAbs / (1e3 * 60 * 60 * 24));
|
|
20089
|
+
const isPast = diffMs < 0;
|
|
20090
|
+
if (days > 0) {
|
|
20091
|
+
return isPast ? `${days}d ago` : `in ${days}d`;
|
|
20092
|
+
} else if (hours > 0) {
|
|
20093
|
+
return isPast ? `${hours}h ago` : `in ${hours}h`;
|
|
20094
|
+
} else if (minutes > 0) {
|
|
20095
|
+
return isPast ? `${minutes}m ago` : `in ${minutes}m`;
|
|
20096
|
+
} else {
|
|
20097
|
+
return isPast ? "just now" : "soon";
|
|
20098
|
+
}
|
|
20099
|
+
}
|
|
20100
|
+
function formatDateTime(dateStr) {
|
|
20101
|
+
if (!dateStr) return "-";
|
|
20102
|
+
const date5 = new Date(dateStr);
|
|
20103
|
+
const formatted = date5.toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC");
|
|
20104
|
+
const relative2 = formatRelativeTime2(dateStr);
|
|
20105
|
+
return `${formatted} (${relative2})`;
|
|
20106
|
+
}
|
|
20107
|
+
function generateCronExpression(frequency, time3, day) {
|
|
20108
|
+
const [hourStr, minuteStr] = time3.split(":");
|
|
20109
|
+
const hour = parseInt(hourStr ?? "0", 10);
|
|
20110
|
+
const minute = parseInt(minuteStr ?? "0", 10);
|
|
20111
|
+
switch (frequency) {
|
|
20112
|
+
case "daily":
|
|
20113
|
+
return `${minute} ${hour} * * *`;
|
|
20114
|
+
case "weekly":
|
|
20115
|
+
return `${minute} ${hour} * * ${day ?? 1}`;
|
|
20116
|
+
case "monthly":
|
|
20117
|
+
return `${minute} ${hour} ${day ?? 1} * *`;
|
|
20118
|
+
}
|
|
20119
|
+
}
|
|
20120
|
+
function detectTimezone() {
|
|
20121
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
20122
|
+
}
|
|
20123
|
+
function extractVarsAndSecrets() {
|
|
20124
|
+
const result = { vars: [], secrets: [] };
|
|
20125
|
+
if (!existsSync11(CONFIG_FILE4)) {
|
|
20126
|
+
return result;
|
|
20127
|
+
}
|
|
20128
|
+
try {
|
|
20129
|
+
const content = readFileSync2(CONFIG_FILE4, "utf8");
|
|
20130
|
+
const config2 = parseYaml6(content);
|
|
20131
|
+
const agents = Object.values(config2.agents || {});
|
|
20132
|
+
const agent = agents[0];
|
|
20133
|
+
if (!agent) {
|
|
20134
|
+
return result;
|
|
20135
|
+
}
|
|
20136
|
+
if (agent.experimental_vars) {
|
|
20137
|
+
result.vars.push(...agent.experimental_vars);
|
|
20138
|
+
}
|
|
20139
|
+
if (agent.experimental_secrets) {
|
|
20140
|
+
result.secrets.push(...agent.experimental_secrets);
|
|
20141
|
+
}
|
|
20142
|
+
if (agent.environment) {
|
|
20143
|
+
for (const value of Object.values(agent.environment)) {
|
|
20144
|
+
const varsMatches = value.matchAll(/\$\{\{\s*vars\.(\w+)\s*\}\}/g);
|
|
20145
|
+
for (const match of varsMatches) {
|
|
20146
|
+
if (match[1] && !result.vars.includes(match[1])) {
|
|
20147
|
+
result.vars.push(match[1]);
|
|
20148
|
+
}
|
|
20149
|
+
}
|
|
20150
|
+
const secretsMatches = value.matchAll(
|
|
20151
|
+
/\$\{\{\s*secrets\.(\w+)\s*\}\}/g
|
|
20152
|
+
);
|
|
20153
|
+
for (const match of secretsMatches) {
|
|
20154
|
+
if (match[1] && !result.secrets.includes(match[1])) {
|
|
20155
|
+
result.secrets.push(match[1]);
|
|
20156
|
+
}
|
|
20157
|
+
}
|
|
20158
|
+
}
|
|
20159
|
+
}
|
|
20160
|
+
return result;
|
|
20161
|
+
} catch {
|
|
20162
|
+
return result;
|
|
20163
|
+
}
|
|
20164
|
+
}
|
|
20165
|
+
function validateTimeFormat(time3) {
|
|
20166
|
+
const match = time3.match(/^(\d{1,2}):(\d{2})$/);
|
|
20167
|
+
if (!match) {
|
|
20168
|
+
return "Invalid format. Use HH:MM (e.g., 09:00)";
|
|
20169
|
+
}
|
|
20170
|
+
const hour = parseInt(match[1], 10);
|
|
20171
|
+
const minute = parseInt(match[2], 10);
|
|
20172
|
+
if (hour < 0 || hour > 23) {
|
|
20173
|
+
return "Hour must be 0-23";
|
|
20174
|
+
}
|
|
20175
|
+
if (minute < 0 || minute > 59) {
|
|
20176
|
+
return "Minute must be 0-59";
|
|
20177
|
+
}
|
|
20178
|
+
return true;
|
|
20179
|
+
}
|
|
20180
|
+
|
|
20181
|
+
// src/commands/schedule/init.ts
|
|
20182
|
+
var SCHEDULE_FILE = "schedule.yaml";
|
|
20183
|
+
var FREQUENCY_CHOICES = [
|
|
20184
|
+
{ title: "Daily", value: "daily", description: "Run every day" },
|
|
20185
|
+
{
|
|
20186
|
+
title: "Weekly",
|
|
20187
|
+
value: "weekly",
|
|
20188
|
+
description: "Run once per week"
|
|
20189
|
+
},
|
|
20190
|
+
{
|
|
20191
|
+
title: "Monthly",
|
|
20192
|
+
value: "monthly",
|
|
20193
|
+
description: "Run once per month"
|
|
20194
|
+
},
|
|
20195
|
+
{
|
|
20196
|
+
title: "One-time",
|
|
20197
|
+
value: "once",
|
|
20198
|
+
description: "Run once at specific time"
|
|
20199
|
+
}
|
|
20200
|
+
];
|
|
20201
|
+
var DAY_OF_WEEK_CHOICES = [
|
|
20202
|
+
{ title: "Monday", value: 1 },
|
|
20203
|
+
{ title: "Tuesday", value: 2 },
|
|
20204
|
+
{ title: "Wednesday", value: 3 },
|
|
20205
|
+
{ title: "Thursday", value: 4 },
|
|
20206
|
+
{ title: "Friday", value: 5 },
|
|
20207
|
+
{ title: "Saturday", value: 6 },
|
|
20208
|
+
{ title: "Sunday", value: 0 }
|
|
20209
|
+
];
|
|
20210
|
+
function parseDayOption(day, frequency) {
|
|
20211
|
+
if (frequency === "weekly") {
|
|
20212
|
+
const dayMap = {
|
|
20213
|
+
sun: 0,
|
|
20214
|
+
mon: 1,
|
|
20215
|
+
tue: 2,
|
|
20216
|
+
wed: 3,
|
|
20217
|
+
thu: 4,
|
|
20218
|
+
fri: 5,
|
|
20219
|
+
sat: 6
|
|
20220
|
+
};
|
|
20221
|
+
return dayMap[day.toLowerCase()];
|
|
20222
|
+
} else if (frequency === "monthly") {
|
|
20223
|
+
const num = parseInt(day, 10);
|
|
20224
|
+
if (num >= 1 && num <= 31) {
|
|
20225
|
+
return num;
|
|
20226
|
+
}
|
|
20227
|
+
}
|
|
20228
|
+
return void 0;
|
|
20229
|
+
}
|
|
20230
|
+
var initCommand4 = new Command27().name("init").description("Create a schedule.yaml interactively").option("-n, --name <name>", "Schedule name").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--no-vars", "Don't include vars from vm0.yaml").option("--force", "Overwrite existing schedule.yaml").action(
|
|
20231
|
+
async (options) => {
|
|
20232
|
+
try {
|
|
20233
|
+
const { agentName, error: error43 } = loadAgentName();
|
|
20234
|
+
if (error43) {
|
|
20235
|
+
console.error(chalk29.red(`\u2717 Invalid vm0.yaml: ${error43}`));
|
|
20236
|
+
process.exit(1);
|
|
20237
|
+
}
|
|
20238
|
+
if (!agentName) {
|
|
20239
|
+
console.error(chalk29.red("\u2717 No vm0.yaml found"));
|
|
20240
|
+
console.error(
|
|
20241
|
+
chalk29.dim(" Run this command from an agent directory")
|
|
20242
|
+
);
|
|
20243
|
+
process.exit(1);
|
|
20244
|
+
}
|
|
20245
|
+
if (existsSync12(SCHEDULE_FILE) && !options.force) {
|
|
20246
|
+
if (!isInteractive()) {
|
|
20247
|
+
console.error(chalk29.red("\u2717 schedule.yaml already exists"));
|
|
20248
|
+
console.error(chalk29.dim(" Use --force to overwrite"));
|
|
20249
|
+
process.exit(1);
|
|
20250
|
+
}
|
|
20251
|
+
const overwrite = await promptConfirm(
|
|
20252
|
+
"schedule.yaml exists. Overwrite?",
|
|
20253
|
+
false
|
|
20254
|
+
);
|
|
20255
|
+
if (!overwrite) {
|
|
20256
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20257
|
+
return;
|
|
20258
|
+
}
|
|
20259
|
+
}
|
|
20260
|
+
let scheduleName = options.name;
|
|
20261
|
+
if (!scheduleName) {
|
|
20262
|
+
if (!isInteractive()) {
|
|
20263
|
+
console.error(
|
|
20264
|
+
chalk29.red("\u2717 --name is required in non-interactive mode")
|
|
20265
|
+
);
|
|
20266
|
+
process.exit(1);
|
|
20267
|
+
}
|
|
20268
|
+
scheduleName = await promptText(
|
|
20269
|
+
"Schedule name",
|
|
20270
|
+
`${agentName}-schedule`
|
|
20271
|
+
);
|
|
20272
|
+
if (!scheduleName) {
|
|
20273
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20274
|
+
return;
|
|
20275
|
+
}
|
|
20276
|
+
}
|
|
20277
|
+
let frequency = options.frequency;
|
|
20278
|
+
if (!frequency || !["daily", "weekly", "monthly", "once"].includes(frequency)) {
|
|
20279
|
+
if (!isInteractive()) {
|
|
20280
|
+
console.error(
|
|
20281
|
+
chalk29.red(
|
|
20282
|
+
"\u2717 --frequency is required (daily|weekly|monthly|once)"
|
|
20283
|
+
)
|
|
20284
|
+
);
|
|
20285
|
+
process.exit(1);
|
|
20286
|
+
}
|
|
20287
|
+
frequency = await promptSelect(
|
|
20288
|
+
"Schedule frequency",
|
|
20289
|
+
FREQUENCY_CHOICES,
|
|
20290
|
+
0
|
|
20291
|
+
);
|
|
20292
|
+
if (!frequency) {
|
|
20293
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20294
|
+
return;
|
|
20295
|
+
}
|
|
20296
|
+
}
|
|
20297
|
+
let day;
|
|
20298
|
+
if (frequency === "weekly" || frequency === "monthly") {
|
|
20299
|
+
if (options.day) {
|
|
20300
|
+
day = parseDayOption(options.day, frequency);
|
|
20301
|
+
if (day === void 0) {
|
|
20302
|
+
console.error(
|
|
20303
|
+
chalk29.red(
|
|
20304
|
+
`\u2717 Invalid day: ${options.day}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
20305
|
+
)
|
|
20306
|
+
);
|
|
20307
|
+
process.exit(1);
|
|
20308
|
+
}
|
|
20309
|
+
} else if (isInteractive()) {
|
|
20310
|
+
if (frequency === "weekly") {
|
|
20311
|
+
day = await promptSelect("Day of week", DAY_OF_WEEK_CHOICES, 0);
|
|
20312
|
+
if (day === void 0) {
|
|
20313
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20314
|
+
return;
|
|
20315
|
+
}
|
|
20316
|
+
} else {
|
|
20317
|
+
const dayStr = await promptText("Day of month (1-31)", "1");
|
|
20318
|
+
if (!dayStr) {
|
|
20319
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20320
|
+
return;
|
|
20321
|
+
}
|
|
20322
|
+
day = parseInt(dayStr, 10);
|
|
20323
|
+
if (isNaN(day) || day < 1 || day > 31) {
|
|
20324
|
+
console.error(chalk29.red("\u2717 Day must be between 1 and 31"));
|
|
20325
|
+
process.exit(1);
|
|
20326
|
+
}
|
|
20327
|
+
}
|
|
20328
|
+
} else {
|
|
20329
|
+
console.error(chalk29.red("\u2717 --day is required for weekly/monthly"));
|
|
20330
|
+
process.exit(1);
|
|
20331
|
+
}
|
|
20332
|
+
}
|
|
20333
|
+
let time3 = options.time;
|
|
20334
|
+
let atTime;
|
|
20335
|
+
if (frequency === "once") {
|
|
20336
|
+
if (!isInteractive()) {
|
|
20337
|
+
console.error(
|
|
20338
|
+
chalk29.red("\u2717 One-time schedules require interactive mode")
|
|
20339
|
+
);
|
|
20340
|
+
console.error(
|
|
20341
|
+
chalk29.dim(" Use cron frequency for non-interactive mode")
|
|
20342
|
+
);
|
|
20343
|
+
process.exit(1);
|
|
20344
|
+
}
|
|
20345
|
+
const dateStr = await promptText(
|
|
20346
|
+
"Date and time (YYYY-MM-DD HH:MM)",
|
|
20347
|
+
new Date(Date.now() + 24 * 60 * 60 * 1e3).toISOString().slice(0, 16).replace("T", " ")
|
|
20348
|
+
);
|
|
20349
|
+
if (!dateStr) {
|
|
20350
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20351
|
+
return;
|
|
20352
|
+
}
|
|
20353
|
+
atTime = (/* @__PURE__ */ new Date(dateStr.replace(" ", "T") + ":00Z")).toISOString();
|
|
20354
|
+
} else {
|
|
20355
|
+
if (!time3) {
|
|
20356
|
+
if (!isInteractive()) {
|
|
20357
|
+
console.error(chalk29.red("\u2717 --time is required (HH:MM format)"));
|
|
20358
|
+
process.exit(1);
|
|
20359
|
+
}
|
|
20360
|
+
time3 = await promptText(
|
|
20361
|
+
"Time (HH:MM)",
|
|
20362
|
+
"09:00",
|
|
20363
|
+
validateTimeFormat
|
|
20364
|
+
);
|
|
20365
|
+
if (!time3) {
|
|
20366
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20367
|
+
return;
|
|
20368
|
+
}
|
|
20369
|
+
} else {
|
|
20370
|
+
const validation = validateTimeFormat(time3);
|
|
20371
|
+
if (validation !== true) {
|
|
20372
|
+
console.error(chalk29.red(`\u2717 Invalid time: ${validation}`));
|
|
20373
|
+
process.exit(1);
|
|
20374
|
+
}
|
|
20375
|
+
}
|
|
20376
|
+
}
|
|
20377
|
+
const detectedTimezone = detectTimezone();
|
|
20378
|
+
let timezone = options.timezone;
|
|
20379
|
+
if (!timezone) {
|
|
20380
|
+
if (isInteractive()) {
|
|
20381
|
+
timezone = await promptText("Timezone", detectedTimezone);
|
|
20382
|
+
if (!timezone) {
|
|
20383
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20384
|
+
return;
|
|
20385
|
+
}
|
|
20386
|
+
} else {
|
|
20387
|
+
timezone = detectedTimezone;
|
|
20388
|
+
}
|
|
20389
|
+
}
|
|
20390
|
+
let promptText_ = options.prompt;
|
|
20391
|
+
if (!promptText_) {
|
|
20392
|
+
if (!isInteractive()) {
|
|
20393
|
+
console.error(chalk29.red("\u2717 --prompt is required"));
|
|
20394
|
+
process.exit(1);
|
|
20395
|
+
}
|
|
20396
|
+
promptText_ = await promptText("Prompt to run");
|
|
20397
|
+
if (!promptText_) {
|
|
20398
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20399
|
+
return;
|
|
20400
|
+
}
|
|
20401
|
+
}
|
|
20402
|
+
let vars;
|
|
20403
|
+
let secrets;
|
|
20404
|
+
if (options.vars) {
|
|
20405
|
+
const extracted = extractVarsAndSecrets();
|
|
20406
|
+
if (extracted.vars.length > 0 || extracted.secrets.length > 0) {
|
|
20407
|
+
let includeVars = true;
|
|
20408
|
+
if (isInteractive()) {
|
|
20409
|
+
const varList = [
|
|
20410
|
+
...extracted.vars.map((v) => `vars.${v}`),
|
|
20411
|
+
...extracted.secrets.map((s) => `secrets.${s}`)
|
|
20412
|
+
];
|
|
20413
|
+
includeVars = await promptConfirm(
|
|
20414
|
+
`Include ${varList.length} variable(s) from vm0.yaml? (${varList.join(", ")})`,
|
|
20415
|
+
true
|
|
20416
|
+
) ?? true;
|
|
20417
|
+
}
|
|
20418
|
+
if (includeVars) {
|
|
20419
|
+
if (extracted.vars.length > 0) {
|
|
20420
|
+
vars = {};
|
|
20421
|
+
for (const v of extracted.vars) {
|
|
20422
|
+
vars[v] = `\${${v}}`;
|
|
20423
|
+
}
|
|
20424
|
+
}
|
|
20425
|
+
if (extracted.secrets.length > 0) {
|
|
20426
|
+
secrets = {};
|
|
20427
|
+
for (const s of extracted.secrets) {
|
|
20428
|
+
secrets[s] = `\${${s}}`;
|
|
20429
|
+
}
|
|
20430
|
+
}
|
|
20431
|
+
}
|
|
20432
|
+
}
|
|
20433
|
+
}
|
|
20434
|
+
const scheduleYaml = {
|
|
20435
|
+
version: "1.0",
|
|
20436
|
+
schedules: {
|
|
20437
|
+
[scheduleName]: {
|
|
20438
|
+
on: {
|
|
20439
|
+
timezone
|
|
20440
|
+
},
|
|
20441
|
+
run: {
|
|
20442
|
+
agent: agentName,
|
|
20443
|
+
prompt: promptText_
|
|
20444
|
+
}
|
|
20445
|
+
}
|
|
20446
|
+
}
|
|
20447
|
+
};
|
|
20448
|
+
if (atTime) {
|
|
20449
|
+
scheduleYaml.schedules[scheduleName].on.at = atTime;
|
|
20450
|
+
} else if (time3 && frequency !== "once") {
|
|
20451
|
+
scheduleYaml.schedules[scheduleName].on.cron = generateCronExpression(frequency, time3, day);
|
|
20452
|
+
}
|
|
20453
|
+
if (vars && Object.keys(vars).length > 0) {
|
|
20454
|
+
scheduleYaml.schedules[scheduleName].run.vars = vars;
|
|
20455
|
+
}
|
|
20456
|
+
if (secrets && Object.keys(secrets).length > 0) {
|
|
20457
|
+
scheduleYaml.schedules[scheduleName].run.secrets = secrets;
|
|
20458
|
+
}
|
|
20459
|
+
writeFileSync(SCHEDULE_FILE, stringifyYaml2(scheduleYaml));
|
|
20460
|
+
console.log(chalk29.green(`\u2713 Created ${SCHEDULE_FILE}`));
|
|
20461
|
+
console.log(chalk29.dim(" Deploy with: vm0 schedule deploy"));
|
|
20462
|
+
} catch (error43) {
|
|
20463
|
+
console.error(chalk29.red("\u2717 Failed to create schedule.yaml"));
|
|
20464
|
+
if (error43 instanceof Error) {
|
|
20465
|
+
console.error(chalk29.dim(` ${error43.message}`));
|
|
20466
|
+
}
|
|
20467
|
+
process.exit(1);
|
|
20468
|
+
}
|
|
20469
|
+
}
|
|
20470
|
+
);
|
|
20471
|
+
|
|
20472
|
+
// src/commands/schedule/deploy.ts
|
|
20473
|
+
import { Command as Command28 } from "commander";
|
|
20474
|
+
import chalk30 from "chalk";
|
|
20475
|
+
import { existsSync as existsSync13, readFileSync as readFileSync3 } from "fs";
|
|
20476
|
+
import { parse as parseYaml7 } from "yaml";
|
|
20069
20477
|
function expandEnvVars(value) {
|
|
20070
20478
|
return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
20071
20479
|
const envValue = process.env[varName];
|
|
20072
20480
|
if (envValue === void 0) {
|
|
20073
20481
|
console.warn(
|
|
20074
|
-
|
|
20482
|
+
chalk30.yellow(` Warning: Environment variable ${varName} not set`)
|
|
20075
20483
|
);
|
|
20076
20484
|
return match;
|
|
20077
20485
|
}
|
|
@@ -20086,30 +20494,30 @@ function expandEnvVarsInObject(obj) {
|
|
|
20086
20494
|
}
|
|
20087
20495
|
return result;
|
|
20088
20496
|
}
|
|
20089
|
-
var deployCommand = new
|
|
20497
|
+
var deployCommand = new Command28().name("deploy").description("Deploy a schedule from schedule.yaml (create or update)").argument("[file]", "Path to schedule.yaml", "schedule.yaml").action(async (file2) => {
|
|
20090
20498
|
try {
|
|
20091
|
-
if (!
|
|
20092
|
-
console.error(
|
|
20093
|
-
console.error(
|
|
20499
|
+
if (!existsSync13(file2)) {
|
|
20500
|
+
console.error(chalk30.red(`\u2717 File not found: ${file2}`));
|
|
20501
|
+
console.error(chalk30.dim(" Create a schedule.yaml file first"));
|
|
20094
20502
|
process.exit(1);
|
|
20095
20503
|
}
|
|
20096
|
-
const content =
|
|
20504
|
+
const content = readFileSync3(file2, "utf-8");
|
|
20097
20505
|
let parsed;
|
|
20098
20506
|
try {
|
|
20099
|
-
parsed =
|
|
20507
|
+
parsed = parseYaml7(content);
|
|
20100
20508
|
} catch (err) {
|
|
20101
|
-
console.error(
|
|
20509
|
+
console.error(chalk30.red("\u2717 Invalid YAML syntax"));
|
|
20102
20510
|
if (err instanceof Error) {
|
|
20103
|
-
console.error(
|
|
20511
|
+
console.error(chalk30.dim(` ${err.message}`));
|
|
20104
20512
|
}
|
|
20105
20513
|
process.exit(1);
|
|
20106
20514
|
}
|
|
20107
20515
|
const result = scheduleYamlSchema.safeParse(parsed);
|
|
20108
20516
|
if (!result.success) {
|
|
20109
|
-
console.error(
|
|
20517
|
+
console.error(chalk30.red("\u2717 Invalid schedule.yaml format"));
|
|
20110
20518
|
for (const issue2 of result.error.issues) {
|
|
20111
20519
|
console.error(
|
|
20112
|
-
|
|
20520
|
+
chalk30.dim(` ${issue2.path.join(".")}: ${issue2.message}`)
|
|
20113
20521
|
);
|
|
20114
20522
|
}
|
|
20115
20523
|
process.exit(1);
|
|
@@ -20117,18 +20525,18 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20117
20525
|
const scheduleYaml = result.data;
|
|
20118
20526
|
const scheduleEntries = Object.entries(scheduleYaml.schedules);
|
|
20119
20527
|
if (scheduleEntries.length === 0) {
|
|
20120
|
-
console.error(
|
|
20528
|
+
console.error(chalk30.red("\u2717 No schedules defined in file"));
|
|
20121
20529
|
process.exit(1);
|
|
20122
20530
|
}
|
|
20123
20531
|
if (scheduleEntries.length > 1) {
|
|
20124
20532
|
console.error(
|
|
20125
|
-
|
|
20533
|
+
chalk30.red("\u2717 Multiple schedules per file not supported yet")
|
|
20126
20534
|
);
|
|
20127
|
-
console.error(
|
|
20535
|
+
console.error(chalk30.dim(" Please use one schedule per file"));
|
|
20128
20536
|
process.exit(1);
|
|
20129
20537
|
}
|
|
20130
20538
|
const [scheduleName, schedule] = scheduleEntries[0];
|
|
20131
|
-
console.log(`Deploying schedule ${
|
|
20539
|
+
console.log(`Deploying schedule ${chalk30.cyan(scheduleName)}...`);
|
|
20132
20540
|
const agentRef = schedule.run.agent;
|
|
20133
20541
|
let composeId;
|
|
20134
20542
|
try {
|
|
@@ -20137,8 +20545,8 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20137
20545
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20138
20546
|
composeId = compose.id;
|
|
20139
20547
|
} catch {
|
|
20140
|
-
console.error(
|
|
20141
|
-
console.error(
|
|
20548
|
+
console.error(chalk30.red(`\u2717 Agent not found: ${agentRef}`));
|
|
20549
|
+
console.error(chalk30.dim(" Make sure the agent is pushed first"));
|
|
20142
20550
|
process.exit(1);
|
|
20143
20551
|
}
|
|
20144
20552
|
const expandedVars = expandEnvVarsInObject(schedule.run.vars);
|
|
@@ -20166,33 +20574,33 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20166
20574
|
const deployResult = await response.json();
|
|
20167
20575
|
if (deployResult.created) {
|
|
20168
20576
|
console.log(
|
|
20169
|
-
|
|
20577
|
+
chalk30.green(`\u2713 Created schedule ${chalk30.cyan(scheduleName)}`)
|
|
20170
20578
|
);
|
|
20171
20579
|
} else {
|
|
20172
20580
|
console.log(
|
|
20173
|
-
|
|
20581
|
+
chalk30.green(`\u2713 Updated schedule ${chalk30.cyan(scheduleName)}`)
|
|
20174
20582
|
);
|
|
20175
20583
|
}
|
|
20176
20584
|
if (deployResult.schedule.nextRunAt) {
|
|
20177
20585
|
const nextRun = new Date(deployResult.schedule.nextRunAt);
|
|
20178
|
-
console.log(
|
|
20586
|
+
console.log(chalk30.dim(` Next run: ${nextRun.toLocaleString()}`));
|
|
20179
20587
|
}
|
|
20180
20588
|
if (deployResult.schedule.cronExpression) {
|
|
20181
20589
|
console.log(
|
|
20182
|
-
|
|
20590
|
+
chalk30.dim(
|
|
20183
20591
|
` Cron: ${deployResult.schedule.cronExpression} (${deployResult.schedule.timezone})`
|
|
20184
20592
|
)
|
|
20185
20593
|
);
|
|
20186
20594
|
} else if (deployResult.schedule.atTime) {
|
|
20187
|
-
console.log(
|
|
20595
|
+
console.log(chalk30.dim(` At: ${deployResult.schedule.atTime}`));
|
|
20188
20596
|
}
|
|
20189
20597
|
} catch (error43) {
|
|
20190
|
-
console.error(
|
|
20598
|
+
console.error(chalk30.red("\u2717 Failed to deploy schedule"));
|
|
20191
20599
|
if (error43 instanceof Error) {
|
|
20192
20600
|
if (error43.message.includes("Not authenticated")) {
|
|
20193
|
-
console.error(
|
|
20601
|
+
console.error(chalk30.dim(" Run: vm0 auth login"));
|
|
20194
20602
|
} else {
|
|
20195
|
-
console.error(
|
|
20603
|
+
console.error(chalk30.dim(` ${error43.message}`));
|
|
20196
20604
|
}
|
|
20197
20605
|
}
|
|
20198
20606
|
process.exit(1);
|
|
@@ -20200,59 +20608,9 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20200
20608
|
});
|
|
20201
20609
|
|
|
20202
20610
|
// src/commands/schedule/list.ts
|
|
20203
|
-
import { Command as
|
|
20204
|
-
import
|
|
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 () => {
|
|
20611
|
+
import { Command as Command29 } from "commander";
|
|
20612
|
+
import chalk31 from "chalk";
|
|
20613
|
+
var listCommand4 = new Command29().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
20256
20614
|
try {
|
|
20257
20615
|
const response = await apiClient.get("/api/agent/schedules");
|
|
20258
20616
|
if (!response.ok) {
|
|
@@ -20261,9 +20619,9 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20261
20619
|
}
|
|
20262
20620
|
const result = await response.json();
|
|
20263
20621
|
if (result.schedules.length === 0) {
|
|
20264
|
-
console.log(
|
|
20622
|
+
console.log(chalk31.dim("No schedules found"));
|
|
20265
20623
|
console.log(
|
|
20266
|
-
|
|
20624
|
+
chalk31.dim(" Create one with: vm0 schedule deploy schedule.yaml")
|
|
20267
20625
|
);
|
|
20268
20626
|
return;
|
|
20269
20627
|
}
|
|
@@ -20288,10 +20646,10 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20288
20646
|
"STATUS".padEnd(8),
|
|
20289
20647
|
"NEXT RUN"
|
|
20290
20648
|
].join(" ");
|
|
20291
|
-
console.log(
|
|
20649
|
+
console.log(chalk31.dim(header));
|
|
20292
20650
|
for (const schedule of result.schedules) {
|
|
20293
20651
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
20294
|
-
const status = schedule.enabled ?
|
|
20652
|
+
const status = schedule.enabled ? chalk31.green("enabled") : chalk31.yellow("disabled");
|
|
20295
20653
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
20296
20654
|
const row = [
|
|
20297
20655
|
schedule.name.padEnd(nameWidth),
|
|
@@ -20304,12 +20662,12 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20304
20662
|
console.log(row);
|
|
20305
20663
|
}
|
|
20306
20664
|
} catch (error43) {
|
|
20307
|
-
console.error(
|
|
20665
|
+
console.error(chalk31.red("\u2717 Failed to list schedules"));
|
|
20308
20666
|
if (error43 instanceof Error) {
|
|
20309
20667
|
if (error43.message.includes("Not authenticated")) {
|
|
20310
|
-
console.error(
|
|
20668
|
+
console.error(chalk31.dim(" Run: vm0 auth login"));
|
|
20311
20669
|
} else {
|
|
20312
|
-
console.error(
|
|
20670
|
+
console.error(chalk31.dim(` ${error43.message}`));
|
|
20313
20671
|
}
|
|
20314
20672
|
}
|
|
20315
20673
|
process.exit(1);
|
|
@@ -20317,32 +20675,32 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20317
20675
|
});
|
|
20318
20676
|
|
|
20319
20677
|
// src/commands/schedule/status.ts
|
|
20320
|
-
import { Command as
|
|
20321
|
-
import
|
|
20678
|
+
import { Command as Command30 } from "commander";
|
|
20679
|
+
import chalk32 from "chalk";
|
|
20322
20680
|
function formatDateTimeStyled(dateStr) {
|
|
20323
|
-
if (!dateStr) return
|
|
20681
|
+
if (!dateStr) return chalk32.dim("-");
|
|
20324
20682
|
const formatted = formatDateTime(dateStr);
|
|
20325
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
20683
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk32.dim("($1)"));
|
|
20326
20684
|
}
|
|
20327
20685
|
function formatTrigger(schedule) {
|
|
20328
20686
|
if (schedule.cronExpression) {
|
|
20329
|
-
return `${schedule.cronExpression} ${
|
|
20687
|
+
return `${schedule.cronExpression} ${chalk32.dim(`(${schedule.timezone})`)}`;
|
|
20330
20688
|
}
|
|
20331
20689
|
if (schedule.atTime) {
|
|
20332
|
-
return `${schedule.atTime} ${
|
|
20690
|
+
return `${schedule.atTime} ${chalk32.dim("(one-time)")}`;
|
|
20333
20691
|
}
|
|
20334
|
-
return
|
|
20692
|
+
return chalk32.dim("-");
|
|
20335
20693
|
}
|
|
20336
|
-
var statusCommand4 = new
|
|
20694
|
+
var statusCommand4 = new Command30().name("status").description("Show detailed status of a schedule").argument("<name>", "Schedule name").action(async (name) => {
|
|
20337
20695
|
try {
|
|
20338
20696
|
const result = loadAgentName();
|
|
20339
20697
|
if (result.error) {
|
|
20340
|
-
console.error(
|
|
20698
|
+
console.error(chalk32.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20341
20699
|
process.exit(1);
|
|
20342
20700
|
}
|
|
20343
20701
|
if (!result.agentName) {
|
|
20344
|
-
console.error(
|
|
20345
|
-
console.error(
|
|
20702
|
+
console.error(chalk32.red("\u2717 No vm0.yaml found in current directory"));
|
|
20703
|
+
console.error(chalk32.dim(" Run this command from the agent directory"));
|
|
20346
20704
|
process.exit(1);
|
|
20347
20705
|
}
|
|
20348
20706
|
const agentName = result.agentName;
|
|
@@ -20351,8 +20709,8 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20351
20709
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20352
20710
|
composeId = compose.id;
|
|
20353
20711
|
} catch {
|
|
20354
|
-
console.error(
|
|
20355
|
-
console.error(
|
|
20712
|
+
console.error(chalk32.red(`\u2717 Agent not found: ${agentName}`));
|
|
20713
|
+
console.error(chalk32.dim(" Make sure the agent is pushed first"));
|
|
20356
20714
|
process.exit(1);
|
|
20357
20715
|
}
|
|
20358
20716
|
const response = await apiClient.get(
|
|
@@ -20364,12 +20722,12 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20364
20722
|
}
|
|
20365
20723
|
const schedule = await response.json();
|
|
20366
20724
|
console.log();
|
|
20367
|
-
console.log(`Schedule: ${
|
|
20368
|
-
console.log(
|
|
20369
|
-
const statusText = schedule.enabled ?
|
|
20725
|
+
console.log(`Schedule: ${chalk32.cyan(schedule.name)}`);
|
|
20726
|
+
console.log(chalk32.dim("\u2501".repeat(50)));
|
|
20727
|
+
const statusText = schedule.enabled ? chalk32.green("enabled") : chalk32.yellow("disabled");
|
|
20370
20728
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
20371
20729
|
console.log(
|
|
20372
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
20730
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk32.dim(`(${schedule.scopeSlug})`)}`
|
|
20373
20731
|
);
|
|
20374
20732
|
console.log(`${"Trigger:".padEnd(16)}${formatTrigger(schedule)}`);
|
|
20375
20733
|
if (schedule.enabled) {
|
|
@@ -20378,11 +20736,11 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20378
20736
|
);
|
|
20379
20737
|
}
|
|
20380
20738
|
if (schedule.lastRunAt) {
|
|
20381
|
-
const lastRunInfo = schedule.lastRunId ? `${formatDateTimeStyled(schedule.lastRunAt)} ${
|
|
20739
|
+
const lastRunInfo = schedule.lastRunId ? `${formatDateTimeStyled(schedule.lastRunAt)} ${chalk32.dim(`[${schedule.lastRunId.slice(0, 8)}]`)}` : formatDateTimeStyled(schedule.lastRunAt);
|
|
20382
20740
|
console.log(`${"Last Run:".padEnd(16)}${lastRunInfo}`);
|
|
20383
20741
|
}
|
|
20384
20742
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
20385
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
20743
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk32.dim(promptPreview)}`);
|
|
20386
20744
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
20387
20745
|
console.log(
|
|
20388
20746
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -20404,26 +20762,26 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20404
20762
|
}
|
|
20405
20763
|
console.log();
|
|
20406
20764
|
console.log(
|
|
20407
|
-
|
|
20765
|
+
chalk32.dim(
|
|
20408
20766
|
`Created: ${new Date(schedule.createdAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20409
20767
|
)
|
|
20410
20768
|
);
|
|
20411
20769
|
console.log(
|
|
20412
|
-
|
|
20770
|
+
chalk32.dim(
|
|
20413
20771
|
`Updated: ${new Date(schedule.updatedAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20414
20772
|
)
|
|
20415
20773
|
);
|
|
20416
|
-
console.log(
|
|
20774
|
+
console.log(chalk32.dim(`ID: ${schedule.id}`));
|
|
20417
20775
|
console.log();
|
|
20418
20776
|
} catch (error43) {
|
|
20419
|
-
console.error(
|
|
20777
|
+
console.error(chalk32.red("\u2717 Failed to get schedule status"));
|
|
20420
20778
|
if (error43 instanceof Error) {
|
|
20421
20779
|
if (error43.message.includes("Not authenticated")) {
|
|
20422
|
-
console.error(
|
|
20780
|
+
console.error(chalk32.dim(" Run: vm0 auth login"));
|
|
20423
20781
|
} else if (error43.message.includes("not found") || error43.message.includes("Not found")) {
|
|
20424
|
-
console.error(
|
|
20782
|
+
console.error(chalk32.dim(` Schedule "${name}" not found`));
|
|
20425
20783
|
} else {
|
|
20426
|
-
console.error(
|
|
20784
|
+
console.error(chalk32.dim(` ${error43.message}`));
|
|
20427
20785
|
}
|
|
20428
20786
|
}
|
|
20429
20787
|
process.exit(1);
|
|
@@ -20431,8 +20789,8 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20431
20789
|
});
|
|
20432
20790
|
|
|
20433
20791
|
// src/commands/schedule/delete.ts
|
|
20434
|
-
import { Command as
|
|
20435
|
-
import
|
|
20792
|
+
import { Command as Command31 } from "commander";
|
|
20793
|
+
import chalk33 from "chalk";
|
|
20436
20794
|
import * as readline from "readline";
|
|
20437
20795
|
async function confirm(message) {
|
|
20438
20796
|
const rl = readline.createInterface({
|
|
@@ -20446,16 +20804,16 @@ async function confirm(message) {
|
|
|
20446
20804
|
});
|
|
20447
20805
|
});
|
|
20448
20806
|
}
|
|
20449
|
-
var deleteCommand = new
|
|
20807
|
+
var deleteCommand = new Command31().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
20808
|
try {
|
|
20451
20809
|
const result = loadAgentName();
|
|
20452
20810
|
if (result.error) {
|
|
20453
|
-
console.error(
|
|
20811
|
+
console.error(chalk33.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20454
20812
|
process.exit(1);
|
|
20455
20813
|
}
|
|
20456
20814
|
if (!result.agentName) {
|
|
20457
|
-
console.error(
|
|
20458
|
-
console.error(
|
|
20815
|
+
console.error(chalk33.red("\u2717 No vm0.yaml found in current directory"));
|
|
20816
|
+
console.error(chalk33.dim(" Run this command from the agent directory"));
|
|
20459
20817
|
process.exit(1);
|
|
20460
20818
|
}
|
|
20461
20819
|
const agentName = result.agentName;
|
|
@@ -20464,14 +20822,14 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20464
20822
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20465
20823
|
composeId = compose.id;
|
|
20466
20824
|
} catch {
|
|
20467
|
-
console.error(
|
|
20468
|
-
console.error(
|
|
20825
|
+
console.error(chalk33.red(`\u2717 Agent not found: ${agentName}`));
|
|
20826
|
+
console.error(chalk33.dim(" Make sure the agent is pushed first"));
|
|
20469
20827
|
process.exit(1);
|
|
20470
20828
|
}
|
|
20471
20829
|
if (!options.force) {
|
|
20472
|
-
const confirmed = await confirm(`Delete schedule ${
|
|
20830
|
+
const confirmed = await confirm(`Delete schedule ${chalk33.cyan(name)}?`);
|
|
20473
20831
|
if (!confirmed) {
|
|
20474
|
-
console.log(
|
|
20832
|
+
console.log(chalk33.dim("Cancelled"));
|
|
20475
20833
|
return;
|
|
20476
20834
|
}
|
|
20477
20835
|
}
|
|
@@ -20482,14 +20840,14 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20482
20840
|
const error43 = await response.json();
|
|
20483
20841
|
throw new Error(error43.error?.message || "Delete failed");
|
|
20484
20842
|
}
|
|
20485
|
-
console.log(
|
|
20843
|
+
console.log(chalk33.green(`\u2713 Deleted schedule ${chalk33.cyan(name)}`));
|
|
20486
20844
|
} catch (error43) {
|
|
20487
|
-
console.error(
|
|
20845
|
+
console.error(chalk33.red("\u2717 Failed to delete schedule"));
|
|
20488
20846
|
if (error43 instanceof Error) {
|
|
20489
20847
|
if (error43.message.includes("Not authenticated")) {
|
|
20490
|
-
console.error(
|
|
20848
|
+
console.error(chalk33.dim(" Run: vm0 auth login"));
|
|
20491
20849
|
} else {
|
|
20492
|
-
console.error(
|
|
20850
|
+
console.error(chalk33.dim(` ${error43.message}`));
|
|
20493
20851
|
}
|
|
20494
20852
|
}
|
|
20495
20853
|
process.exit(1);
|
|
@@ -20497,18 +20855,18 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20497
20855
|
});
|
|
20498
20856
|
|
|
20499
20857
|
// src/commands/schedule/enable.ts
|
|
20500
|
-
import { Command as
|
|
20501
|
-
import
|
|
20502
|
-
var enableCommand = new
|
|
20858
|
+
import { Command as Command32 } from "commander";
|
|
20859
|
+
import chalk34 from "chalk";
|
|
20860
|
+
var enableCommand = new Command32().name("enable").description("Enable a schedule").argument("<name>", "Schedule name to enable").action(async (name) => {
|
|
20503
20861
|
try {
|
|
20504
20862
|
const result = loadAgentName();
|
|
20505
20863
|
if (result.error) {
|
|
20506
|
-
console.error(
|
|
20864
|
+
console.error(chalk34.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20507
20865
|
process.exit(1);
|
|
20508
20866
|
}
|
|
20509
20867
|
if (!result.agentName) {
|
|
20510
|
-
console.error(
|
|
20511
|
-
console.error(
|
|
20868
|
+
console.error(chalk34.red("\u2717 No vm0.yaml found in current directory"));
|
|
20869
|
+
console.error(chalk34.dim(" Run this command from the agent directory"));
|
|
20512
20870
|
process.exit(1);
|
|
20513
20871
|
}
|
|
20514
20872
|
const agentName = result.agentName;
|
|
@@ -20517,8 +20875,8 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20517
20875
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20518
20876
|
composeId = compose.id;
|
|
20519
20877
|
} catch {
|
|
20520
|
-
console.error(
|
|
20521
|
-
console.error(
|
|
20878
|
+
console.error(chalk34.red(`\u2717 Agent not found: ${agentName}`));
|
|
20879
|
+
console.error(chalk34.dim(" Make sure the agent is pushed first"));
|
|
20522
20880
|
process.exit(1);
|
|
20523
20881
|
}
|
|
20524
20882
|
const response = await apiClient.post(
|
|
@@ -20529,14 +20887,14 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20529
20887
|
const error43 = await response.json();
|
|
20530
20888
|
throw new Error(error43.error?.message || "Enable failed");
|
|
20531
20889
|
}
|
|
20532
|
-
console.log(
|
|
20890
|
+
console.log(chalk34.green(`\u2713 Enabled schedule ${chalk34.cyan(name)}`));
|
|
20533
20891
|
} catch (error43) {
|
|
20534
|
-
console.error(
|
|
20892
|
+
console.error(chalk34.red("\u2717 Failed to enable schedule"));
|
|
20535
20893
|
if (error43 instanceof Error) {
|
|
20536
20894
|
if (error43.message.includes("Not authenticated")) {
|
|
20537
|
-
console.error(
|
|
20895
|
+
console.error(chalk34.dim(" Run: vm0 auth login"));
|
|
20538
20896
|
} else {
|
|
20539
|
-
console.error(
|
|
20897
|
+
console.error(chalk34.dim(` ${error43.message}`));
|
|
20540
20898
|
}
|
|
20541
20899
|
}
|
|
20542
20900
|
process.exit(1);
|
|
@@ -20544,18 +20902,18 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20544
20902
|
});
|
|
20545
20903
|
|
|
20546
20904
|
// src/commands/schedule/disable.ts
|
|
20547
|
-
import { Command as
|
|
20548
|
-
import
|
|
20549
|
-
var disableCommand = new
|
|
20905
|
+
import { Command as Command33 } from "commander";
|
|
20906
|
+
import chalk35 from "chalk";
|
|
20907
|
+
var disableCommand = new Command33().name("disable").description("Disable a schedule").argument("<name>", "Schedule name to disable").action(async (name) => {
|
|
20550
20908
|
try {
|
|
20551
20909
|
const result = loadAgentName();
|
|
20552
20910
|
if (result.error) {
|
|
20553
|
-
console.error(
|
|
20911
|
+
console.error(chalk35.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20554
20912
|
process.exit(1);
|
|
20555
20913
|
}
|
|
20556
20914
|
if (!result.agentName) {
|
|
20557
|
-
console.error(
|
|
20558
|
-
console.error(
|
|
20915
|
+
console.error(chalk35.red("\u2717 No vm0.yaml found in current directory"));
|
|
20916
|
+
console.error(chalk35.dim(" Run this command from the agent directory"));
|
|
20559
20917
|
process.exit(1);
|
|
20560
20918
|
}
|
|
20561
20919
|
const agentName = result.agentName;
|
|
@@ -20564,8 +20922,8 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20564
20922
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20565
20923
|
composeId = compose.id;
|
|
20566
20924
|
} catch {
|
|
20567
|
-
console.error(
|
|
20568
|
-
console.error(
|
|
20925
|
+
console.error(chalk35.red(`\u2717 Agent not found: ${agentName}`));
|
|
20926
|
+
console.error(chalk35.dim(" Make sure the agent is pushed first"));
|
|
20569
20927
|
process.exit(1);
|
|
20570
20928
|
}
|
|
20571
20929
|
const response = await apiClient.post(
|
|
@@ -20576,14 +20934,14 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20576
20934
|
const error43 = await response.json();
|
|
20577
20935
|
throw new Error(error43.error?.message || "Disable failed");
|
|
20578
20936
|
}
|
|
20579
|
-
console.log(
|
|
20937
|
+
console.log(chalk35.green(`\u2713 Disabled schedule ${chalk35.cyan(name)}`));
|
|
20580
20938
|
} catch (error43) {
|
|
20581
|
-
console.error(
|
|
20939
|
+
console.error(chalk35.red("\u2717 Failed to disable schedule"));
|
|
20582
20940
|
if (error43 instanceof Error) {
|
|
20583
20941
|
if (error43.message.includes("Not authenticated")) {
|
|
20584
|
-
console.error(
|
|
20942
|
+
console.error(chalk35.dim(" Run: vm0 auth login"));
|
|
20585
20943
|
} else {
|
|
20586
|
-
console.error(
|
|
20944
|
+
console.error(chalk35.dim(` ${error43.message}`));
|
|
20587
20945
|
}
|
|
20588
20946
|
}
|
|
20589
20947
|
process.exit(1);
|
|
@@ -20591,13 +20949,13 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20591
20949
|
});
|
|
20592
20950
|
|
|
20593
20951
|
// src/commands/schedule/index.ts
|
|
20594
|
-
var scheduleCommand = new
|
|
20952
|
+
var scheduleCommand = new Command34().name("schedule").description("Manage agent schedules").addCommand(initCommand4).addCommand(deployCommand).addCommand(listCommand4).addCommand(statusCommand4).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
|
|
20595
20953
|
|
|
20596
20954
|
// src/index.ts
|
|
20597
|
-
var program = new
|
|
20598
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.
|
|
20955
|
+
var program = new Command35();
|
|
20956
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.3.0");
|
|
20599
20957
|
program.command("info").description("Display environment information").action(async () => {
|
|
20600
|
-
console.log(
|
|
20958
|
+
console.log(chalk36.bold("System Information:"));
|
|
20601
20959
|
console.log(`Node Version: ${process.version}`);
|
|
20602
20960
|
console.log(`Platform: ${process.platform}`);
|
|
20603
20961
|
console.log(`Architecture: ${process.arch}`);
|