@vm0/cli 5.2.0 → 5.3.1
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 +579 -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.1", 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,445 @@ 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(
|
|
20397
|
+
"Prompt to run",
|
|
20398
|
+
"let's start working."
|
|
20399
|
+
);
|
|
20400
|
+
if (!promptText_) {
|
|
20401
|
+
console.log(chalk29.dim("Cancelled"));
|
|
20402
|
+
return;
|
|
20403
|
+
}
|
|
20404
|
+
}
|
|
20405
|
+
let vars;
|
|
20406
|
+
let secrets;
|
|
20407
|
+
if (options.vars) {
|
|
20408
|
+
const extracted = extractVarsAndSecrets();
|
|
20409
|
+
if (extracted.vars.length > 0 || extracted.secrets.length > 0) {
|
|
20410
|
+
let includeVars = true;
|
|
20411
|
+
if (isInteractive()) {
|
|
20412
|
+
const varCount = extracted.vars.length;
|
|
20413
|
+
const secretCount = extracted.secrets.length;
|
|
20414
|
+
const parts = [];
|
|
20415
|
+
if (varCount > 0) parts.push(`${varCount} variable(s)`);
|
|
20416
|
+
if (secretCount > 0) parts.push(`${secretCount} secret(s)`);
|
|
20417
|
+
const itemList = [
|
|
20418
|
+
...extracted.vars.map((v) => `vars.${v}`),
|
|
20419
|
+
...extracted.secrets.map((s) => `secrets.${s}`)
|
|
20420
|
+
];
|
|
20421
|
+
includeVars = await promptConfirm(
|
|
20422
|
+
`Include ${parts.join(" and ")} from vm0.yaml? (${itemList.join(", ")})`,
|
|
20423
|
+
true
|
|
20424
|
+
) ?? true;
|
|
20425
|
+
}
|
|
20426
|
+
if (includeVars) {
|
|
20427
|
+
if (extracted.vars.length > 0) {
|
|
20428
|
+
vars = {};
|
|
20429
|
+
for (const v of extracted.vars) {
|
|
20430
|
+
vars[v] = `\${${v}}`;
|
|
20431
|
+
}
|
|
20432
|
+
}
|
|
20433
|
+
if (extracted.secrets.length > 0) {
|
|
20434
|
+
secrets = {};
|
|
20435
|
+
for (const s of extracted.secrets) {
|
|
20436
|
+
secrets[s] = `\${${s}}`;
|
|
20437
|
+
}
|
|
20438
|
+
}
|
|
20439
|
+
}
|
|
20440
|
+
}
|
|
20441
|
+
}
|
|
20442
|
+
const scheduleYaml = {
|
|
20443
|
+
version: "1.0",
|
|
20444
|
+
schedules: {
|
|
20445
|
+
[scheduleName]: {
|
|
20446
|
+
on: {
|
|
20447
|
+
timezone
|
|
20448
|
+
},
|
|
20449
|
+
run: {
|
|
20450
|
+
agent: agentName,
|
|
20451
|
+
prompt: promptText_
|
|
20452
|
+
}
|
|
20453
|
+
}
|
|
20454
|
+
}
|
|
20455
|
+
};
|
|
20456
|
+
if (atTime) {
|
|
20457
|
+
scheduleYaml.schedules[scheduleName].on.at = atTime;
|
|
20458
|
+
} else if (time3 && frequency !== "once") {
|
|
20459
|
+
scheduleYaml.schedules[scheduleName].on.cron = generateCronExpression(frequency, time3, day);
|
|
20460
|
+
}
|
|
20461
|
+
if (vars && Object.keys(vars).length > 0) {
|
|
20462
|
+
scheduleYaml.schedules[scheduleName].run.vars = vars;
|
|
20463
|
+
}
|
|
20464
|
+
if (secrets && Object.keys(secrets).length > 0) {
|
|
20465
|
+
scheduleYaml.schedules[scheduleName].run.secrets = secrets;
|
|
20466
|
+
}
|
|
20467
|
+
writeFileSync(SCHEDULE_FILE, stringifyYaml2(scheduleYaml));
|
|
20468
|
+
console.log(chalk29.green(`\u2713 Created ${SCHEDULE_FILE}`));
|
|
20469
|
+
console.log(chalk29.dim(" Deploy with: vm0 schedule deploy"));
|
|
20470
|
+
} catch (error43) {
|
|
20471
|
+
console.error(chalk29.red("\u2717 Failed to create schedule.yaml"));
|
|
20472
|
+
if (error43 instanceof Error) {
|
|
20473
|
+
console.error(chalk29.dim(` ${error43.message}`));
|
|
20474
|
+
}
|
|
20475
|
+
process.exit(1);
|
|
20476
|
+
}
|
|
20477
|
+
}
|
|
20478
|
+
);
|
|
20479
|
+
|
|
20480
|
+
// src/commands/schedule/deploy.ts
|
|
20481
|
+
import { Command as Command28 } from "commander";
|
|
20482
|
+
import chalk30 from "chalk";
|
|
20483
|
+
import { existsSync as existsSync13, readFileSync as readFileSync3 } from "fs";
|
|
20484
|
+
import { parse as parseYaml7 } from "yaml";
|
|
20069
20485
|
function expandEnvVars(value) {
|
|
20070
20486
|
return value.replace(/\$\{([^}]+)\}/g, (match, varName) => {
|
|
20071
20487
|
const envValue = process.env[varName];
|
|
20072
20488
|
if (envValue === void 0) {
|
|
20073
20489
|
console.warn(
|
|
20074
|
-
|
|
20490
|
+
chalk30.yellow(` Warning: Environment variable ${varName} not set`)
|
|
20075
20491
|
);
|
|
20076
20492
|
return match;
|
|
20077
20493
|
}
|
|
@@ -20086,30 +20502,30 @@ function expandEnvVarsInObject(obj) {
|
|
|
20086
20502
|
}
|
|
20087
20503
|
return result;
|
|
20088
20504
|
}
|
|
20089
|
-
var deployCommand = new
|
|
20505
|
+
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
20506
|
try {
|
|
20091
|
-
if (!
|
|
20092
|
-
console.error(
|
|
20093
|
-
console.error(
|
|
20507
|
+
if (!existsSync13(file2)) {
|
|
20508
|
+
console.error(chalk30.red(`\u2717 File not found: ${file2}`));
|
|
20509
|
+
console.error(chalk30.dim(" Create a schedule.yaml file first"));
|
|
20094
20510
|
process.exit(1);
|
|
20095
20511
|
}
|
|
20096
|
-
const content =
|
|
20512
|
+
const content = readFileSync3(file2, "utf-8");
|
|
20097
20513
|
let parsed;
|
|
20098
20514
|
try {
|
|
20099
|
-
parsed =
|
|
20515
|
+
parsed = parseYaml7(content);
|
|
20100
20516
|
} catch (err) {
|
|
20101
|
-
console.error(
|
|
20517
|
+
console.error(chalk30.red("\u2717 Invalid YAML syntax"));
|
|
20102
20518
|
if (err instanceof Error) {
|
|
20103
|
-
console.error(
|
|
20519
|
+
console.error(chalk30.dim(` ${err.message}`));
|
|
20104
20520
|
}
|
|
20105
20521
|
process.exit(1);
|
|
20106
20522
|
}
|
|
20107
20523
|
const result = scheduleYamlSchema.safeParse(parsed);
|
|
20108
20524
|
if (!result.success) {
|
|
20109
|
-
console.error(
|
|
20525
|
+
console.error(chalk30.red("\u2717 Invalid schedule.yaml format"));
|
|
20110
20526
|
for (const issue2 of result.error.issues) {
|
|
20111
20527
|
console.error(
|
|
20112
|
-
|
|
20528
|
+
chalk30.dim(` ${issue2.path.join(".")}: ${issue2.message}`)
|
|
20113
20529
|
);
|
|
20114
20530
|
}
|
|
20115
20531
|
process.exit(1);
|
|
@@ -20117,18 +20533,18 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20117
20533
|
const scheduleYaml = result.data;
|
|
20118
20534
|
const scheduleEntries = Object.entries(scheduleYaml.schedules);
|
|
20119
20535
|
if (scheduleEntries.length === 0) {
|
|
20120
|
-
console.error(
|
|
20536
|
+
console.error(chalk30.red("\u2717 No schedules defined in file"));
|
|
20121
20537
|
process.exit(1);
|
|
20122
20538
|
}
|
|
20123
20539
|
if (scheduleEntries.length > 1) {
|
|
20124
20540
|
console.error(
|
|
20125
|
-
|
|
20541
|
+
chalk30.red("\u2717 Multiple schedules per file not supported yet")
|
|
20126
20542
|
);
|
|
20127
|
-
console.error(
|
|
20543
|
+
console.error(chalk30.dim(" Please use one schedule per file"));
|
|
20128
20544
|
process.exit(1);
|
|
20129
20545
|
}
|
|
20130
20546
|
const [scheduleName, schedule] = scheduleEntries[0];
|
|
20131
|
-
console.log(`Deploying schedule ${
|
|
20547
|
+
console.log(`Deploying schedule ${chalk30.cyan(scheduleName)}...`);
|
|
20132
20548
|
const agentRef = schedule.run.agent;
|
|
20133
20549
|
let composeId;
|
|
20134
20550
|
try {
|
|
@@ -20137,8 +20553,8 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20137
20553
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20138
20554
|
composeId = compose.id;
|
|
20139
20555
|
} catch {
|
|
20140
|
-
console.error(
|
|
20141
|
-
console.error(
|
|
20556
|
+
console.error(chalk30.red(`\u2717 Agent not found: ${agentRef}`));
|
|
20557
|
+
console.error(chalk30.dim(" Make sure the agent is pushed first"));
|
|
20142
20558
|
process.exit(1);
|
|
20143
20559
|
}
|
|
20144
20560
|
const expandedVars = expandEnvVarsInObject(schedule.run.vars);
|
|
@@ -20166,33 +20582,33 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20166
20582
|
const deployResult = await response.json();
|
|
20167
20583
|
if (deployResult.created) {
|
|
20168
20584
|
console.log(
|
|
20169
|
-
|
|
20585
|
+
chalk30.green(`\u2713 Created schedule ${chalk30.cyan(scheduleName)}`)
|
|
20170
20586
|
);
|
|
20171
20587
|
} else {
|
|
20172
20588
|
console.log(
|
|
20173
|
-
|
|
20589
|
+
chalk30.green(`\u2713 Updated schedule ${chalk30.cyan(scheduleName)}`)
|
|
20174
20590
|
);
|
|
20175
20591
|
}
|
|
20176
20592
|
if (deployResult.schedule.nextRunAt) {
|
|
20177
20593
|
const nextRun = new Date(deployResult.schedule.nextRunAt);
|
|
20178
|
-
console.log(
|
|
20594
|
+
console.log(chalk30.dim(` Next run: ${nextRun.toLocaleString()}`));
|
|
20179
20595
|
}
|
|
20180
20596
|
if (deployResult.schedule.cronExpression) {
|
|
20181
20597
|
console.log(
|
|
20182
|
-
|
|
20598
|
+
chalk30.dim(
|
|
20183
20599
|
` Cron: ${deployResult.schedule.cronExpression} (${deployResult.schedule.timezone})`
|
|
20184
20600
|
)
|
|
20185
20601
|
);
|
|
20186
20602
|
} else if (deployResult.schedule.atTime) {
|
|
20187
|
-
console.log(
|
|
20603
|
+
console.log(chalk30.dim(` At: ${deployResult.schedule.atTime}`));
|
|
20188
20604
|
}
|
|
20189
20605
|
} catch (error43) {
|
|
20190
|
-
console.error(
|
|
20606
|
+
console.error(chalk30.red("\u2717 Failed to deploy schedule"));
|
|
20191
20607
|
if (error43 instanceof Error) {
|
|
20192
20608
|
if (error43.message.includes("Not authenticated")) {
|
|
20193
|
-
console.error(
|
|
20609
|
+
console.error(chalk30.dim(" Run: vm0 auth login"));
|
|
20194
20610
|
} else {
|
|
20195
|
-
console.error(
|
|
20611
|
+
console.error(chalk30.dim(` ${error43.message}`));
|
|
20196
20612
|
}
|
|
20197
20613
|
}
|
|
20198
20614
|
process.exit(1);
|
|
@@ -20200,59 +20616,9 @@ var deployCommand = new Command27().name("deploy").description("Deploy a schedul
|
|
|
20200
20616
|
});
|
|
20201
20617
|
|
|
20202
20618
|
// 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 () => {
|
|
20619
|
+
import { Command as Command29 } from "commander";
|
|
20620
|
+
import chalk31 from "chalk";
|
|
20621
|
+
var listCommand4 = new Command29().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
20256
20622
|
try {
|
|
20257
20623
|
const response = await apiClient.get("/api/agent/schedules");
|
|
20258
20624
|
if (!response.ok) {
|
|
@@ -20261,9 +20627,9 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20261
20627
|
}
|
|
20262
20628
|
const result = await response.json();
|
|
20263
20629
|
if (result.schedules.length === 0) {
|
|
20264
|
-
console.log(
|
|
20630
|
+
console.log(chalk31.dim("No schedules found"));
|
|
20265
20631
|
console.log(
|
|
20266
|
-
|
|
20632
|
+
chalk31.dim(" Create one with: vm0 schedule deploy schedule.yaml")
|
|
20267
20633
|
);
|
|
20268
20634
|
return;
|
|
20269
20635
|
}
|
|
@@ -20288,10 +20654,10 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20288
20654
|
"STATUS".padEnd(8),
|
|
20289
20655
|
"NEXT RUN"
|
|
20290
20656
|
].join(" ");
|
|
20291
|
-
console.log(
|
|
20657
|
+
console.log(chalk31.dim(header));
|
|
20292
20658
|
for (const schedule of result.schedules) {
|
|
20293
20659
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
20294
|
-
const status = schedule.enabled ?
|
|
20660
|
+
const status = schedule.enabled ? chalk31.green("enabled") : chalk31.yellow("disabled");
|
|
20295
20661
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
20296
20662
|
const row = [
|
|
20297
20663
|
schedule.name.padEnd(nameWidth),
|
|
@@ -20304,12 +20670,12 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20304
20670
|
console.log(row);
|
|
20305
20671
|
}
|
|
20306
20672
|
} catch (error43) {
|
|
20307
|
-
console.error(
|
|
20673
|
+
console.error(chalk31.red("\u2717 Failed to list schedules"));
|
|
20308
20674
|
if (error43 instanceof Error) {
|
|
20309
20675
|
if (error43.message.includes("Not authenticated")) {
|
|
20310
|
-
console.error(
|
|
20676
|
+
console.error(chalk31.dim(" Run: vm0 auth login"));
|
|
20311
20677
|
} else {
|
|
20312
|
-
console.error(
|
|
20678
|
+
console.error(chalk31.dim(` ${error43.message}`));
|
|
20313
20679
|
}
|
|
20314
20680
|
}
|
|
20315
20681
|
process.exit(1);
|
|
@@ -20317,32 +20683,32 @@ var listCommand4 = new Command28().name("list").alias("ls").description("List al
|
|
|
20317
20683
|
});
|
|
20318
20684
|
|
|
20319
20685
|
// src/commands/schedule/status.ts
|
|
20320
|
-
import { Command as
|
|
20321
|
-
import
|
|
20686
|
+
import { Command as Command30 } from "commander";
|
|
20687
|
+
import chalk32 from "chalk";
|
|
20322
20688
|
function formatDateTimeStyled(dateStr) {
|
|
20323
|
-
if (!dateStr) return
|
|
20689
|
+
if (!dateStr) return chalk32.dim("-");
|
|
20324
20690
|
const formatted = formatDateTime(dateStr);
|
|
20325
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
20691
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk32.dim("($1)"));
|
|
20326
20692
|
}
|
|
20327
20693
|
function formatTrigger(schedule) {
|
|
20328
20694
|
if (schedule.cronExpression) {
|
|
20329
|
-
return `${schedule.cronExpression} ${
|
|
20695
|
+
return `${schedule.cronExpression} ${chalk32.dim(`(${schedule.timezone})`)}`;
|
|
20330
20696
|
}
|
|
20331
20697
|
if (schedule.atTime) {
|
|
20332
|
-
return `${schedule.atTime} ${
|
|
20698
|
+
return `${schedule.atTime} ${chalk32.dim("(one-time)")}`;
|
|
20333
20699
|
}
|
|
20334
|
-
return
|
|
20700
|
+
return chalk32.dim("-");
|
|
20335
20701
|
}
|
|
20336
|
-
var statusCommand4 = new
|
|
20702
|
+
var statusCommand4 = new Command30().name("status").description("Show detailed status of a schedule").argument("<name>", "Schedule name").action(async (name) => {
|
|
20337
20703
|
try {
|
|
20338
20704
|
const result = loadAgentName();
|
|
20339
20705
|
if (result.error) {
|
|
20340
|
-
console.error(
|
|
20706
|
+
console.error(chalk32.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20341
20707
|
process.exit(1);
|
|
20342
20708
|
}
|
|
20343
20709
|
if (!result.agentName) {
|
|
20344
|
-
console.error(
|
|
20345
|
-
console.error(
|
|
20710
|
+
console.error(chalk32.red("\u2717 No vm0.yaml found in current directory"));
|
|
20711
|
+
console.error(chalk32.dim(" Run this command from the agent directory"));
|
|
20346
20712
|
process.exit(1);
|
|
20347
20713
|
}
|
|
20348
20714
|
const agentName = result.agentName;
|
|
@@ -20351,8 +20717,8 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20351
20717
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20352
20718
|
composeId = compose.id;
|
|
20353
20719
|
} catch {
|
|
20354
|
-
console.error(
|
|
20355
|
-
console.error(
|
|
20720
|
+
console.error(chalk32.red(`\u2717 Agent not found: ${agentName}`));
|
|
20721
|
+
console.error(chalk32.dim(" Make sure the agent is pushed first"));
|
|
20356
20722
|
process.exit(1);
|
|
20357
20723
|
}
|
|
20358
20724
|
const response = await apiClient.get(
|
|
@@ -20364,12 +20730,12 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20364
20730
|
}
|
|
20365
20731
|
const schedule = await response.json();
|
|
20366
20732
|
console.log();
|
|
20367
|
-
console.log(`Schedule: ${
|
|
20368
|
-
console.log(
|
|
20369
|
-
const statusText = schedule.enabled ?
|
|
20733
|
+
console.log(`Schedule: ${chalk32.cyan(schedule.name)}`);
|
|
20734
|
+
console.log(chalk32.dim("\u2501".repeat(50)));
|
|
20735
|
+
const statusText = schedule.enabled ? chalk32.green("enabled") : chalk32.yellow("disabled");
|
|
20370
20736
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
20371
20737
|
console.log(
|
|
20372
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
20738
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk32.dim(`(${schedule.scopeSlug})`)}`
|
|
20373
20739
|
);
|
|
20374
20740
|
console.log(`${"Trigger:".padEnd(16)}${formatTrigger(schedule)}`);
|
|
20375
20741
|
if (schedule.enabled) {
|
|
@@ -20378,11 +20744,11 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20378
20744
|
);
|
|
20379
20745
|
}
|
|
20380
20746
|
if (schedule.lastRunAt) {
|
|
20381
|
-
const lastRunInfo = schedule.lastRunId ? `${formatDateTimeStyled(schedule.lastRunAt)} ${
|
|
20747
|
+
const lastRunInfo = schedule.lastRunId ? `${formatDateTimeStyled(schedule.lastRunAt)} ${chalk32.dim(`[${schedule.lastRunId.slice(0, 8)}]`)}` : formatDateTimeStyled(schedule.lastRunAt);
|
|
20382
20748
|
console.log(`${"Last Run:".padEnd(16)}${lastRunInfo}`);
|
|
20383
20749
|
}
|
|
20384
20750
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
20385
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
20751
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk32.dim(promptPreview)}`);
|
|
20386
20752
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
20387
20753
|
console.log(
|
|
20388
20754
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -20404,26 +20770,26 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20404
20770
|
}
|
|
20405
20771
|
console.log();
|
|
20406
20772
|
console.log(
|
|
20407
|
-
|
|
20773
|
+
chalk32.dim(
|
|
20408
20774
|
`Created: ${new Date(schedule.createdAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20409
20775
|
)
|
|
20410
20776
|
);
|
|
20411
20777
|
console.log(
|
|
20412
|
-
|
|
20778
|
+
chalk32.dim(
|
|
20413
20779
|
`Updated: ${new Date(schedule.updatedAt).toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC")}`
|
|
20414
20780
|
)
|
|
20415
20781
|
);
|
|
20416
|
-
console.log(
|
|
20782
|
+
console.log(chalk32.dim(`ID: ${schedule.id}`));
|
|
20417
20783
|
console.log();
|
|
20418
20784
|
} catch (error43) {
|
|
20419
|
-
console.error(
|
|
20785
|
+
console.error(chalk32.red("\u2717 Failed to get schedule status"));
|
|
20420
20786
|
if (error43 instanceof Error) {
|
|
20421
20787
|
if (error43.message.includes("Not authenticated")) {
|
|
20422
|
-
console.error(
|
|
20788
|
+
console.error(chalk32.dim(" Run: vm0 auth login"));
|
|
20423
20789
|
} else if (error43.message.includes("not found") || error43.message.includes("Not found")) {
|
|
20424
|
-
console.error(
|
|
20790
|
+
console.error(chalk32.dim(` Schedule "${name}" not found`));
|
|
20425
20791
|
} else {
|
|
20426
|
-
console.error(
|
|
20792
|
+
console.error(chalk32.dim(` ${error43.message}`));
|
|
20427
20793
|
}
|
|
20428
20794
|
}
|
|
20429
20795
|
process.exit(1);
|
|
@@ -20431,8 +20797,8 @@ var statusCommand4 = new Command29().name("status").description("Show detailed s
|
|
|
20431
20797
|
});
|
|
20432
20798
|
|
|
20433
20799
|
// src/commands/schedule/delete.ts
|
|
20434
|
-
import { Command as
|
|
20435
|
-
import
|
|
20800
|
+
import { Command as Command31 } from "commander";
|
|
20801
|
+
import chalk33 from "chalk";
|
|
20436
20802
|
import * as readline from "readline";
|
|
20437
20803
|
async function confirm(message) {
|
|
20438
20804
|
const rl = readline.createInterface({
|
|
@@ -20446,16 +20812,16 @@ async function confirm(message) {
|
|
|
20446
20812
|
});
|
|
20447
20813
|
});
|
|
20448
20814
|
}
|
|
20449
|
-
var deleteCommand = new
|
|
20815
|
+
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
20816
|
try {
|
|
20451
20817
|
const result = loadAgentName();
|
|
20452
20818
|
if (result.error) {
|
|
20453
|
-
console.error(
|
|
20819
|
+
console.error(chalk33.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20454
20820
|
process.exit(1);
|
|
20455
20821
|
}
|
|
20456
20822
|
if (!result.agentName) {
|
|
20457
|
-
console.error(
|
|
20458
|
-
console.error(
|
|
20823
|
+
console.error(chalk33.red("\u2717 No vm0.yaml found in current directory"));
|
|
20824
|
+
console.error(chalk33.dim(" Run this command from the agent directory"));
|
|
20459
20825
|
process.exit(1);
|
|
20460
20826
|
}
|
|
20461
20827
|
const agentName = result.agentName;
|
|
@@ -20464,14 +20830,14 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20464
20830
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20465
20831
|
composeId = compose.id;
|
|
20466
20832
|
} catch {
|
|
20467
|
-
console.error(
|
|
20468
|
-
console.error(
|
|
20833
|
+
console.error(chalk33.red(`\u2717 Agent not found: ${agentName}`));
|
|
20834
|
+
console.error(chalk33.dim(" Make sure the agent is pushed first"));
|
|
20469
20835
|
process.exit(1);
|
|
20470
20836
|
}
|
|
20471
20837
|
if (!options.force) {
|
|
20472
|
-
const confirmed = await confirm(`Delete schedule ${
|
|
20838
|
+
const confirmed = await confirm(`Delete schedule ${chalk33.cyan(name)}?`);
|
|
20473
20839
|
if (!confirmed) {
|
|
20474
|
-
console.log(
|
|
20840
|
+
console.log(chalk33.dim("Cancelled"));
|
|
20475
20841
|
return;
|
|
20476
20842
|
}
|
|
20477
20843
|
}
|
|
@@ -20482,14 +20848,14 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20482
20848
|
const error43 = await response.json();
|
|
20483
20849
|
throw new Error(error43.error?.message || "Delete failed");
|
|
20484
20850
|
}
|
|
20485
|
-
console.log(
|
|
20851
|
+
console.log(chalk33.green(`\u2713 Deleted schedule ${chalk33.cyan(name)}`));
|
|
20486
20852
|
} catch (error43) {
|
|
20487
|
-
console.error(
|
|
20853
|
+
console.error(chalk33.red("\u2717 Failed to delete schedule"));
|
|
20488
20854
|
if (error43 instanceof Error) {
|
|
20489
20855
|
if (error43.message.includes("Not authenticated")) {
|
|
20490
|
-
console.error(
|
|
20856
|
+
console.error(chalk33.dim(" Run: vm0 auth login"));
|
|
20491
20857
|
} else {
|
|
20492
|
-
console.error(
|
|
20858
|
+
console.error(chalk33.dim(` ${error43.message}`));
|
|
20493
20859
|
}
|
|
20494
20860
|
}
|
|
20495
20861
|
process.exit(1);
|
|
@@ -20497,18 +20863,18 @@ var deleteCommand = new Command30().name("delete").alias("rm").description("Dele
|
|
|
20497
20863
|
});
|
|
20498
20864
|
|
|
20499
20865
|
// src/commands/schedule/enable.ts
|
|
20500
|
-
import { Command as
|
|
20501
|
-
import
|
|
20502
|
-
var enableCommand = new
|
|
20866
|
+
import { Command as Command32 } from "commander";
|
|
20867
|
+
import chalk34 from "chalk";
|
|
20868
|
+
var enableCommand = new Command32().name("enable").description("Enable a schedule").argument("<name>", "Schedule name to enable").action(async (name) => {
|
|
20503
20869
|
try {
|
|
20504
20870
|
const result = loadAgentName();
|
|
20505
20871
|
if (result.error) {
|
|
20506
|
-
console.error(
|
|
20872
|
+
console.error(chalk34.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20507
20873
|
process.exit(1);
|
|
20508
20874
|
}
|
|
20509
20875
|
if (!result.agentName) {
|
|
20510
|
-
console.error(
|
|
20511
|
-
console.error(
|
|
20876
|
+
console.error(chalk34.red("\u2717 No vm0.yaml found in current directory"));
|
|
20877
|
+
console.error(chalk34.dim(" Run this command from the agent directory"));
|
|
20512
20878
|
process.exit(1);
|
|
20513
20879
|
}
|
|
20514
20880
|
const agentName = result.agentName;
|
|
@@ -20517,8 +20883,8 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20517
20883
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20518
20884
|
composeId = compose.id;
|
|
20519
20885
|
} catch {
|
|
20520
|
-
console.error(
|
|
20521
|
-
console.error(
|
|
20886
|
+
console.error(chalk34.red(`\u2717 Agent not found: ${agentName}`));
|
|
20887
|
+
console.error(chalk34.dim(" Make sure the agent is pushed first"));
|
|
20522
20888
|
process.exit(1);
|
|
20523
20889
|
}
|
|
20524
20890
|
const response = await apiClient.post(
|
|
@@ -20529,14 +20895,14 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20529
20895
|
const error43 = await response.json();
|
|
20530
20896
|
throw new Error(error43.error?.message || "Enable failed");
|
|
20531
20897
|
}
|
|
20532
|
-
console.log(
|
|
20898
|
+
console.log(chalk34.green(`\u2713 Enabled schedule ${chalk34.cyan(name)}`));
|
|
20533
20899
|
} catch (error43) {
|
|
20534
|
-
console.error(
|
|
20900
|
+
console.error(chalk34.red("\u2717 Failed to enable schedule"));
|
|
20535
20901
|
if (error43 instanceof Error) {
|
|
20536
20902
|
if (error43.message.includes("Not authenticated")) {
|
|
20537
|
-
console.error(
|
|
20903
|
+
console.error(chalk34.dim(" Run: vm0 auth login"));
|
|
20538
20904
|
} else {
|
|
20539
|
-
console.error(
|
|
20905
|
+
console.error(chalk34.dim(` ${error43.message}`));
|
|
20540
20906
|
}
|
|
20541
20907
|
}
|
|
20542
20908
|
process.exit(1);
|
|
@@ -20544,18 +20910,18 @@ var enableCommand = new Command31().name("enable").description("Enable a schedul
|
|
|
20544
20910
|
});
|
|
20545
20911
|
|
|
20546
20912
|
// src/commands/schedule/disable.ts
|
|
20547
|
-
import { Command as
|
|
20548
|
-
import
|
|
20549
|
-
var disableCommand = new
|
|
20913
|
+
import { Command as Command33 } from "commander";
|
|
20914
|
+
import chalk35 from "chalk";
|
|
20915
|
+
var disableCommand = new Command33().name("disable").description("Disable a schedule").argument("<name>", "Schedule name to disable").action(async (name) => {
|
|
20550
20916
|
try {
|
|
20551
20917
|
const result = loadAgentName();
|
|
20552
20918
|
if (result.error) {
|
|
20553
|
-
console.error(
|
|
20919
|
+
console.error(chalk35.red(`\u2717 Invalid vm0.yaml: ${result.error}`));
|
|
20554
20920
|
process.exit(1);
|
|
20555
20921
|
}
|
|
20556
20922
|
if (!result.agentName) {
|
|
20557
|
-
console.error(
|
|
20558
|
-
console.error(
|
|
20923
|
+
console.error(chalk35.red("\u2717 No vm0.yaml found in current directory"));
|
|
20924
|
+
console.error(chalk35.dim(" Run this command from the agent directory"));
|
|
20559
20925
|
process.exit(1);
|
|
20560
20926
|
}
|
|
20561
20927
|
const agentName = result.agentName;
|
|
@@ -20564,8 +20930,8 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20564
20930
|
const compose = await apiClient.getComposeByName(agentName);
|
|
20565
20931
|
composeId = compose.id;
|
|
20566
20932
|
} catch {
|
|
20567
|
-
console.error(
|
|
20568
|
-
console.error(
|
|
20933
|
+
console.error(chalk35.red(`\u2717 Agent not found: ${agentName}`));
|
|
20934
|
+
console.error(chalk35.dim(" Make sure the agent is pushed first"));
|
|
20569
20935
|
process.exit(1);
|
|
20570
20936
|
}
|
|
20571
20937
|
const response = await apiClient.post(
|
|
@@ -20576,14 +20942,14 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20576
20942
|
const error43 = await response.json();
|
|
20577
20943
|
throw new Error(error43.error?.message || "Disable failed");
|
|
20578
20944
|
}
|
|
20579
|
-
console.log(
|
|
20945
|
+
console.log(chalk35.green(`\u2713 Disabled schedule ${chalk35.cyan(name)}`));
|
|
20580
20946
|
} catch (error43) {
|
|
20581
|
-
console.error(
|
|
20947
|
+
console.error(chalk35.red("\u2717 Failed to disable schedule"));
|
|
20582
20948
|
if (error43 instanceof Error) {
|
|
20583
20949
|
if (error43.message.includes("Not authenticated")) {
|
|
20584
|
-
console.error(
|
|
20950
|
+
console.error(chalk35.dim(" Run: vm0 auth login"));
|
|
20585
20951
|
} else {
|
|
20586
|
-
console.error(
|
|
20952
|
+
console.error(chalk35.dim(` ${error43.message}`));
|
|
20587
20953
|
}
|
|
20588
20954
|
}
|
|
20589
20955
|
process.exit(1);
|
|
@@ -20591,13 +20957,13 @@ var disableCommand = new Command32().name("disable").description("Disable a sche
|
|
|
20591
20957
|
});
|
|
20592
20958
|
|
|
20593
20959
|
// src/commands/schedule/index.ts
|
|
20594
|
-
var scheduleCommand = new
|
|
20960
|
+
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
20961
|
|
|
20596
20962
|
// src/index.ts
|
|
20597
|
-
var program = new
|
|
20598
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.
|
|
20963
|
+
var program = new Command35();
|
|
20964
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("5.3.1");
|
|
20599
20965
|
program.command("info").description("Display environment information").action(async () => {
|
|
20600
|
-
console.log(
|
|
20966
|
+
console.log(chalk36.bold("System Information:"));
|
|
20601
20967
|
console.log(`Node Version: ${process.version}`);
|
|
20602
20968
|
console.log(`Platform: ${process.platform}`);
|
|
20603
20969
|
console.log(`Architecture: ${process.arch}`);
|