@vm0/cli 4.20.0 → 4.21.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 +774 -370
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { Command as Command23 } from "commander";
|
|
10
|
-
import
|
|
10
|
+
import chalk24 from "chalk";
|
|
11
11
|
|
|
12
12
|
// src/lib/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -12559,7 +12559,8 @@ var eventsResponseSchema = external_exports.object({
|
|
|
12559
12559
|
events: external_exports.array(runEventSchema),
|
|
12560
12560
|
hasMore: external_exports.boolean(),
|
|
12561
12561
|
nextSequence: external_exports.number(),
|
|
12562
|
-
run: runStateSchema
|
|
12562
|
+
run: runStateSchema,
|
|
12563
|
+
provider: external_exports.string()
|
|
12563
12564
|
});
|
|
12564
12565
|
var runsMainContract = c3.router({
|
|
12565
12566
|
/**
|
|
@@ -12640,7 +12641,8 @@ var metricsResponseSchema = external_exports.object({
|
|
|
12640
12641
|
});
|
|
12641
12642
|
var agentEventsResponseSchema = external_exports.object({
|
|
12642
12643
|
events: external_exports.array(runEventSchema),
|
|
12643
|
-
hasMore: external_exports.boolean()
|
|
12644
|
+
hasMore: external_exports.boolean(),
|
|
12645
|
+
provider: external_exports.string()
|
|
12644
12646
|
});
|
|
12645
12647
|
var networkLogEntrySchema = external_exports.object({
|
|
12646
12648
|
timestamp: external_exports.string(),
|
|
@@ -13493,6 +13495,12 @@ function getLegacySystemTemplateWarning(legacyFormat) {
|
|
|
13493
13495
|
if (legacyFormat === "vm0-claude-code-dev") {
|
|
13494
13496
|
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/claude-code:dev" instead.`;
|
|
13495
13497
|
}
|
|
13498
|
+
if (legacyFormat === "vm0-codex") {
|
|
13499
|
+
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/codex" instead.`;
|
|
13500
|
+
}
|
|
13501
|
+
if (legacyFormat === "vm0-codex-dev") {
|
|
13502
|
+
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/codex:dev" instead.`;
|
|
13503
|
+
}
|
|
13496
13504
|
if (legacyFormat.startsWith("vm0-github-cli")) {
|
|
13497
13505
|
return `Warning: "${legacyFormat}" is deprecated and will be removed. No replacement available.`;
|
|
13498
13506
|
}
|
|
@@ -13516,6 +13524,61 @@ function getSkillStorageName(fullPath) {
|
|
|
13516
13524
|
return `agent-skills@${fullPath}`;
|
|
13517
13525
|
}
|
|
13518
13526
|
|
|
13527
|
+
// ../../packages/core/src/github-url.ts
|
|
13528
|
+
function parseGitHubTreeUrl(url2) {
|
|
13529
|
+
const fullPathMatch = url2.match(/^https:\/\/github\.com\/(.+)$/);
|
|
13530
|
+
if (!fullPathMatch) {
|
|
13531
|
+
return null;
|
|
13532
|
+
}
|
|
13533
|
+
const fullPath = fullPathMatch[1];
|
|
13534
|
+
const regex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
|
|
13535
|
+
const match = url2.match(regex);
|
|
13536
|
+
if (!match) {
|
|
13537
|
+
return null;
|
|
13538
|
+
}
|
|
13539
|
+
const [, owner, repo, branch, pathPart] = match;
|
|
13540
|
+
const pathSegments = pathPart.split("/").filter(Boolean);
|
|
13541
|
+
const skillName = pathSegments[pathSegments.length - 1] || pathPart;
|
|
13542
|
+
return {
|
|
13543
|
+
owner,
|
|
13544
|
+
repo,
|
|
13545
|
+
branch,
|
|
13546
|
+
path: pathPart,
|
|
13547
|
+
skillName,
|
|
13548
|
+
fullPath
|
|
13549
|
+
};
|
|
13550
|
+
}
|
|
13551
|
+
|
|
13552
|
+
// ../../packages/core/src/providers.ts
|
|
13553
|
+
var SUPPORTED_PROVIDERS = ["claude-code", "codex"];
|
|
13554
|
+
function isSupportedProvider(provider) {
|
|
13555
|
+
if (!provider) return false;
|
|
13556
|
+
return SUPPORTED_PROVIDERS.includes(provider);
|
|
13557
|
+
}
|
|
13558
|
+
function assertSupportedProvider(provider, context) {
|
|
13559
|
+
if (!isSupportedProvider(provider)) {
|
|
13560
|
+
const contextMsg = context ? ` in ${context}` : "";
|
|
13561
|
+
throw new Error(
|
|
13562
|
+
`Unsupported provider "${provider}"${contextMsg}. Supported providers: ${SUPPORTED_PROVIDERS.join(", ")}`
|
|
13563
|
+
);
|
|
13564
|
+
}
|
|
13565
|
+
}
|
|
13566
|
+
function getValidatedProvider(provider) {
|
|
13567
|
+
if (provider === void 0) {
|
|
13568
|
+
return "claude-code";
|
|
13569
|
+
}
|
|
13570
|
+
assertSupportedProvider(provider);
|
|
13571
|
+
return provider;
|
|
13572
|
+
}
|
|
13573
|
+
var PROVIDER_DISPLAY_NAMES = {
|
|
13574
|
+
"claude-code": "Claude Code",
|
|
13575
|
+
codex: "Codex"
|
|
13576
|
+
};
|
|
13577
|
+
function getProviderDisplayName(provider) {
|
|
13578
|
+
assertSupportedProvider(provider);
|
|
13579
|
+
return PROVIDER_DISPLAY_NAMES[provider];
|
|
13580
|
+
}
|
|
13581
|
+
|
|
13519
13582
|
// src/lib/api-client.ts
|
|
13520
13583
|
var ApiClient = class {
|
|
13521
13584
|
async getHeaders() {
|
|
@@ -13900,6 +13963,13 @@ var PROVIDER_DEFAULTS = {
|
|
|
13900
13963
|
production: "vm0/claude-code:latest",
|
|
13901
13964
|
development: "vm0/claude-code:dev"
|
|
13902
13965
|
}
|
|
13966
|
+
},
|
|
13967
|
+
codex: {
|
|
13968
|
+
workingDir: "/home/user/workspace",
|
|
13969
|
+
image: {
|
|
13970
|
+
production: "vm0/codex:latest",
|
|
13971
|
+
development: "vm0/codex:dev"
|
|
13972
|
+
}
|
|
13903
13973
|
}
|
|
13904
13974
|
};
|
|
13905
13975
|
function getProviderDefaults(provider) {
|
|
@@ -14115,32 +14185,14 @@ import * as os from "os";
|
|
|
14115
14185
|
import { exec } from "child_process";
|
|
14116
14186
|
import { promisify } from "util";
|
|
14117
14187
|
var execAsync = promisify(exec);
|
|
14118
|
-
function
|
|
14119
|
-
const
|
|
14120
|
-
if (!
|
|
14121
|
-
throw new Error(
|
|
14122
|
-
`Invalid GitHub URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
|
|
14123
|
-
);
|
|
14124
|
-
}
|
|
14125
|
-
const fullPath = fullPathMatch[1];
|
|
14126
|
-
const regex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
|
|
14127
|
-
const match = url2.match(regex);
|
|
14128
|
-
if (!match) {
|
|
14188
|
+
function parseGitHubTreeUrl2(url2) {
|
|
14189
|
+
const parsed = parseGitHubTreeUrl(url2);
|
|
14190
|
+
if (!parsed) {
|
|
14129
14191
|
throw new Error(
|
|
14130
14192
|
`Invalid GitHub tree URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
|
|
14131
14193
|
);
|
|
14132
14194
|
}
|
|
14133
|
-
|
|
14134
|
-
const pathSegments = pathPart.split("/");
|
|
14135
|
-
const skillName = pathSegments[pathSegments.length - 1];
|
|
14136
|
-
return {
|
|
14137
|
-
owner,
|
|
14138
|
-
repo,
|
|
14139
|
-
branch,
|
|
14140
|
-
path: pathPart,
|
|
14141
|
-
skillName,
|
|
14142
|
-
fullPath
|
|
14143
|
-
};
|
|
14195
|
+
return parsed;
|
|
14144
14196
|
}
|
|
14145
14197
|
function getSkillStorageName2(parsed) {
|
|
14146
14198
|
return getSkillStorageName(parsed.fullPath);
|
|
@@ -14479,14 +14531,22 @@ async function directUpload(storageName, storageType, cwd, options) {
|
|
|
14479
14531
|
}
|
|
14480
14532
|
|
|
14481
14533
|
// src/lib/system-storage.ts
|
|
14482
|
-
|
|
14534
|
+
function getInstructionsFilename(provider) {
|
|
14535
|
+
const validatedProvider = getValidatedProvider(provider);
|
|
14536
|
+
if (validatedProvider === "codex") {
|
|
14537
|
+
return "AGENTS.md";
|
|
14538
|
+
}
|
|
14539
|
+
return "CLAUDE.md";
|
|
14540
|
+
}
|
|
14541
|
+
async function uploadInstructions(agentName, instructionsFilePath, basePath, provider) {
|
|
14483
14542
|
const storageName = getInstructionsStorageName(agentName);
|
|
14484
14543
|
const absolutePath = path4.isAbsolute(instructionsFilePath) ? instructionsFilePath : path4.join(basePath, instructionsFilePath);
|
|
14485
14544
|
const content = await fs4.readFile(absolutePath, "utf8");
|
|
14486
14545
|
const tmpDir = await fs4.mkdtemp(path4.join(os3.tmpdir(), "vm0-instructions-"));
|
|
14487
14546
|
const instructionsDir = path4.join(tmpDir, "instructions");
|
|
14488
14547
|
await fs4.mkdir(instructionsDir);
|
|
14489
|
-
|
|
14548
|
+
const filename = getInstructionsFilename(provider);
|
|
14549
|
+
await fs4.writeFile(path4.join(instructionsDir, filename), content);
|
|
14490
14550
|
try {
|
|
14491
14551
|
const result = await directUpload(storageName, "volume", instructionsDir);
|
|
14492
14552
|
return {
|
|
@@ -14499,7 +14559,7 @@ async function uploadInstructions(agentName, instructionsFilePath, basePath) {
|
|
|
14499
14559
|
}
|
|
14500
14560
|
}
|
|
14501
14561
|
async function uploadSkill(skillUrl) {
|
|
14502
|
-
const parsed =
|
|
14562
|
+
const parsed = parseGitHubTreeUrl2(skillUrl);
|
|
14503
14563
|
const storageName = getSkillStorageName2(parsed);
|
|
14504
14564
|
const tmpDir = await fs4.mkdtemp(path4.join(os3.tmpdir(), "vm0-skill-"));
|
|
14505
14565
|
try {
|
|
@@ -14578,12 +14638,14 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
14578
14638
|
}
|
|
14579
14639
|
if (agent.instructions) {
|
|
14580
14640
|
const instructionsPath = agent.instructions;
|
|
14641
|
+
const provider = agent.provider;
|
|
14581
14642
|
console.log(chalk2.blue(`Uploading instructions: ${instructionsPath}`));
|
|
14582
14643
|
try {
|
|
14583
14644
|
const result = await uploadInstructions(
|
|
14584
14645
|
agentName,
|
|
14585
14646
|
instructionsPath,
|
|
14586
|
-
basePath
|
|
14647
|
+
basePath,
|
|
14648
|
+
provider
|
|
14587
14649
|
);
|
|
14588
14650
|
console.log(
|
|
14589
14651
|
chalk2.green(
|
|
@@ -14658,12 +14720,12 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
14658
14720
|
|
|
14659
14721
|
// src/commands/run.ts
|
|
14660
14722
|
import { Command as Command2 } from "commander";
|
|
14661
|
-
import
|
|
14723
|
+
import chalk5 from "chalk";
|
|
14662
14724
|
import * as fs5 from "fs";
|
|
14663
14725
|
import * as path5 from "path";
|
|
14664
14726
|
import { config as dotenvConfig } from "dotenv";
|
|
14665
14727
|
|
|
14666
|
-
// src/lib/event-parser.ts
|
|
14728
|
+
// src/lib/claude-event-parser.ts
|
|
14667
14729
|
var ClaudeEventParser = class {
|
|
14668
14730
|
/**
|
|
14669
14731
|
* Parse a raw Claude Code JSONL event into a simplified format
|
|
@@ -14694,6 +14756,7 @@ var ClaudeEventParser = class {
|
|
|
14694
14756
|
type: "init",
|
|
14695
14757
|
timestamp: /* @__PURE__ */ new Date(),
|
|
14696
14758
|
data: {
|
|
14759
|
+
provider: "claude-code",
|
|
14697
14760
|
sessionId: event.session_id,
|
|
14698
14761
|
model: event.model,
|
|
14699
14762
|
tools: event.tools,
|
|
@@ -14766,6 +14829,222 @@ var ClaudeEventParser = class {
|
|
|
14766
14829
|
}
|
|
14767
14830
|
};
|
|
14768
14831
|
|
|
14832
|
+
// src/lib/codex-event-parser.ts
|
|
14833
|
+
var CodexEventParser = class {
|
|
14834
|
+
/**
|
|
14835
|
+
* Parse a raw Codex CLI JSONL event into a simplified format
|
|
14836
|
+
* Returns null if the event type is unknown or malformed
|
|
14837
|
+
*/
|
|
14838
|
+
static parse(rawEvent) {
|
|
14839
|
+
if (!rawEvent || typeof rawEvent !== "object" || !("type" in rawEvent)) {
|
|
14840
|
+
return null;
|
|
14841
|
+
}
|
|
14842
|
+
const eventType = rawEvent.type;
|
|
14843
|
+
if (eventType === "thread.started") {
|
|
14844
|
+
return this.parseThreadStarted(rawEvent);
|
|
14845
|
+
}
|
|
14846
|
+
if (eventType === "turn.completed") {
|
|
14847
|
+
return this.parseTurnCompleted(rawEvent);
|
|
14848
|
+
}
|
|
14849
|
+
if (eventType === "turn.failed") {
|
|
14850
|
+
return this.parseTurnFailed(rawEvent);
|
|
14851
|
+
}
|
|
14852
|
+
if (eventType.startsWith("item.")) {
|
|
14853
|
+
return this.parseItemEvent(rawEvent);
|
|
14854
|
+
}
|
|
14855
|
+
if (eventType === "error") {
|
|
14856
|
+
return this.parseErrorEvent(rawEvent);
|
|
14857
|
+
}
|
|
14858
|
+
return null;
|
|
14859
|
+
}
|
|
14860
|
+
static parseThreadStarted(event) {
|
|
14861
|
+
return {
|
|
14862
|
+
type: "init",
|
|
14863
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14864
|
+
data: {
|
|
14865
|
+
provider: "codex",
|
|
14866
|
+
sessionId: event.thread_id,
|
|
14867
|
+
tools: []
|
|
14868
|
+
}
|
|
14869
|
+
};
|
|
14870
|
+
}
|
|
14871
|
+
static parseTurnCompleted(event) {
|
|
14872
|
+
return {
|
|
14873
|
+
type: "result",
|
|
14874
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14875
|
+
data: {
|
|
14876
|
+
success: true,
|
|
14877
|
+
result: "",
|
|
14878
|
+
durationMs: 0,
|
|
14879
|
+
numTurns: 1,
|
|
14880
|
+
cost: 0,
|
|
14881
|
+
usage: event.usage || {}
|
|
14882
|
+
}
|
|
14883
|
+
};
|
|
14884
|
+
}
|
|
14885
|
+
static parseTurnFailed(event) {
|
|
14886
|
+
return {
|
|
14887
|
+
type: "result",
|
|
14888
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14889
|
+
data: {
|
|
14890
|
+
success: false,
|
|
14891
|
+
result: event.error || "Turn failed",
|
|
14892
|
+
durationMs: 0,
|
|
14893
|
+
numTurns: 1,
|
|
14894
|
+
cost: 0,
|
|
14895
|
+
usage: {}
|
|
14896
|
+
}
|
|
14897
|
+
};
|
|
14898
|
+
}
|
|
14899
|
+
static parseItemEvent(event) {
|
|
14900
|
+
const item = event.item;
|
|
14901
|
+
if (!item) {
|
|
14902
|
+
return null;
|
|
14903
|
+
}
|
|
14904
|
+
const itemType = item.type;
|
|
14905
|
+
if (itemType === "agent_message" && item.text) {
|
|
14906
|
+
return {
|
|
14907
|
+
type: "text",
|
|
14908
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14909
|
+
data: { text: item.text }
|
|
14910
|
+
};
|
|
14911
|
+
}
|
|
14912
|
+
if (itemType === "command_execution") {
|
|
14913
|
+
if (event.type === "item.started" && item.command) {
|
|
14914
|
+
return {
|
|
14915
|
+
type: "tool_use",
|
|
14916
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14917
|
+
data: {
|
|
14918
|
+
tool: "Bash",
|
|
14919
|
+
toolUseId: item.id,
|
|
14920
|
+
input: { command: item.command }
|
|
14921
|
+
}
|
|
14922
|
+
};
|
|
14923
|
+
}
|
|
14924
|
+
if (event.type === "item.completed") {
|
|
14925
|
+
const output = item.aggregated_output ?? item.output ?? "";
|
|
14926
|
+
return {
|
|
14927
|
+
type: "tool_result",
|
|
14928
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14929
|
+
data: {
|
|
14930
|
+
toolUseId: item.id,
|
|
14931
|
+
result: output,
|
|
14932
|
+
isError: item.exit_code !== 0
|
|
14933
|
+
}
|
|
14934
|
+
};
|
|
14935
|
+
}
|
|
14936
|
+
}
|
|
14937
|
+
if (itemType === "file_edit" || itemType === "file_write") {
|
|
14938
|
+
if (event.type === "item.started" && item.path) {
|
|
14939
|
+
return {
|
|
14940
|
+
type: "tool_use",
|
|
14941
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14942
|
+
data: {
|
|
14943
|
+
tool: itemType === "file_edit" ? "Edit" : "Write",
|
|
14944
|
+
toolUseId: item.id,
|
|
14945
|
+
input: { file_path: item.path }
|
|
14946
|
+
}
|
|
14947
|
+
};
|
|
14948
|
+
}
|
|
14949
|
+
if (event.type === "item.completed") {
|
|
14950
|
+
return {
|
|
14951
|
+
type: "tool_result",
|
|
14952
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14953
|
+
data: {
|
|
14954
|
+
toolUseId: item.id,
|
|
14955
|
+
result: item.diff || "File operation completed",
|
|
14956
|
+
isError: false
|
|
14957
|
+
}
|
|
14958
|
+
};
|
|
14959
|
+
}
|
|
14960
|
+
}
|
|
14961
|
+
if (itemType === "file_read") {
|
|
14962
|
+
if (event.type === "item.started" && item.path) {
|
|
14963
|
+
return {
|
|
14964
|
+
type: "tool_use",
|
|
14965
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14966
|
+
data: {
|
|
14967
|
+
tool: "Read",
|
|
14968
|
+
toolUseId: item.id,
|
|
14969
|
+
input: { file_path: item.path }
|
|
14970
|
+
}
|
|
14971
|
+
};
|
|
14972
|
+
}
|
|
14973
|
+
if (event.type === "item.completed") {
|
|
14974
|
+
return {
|
|
14975
|
+
type: "tool_result",
|
|
14976
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14977
|
+
data: {
|
|
14978
|
+
toolUseId: item.id,
|
|
14979
|
+
result: "File read completed",
|
|
14980
|
+
isError: false
|
|
14981
|
+
}
|
|
14982
|
+
};
|
|
14983
|
+
}
|
|
14984
|
+
}
|
|
14985
|
+
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
14986
|
+
const changes = item.changes.map((c12) => {
|
|
14987
|
+
const action = c12.kind === "add" ? "Created" : c12.kind === "modify" ? "Modified" : "Deleted";
|
|
14988
|
+
return `${action}: ${c12.path}`;
|
|
14989
|
+
}).join("\n");
|
|
14990
|
+
return {
|
|
14991
|
+
type: "text",
|
|
14992
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
14993
|
+
data: { text: `[files]
|
|
14994
|
+
${changes}` }
|
|
14995
|
+
};
|
|
14996
|
+
}
|
|
14997
|
+
if (itemType === "reasoning" && item.text) {
|
|
14998
|
+
return {
|
|
14999
|
+
type: "text",
|
|
15000
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
15001
|
+
data: { text: `[thinking] ${item.text}` }
|
|
15002
|
+
};
|
|
15003
|
+
}
|
|
15004
|
+
return null;
|
|
15005
|
+
}
|
|
15006
|
+
static parseErrorEvent(event) {
|
|
15007
|
+
return {
|
|
15008
|
+
type: "result",
|
|
15009
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
15010
|
+
data: {
|
|
15011
|
+
success: false,
|
|
15012
|
+
result: event.message || event.error || "Unknown error",
|
|
15013
|
+
durationMs: 0,
|
|
15014
|
+
numTurns: 0,
|
|
15015
|
+
cost: 0,
|
|
15016
|
+
usage: {}
|
|
15017
|
+
}
|
|
15018
|
+
};
|
|
15019
|
+
}
|
|
15020
|
+
};
|
|
15021
|
+
|
|
15022
|
+
// src/lib/event-parser-factory.ts
|
|
15023
|
+
function detectProviderFromEvent(rawEvent) {
|
|
15024
|
+
if (!rawEvent || typeof rawEvent !== "object") {
|
|
15025
|
+
return null;
|
|
15026
|
+
}
|
|
15027
|
+
const eventType = rawEvent.type;
|
|
15028
|
+
if (eventType === "thread.started" || eventType === "turn.started" || eventType === "turn.completed" || eventType === "turn.failed" || eventType?.startsWith("item.")) {
|
|
15029
|
+
return "codex";
|
|
15030
|
+
}
|
|
15031
|
+
if (eventType === "system" || eventType === "assistant" || eventType === "user" || eventType === "result") {
|
|
15032
|
+
return "claude-code";
|
|
15033
|
+
}
|
|
15034
|
+
return null;
|
|
15035
|
+
}
|
|
15036
|
+
function getEventParser(provider) {
|
|
15037
|
+
if (provider === "codex") {
|
|
15038
|
+
return CodexEventParser;
|
|
15039
|
+
}
|
|
15040
|
+
return ClaudeEventParser;
|
|
15041
|
+
}
|
|
15042
|
+
function parseEvent(rawEvent, provider) {
|
|
15043
|
+
const effectiveProvider = provider ? getValidatedProvider(provider) : detectProviderFromEvent(rawEvent) || "claude-code";
|
|
15044
|
+
const Parser = getEventParser(effectiveProvider);
|
|
15045
|
+
return Parser.parse(rawEvent);
|
|
15046
|
+
}
|
|
15047
|
+
|
|
14769
15048
|
// src/lib/event-renderer.ts
|
|
14770
15049
|
import chalk3 from "chalk";
|
|
14771
15050
|
var EventRenderer = class {
|
|
@@ -14880,11 +15159,15 @@ var EventRenderer = class {
|
|
|
14880
15159
|
);
|
|
14881
15160
|
}
|
|
14882
15161
|
static renderInit(event, prefix, suffix) {
|
|
15162
|
+
const providerStr = String(event.data.provider || "claude-code");
|
|
15163
|
+
const displayName = isSupportedProvider(providerStr) ? getProviderDisplayName(providerStr) : providerStr;
|
|
14883
15164
|
console.log(
|
|
14884
|
-
prefix + chalk3.cyan("[init]") + suffix +
|
|
15165
|
+
prefix + chalk3.cyan("[init]") + suffix + ` Starting ${displayName} agent`
|
|
14885
15166
|
);
|
|
14886
15167
|
console.log(` Session: ${chalk3.gray(String(event.data.sessionId || ""))}`);
|
|
14887
|
-
|
|
15168
|
+
if (event.data.model) {
|
|
15169
|
+
console.log(` Model: ${chalk3.gray(String(event.data.model))}`);
|
|
15170
|
+
}
|
|
14888
15171
|
console.log(
|
|
14889
15172
|
` Tools: ${chalk3.gray(
|
|
14890
15173
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
@@ -14956,6 +15239,121 @@ var EventRenderer = class {
|
|
|
14956
15239
|
}
|
|
14957
15240
|
};
|
|
14958
15241
|
|
|
15242
|
+
// src/lib/codex-event-renderer.ts
|
|
15243
|
+
import chalk4 from "chalk";
|
|
15244
|
+
var CodexEventRenderer = class {
|
|
15245
|
+
/**
|
|
15246
|
+
* Check if an event is a Codex event
|
|
15247
|
+
*/
|
|
15248
|
+
static isCodexEvent(event) {
|
|
15249
|
+
const type = event.type;
|
|
15250
|
+
return type === "thread.started" || type === "turn.started" || type === "turn.completed" || type === "turn.failed" || type?.startsWith("item.") || type === "error";
|
|
15251
|
+
}
|
|
15252
|
+
/**
|
|
15253
|
+
* Render a raw Codex event
|
|
15254
|
+
*/
|
|
15255
|
+
static render(rawEvent) {
|
|
15256
|
+
const event = rawEvent;
|
|
15257
|
+
const type = event.type;
|
|
15258
|
+
switch (type) {
|
|
15259
|
+
case "thread.started":
|
|
15260
|
+
this.renderThreadStarted(event);
|
|
15261
|
+
break;
|
|
15262
|
+
case "turn.started":
|
|
15263
|
+
break;
|
|
15264
|
+
case "turn.completed":
|
|
15265
|
+
this.renderTurnCompleted(event);
|
|
15266
|
+
break;
|
|
15267
|
+
case "turn.failed":
|
|
15268
|
+
this.renderTurnFailed(event);
|
|
15269
|
+
break;
|
|
15270
|
+
case "item.started":
|
|
15271
|
+
case "item.updated":
|
|
15272
|
+
case "item.completed":
|
|
15273
|
+
this.renderItem(event);
|
|
15274
|
+
break;
|
|
15275
|
+
case "error":
|
|
15276
|
+
this.renderError(event);
|
|
15277
|
+
break;
|
|
15278
|
+
}
|
|
15279
|
+
}
|
|
15280
|
+
static renderThreadStarted(event) {
|
|
15281
|
+
console.log(chalk4.cyan("[thread.started]") + ` ${event.thread_id}`);
|
|
15282
|
+
}
|
|
15283
|
+
static renderTurnCompleted(event) {
|
|
15284
|
+
if (event.usage) {
|
|
15285
|
+
const input = event.usage.input_tokens || 0;
|
|
15286
|
+
const output = event.usage.output_tokens || 0;
|
|
15287
|
+
const cached2 = event.usage.cached_input_tokens || 0;
|
|
15288
|
+
const cachedStr = cached2 ? ` (${cached2} cached)` : "";
|
|
15289
|
+
console.log(
|
|
15290
|
+
chalk4.cyan("[turn.completed]") + chalk4.gray(` ${input} in / ${output} out${cachedStr}`)
|
|
15291
|
+
);
|
|
15292
|
+
}
|
|
15293
|
+
}
|
|
15294
|
+
static renderTurnFailed(event) {
|
|
15295
|
+
console.log(
|
|
15296
|
+
chalk4.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
|
|
15297
|
+
);
|
|
15298
|
+
}
|
|
15299
|
+
static renderItem(event) {
|
|
15300
|
+
const item = event.item;
|
|
15301
|
+
if (!item) return;
|
|
15302
|
+
const itemType = item.type;
|
|
15303
|
+
const eventType = event.type;
|
|
15304
|
+
if (itemType === "reasoning" && item.text) {
|
|
15305
|
+
console.log(chalk4.magenta("[reasoning]") + ` ${item.text}`);
|
|
15306
|
+
return;
|
|
15307
|
+
}
|
|
15308
|
+
if (itemType === "agent_message" && item.text) {
|
|
15309
|
+
console.log(chalk4.blue("[message]") + ` ${item.text}`);
|
|
15310
|
+
return;
|
|
15311
|
+
}
|
|
15312
|
+
if (itemType === "command_execution") {
|
|
15313
|
+
if (eventType === "item.started" && item.command) {
|
|
15314
|
+
console.log(chalk4.yellow("[exec]") + ` ${item.command}`);
|
|
15315
|
+
} else if (eventType === "item.completed") {
|
|
15316
|
+
const output = item.aggregated_output || "";
|
|
15317
|
+
const exitCode = item.exit_code ?? 0;
|
|
15318
|
+
if (output) {
|
|
15319
|
+
const lines = output.split("\n").filter((l) => l.trim());
|
|
15320
|
+
const preview = lines.slice(0, 3).join("\n ");
|
|
15321
|
+
const more = lines.length > 3 ? chalk4.gray(` ... (${lines.length - 3} more lines)`) : "";
|
|
15322
|
+
console.log(
|
|
15323
|
+
chalk4.gray("[output]") + (exitCode !== 0 ? chalk4.red(` exit=${exitCode}`) : "")
|
|
15324
|
+
);
|
|
15325
|
+
if (preview) {
|
|
15326
|
+
console.log(" " + preview + more);
|
|
15327
|
+
}
|
|
15328
|
+
} else if (exitCode !== 0) {
|
|
15329
|
+
console.log(chalk4.red("[output]") + chalk4.red(` exit=${exitCode}`));
|
|
15330
|
+
}
|
|
15331
|
+
}
|
|
15332
|
+
return;
|
|
15333
|
+
}
|
|
15334
|
+
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
15335
|
+
const summary = item.changes.map((c12) => {
|
|
15336
|
+
const icon = c12.kind === "add" ? "+" : c12.kind === "delete" ? "-" : "~";
|
|
15337
|
+
return `${icon}${c12.path}`;
|
|
15338
|
+
}).join(", ");
|
|
15339
|
+
console.log(chalk4.green("[files]") + ` ${summary}`);
|
|
15340
|
+
return;
|
|
15341
|
+
}
|
|
15342
|
+
if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
|
|
15343
|
+
const action = itemType.replace("file_", "");
|
|
15344
|
+
if (eventType === "item.started" && item.path) {
|
|
15345
|
+
console.log(chalk4.blue(`[${action}]`) + ` ${item.path}`);
|
|
15346
|
+
}
|
|
15347
|
+
return;
|
|
15348
|
+
}
|
|
15349
|
+
}
|
|
15350
|
+
static renderError(event) {
|
|
15351
|
+
console.log(
|
|
15352
|
+
chalk4.red("[error]") + ` ${event.message || event.error || "Unknown error"}`
|
|
15353
|
+
);
|
|
15354
|
+
}
|
|
15355
|
+
};
|
|
15356
|
+
|
|
14959
15357
|
// src/commands/run.ts
|
|
14960
15358
|
function collectKeyValue(value, previous) {
|
|
14961
15359
|
const [key, ...valueParts] = value.split("=");
|
|
@@ -15041,16 +15439,19 @@ async function pollEvents(runId, options) {
|
|
|
15041
15439
|
since: nextSequence
|
|
15042
15440
|
});
|
|
15043
15441
|
for (const event of response.events) {
|
|
15044
|
-
const
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15442
|
+
const eventData = event.eventData;
|
|
15443
|
+
if (response.provider === "codex") {
|
|
15444
|
+
CodexEventRenderer.render(eventData);
|
|
15445
|
+
} else {
|
|
15446
|
+
const parsed = parseEvent(eventData);
|
|
15447
|
+
if (parsed) {
|
|
15448
|
+
EventRenderer.render(parsed, {
|
|
15449
|
+
verbose,
|
|
15450
|
+
previousTimestamp,
|
|
15451
|
+
startTimestamp
|
|
15452
|
+
});
|
|
15453
|
+
previousTimestamp = parsed.timestamp;
|
|
15454
|
+
}
|
|
15054
15455
|
}
|
|
15055
15456
|
}
|
|
15056
15457
|
nextSequence = response.nextSequence;
|
|
@@ -15074,9 +15475,9 @@ async function pollEvents(runId, options) {
|
|
|
15074
15475
|
result = { succeeded: false, runId };
|
|
15075
15476
|
} else if (runStatus === "timeout") {
|
|
15076
15477
|
complete = true;
|
|
15077
|
-
console.error(
|
|
15478
|
+
console.error(chalk5.red("\n\u2717 Run timed out"));
|
|
15078
15479
|
console.error(
|
|
15079
|
-
|
|
15480
|
+
chalk5.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
15080
15481
|
);
|
|
15081
15482
|
result = { succeeded: false, runId };
|
|
15082
15483
|
}
|
|
@@ -15087,15 +15488,15 @@ async function pollEvents(runId, options) {
|
|
|
15087
15488
|
return result;
|
|
15088
15489
|
}
|
|
15089
15490
|
function logVerbosePreFlight(action, details) {
|
|
15090
|
-
console.log(
|
|
15491
|
+
console.log(chalk5.blue(`
|
|
15091
15492
|
${action}...`));
|
|
15092
15493
|
for (const { label, value } of details) {
|
|
15093
15494
|
if (value !== void 0) {
|
|
15094
|
-
console.log(
|
|
15495
|
+
console.log(chalk5.gray(` ${label}: ${value}`));
|
|
15095
15496
|
}
|
|
15096
15497
|
}
|
|
15097
15498
|
console.log();
|
|
15098
|
-
console.log(
|
|
15499
|
+
console.log(chalk5.blue("Executing in sandbox..."));
|
|
15099
15500
|
console.log();
|
|
15100
15501
|
}
|
|
15101
15502
|
function showNextSteps(result) {
|
|
@@ -15103,17 +15504,17 @@ function showNextSteps(result) {
|
|
|
15103
15504
|
console.log();
|
|
15104
15505
|
console.log("Next steps:");
|
|
15105
15506
|
console.log(" View telemetry logs:");
|
|
15106
|
-
console.log(
|
|
15507
|
+
console.log(chalk5.cyan(` vm0 logs ${runId}`));
|
|
15107
15508
|
if (sessionId) {
|
|
15108
15509
|
console.log(" Continue with session (latest state):");
|
|
15109
15510
|
console.log(
|
|
15110
|
-
|
|
15511
|
+
chalk5.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
15111
15512
|
);
|
|
15112
15513
|
}
|
|
15113
15514
|
if (checkpointId) {
|
|
15114
15515
|
console.log(" Resume from checkpoint (exact snapshot state):");
|
|
15115
15516
|
console.log(
|
|
15116
|
-
|
|
15517
|
+
chalk5.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
15117
15518
|
);
|
|
15118
15519
|
}
|
|
15119
15520
|
}
|
|
@@ -15151,7 +15552,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15151
15552
|
let composeContent;
|
|
15152
15553
|
if (isUUID(name)) {
|
|
15153
15554
|
if (verbose) {
|
|
15154
|
-
console.log(
|
|
15555
|
+
console.log(chalk5.gray(` Using compose ID: ${identifier}`));
|
|
15155
15556
|
}
|
|
15156
15557
|
try {
|
|
15157
15558
|
const compose = await apiClient.getComposeById(name);
|
|
@@ -15159,26 +15560,26 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15159
15560
|
composeContent = compose.content;
|
|
15160
15561
|
} catch (error43) {
|
|
15161
15562
|
if (error43 instanceof Error) {
|
|
15162
|
-
console.error(
|
|
15563
|
+
console.error(chalk5.red(`\u2717 Compose not found: ${name}`));
|
|
15163
15564
|
}
|
|
15164
15565
|
process.exit(1);
|
|
15165
15566
|
}
|
|
15166
15567
|
} else {
|
|
15167
15568
|
if (verbose) {
|
|
15168
|
-
console.log(
|
|
15569
|
+
console.log(chalk5.gray(` Resolving agent name: ${name}`));
|
|
15169
15570
|
}
|
|
15170
15571
|
try {
|
|
15171
15572
|
const compose = await apiClient.getComposeByName(name);
|
|
15172
15573
|
composeId = compose.id;
|
|
15173
15574
|
composeContent = compose.content;
|
|
15174
15575
|
if (verbose) {
|
|
15175
|
-
console.log(
|
|
15576
|
+
console.log(chalk5.gray(` Resolved to compose ID: ${composeId}`));
|
|
15176
15577
|
}
|
|
15177
15578
|
} catch (error43) {
|
|
15178
15579
|
if (error43 instanceof Error) {
|
|
15179
|
-
console.error(
|
|
15580
|
+
console.error(chalk5.red(`\u2717 Agent not found: ${name}`));
|
|
15180
15581
|
console.error(
|
|
15181
|
-
|
|
15582
|
+
chalk5.gray(
|
|
15182
15583
|
" Make sure you've composed the agent with: vm0 compose"
|
|
15183
15584
|
)
|
|
15184
15585
|
);
|
|
@@ -15189,7 +15590,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15189
15590
|
let agentComposeVersionId;
|
|
15190
15591
|
if (version2 && version2 !== "latest") {
|
|
15191
15592
|
if (verbose) {
|
|
15192
|
-
console.log(
|
|
15593
|
+
console.log(chalk5.gray(` Resolving version: ${version2}`));
|
|
15193
15594
|
}
|
|
15194
15595
|
try {
|
|
15195
15596
|
const versionInfo = await apiClient.getComposeVersion(
|
|
@@ -15199,16 +15600,16 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15199
15600
|
agentComposeVersionId = versionInfo.versionId;
|
|
15200
15601
|
if (verbose) {
|
|
15201
15602
|
console.log(
|
|
15202
|
-
|
|
15603
|
+
chalk5.gray(
|
|
15203
15604
|
` Resolved to version ID: ${agentComposeVersionId.slice(0, 8)}...`
|
|
15204
15605
|
)
|
|
15205
15606
|
);
|
|
15206
15607
|
}
|
|
15207
15608
|
} catch (error43) {
|
|
15208
15609
|
if (error43 instanceof Error) {
|
|
15209
|
-
console.error(
|
|
15610
|
+
console.error(chalk5.red(`\u2717 Version not found: ${version2}`));
|
|
15210
15611
|
console.error(
|
|
15211
|
-
|
|
15612
|
+
chalk5.gray(" Make sure the version hash is correct.")
|
|
15212
15613
|
);
|
|
15213
15614
|
}
|
|
15214
15615
|
process.exit(1);
|
|
@@ -15219,20 +15620,20 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15219
15620
|
const secretNames = extractSecretNames(composeContent);
|
|
15220
15621
|
const secrets = loadValues(options.secrets, secretNames);
|
|
15221
15622
|
if (verbose && varNames.length > 0) {
|
|
15222
|
-
console.log(
|
|
15623
|
+
console.log(chalk5.gray(` Required vars: ${varNames.join(", ")}`));
|
|
15223
15624
|
if (vars) {
|
|
15224
15625
|
console.log(
|
|
15225
|
-
|
|
15626
|
+
chalk5.gray(` Loaded vars: ${Object.keys(vars).join(", ")}`)
|
|
15226
15627
|
);
|
|
15227
15628
|
}
|
|
15228
15629
|
}
|
|
15229
15630
|
if (verbose && secretNames.length > 0) {
|
|
15230
15631
|
console.log(
|
|
15231
|
-
|
|
15632
|
+
chalk5.gray(` Required secrets: ${secretNames.join(", ")}`)
|
|
15232
15633
|
);
|
|
15233
15634
|
if (secrets) {
|
|
15234
15635
|
console.log(
|
|
15235
|
-
|
|
15636
|
+
chalk5.gray(
|
|
15236
15637
|
` Loaded secrets: ${Object.keys(secrets).join(", ")}`
|
|
15237
15638
|
)
|
|
15238
15639
|
);
|
|
@@ -15271,9 +15672,9 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15271
15672
|
conversationId: options.conversation
|
|
15272
15673
|
});
|
|
15273
15674
|
if (response.status === "failed") {
|
|
15274
|
-
console.error(
|
|
15675
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15275
15676
|
if (response.error) {
|
|
15276
|
-
console.error(
|
|
15677
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15277
15678
|
}
|
|
15278
15679
|
process.exit(1);
|
|
15279
15680
|
}
|
|
@@ -15293,21 +15694,21 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15293
15694
|
if (error43 instanceof Error) {
|
|
15294
15695
|
if (error43.message.includes("Not authenticated")) {
|
|
15295
15696
|
console.error(
|
|
15296
|
-
|
|
15697
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15297
15698
|
);
|
|
15298
15699
|
} else if (error43.message.includes("not found")) {
|
|
15299
|
-
console.error(
|
|
15700
|
+
console.error(chalk5.red(`\u2717 Agent not found: ${identifier}`));
|
|
15300
15701
|
console.error(
|
|
15301
|
-
|
|
15702
|
+
chalk5.gray(
|
|
15302
15703
|
" Make sure you've composed the agent with: vm0 compose"
|
|
15303
15704
|
)
|
|
15304
15705
|
);
|
|
15305
15706
|
} else {
|
|
15306
|
-
console.error(
|
|
15307
|
-
console.error(
|
|
15707
|
+
console.error(chalk5.red("\u2717 Run failed"));
|
|
15708
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15308
15709
|
}
|
|
15309
15710
|
} else {
|
|
15310
|
-
console.error(
|
|
15711
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15311
15712
|
}
|
|
15312
15713
|
process.exit(1);
|
|
15313
15714
|
}
|
|
@@ -15326,9 +15727,9 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15326
15727
|
try {
|
|
15327
15728
|
if (!isUUID(checkpointId)) {
|
|
15328
15729
|
console.error(
|
|
15329
|
-
|
|
15730
|
+
chalk5.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
15330
15731
|
);
|
|
15331
|
-
console.error(
|
|
15732
|
+
console.error(chalk5.gray(" Checkpoint ID must be a valid UUID"));
|
|
15332
15733
|
process.exit(1);
|
|
15333
15734
|
}
|
|
15334
15735
|
if (verbose) {
|
|
@@ -15347,9 +15748,9 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15347
15748
|
volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
|
|
15348
15749
|
});
|
|
15349
15750
|
if (response.status === "failed") {
|
|
15350
|
-
console.error(
|
|
15751
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15351
15752
|
if (response.error) {
|
|
15352
|
-
console.error(
|
|
15753
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15353
15754
|
}
|
|
15354
15755
|
process.exit(1);
|
|
15355
15756
|
}
|
|
@@ -15369,16 +15770,16 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15369
15770
|
if (error43 instanceof Error) {
|
|
15370
15771
|
if (error43.message.includes("Not authenticated")) {
|
|
15371
15772
|
console.error(
|
|
15372
|
-
|
|
15773
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15373
15774
|
);
|
|
15374
15775
|
} else if (error43.message.includes("not found")) {
|
|
15375
|
-
console.error(
|
|
15776
|
+
console.error(chalk5.red(`\u2717 Checkpoint not found: ${checkpointId}`));
|
|
15376
15777
|
} else {
|
|
15377
|
-
console.error(
|
|
15378
|
-
console.error(
|
|
15778
|
+
console.error(chalk5.red("\u2717 Resume failed"));
|
|
15779
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15379
15780
|
}
|
|
15380
15781
|
} else {
|
|
15381
|
-
console.error(
|
|
15782
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15382
15783
|
}
|
|
15383
15784
|
process.exit(1);
|
|
15384
15785
|
}
|
|
@@ -15399,9 +15800,9 @@ runCmd.command("continue").description(
|
|
|
15399
15800
|
try {
|
|
15400
15801
|
if (!isUUID(agentSessionId)) {
|
|
15401
15802
|
console.error(
|
|
15402
|
-
|
|
15803
|
+
chalk5.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
15403
15804
|
);
|
|
15404
|
-
console.error(
|
|
15805
|
+
console.error(chalk5.gray(" Agent session ID must be a valid UUID"));
|
|
15405
15806
|
process.exit(1);
|
|
15406
15807
|
}
|
|
15407
15808
|
if (verbose) {
|
|
@@ -15421,9 +15822,9 @@ runCmd.command("continue").description(
|
|
|
15421
15822
|
volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
|
|
15422
15823
|
});
|
|
15423
15824
|
if (response.status === "failed") {
|
|
15424
|
-
console.error(
|
|
15825
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15425
15826
|
if (response.error) {
|
|
15426
|
-
console.error(
|
|
15827
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15427
15828
|
}
|
|
15428
15829
|
process.exit(1);
|
|
15429
15830
|
}
|
|
@@ -15443,18 +15844,18 @@ runCmd.command("continue").description(
|
|
|
15443
15844
|
if (error43 instanceof Error) {
|
|
15444
15845
|
if (error43.message.includes("Not authenticated")) {
|
|
15445
15846
|
console.error(
|
|
15446
|
-
|
|
15847
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15447
15848
|
);
|
|
15448
15849
|
} else if (error43.message.includes("not found")) {
|
|
15449
15850
|
console.error(
|
|
15450
|
-
|
|
15851
|
+
chalk5.red(`\u2717 Agent session not found: ${agentSessionId}`)
|
|
15451
15852
|
);
|
|
15452
15853
|
} else {
|
|
15453
|
-
console.error(
|
|
15454
|
-
console.error(
|
|
15854
|
+
console.error(chalk5.red("\u2717 Continue failed"));
|
|
15855
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15455
15856
|
}
|
|
15456
15857
|
} else {
|
|
15457
|
-
console.error(
|
|
15858
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15458
15859
|
}
|
|
15459
15860
|
process.exit(1);
|
|
15460
15861
|
}
|
|
@@ -15467,7 +15868,7 @@ import { Command as Command7 } from "commander";
|
|
|
15467
15868
|
|
|
15468
15869
|
// src/commands/volume/init.ts
|
|
15469
15870
|
import { Command as Command3 } from "commander";
|
|
15470
|
-
import
|
|
15871
|
+
import chalk6 from "chalk";
|
|
15471
15872
|
import path7 from "path";
|
|
15472
15873
|
|
|
15473
15874
|
// src/lib/storage-utils.ts
|
|
@@ -15525,37 +15926,37 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
|
|
|
15525
15926
|
const existingConfig = await readStorageConfig(cwd);
|
|
15526
15927
|
if (existingConfig) {
|
|
15527
15928
|
console.log(
|
|
15528
|
-
|
|
15929
|
+
chalk6.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
15529
15930
|
);
|
|
15530
15931
|
console.log(
|
|
15531
|
-
|
|
15932
|
+
chalk6.gray(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
|
|
15532
15933
|
);
|
|
15533
15934
|
return;
|
|
15534
15935
|
}
|
|
15535
15936
|
const volumeName = dirName;
|
|
15536
15937
|
if (!isValidStorageName(volumeName)) {
|
|
15537
|
-
console.error(
|
|
15938
|
+
console.error(chalk6.red(`\u2717 Invalid volume name: "${dirName}"`));
|
|
15538
15939
|
console.error(
|
|
15539
|
-
|
|
15940
|
+
chalk6.gray(
|
|
15540
15941
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
15541
15942
|
)
|
|
15542
15943
|
);
|
|
15543
15944
|
console.error(
|
|
15544
|
-
|
|
15945
|
+
chalk6.gray(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
15545
15946
|
);
|
|
15546
15947
|
process.exit(1);
|
|
15547
15948
|
}
|
|
15548
15949
|
await writeStorageConfig(volumeName, cwd);
|
|
15549
|
-
console.log(
|
|
15950
|
+
console.log(chalk6.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
15550
15951
|
console.log(
|
|
15551
|
-
|
|
15952
|
+
chalk6.gray(
|
|
15552
15953
|
`\u2713 Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
|
|
15553
15954
|
)
|
|
15554
15955
|
);
|
|
15555
15956
|
} catch (error43) {
|
|
15556
|
-
console.error(
|
|
15957
|
+
console.error(chalk6.red("\u2717 Failed to initialize volume"));
|
|
15557
15958
|
if (error43 instanceof Error) {
|
|
15558
|
-
console.error(
|
|
15959
|
+
console.error(chalk6.gray(` ${error43.message}`));
|
|
15559
15960
|
}
|
|
15560
15961
|
process.exit(1);
|
|
15561
15962
|
}
|
|
@@ -15563,7 +15964,7 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
|
|
|
15563
15964
|
|
|
15564
15965
|
// src/commands/volume/push.ts
|
|
15565
15966
|
import { Command as Command4 } from "commander";
|
|
15566
|
-
import
|
|
15967
|
+
import chalk7 from "chalk";
|
|
15567
15968
|
function formatBytes(bytes) {
|
|
15568
15969
|
if (bytes === 0) return "0 B";
|
|
15569
15970
|
const k = 1024;
|
|
@@ -15579,32 +15980,32 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
15579
15980
|
const cwd = process.cwd();
|
|
15580
15981
|
const config2 = await readStorageConfig(cwd);
|
|
15581
15982
|
if (!config2) {
|
|
15582
|
-
console.error(
|
|
15583
|
-
console.error(
|
|
15983
|
+
console.error(chalk7.red("\u2717 No volume initialized in this directory"));
|
|
15984
|
+
console.error(chalk7.gray(" Run: vm0 volume init"));
|
|
15584
15985
|
process.exit(1);
|
|
15585
15986
|
}
|
|
15586
|
-
console.log(
|
|
15987
|
+
console.log(chalk7.cyan(`Pushing volume: ${config2.name}`));
|
|
15587
15988
|
const result = await directUpload(config2.name, "volume", cwd, {
|
|
15588
15989
|
onProgress: (message) => {
|
|
15589
|
-
console.log(
|
|
15990
|
+
console.log(chalk7.gray(message));
|
|
15590
15991
|
},
|
|
15591
15992
|
force: options.force
|
|
15592
15993
|
});
|
|
15593
15994
|
const shortVersion = result.versionId.slice(0, 8);
|
|
15594
15995
|
if (result.empty) {
|
|
15595
|
-
console.log(
|
|
15996
|
+
console.log(chalk7.yellow("No files found (empty volume)"));
|
|
15596
15997
|
} else if (result.deduplicated) {
|
|
15597
|
-
console.log(
|
|
15998
|
+
console.log(chalk7.green("\u2713 Content unchanged (deduplicated)"));
|
|
15598
15999
|
} else {
|
|
15599
|
-
console.log(
|
|
16000
|
+
console.log(chalk7.green("\u2713 Upload complete"));
|
|
15600
16001
|
}
|
|
15601
|
-
console.log(
|
|
15602
|
-
console.log(
|
|
15603
|
-
console.log(
|
|
16002
|
+
console.log(chalk7.gray(` Version: ${shortVersion}`));
|
|
16003
|
+
console.log(chalk7.gray(` Files: ${result.fileCount.toLocaleString()}`));
|
|
16004
|
+
console.log(chalk7.gray(` Size: ${formatBytes(result.size)}`));
|
|
15604
16005
|
} catch (error43) {
|
|
15605
|
-
console.error(
|
|
16006
|
+
console.error(chalk7.red("\u2717 Push failed"));
|
|
15606
16007
|
if (error43 instanceof Error) {
|
|
15607
|
-
console.error(
|
|
16008
|
+
console.error(chalk7.gray(` ${error43.message}`));
|
|
15608
16009
|
}
|
|
15609
16010
|
process.exit(1);
|
|
15610
16011
|
}
|
|
@@ -15612,21 +16013,21 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
15612
16013
|
|
|
15613
16014
|
// src/commands/volume/pull.ts
|
|
15614
16015
|
import { Command as Command5 } from "commander";
|
|
15615
|
-
import
|
|
16016
|
+
import chalk9 from "chalk";
|
|
15616
16017
|
import path8 from "path";
|
|
15617
16018
|
import * as fs6 from "fs";
|
|
15618
16019
|
import * as os4 from "os";
|
|
15619
16020
|
import * as tar3 from "tar";
|
|
15620
16021
|
|
|
15621
16022
|
// src/lib/pull-utils.ts
|
|
15622
|
-
import
|
|
16023
|
+
import chalk8 from "chalk";
|
|
15623
16024
|
async function handleEmptyStorageResponse(cwd) {
|
|
15624
|
-
console.log(
|
|
16025
|
+
console.log(chalk8.gray("Syncing local files..."));
|
|
15625
16026
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
15626
16027
|
if (removedCount > 0) {
|
|
15627
|
-
console.log(
|
|
16028
|
+
console.log(chalk8.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
15628
16029
|
}
|
|
15629
|
-
console.log(
|
|
16030
|
+
console.log(chalk8.green("\u2713 Synced (0 files)"));
|
|
15630
16031
|
return { removedCount };
|
|
15631
16032
|
}
|
|
15632
16033
|
|
|
@@ -15643,18 +16044,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15643
16044
|
const cwd = process.cwd();
|
|
15644
16045
|
const config2 = await readStorageConfig(cwd);
|
|
15645
16046
|
if (!config2) {
|
|
15646
|
-
console.error(
|
|
15647
|
-
console.error(
|
|
16047
|
+
console.error(chalk9.red("\u2717 No volume initialized in this directory"));
|
|
16048
|
+
console.error(chalk9.gray(" Run: vm0 volume init"));
|
|
15648
16049
|
process.exit(1);
|
|
15649
16050
|
}
|
|
15650
16051
|
if (versionId) {
|
|
15651
16052
|
console.log(
|
|
15652
|
-
|
|
16053
|
+
chalk9.cyan(`Pulling volume: ${config2.name} (version: ${versionId})`)
|
|
15653
16054
|
);
|
|
15654
16055
|
} else {
|
|
15655
|
-
console.log(
|
|
16056
|
+
console.log(chalk9.cyan(`Pulling volume: ${config2.name}`));
|
|
15656
16057
|
}
|
|
15657
|
-
console.log(
|
|
16058
|
+
console.log(chalk9.gray("Getting download URL..."));
|
|
15658
16059
|
let url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=volume`;
|
|
15659
16060
|
if (versionId) {
|
|
15660
16061
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15662,14 +16063,14 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15662
16063
|
const response = await apiClient.get(url2);
|
|
15663
16064
|
if (!response.ok) {
|
|
15664
16065
|
if (response.status === 404) {
|
|
15665
|
-
console.error(
|
|
16066
|
+
console.error(chalk9.red(`\u2717 Volume "${config2.name}" not found`));
|
|
15666
16067
|
console.error(
|
|
15667
|
-
|
|
16068
|
+
chalk9.gray(
|
|
15668
16069
|
" Make sure the volume name is correct in .vm0/storage.yaml"
|
|
15669
16070
|
)
|
|
15670
16071
|
);
|
|
15671
16072
|
console.error(
|
|
15672
|
-
|
|
16073
|
+
chalk9.gray(" Or push the volume first with: vm0 volume push")
|
|
15673
16074
|
);
|
|
15674
16075
|
} else {
|
|
15675
16076
|
const error43 = await response.json();
|
|
@@ -15685,18 +16086,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15685
16086
|
if (!downloadInfo.url) {
|
|
15686
16087
|
throw new Error("No download URL returned");
|
|
15687
16088
|
}
|
|
15688
|
-
console.log(
|
|
16089
|
+
console.log(chalk9.gray("Downloading from S3..."));
|
|
15689
16090
|
const s3Response = await fetch(downloadInfo.url);
|
|
15690
16091
|
if (!s3Response.ok) {
|
|
15691
16092
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
15692
16093
|
}
|
|
15693
16094
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
15694
16095
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15695
|
-
console.log(
|
|
16096
|
+
console.log(chalk9.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
|
|
15696
16097
|
const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
|
|
15697
16098
|
const tarPath = path8.join(tmpDir, "volume.tar.gz");
|
|
15698
16099
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
15699
|
-
console.log(
|
|
16100
|
+
console.log(chalk9.gray("Syncing local files..."));
|
|
15700
16101
|
const remoteFiles = await listTarFiles(tarPath);
|
|
15701
16102
|
const remoteFilesSet = new Set(
|
|
15702
16103
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -15704,10 +16105,10 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15704
16105
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
15705
16106
|
if (removedCount > 0) {
|
|
15706
16107
|
console.log(
|
|
15707
|
-
|
|
16108
|
+
chalk9.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
15708
16109
|
);
|
|
15709
16110
|
}
|
|
15710
|
-
console.log(
|
|
16111
|
+
console.log(chalk9.gray("Extracting files..."));
|
|
15711
16112
|
await tar3.extract({
|
|
15712
16113
|
file: tarPath,
|
|
15713
16114
|
cwd,
|
|
@@ -15715,11 +16116,11 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15715
16116
|
});
|
|
15716
16117
|
await fs6.promises.unlink(tarPath);
|
|
15717
16118
|
await fs6.promises.rmdir(tmpDir);
|
|
15718
|
-
console.log(
|
|
16119
|
+
console.log(chalk9.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
15719
16120
|
} catch (error43) {
|
|
15720
|
-
console.error(
|
|
16121
|
+
console.error(chalk9.red("\u2717 Pull failed"));
|
|
15721
16122
|
if (error43 instanceof Error) {
|
|
15722
|
-
console.error(
|
|
16123
|
+
console.error(chalk9.gray(` ${error43.message}`));
|
|
15723
16124
|
}
|
|
15724
16125
|
process.exit(1);
|
|
15725
16126
|
}
|
|
@@ -15727,7 +16128,7 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15727
16128
|
|
|
15728
16129
|
// src/commands/volume/status.ts
|
|
15729
16130
|
import { Command as Command6 } from "commander";
|
|
15730
|
-
import
|
|
16131
|
+
import chalk10 from "chalk";
|
|
15731
16132
|
function formatBytes3(bytes) {
|
|
15732
16133
|
if (bytes === 0) return "0 B";
|
|
15733
16134
|
const k = 1024;
|
|
@@ -15740,26 +16141,26 @@ var statusCommand = new Command6().name("status").description("Show status of cl
|
|
|
15740
16141
|
const cwd = process.cwd();
|
|
15741
16142
|
const config2 = await readStorageConfig(cwd);
|
|
15742
16143
|
if (!config2) {
|
|
15743
|
-
console.error(
|
|
15744
|
-
console.error(
|
|
16144
|
+
console.error(chalk10.red("\u2717 No volume initialized in this directory"));
|
|
16145
|
+
console.error(chalk10.gray(" Run: vm0 volume init"));
|
|
15745
16146
|
process.exit(1);
|
|
15746
16147
|
}
|
|
15747
16148
|
if (config2.type !== "volume") {
|
|
15748
16149
|
console.error(
|
|
15749
|
-
|
|
16150
|
+
chalk10.red(
|
|
15750
16151
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
15751
16152
|
)
|
|
15752
16153
|
);
|
|
15753
|
-
console.error(
|
|
16154
|
+
console.error(chalk10.gray(" Use: vm0 artifact status"));
|
|
15754
16155
|
process.exit(1);
|
|
15755
16156
|
}
|
|
15756
|
-
console.log(
|
|
16157
|
+
console.log(chalk10.cyan(`Checking volume: ${config2.name}`));
|
|
15757
16158
|
const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=volume`;
|
|
15758
16159
|
const response = await apiClient.get(url2);
|
|
15759
16160
|
if (!response.ok) {
|
|
15760
16161
|
if (response.status === 404) {
|
|
15761
|
-
console.error(
|
|
15762
|
-
console.error(
|
|
16162
|
+
console.error(chalk10.red("\u2717 Not found on remote"));
|
|
16163
|
+
console.error(chalk10.gray(" Run: vm0 volume push"));
|
|
15763
16164
|
} else {
|
|
15764
16165
|
const error43 = await response.json();
|
|
15765
16166
|
throw new Error(error43.error?.message || "Status check failed");
|
|
@@ -15769,18 +16170,18 @@ var statusCommand = new Command6().name("status").description("Show status of cl
|
|
|
15769
16170
|
const info = await response.json();
|
|
15770
16171
|
const shortVersion = info.versionId.slice(0, 8);
|
|
15771
16172
|
if (info.empty) {
|
|
15772
|
-
console.log(
|
|
15773
|
-
console.log(
|
|
16173
|
+
console.log(chalk10.green("\u2713 Found (empty)"));
|
|
16174
|
+
console.log(chalk10.gray(` Version: ${shortVersion}`));
|
|
15774
16175
|
} else {
|
|
15775
|
-
console.log(
|
|
15776
|
-
console.log(
|
|
15777
|
-
console.log(
|
|
15778
|
-
console.log(
|
|
16176
|
+
console.log(chalk10.green("\u2713 Found"));
|
|
16177
|
+
console.log(chalk10.gray(` Version: ${shortVersion}`));
|
|
16178
|
+
console.log(chalk10.gray(` Files: ${info.fileCount.toLocaleString()}`));
|
|
16179
|
+
console.log(chalk10.gray(` Size: ${formatBytes3(info.size)}`));
|
|
15779
16180
|
}
|
|
15780
16181
|
} catch (error43) {
|
|
15781
|
-
console.error(
|
|
16182
|
+
console.error(chalk10.red("\u2717 Status check failed"));
|
|
15782
16183
|
if (error43 instanceof Error) {
|
|
15783
|
-
console.error(
|
|
16184
|
+
console.error(chalk10.gray(` ${error43.message}`));
|
|
15784
16185
|
}
|
|
15785
16186
|
process.exit(1);
|
|
15786
16187
|
}
|
|
@@ -15794,7 +16195,7 @@ import { Command as Command12 } from "commander";
|
|
|
15794
16195
|
|
|
15795
16196
|
// src/commands/artifact/init.ts
|
|
15796
16197
|
import { Command as Command8 } from "commander";
|
|
15797
|
-
import
|
|
16198
|
+
import chalk11 from "chalk";
|
|
15798
16199
|
import path9 from "path";
|
|
15799
16200
|
var initCommand2 = new Command8().name("init").description("Initialize an artifact in the current directory").action(async () => {
|
|
15800
16201
|
try {
|
|
@@ -15804,51 +16205,51 @@ var initCommand2 = new Command8().name("init").description("Initialize an artifa
|
|
|
15804
16205
|
if (existingConfig) {
|
|
15805
16206
|
if (existingConfig.type === "artifact") {
|
|
15806
16207
|
console.log(
|
|
15807
|
-
|
|
16208
|
+
chalk11.yellow(
|
|
15808
16209
|
`Artifact already initialized: ${existingConfig.name}`
|
|
15809
16210
|
)
|
|
15810
16211
|
);
|
|
15811
16212
|
} else {
|
|
15812
16213
|
console.log(
|
|
15813
|
-
|
|
16214
|
+
chalk11.yellow(
|
|
15814
16215
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
15815
16216
|
)
|
|
15816
16217
|
);
|
|
15817
16218
|
console.log(
|
|
15818
|
-
|
|
16219
|
+
chalk11.gray(
|
|
15819
16220
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
15820
16221
|
)
|
|
15821
16222
|
);
|
|
15822
16223
|
}
|
|
15823
16224
|
console.log(
|
|
15824
|
-
|
|
16225
|
+
chalk11.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
15825
16226
|
);
|
|
15826
16227
|
return;
|
|
15827
16228
|
}
|
|
15828
16229
|
const artifactName = dirName;
|
|
15829
16230
|
if (!isValidStorageName(artifactName)) {
|
|
15830
|
-
console.error(
|
|
16231
|
+
console.error(chalk11.red(`\u2717 Invalid artifact name: "${dirName}"`));
|
|
15831
16232
|
console.error(
|
|
15832
|
-
|
|
16233
|
+
chalk11.gray(
|
|
15833
16234
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
15834
16235
|
)
|
|
15835
16236
|
);
|
|
15836
16237
|
console.error(
|
|
15837
|
-
|
|
16238
|
+
chalk11.gray(" Example: my-project, user-workspace, code-artifact")
|
|
15838
16239
|
);
|
|
15839
16240
|
process.exit(1);
|
|
15840
16241
|
}
|
|
15841
16242
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
15842
|
-
console.log(
|
|
16243
|
+
console.log(chalk11.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
15843
16244
|
console.log(
|
|
15844
|
-
|
|
16245
|
+
chalk11.gray(
|
|
15845
16246
|
`\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
15846
16247
|
)
|
|
15847
16248
|
);
|
|
15848
16249
|
} catch (error43) {
|
|
15849
|
-
console.error(
|
|
16250
|
+
console.error(chalk11.red("\u2717 Failed to initialize artifact"));
|
|
15850
16251
|
if (error43 instanceof Error) {
|
|
15851
|
-
console.error(
|
|
16252
|
+
console.error(chalk11.gray(` ${error43.message}`));
|
|
15852
16253
|
}
|
|
15853
16254
|
process.exit(1);
|
|
15854
16255
|
}
|
|
@@ -15856,7 +16257,7 @@ var initCommand2 = new Command8().name("init").description("Initialize an artifa
|
|
|
15856
16257
|
|
|
15857
16258
|
// src/commands/artifact/push.ts
|
|
15858
16259
|
import { Command as Command9 } from "commander";
|
|
15859
|
-
import
|
|
16260
|
+
import chalk12 from "chalk";
|
|
15860
16261
|
function formatBytes4(bytes) {
|
|
15861
16262
|
if (bytes === 0) return "0 B";
|
|
15862
16263
|
const k = 1024;
|
|
@@ -15872,41 +16273,41 @@ var pushCommand2 = new Command9().name("push").description("Push local files to
|
|
|
15872
16273
|
const cwd = process.cwd();
|
|
15873
16274
|
const config2 = await readStorageConfig(cwd);
|
|
15874
16275
|
if (!config2) {
|
|
15875
|
-
console.error(
|
|
15876
|
-
console.error(
|
|
16276
|
+
console.error(chalk12.red("\u2717 No artifact initialized in this directory"));
|
|
16277
|
+
console.error(chalk12.gray(" Run: vm0 artifact init"));
|
|
15877
16278
|
process.exit(1);
|
|
15878
16279
|
}
|
|
15879
16280
|
if (config2.type !== "artifact") {
|
|
15880
16281
|
console.error(
|
|
15881
|
-
|
|
16282
|
+
chalk12.red(
|
|
15882
16283
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15883
16284
|
)
|
|
15884
16285
|
);
|
|
15885
|
-
console.error(
|
|
16286
|
+
console.error(chalk12.gray(" Use: vm0 volume push"));
|
|
15886
16287
|
process.exit(1);
|
|
15887
16288
|
}
|
|
15888
|
-
console.log(
|
|
16289
|
+
console.log(chalk12.cyan(`Pushing artifact: ${config2.name}`));
|
|
15889
16290
|
const result = await directUpload(config2.name, "artifact", cwd, {
|
|
15890
16291
|
onProgress: (message) => {
|
|
15891
|
-
console.log(
|
|
16292
|
+
console.log(chalk12.gray(message));
|
|
15892
16293
|
},
|
|
15893
16294
|
force: options.force
|
|
15894
16295
|
});
|
|
15895
16296
|
const shortVersion = result.versionId.slice(0, 8);
|
|
15896
16297
|
if (result.empty) {
|
|
15897
|
-
console.log(
|
|
16298
|
+
console.log(chalk12.yellow("No files found (empty artifact)"));
|
|
15898
16299
|
} else if (result.deduplicated) {
|
|
15899
|
-
console.log(
|
|
16300
|
+
console.log(chalk12.green("\u2713 Content unchanged (deduplicated)"));
|
|
15900
16301
|
} else {
|
|
15901
|
-
console.log(
|
|
16302
|
+
console.log(chalk12.green("\u2713 Upload complete"));
|
|
15902
16303
|
}
|
|
15903
|
-
console.log(
|
|
15904
|
-
console.log(
|
|
15905
|
-
console.log(
|
|
16304
|
+
console.log(chalk12.gray(` Version: ${shortVersion}`));
|
|
16305
|
+
console.log(chalk12.gray(` Files: ${result.fileCount.toLocaleString()}`));
|
|
16306
|
+
console.log(chalk12.gray(` Size: ${formatBytes4(result.size)}`));
|
|
15906
16307
|
} catch (error43) {
|
|
15907
|
-
console.error(
|
|
16308
|
+
console.error(chalk12.red("\u2717 Push failed"));
|
|
15908
16309
|
if (error43 instanceof Error) {
|
|
15909
|
-
console.error(
|
|
16310
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15910
16311
|
}
|
|
15911
16312
|
process.exit(1);
|
|
15912
16313
|
}
|
|
@@ -15914,7 +16315,7 @@ var pushCommand2 = new Command9().name("push").description("Push local files to
|
|
|
15914
16315
|
|
|
15915
16316
|
// src/commands/artifact/pull.ts
|
|
15916
16317
|
import { Command as Command10 } from "commander";
|
|
15917
|
-
import
|
|
16318
|
+
import chalk13 from "chalk";
|
|
15918
16319
|
import path10 from "path";
|
|
15919
16320
|
import * as fs7 from "fs";
|
|
15920
16321
|
import * as os5 from "os";
|
|
@@ -15931,29 +16332,29 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15931
16332
|
const cwd = process.cwd();
|
|
15932
16333
|
const config2 = await readStorageConfig(cwd);
|
|
15933
16334
|
if (!config2) {
|
|
15934
|
-
console.error(
|
|
15935
|
-
console.error(
|
|
16335
|
+
console.error(chalk13.red("\u2717 No artifact initialized in this directory"));
|
|
16336
|
+
console.error(chalk13.gray(" Run: vm0 artifact init"));
|
|
15936
16337
|
process.exit(1);
|
|
15937
16338
|
}
|
|
15938
16339
|
if (config2.type !== "artifact") {
|
|
15939
16340
|
console.error(
|
|
15940
|
-
|
|
16341
|
+
chalk13.red(
|
|
15941
16342
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15942
16343
|
)
|
|
15943
16344
|
);
|
|
15944
|
-
console.error(
|
|
16345
|
+
console.error(chalk13.gray(" Use: vm0 volume pull"));
|
|
15945
16346
|
process.exit(1);
|
|
15946
16347
|
}
|
|
15947
16348
|
if (versionId) {
|
|
15948
16349
|
console.log(
|
|
15949
|
-
|
|
16350
|
+
chalk13.cyan(
|
|
15950
16351
|
`Pulling artifact: ${config2.name} (version: ${versionId})`
|
|
15951
16352
|
)
|
|
15952
16353
|
);
|
|
15953
16354
|
} else {
|
|
15954
|
-
console.log(
|
|
16355
|
+
console.log(chalk13.cyan(`Pulling artifact: ${config2.name}`));
|
|
15955
16356
|
}
|
|
15956
|
-
console.log(
|
|
16357
|
+
console.log(chalk13.gray("Getting download URL..."));
|
|
15957
16358
|
let url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
|
|
15958
16359
|
if (versionId) {
|
|
15959
16360
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15961,14 +16362,14 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15961
16362
|
const response = await apiClient.get(url2);
|
|
15962
16363
|
if (!response.ok) {
|
|
15963
16364
|
if (response.status === 404) {
|
|
15964
|
-
console.error(
|
|
16365
|
+
console.error(chalk13.red(`\u2717 Artifact "${config2.name}" not found`));
|
|
15965
16366
|
console.error(
|
|
15966
|
-
|
|
16367
|
+
chalk13.gray(
|
|
15967
16368
|
" Make sure the artifact name is correct in .vm0/storage.yaml"
|
|
15968
16369
|
)
|
|
15969
16370
|
);
|
|
15970
16371
|
console.error(
|
|
15971
|
-
|
|
16372
|
+
chalk13.gray(" Or push the artifact first with: vm0 artifact push")
|
|
15972
16373
|
);
|
|
15973
16374
|
} else {
|
|
15974
16375
|
const error43 = await response.json();
|
|
@@ -15984,18 +16385,18 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15984
16385
|
if (!downloadInfo.url) {
|
|
15985
16386
|
throw new Error("No download URL returned");
|
|
15986
16387
|
}
|
|
15987
|
-
console.log(
|
|
16388
|
+
console.log(chalk13.gray("Downloading from S3..."));
|
|
15988
16389
|
const s3Response = await fetch(downloadInfo.url);
|
|
15989
16390
|
if (!s3Response.ok) {
|
|
15990
16391
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
15991
16392
|
}
|
|
15992
16393
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
15993
16394
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15994
|
-
console.log(
|
|
16395
|
+
console.log(chalk13.green(`\u2713 Downloaded ${formatBytes5(tarBuffer.length)}`));
|
|
15995
16396
|
const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
|
|
15996
16397
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
15997
16398
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
15998
|
-
console.log(
|
|
16399
|
+
console.log(chalk13.gray("Syncing local files..."));
|
|
15999
16400
|
const remoteFiles = await listTarFiles(tarPath);
|
|
16000
16401
|
const remoteFilesSet = new Set(
|
|
16001
16402
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -16003,10 +16404,10 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
16003
16404
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
16004
16405
|
if (removedCount > 0) {
|
|
16005
16406
|
console.log(
|
|
16006
|
-
|
|
16407
|
+
chalk13.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
16007
16408
|
);
|
|
16008
16409
|
}
|
|
16009
|
-
console.log(
|
|
16410
|
+
console.log(chalk13.gray("Extracting files..."));
|
|
16010
16411
|
await tar4.extract({
|
|
16011
16412
|
file: tarPath,
|
|
16012
16413
|
cwd,
|
|
@@ -16014,11 +16415,11 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
16014
16415
|
});
|
|
16015
16416
|
await fs7.promises.unlink(tarPath);
|
|
16016
16417
|
await fs7.promises.rmdir(tmpDir);
|
|
16017
|
-
console.log(
|
|
16418
|
+
console.log(chalk13.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
16018
16419
|
} catch (error43) {
|
|
16019
|
-
console.error(
|
|
16420
|
+
console.error(chalk13.red("\u2717 Pull failed"));
|
|
16020
16421
|
if (error43 instanceof Error) {
|
|
16021
|
-
console.error(
|
|
16422
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
16022
16423
|
}
|
|
16023
16424
|
process.exit(1);
|
|
16024
16425
|
}
|
|
@@ -16026,7 +16427,7 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
16026
16427
|
|
|
16027
16428
|
// src/commands/artifact/status.ts
|
|
16028
16429
|
import { Command as Command11 } from "commander";
|
|
16029
|
-
import
|
|
16430
|
+
import chalk14 from "chalk";
|
|
16030
16431
|
function formatBytes6(bytes) {
|
|
16031
16432
|
if (bytes === 0) return "0 B";
|
|
16032
16433
|
const k = 1024;
|
|
@@ -16039,26 +16440,26 @@ var statusCommand2 = new Command11().name("status").description("Show status of
|
|
|
16039
16440
|
const cwd = process.cwd();
|
|
16040
16441
|
const config2 = await readStorageConfig(cwd);
|
|
16041
16442
|
if (!config2) {
|
|
16042
|
-
console.error(
|
|
16043
|
-
console.error(
|
|
16443
|
+
console.error(chalk14.red("\u2717 No artifact initialized in this directory"));
|
|
16444
|
+
console.error(chalk14.gray(" Run: vm0 artifact init"));
|
|
16044
16445
|
process.exit(1);
|
|
16045
16446
|
}
|
|
16046
16447
|
if (config2.type !== "artifact") {
|
|
16047
16448
|
console.error(
|
|
16048
|
-
|
|
16449
|
+
chalk14.red(
|
|
16049
16450
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
16050
16451
|
)
|
|
16051
16452
|
);
|
|
16052
|
-
console.error(
|
|
16453
|
+
console.error(chalk14.gray(" Use: vm0 volume status"));
|
|
16053
16454
|
process.exit(1);
|
|
16054
16455
|
}
|
|
16055
|
-
console.log(
|
|
16456
|
+
console.log(chalk14.cyan(`Checking artifact: ${config2.name}`));
|
|
16056
16457
|
const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
|
|
16057
16458
|
const response = await apiClient.get(url2);
|
|
16058
16459
|
if (!response.ok) {
|
|
16059
16460
|
if (response.status === 404) {
|
|
16060
|
-
console.error(
|
|
16061
|
-
console.error(
|
|
16461
|
+
console.error(chalk14.red("\u2717 Not found on remote"));
|
|
16462
|
+
console.error(chalk14.gray(" Run: vm0 artifact push"));
|
|
16062
16463
|
} else {
|
|
16063
16464
|
const error43 = await response.json();
|
|
16064
16465
|
throw new Error(error43.error?.message || "Status check failed");
|
|
@@ -16068,18 +16469,18 @@ var statusCommand2 = new Command11().name("status").description("Show status of
|
|
|
16068
16469
|
const info = await response.json();
|
|
16069
16470
|
const shortVersion = info.versionId.slice(0, 8);
|
|
16070
16471
|
if (info.empty) {
|
|
16071
|
-
console.log(
|
|
16072
|
-
console.log(
|
|
16472
|
+
console.log(chalk14.green("\u2713 Found (empty)"));
|
|
16473
|
+
console.log(chalk14.gray(` Version: ${shortVersion}`));
|
|
16073
16474
|
} else {
|
|
16074
|
-
console.log(
|
|
16075
|
-
console.log(
|
|
16076
|
-
console.log(
|
|
16077
|
-
console.log(
|
|
16475
|
+
console.log(chalk14.green("\u2713 Found"));
|
|
16476
|
+
console.log(chalk14.gray(` Version: ${shortVersion}`));
|
|
16477
|
+
console.log(chalk14.gray(` Files: ${info.fileCount.toLocaleString()}`));
|
|
16478
|
+
console.log(chalk14.gray(` Size: ${formatBytes6(info.size)}`));
|
|
16078
16479
|
}
|
|
16079
16480
|
} catch (error43) {
|
|
16080
|
-
console.error(
|
|
16481
|
+
console.error(chalk14.red("\u2717 Status check failed"));
|
|
16081
16482
|
if (error43 instanceof Error) {
|
|
16082
|
-
console.error(
|
|
16483
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
16083
16484
|
}
|
|
16084
16485
|
process.exit(1);
|
|
16085
16486
|
}
|
|
@@ -16090,7 +16491,7 @@ var artifactCommand = new Command12().name("artifact").description("Manage cloud
|
|
|
16090
16491
|
|
|
16091
16492
|
// src/commands/cook.ts
|
|
16092
16493
|
import { Command as Command13 } from "commander";
|
|
16093
|
-
import
|
|
16494
|
+
import chalk16 from "chalk";
|
|
16094
16495
|
import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
16095
16496
|
import { existsSync as existsSync6, readFileSync } from "fs";
|
|
16096
16497
|
import path11 from "path";
|
|
@@ -16101,7 +16502,7 @@ import { config as dotenvConfig2 } from "dotenv";
|
|
|
16101
16502
|
// src/lib/update-checker.ts
|
|
16102
16503
|
import https from "https";
|
|
16103
16504
|
import { spawn } from "child_process";
|
|
16104
|
-
import
|
|
16505
|
+
import chalk15 from "chalk";
|
|
16105
16506
|
var PACKAGE_NAME = "@vm0/cli";
|
|
16106
16507
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
16107
16508
|
var TIMEOUT_MS = 5e3;
|
|
@@ -16166,21 +16567,21 @@ function performUpgrade(packageManager) {
|
|
|
16166
16567
|
async function checkAndUpgrade(currentVersion, prompt) {
|
|
16167
16568
|
const latestVersion = await getLatestVersion();
|
|
16168
16569
|
if (latestVersion === null) {
|
|
16169
|
-
console.log(
|
|
16570
|
+
console.log(chalk15.yellow("Warning: Could not check for updates"));
|
|
16170
16571
|
console.log();
|
|
16171
16572
|
return false;
|
|
16172
16573
|
}
|
|
16173
16574
|
if (latestVersion === currentVersion) {
|
|
16174
16575
|
return false;
|
|
16175
16576
|
}
|
|
16176
|
-
console.log(
|
|
16577
|
+
console.log(chalk15.yellow("vm0 is currently in Early Access (EA)."));
|
|
16177
16578
|
console.log(
|
|
16178
|
-
|
|
16579
|
+
chalk15.yellow(
|
|
16179
16580
|
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
16180
16581
|
)
|
|
16181
16582
|
);
|
|
16182
16583
|
console.log(
|
|
16183
|
-
|
|
16584
|
+
chalk15.yellow(
|
|
16184
16585
|
"Please always use the latest version for best compatibility."
|
|
16185
16586
|
)
|
|
16186
16587
|
);
|
|
@@ -16189,20 +16590,20 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
16189
16590
|
console.log(`Upgrading via ${packageManager}...`);
|
|
16190
16591
|
const success2 = await performUpgrade(packageManager);
|
|
16191
16592
|
if (success2) {
|
|
16192
|
-
console.log(
|
|
16593
|
+
console.log(chalk15.green(`Upgraded to ${latestVersion}`));
|
|
16193
16594
|
console.log();
|
|
16194
16595
|
console.log("To continue, run:");
|
|
16195
|
-
console.log(
|
|
16596
|
+
console.log(chalk15.cyan(` ${buildRerunCommand(prompt)}`));
|
|
16196
16597
|
return true;
|
|
16197
16598
|
}
|
|
16198
16599
|
console.log();
|
|
16199
|
-
console.log(
|
|
16200
|
-
console.log(
|
|
16201
|
-
console.log(
|
|
16202
|
-
console.log(
|
|
16600
|
+
console.log(chalk15.red("Upgrade failed. Please run manually:"));
|
|
16601
|
+
console.log(chalk15.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
|
|
16602
|
+
console.log(chalk15.gray(" # or"));
|
|
16603
|
+
console.log(chalk15.cyan(` pnpm add -g ${PACKAGE_NAME}@latest`));
|
|
16203
16604
|
console.log();
|
|
16204
16605
|
console.log("Then re-run:");
|
|
16205
|
-
console.log(
|
|
16606
|
+
console.log(chalk15.cyan(` ${buildRerunCommand(prompt)}`));
|
|
16206
16607
|
return true;
|
|
16207
16608
|
}
|
|
16208
16609
|
|
|
@@ -16323,14 +16724,14 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
|
16323
16724
|
}
|
|
16324
16725
|
}
|
|
16325
16726
|
var cookCommand = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
16326
|
-
const shouldExit = await checkAndUpgrade("4.
|
|
16727
|
+
const shouldExit = await checkAndUpgrade("4.21.1", prompt);
|
|
16327
16728
|
if (shouldExit) {
|
|
16328
16729
|
process.exit(0);
|
|
16329
16730
|
}
|
|
16330
16731
|
const cwd = process.cwd();
|
|
16331
|
-
console.log(
|
|
16732
|
+
console.log(chalk16.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
16332
16733
|
if (!existsSync6(CONFIG_FILE3)) {
|
|
16333
|
-
console.error(
|
|
16734
|
+
console.error(chalk16.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
16334
16735
|
process.exit(1);
|
|
16335
16736
|
}
|
|
16336
16737
|
let config2;
|
|
@@ -16338,22 +16739,22 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16338
16739
|
const content = await readFile5(CONFIG_FILE3, "utf8");
|
|
16339
16740
|
config2 = parseYaml3(content);
|
|
16340
16741
|
} catch (error43) {
|
|
16341
|
-
console.error(
|
|
16742
|
+
console.error(chalk16.red("\u2717 Invalid YAML format"));
|
|
16342
16743
|
if (error43 instanceof Error) {
|
|
16343
|
-
console.error(
|
|
16744
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16344
16745
|
}
|
|
16345
16746
|
process.exit(1);
|
|
16346
16747
|
}
|
|
16347
16748
|
const validation = validateAgentCompose(config2);
|
|
16348
16749
|
if (!validation.valid) {
|
|
16349
|
-
console.error(
|
|
16750
|
+
console.error(chalk16.red(`\u2717 ${validation.error}`));
|
|
16350
16751
|
process.exit(1);
|
|
16351
16752
|
}
|
|
16352
16753
|
const agentNames = Object.keys(config2.agents);
|
|
16353
16754
|
const agentName = agentNames[0];
|
|
16354
16755
|
const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
|
|
16355
16756
|
console.log(
|
|
16356
|
-
|
|
16757
|
+
chalk16.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
16357
16758
|
);
|
|
16358
16759
|
const requiredVarNames = extractRequiredVarNames(config2);
|
|
16359
16760
|
if (requiredVarNames.length > 0) {
|
|
@@ -16363,25 +16764,25 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16363
16764
|
await generateEnvPlaceholders(missingVars, envFilePath);
|
|
16364
16765
|
console.log();
|
|
16365
16766
|
console.log(
|
|
16366
|
-
|
|
16767
|
+
chalk16.yellow(
|
|
16367
16768
|
`\u26A0 Missing environment variables. Please fill in values in .env file:`
|
|
16368
16769
|
)
|
|
16369
16770
|
);
|
|
16370
16771
|
for (const varName of missingVars) {
|
|
16371
|
-
console.log(
|
|
16772
|
+
console.log(chalk16.yellow(` ${varName}`));
|
|
16372
16773
|
}
|
|
16373
16774
|
process.exit(1);
|
|
16374
16775
|
}
|
|
16375
16776
|
}
|
|
16376
16777
|
if (config2.volumes && Object.keys(config2.volumes).length > 0) {
|
|
16377
16778
|
console.log();
|
|
16378
|
-
console.log(
|
|
16779
|
+
console.log(chalk16.blue("Processing volumes..."));
|
|
16379
16780
|
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
16380
16781
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
16381
|
-
console.log(
|
|
16782
|
+
console.log(chalk16.gray(` ${volumeConfig.name}/`));
|
|
16382
16783
|
if (!existsSync6(volumeDir)) {
|
|
16383
16784
|
console.error(
|
|
16384
|
-
|
|
16785
|
+
chalk16.red(
|
|
16385
16786
|
` \u2717 Directory not found. Create the directory and add files first.`
|
|
16386
16787
|
)
|
|
16387
16788
|
);
|
|
@@ -16394,30 +16795,30 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16394
16795
|
cwd: volumeDir,
|
|
16395
16796
|
silent: true
|
|
16396
16797
|
});
|
|
16397
|
-
console.log(
|
|
16798
|
+
console.log(chalk16.green(` \u2713 Initialized`));
|
|
16398
16799
|
}
|
|
16399
16800
|
await execVm0Command(["volume", "push"], {
|
|
16400
16801
|
cwd: volumeDir,
|
|
16401
16802
|
silent: true
|
|
16402
16803
|
});
|
|
16403
|
-
console.log(
|
|
16804
|
+
console.log(chalk16.green(` \u2713 Pushed`));
|
|
16404
16805
|
} catch (error43) {
|
|
16405
|
-
console.error(
|
|
16806
|
+
console.error(chalk16.red(` \u2717 Failed`));
|
|
16406
16807
|
if (error43 instanceof Error) {
|
|
16407
|
-
console.error(
|
|
16808
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16408
16809
|
}
|
|
16409
16810
|
process.exit(1);
|
|
16410
16811
|
}
|
|
16411
16812
|
}
|
|
16412
16813
|
}
|
|
16413
16814
|
console.log();
|
|
16414
|
-
console.log(
|
|
16815
|
+
console.log(chalk16.blue("Processing artifact..."));
|
|
16415
16816
|
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
16416
|
-
console.log(
|
|
16817
|
+
console.log(chalk16.gray(` ${ARTIFACT_DIR}/`));
|
|
16417
16818
|
try {
|
|
16418
16819
|
if (!existsSync6(artifactDir)) {
|
|
16419
16820
|
await mkdir5(artifactDir, { recursive: true });
|
|
16420
|
-
console.log(
|
|
16821
|
+
console.log(chalk16.green(` \u2713 Created directory`));
|
|
16421
16822
|
}
|
|
16422
16823
|
const existingConfig = await readStorageConfig(artifactDir);
|
|
16423
16824
|
if (!existingConfig) {
|
|
@@ -16425,38 +16826,38 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16425
16826
|
cwd: artifactDir,
|
|
16426
16827
|
silent: true
|
|
16427
16828
|
});
|
|
16428
|
-
console.log(
|
|
16829
|
+
console.log(chalk16.green(` \u2713 Initialized`));
|
|
16429
16830
|
}
|
|
16430
16831
|
await execVm0Command(["artifact", "push"], {
|
|
16431
16832
|
cwd: artifactDir,
|
|
16432
16833
|
silent: true
|
|
16433
16834
|
});
|
|
16434
|
-
console.log(
|
|
16835
|
+
console.log(chalk16.green(` \u2713 Pushed`));
|
|
16435
16836
|
} catch (error43) {
|
|
16436
|
-
console.error(
|
|
16837
|
+
console.error(chalk16.red(` \u2717 Failed`));
|
|
16437
16838
|
if (error43 instanceof Error) {
|
|
16438
|
-
console.error(
|
|
16839
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16439
16840
|
}
|
|
16440
16841
|
process.exit(1);
|
|
16441
16842
|
}
|
|
16442
16843
|
console.log();
|
|
16443
|
-
console.log(
|
|
16844
|
+
console.log(chalk16.blue("Uploading compose..."));
|
|
16444
16845
|
try {
|
|
16445
16846
|
await execVm0Command(["compose", CONFIG_FILE3], {
|
|
16446
16847
|
cwd,
|
|
16447
16848
|
silent: true
|
|
16448
16849
|
});
|
|
16449
|
-
console.log(
|
|
16850
|
+
console.log(chalk16.green(`\u2713 Compose uploaded: ${agentName}`));
|
|
16450
16851
|
} catch (error43) {
|
|
16451
|
-
console.error(
|
|
16852
|
+
console.error(chalk16.red(`\u2717 Compose failed`));
|
|
16452
16853
|
if (error43 instanceof Error) {
|
|
16453
|
-
console.error(
|
|
16854
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16454
16855
|
}
|
|
16455
16856
|
process.exit(1);
|
|
16456
16857
|
}
|
|
16457
16858
|
if (prompt) {
|
|
16458
16859
|
console.log();
|
|
16459
|
-
console.log(
|
|
16860
|
+
console.log(chalk16.blue(`Running agent: ${agentName}`));
|
|
16460
16861
|
console.log();
|
|
16461
16862
|
let runOutput;
|
|
16462
16863
|
try {
|
|
@@ -16477,17 +16878,17 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16477
16878
|
);
|
|
16478
16879
|
if (serverVersion) {
|
|
16479
16880
|
console.log();
|
|
16480
|
-
console.log(
|
|
16881
|
+
console.log(chalk16.blue("Pulling updated artifact..."));
|
|
16481
16882
|
try {
|
|
16482
16883
|
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
16483
16884
|
cwd: artifactDir,
|
|
16484
16885
|
silent: true
|
|
16485
16886
|
});
|
|
16486
|
-
console.log(
|
|
16887
|
+
console.log(chalk16.green(`\u2713 Artifact pulled (${serverVersion})`));
|
|
16487
16888
|
} catch (error43) {
|
|
16488
|
-
console.error(
|
|
16889
|
+
console.error(chalk16.red(`\u2717 Artifact pull failed`));
|
|
16489
16890
|
if (error43 instanceof Error) {
|
|
16490
|
-
console.error(
|
|
16891
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16491
16892
|
}
|
|
16492
16893
|
}
|
|
16493
16894
|
}
|
|
@@ -16495,7 +16896,7 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16495
16896
|
console.log();
|
|
16496
16897
|
console.log(" Run your agent:");
|
|
16497
16898
|
console.log(
|
|
16498
|
-
|
|
16899
|
+
chalk16.cyan(
|
|
16499
16900
|
` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
|
|
16500
16901
|
)
|
|
16501
16902
|
);
|
|
@@ -16507,7 +16908,7 @@ import { Command as Command18 } from "commander";
|
|
|
16507
16908
|
|
|
16508
16909
|
// src/commands/image/build.ts
|
|
16509
16910
|
import { Command as Command14 } from "commander";
|
|
16510
|
-
import
|
|
16911
|
+
import chalk17 from "chalk";
|
|
16511
16912
|
import { readFile as readFile6 } from "fs/promises";
|
|
16512
16913
|
import { existsSync as existsSync7 } from "fs";
|
|
16513
16914
|
|
|
@@ -16547,13 +16948,13 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16547
16948
|
async (options) => {
|
|
16548
16949
|
const { file: file2, name, deleteExisting } = options;
|
|
16549
16950
|
if (!existsSync7(file2)) {
|
|
16550
|
-
console.error(
|
|
16951
|
+
console.error(chalk17.red(`\u2717 Dockerfile not found: ${file2}`));
|
|
16551
16952
|
process.exit(1);
|
|
16552
16953
|
}
|
|
16553
16954
|
const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
|
|
16554
16955
|
if (!nameRegex.test(name)) {
|
|
16555
16956
|
console.error(
|
|
16556
|
-
|
|
16957
|
+
chalk17.red(
|
|
16557
16958
|
"\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
|
|
16558
16959
|
)
|
|
16559
16960
|
);
|
|
@@ -16561,7 +16962,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16561
16962
|
}
|
|
16562
16963
|
if (name.startsWith("vm0-")) {
|
|
16563
16964
|
console.error(
|
|
16564
|
-
|
|
16965
|
+
chalk17.red(
|
|
16565
16966
|
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
16566
16967
|
)
|
|
16567
16968
|
);
|
|
@@ -16572,24 +16973,24 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16572
16973
|
const dockerfile = await readFile6(file2, "utf8");
|
|
16573
16974
|
const validation = validateDockerfile(dockerfile);
|
|
16574
16975
|
if (!validation.valid) {
|
|
16575
|
-
console.error(
|
|
16976
|
+
console.error(chalk17.red("\u2717 Dockerfile validation failed\n"));
|
|
16576
16977
|
for (const error43 of validation.errors) {
|
|
16577
|
-
console.error(
|
|
16978
|
+
console.error(chalk17.red(` ${error43}`));
|
|
16578
16979
|
}
|
|
16579
16980
|
console.error();
|
|
16580
16981
|
console.error(
|
|
16581
|
-
|
|
16982
|
+
chalk17.yellow(
|
|
16582
16983
|
" vm0 image build only supports FROM and RUN instructions."
|
|
16583
16984
|
)
|
|
16584
16985
|
);
|
|
16585
16986
|
console.error(
|
|
16586
|
-
|
|
16987
|
+
chalk17.yellow(
|
|
16587
16988
|
" The purpose is to pre-install environment dependencies."
|
|
16588
16989
|
)
|
|
16589
16990
|
);
|
|
16590
16991
|
process.exit(1);
|
|
16591
16992
|
}
|
|
16592
|
-
console.log(
|
|
16993
|
+
console.log(chalk17.blue(`Building image: ${scope.slug}/${name}`));
|
|
16593
16994
|
console.log();
|
|
16594
16995
|
const buildInfo = await apiClient.createImage({
|
|
16595
16996
|
dockerfile,
|
|
@@ -16597,7 +16998,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16597
16998
|
deleteExisting
|
|
16598
16999
|
});
|
|
16599
17000
|
const { imageId, buildId, versionId } = buildInfo;
|
|
16600
|
-
console.log(
|
|
17001
|
+
console.log(chalk17.gray(` Build ID: ${buildId}`));
|
|
16601
17002
|
console.log();
|
|
16602
17003
|
let logsOffset = 0;
|
|
16603
17004
|
let status = "building";
|
|
@@ -16613,7 +17014,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16613
17014
|
}
|
|
16614
17015
|
const statusData = await statusResponse.json();
|
|
16615
17016
|
for (const log of statusData.logs) {
|
|
16616
|
-
console.log(
|
|
17017
|
+
console.log(chalk17.gray(` ${log}`));
|
|
16617
17018
|
}
|
|
16618
17019
|
logsOffset = statusData.logsOffset;
|
|
16619
17020
|
status = statusData.status;
|
|
@@ -16625,23 +17026,23 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16625
17026
|
if (status === "ready") {
|
|
16626
17027
|
const shortVersion = formatVersionIdForDisplay(versionId);
|
|
16627
17028
|
console.log(
|
|
16628
|
-
|
|
17029
|
+
chalk17.green(`\u2713 Image built: ${scope.slug}/${name}:${shortVersion}`)
|
|
16629
17030
|
);
|
|
16630
17031
|
} else {
|
|
16631
|
-
console.error(
|
|
17032
|
+
console.error(chalk17.red(`\u2717 Build failed`));
|
|
16632
17033
|
process.exit(1);
|
|
16633
17034
|
}
|
|
16634
17035
|
} catch (error43) {
|
|
16635
17036
|
if (error43 instanceof Error) {
|
|
16636
17037
|
if (error43.message.includes("Not authenticated")) {
|
|
16637
17038
|
console.error(
|
|
16638
|
-
|
|
17039
|
+
chalk17.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
16639
17040
|
);
|
|
16640
17041
|
} else {
|
|
16641
|
-
console.error(
|
|
17042
|
+
console.error(chalk17.red(`\u2717 ${error43.message}`));
|
|
16642
17043
|
}
|
|
16643
17044
|
} else {
|
|
16644
|
-
console.error(
|
|
17045
|
+
console.error(chalk17.red("\u2717 An unexpected error occurred"));
|
|
16645
17046
|
}
|
|
16646
17047
|
process.exit(1);
|
|
16647
17048
|
}
|
|
@@ -16650,7 +17051,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16650
17051
|
|
|
16651
17052
|
// src/commands/image/list.ts
|
|
16652
17053
|
import { Command as Command15 } from "commander";
|
|
16653
|
-
import
|
|
17054
|
+
import chalk18 from "chalk";
|
|
16654
17055
|
var listCommand = new Command15().name("list").alias("ls").description("List your custom images").action(async () => {
|
|
16655
17056
|
try {
|
|
16656
17057
|
const response = await apiClient.get("/api/images");
|
|
@@ -16663,15 +17064,15 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16663
17064
|
const data = await response.json();
|
|
16664
17065
|
const { images } = data;
|
|
16665
17066
|
if (images.length === 0) {
|
|
16666
|
-
console.log(
|
|
17067
|
+
console.log(chalk18.gray("No images found."));
|
|
16667
17068
|
console.log();
|
|
16668
17069
|
console.log("Build your first image:");
|
|
16669
17070
|
console.log(
|
|
16670
|
-
|
|
17071
|
+
chalk18.cyan(" vm0 image build --file Dockerfile --name my-image")
|
|
16671
17072
|
);
|
|
16672
17073
|
return;
|
|
16673
17074
|
}
|
|
16674
|
-
console.log(
|
|
17075
|
+
console.log(chalk18.bold("Your images:"));
|
|
16675
17076
|
console.log();
|
|
16676
17077
|
const imagesByAlias = /* @__PURE__ */ new Map();
|
|
16677
17078
|
for (const image of images) {
|
|
@@ -16685,40 +17086,40 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16685
17086
|
latestVersions.set(alias, latestReady?.versionId || null);
|
|
16686
17087
|
}
|
|
16687
17088
|
console.log(
|
|
16688
|
-
|
|
17089
|
+
chalk18.gray(
|
|
16689
17090
|
`${"NAME".padEnd(40)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
|
|
16690
17091
|
)
|
|
16691
17092
|
);
|
|
16692
|
-
console.log(
|
|
17093
|
+
console.log(chalk18.gray("-".repeat(72)));
|
|
16693
17094
|
for (const image of images) {
|
|
16694
|
-
const statusColor = image.status === "ready" ?
|
|
17095
|
+
const statusColor = image.status === "ready" ? chalk18.green : image.status === "building" ? chalk18.yellow : chalk18.red;
|
|
16695
17096
|
const createdAt = new Date(image.createdAt).toLocaleString();
|
|
16696
17097
|
let displayName = image.alias;
|
|
16697
17098
|
if (image.versionId) {
|
|
16698
17099
|
const shortVersion = formatVersionIdForDisplay(image.versionId);
|
|
16699
17100
|
displayName = `${image.alias}:${shortVersion}`;
|
|
16700
17101
|
if (image.status === "ready" && latestVersions.get(image.alias) === image.versionId) {
|
|
16701
|
-
displayName = `${displayName} ${
|
|
17102
|
+
displayName = `${displayName} ${chalk18.cyan("(latest)")}`;
|
|
16702
17103
|
}
|
|
16703
17104
|
}
|
|
16704
17105
|
console.log(
|
|
16705
17106
|
`${displayName.padEnd(40)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
|
|
16706
17107
|
);
|
|
16707
17108
|
if (image.status === "error" && image.errorMessage) {
|
|
16708
|
-
console.log(
|
|
17109
|
+
console.log(chalk18.red(` Error: ${image.errorMessage}`));
|
|
16709
17110
|
}
|
|
16710
17111
|
}
|
|
16711
17112
|
console.log();
|
|
16712
|
-
console.log(
|
|
17113
|
+
console.log(chalk18.gray(`Total: ${images.length} version(s)`));
|
|
16713
17114
|
} catch (error43) {
|
|
16714
17115
|
if (error43 instanceof Error) {
|
|
16715
17116
|
if (error43.message.includes("Not authenticated")) {
|
|
16716
|
-
console.error(
|
|
17117
|
+
console.error(chalk18.red("Not authenticated. Run: vm0 auth login"));
|
|
16717
17118
|
} else {
|
|
16718
|
-
console.error(
|
|
17119
|
+
console.error(chalk18.red(`Error: ${error43.message}`));
|
|
16719
17120
|
}
|
|
16720
17121
|
} else {
|
|
16721
|
-
console.error(
|
|
17122
|
+
console.error(chalk18.red("An unexpected error occurred"));
|
|
16722
17123
|
}
|
|
16723
17124
|
process.exit(1);
|
|
16724
17125
|
}
|
|
@@ -16726,7 +17127,7 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16726
17127
|
|
|
16727
17128
|
// src/commands/image/delete.ts
|
|
16728
17129
|
import { Command as Command16 } from "commander";
|
|
16729
|
-
import
|
|
17130
|
+
import chalk19 from "chalk";
|
|
16730
17131
|
import * as readline from "readline";
|
|
16731
17132
|
var deleteCommand = new Command16().name("delete").alias("rm").description("Delete a custom image or specific version").argument("<name>", "Image name or name:version to delete").option("-f, --force", "Skip confirmation prompt").option("--all", "Delete all versions of the image").action(
|
|
16732
17133
|
async (nameArg, options) => {
|
|
@@ -16749,12 +17150,12 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16749
17150
|
(img) => img.alias === name && img.versionId && img.versionId.startsWith(versionId.toLowerCase())
|
|
16750
17151
|
);
|
|
16751
17152
|
if (matchingVersions.length === 0) {
|
|
16752
|
-
console.error(
|
|
17153
|
+
console.error(chalk19.red(`Image version not found: ${nameArg}`));
|
|
16753
17154
|
process.exit(1);
|
|
16754
17155
|
}
|
|
16755
17156
|
if (matchingVersions.length > 1) {
|
|
16756
17157
|
console.error(
|
|
16757
|
-
|
|
17158
|
+
chalk19.red(
|
|
16758
17159
|
`Ambiguous version prefix "${versionId}". Please use more characters.`
|
|
16759
17160
|
)
|
|
16760
17161
|
);
|
|
@@ -16764,7 +17165,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16764
17165
|
} else if (options.all) {
|
|
16765
17166
|
imagesToDelete = data.images.filter((img) => img.alias === name);
|
|
16766
17167
|
if (imagesToDelete.length === 0) {
|
|
16767
|
-
console.error(
|
|
17168
|
+
console.error(chalk19.red(`Image not found: ${name}`));
|
|
16768
17169
|
process.exit(1);
|
|
16769
17170
|
}
|
|
16770
17171
|
} else {
|
|
@@ -16772,7 +17173,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16772
17173
|
(img) => img.alias === name
|
|
16773
17174
|
);
|
|
16774
17175
|
if (matchingImages.length === 0) {
|
|
16775
|
-
console.error(
|
|
17176
|
+
console.error(chalk19.red(`Image not found: ${name}`));
|
|
16776
17177
|
process.exit(1);
|
|
16777
17178
|
}
|
|
16778
17179
|
const latestReady = matchingImages.find(
|
|
@@ -16793,13 +17194,13 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16793
17194
|
output: process.stdout
|
|
16794
17195
|
});
|
|
16795
17196
|
const answer = await new Promise((resolve2) => {
|
|
16796
|
-
rl.question(
|
|
17197
|
+
rl.question(chalk19.yellow(`${confirmMsg} [y/N] `), (answer2) => {
|
|
16797
17198
|
rl.close();
|
|
16798
17199
|
resolve2(answer2);
|
|
16799
17200
|
});
|
|
16800
17201
|
});
|
|
16801
17202
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
16802
|
-
console.log(
|
|
17203
|
+
console.log(chalk19.gray("Cancelled."));
|
|
16803
17204
|
return;
|
|
16804
17205
|
}
|
|
16805
17206
|
}
|
|
@@ -16814,17 +17215,17 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16814
17215
|
);
|
|
16815
17216
|
}
|
|
16816
17217
|
const displayName = image.versionId ? `${image.alias}:${formatVersionIdForDisplay(image.versionId)}` : image.alias;
|
|
16817
|
-
console.log(
|
|
17218
|
+
console.log(chalk19.green(`Deleted image: ${displayName}`));
|
|
16818
17219
|
}
|
|
16819
17220
|
} catch (error43) {
|
|
16820
17221
|
if (error43 instanceof Error) {
|
|
16821
17222
|
if (error43.message.includes("Not authenticated")) {
|
|
16822
|
-
console.error(
|
|
17223
|
+
console.error(chalk19.red("Not authenticated. Run: vm0 auth login"));
|
|
16823
17224
|
} else {
|
|
16824
|
-
console.error(
|
|
17225
|
+
console.error(chalk19.red(`Error: ${error43.message}`));
|
|
16825
17226
|
}
|
|
16826
17227
|
} else {
|
|
16827
|
-
console.error(
|
|
17228
|
+
console.error(chalk19.red("An unexpected error occurred"));
|
|
16828
17229
|
}
|
|
16829
17230
|
process.exit(1);
|
|
16830
17231
|
}
|
|
@@ -16833,7 +17234,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16833
17234
|
|
|
16834
17235
|
// src/commands/image/versions.ts
|
|
16835
17236
|
import { Command as Command17 } from "commander";
|
|
16836
|
-
import
|
|
17237
|
+
import chalk20 from "chalk";
|
|
16837
17238
|
var versionsCommand = new Command17().name("versions").description("List all versions of an image").argument("<name>", "Name of the image").action(async (name) => {
|
|
16838
17239
|
try {
|
|
16839
17240
|
const response = await apiClient.get("/api/images");
|
|
@@ -16846,42 +17247,42 @@ var versionsCommand = new Command17().name("versions").description("List all ver
|
|
|
16846
17247
|
const data = await response.json();
|
|
16847
17248
|
const versions = data.images.filter((img) => img.alias === name);
|
|
16848
17249
|
if (versions.length === 0) {
|
|
16849
|
-
console.error(
|
|
17250
|
+
console.error(chalk20.red(`Image not found: ${name}`));
|
|
16850
17251
|
process.exit(1);
|
|
16851
17252
|
}
|
|
16852
17253
|
const latestReady = versions.find((v) => v.status === "ready");
|
|
16853
17254
|
const latestVersionId = latestReady?.versionId || null;
|
|
16854
|
-
console.log(
|
|
17255
|
+
console.log(chalk20.bold(`Versions of ${name}:`));
|
|
16855
17256
|
console.log();
|
|
16856
17257
|
console.log(
|
|
16857
|
-
|
|
17258
|
+
chalk20.gray(
|
|
16858
17259
|
`${"VERSION".padEnd(20)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(24)}`
|
|
16859
17260
|
)
|
|
16860
17261
|
);
|
|
16861
|
-
console.log(
|
|
17262
|
+
console.log(chalk20.gray("-".repeat(56)));
|
|
16862
17263
|
for (const version2 of versions) {
|
|
16863
|
-
const statusColor = version2.status === "ready" ?
|
|
17264
|
+
const statusColor = version2.status === "ready" ? chalk20.green : version2.status === "building" ? chalk20.yellow : chalk20.red;
|
|
16864
17265
|
const createdAt = new Date(version2.createdAt).toLocaleString();
|
|
16865
17266
|
let versionDisplay = version2.versionId ? formatVersionIdForDisplay(version2.versionId) : "(legacy)";
|
|
16866
17267
|
if (version2.status === "ready" && version2.versionId === latestVersionId) {
|
|
16867
|
-
versionDisplay = `${versionDisplay} ${
|
|
17268
|
+
versionDisplay = `${versionDisplay} ${chalk20.cyan("(latest)")}`;
|
|
16868
17269
|
}
|
|
16869
17270
|
console.log(
|
|
16870
17271
|
`${versionDisplay.padEnd(20)} ${statusColor(version2.status.padEnd(12))} ${createdAt.padEnd(24)}`
|
|
16871
17272
|
);
|
|
16872
17273
|
if (version2.status === "error" && version2.errorMessage) {
|
|
16873
|
-
console.log(
|
|
17274
|
+
console.log(chalk20.red(` Error: ${version2.errorMessage}`));
|
|
16874
17275
|
}
|
|
16875
17276
|
}
|
|
16876
17277
|
console.log();
|
|
16877
|
-
console.log(
|
|
17278
|
+
console.log(chalk20.gray(`Total: ${versions.length} version(s)`));
|
|
16878
17279
|
console.log();
|
|
16879
|
-
console.log(
|
|
16880
|
-
console.log(
|
|
17280
|
+
console.log(chalk20.gray("Usage:"));
|
|
17281
|
+
console.log(chalk20.gray(` image: "${name}" # uses latest`));
|
|
16881
17282
|
if (latestVersionId) {
|
|
16882
17283
|
const shortVersion = formatVersionIdForDisplay(latestVersionId);
|
|
16883
17284
|
console.log(
|
|
16884
|
-
|
|
17285
|
+
chalk20.gray(
|
|
16885
17286
|
` image: "${name}:${shortVersion}" # pin to specific version`
|
|
16886
17287
|
)
|
|
16887
17288
|
);
|
|
@@ -16889,12 +17290,12 @@ var versionsCommand = new Command17().name("versions").description("List all ver
|
|
|
16889
17290
|
} catch (error43) {
|
|
16890
17291
|
if (error43 instanceof Error) {
|
|
16891
17292
|
if (error43.message.includes("Not authenticated")) {
|
|
16892
|
-
console.error(
|
|
17293
|
+
console.error(chalk20.red("Not authenticated. Run: vm0 auth login"));
|
|
16893
17294
|
} else {
|
|
16894
|
-
console.error(
|
|
17295
|
+
console.error(chalk20.red(`Error: ${error43.message}`));
|
|
16895
17296
|
}
|
|
16896
17297
|
} else {
|
|
16897
|
-
console.error(
|
|
17298
|
+
console.error(chalk20.red("An unexpected error occurred"));
|
|
16898
17299
|
}
|
|
16899
17300
|
process.exit(1);
|
|
16900
17301
|
}
|
|
@@ -16905,7 +17306,7 @@ var imageCommand = new Command18().name("image").description("Manage custom imag
|
|
|
16905
17306
|
|
|
16906
17307
|
// src/commands/logs/index.ts
|
|
16907
17308
|
import { Command as Command19 } from "commander";
|
|
16908
|
-
import
|
|
17309
|
+
import chalk21 from "chalk";
|
|
16909
17310
|
|
|
16910
17311
|
// src/lib/time-parser.ts
|
|
16911
17312
|
function parseTime(timeStr) {
|
|
@@ -16967,31 +17368,34 @@ function formatMetric(metric) {
|
|
|
16967
17368
|
function formatNetworkLog(entry) {
|
|
16968
17369
|
let statusColor;
|
|
16969
17370
|
if (entry.status >= 200 && entry.status < 300) {
|
|
16970
|
-
statusColor =
|
|
17371
|
+
statusColor = chalk21.green;
|
|
16971
17372
|
} else if (entry.status >= 300 && entry.status < 400) {
|
|
16972
|
-
statusColor =
|
|
17373
|
+
statusColor = chalk21.yellow;
|
|
16973
17374
|
} else if (entry.status >= 400) {
|
|
16974
|
-
statusColor =
|
|
17375
|
+
statusColor = chalk21.red;
|
|
16975
17376
|
} else {
|
|
16976
|
-
statusColor =
|
|
17377
|
+
statusColor = chalk21.gray;
|
|
16977
17378
|
}
|
|
16978
17379
|
let latencyColor;
|
|
16979
17380
|
if (entry.latency_ms < 500) {
|
|
16980
|
-
latencyColor =
|
|
17381
|
+
latencyColor = chalk21.green;
|
|
16981
17382
|
} else if (entry.latency_ms < 2e3) {
|
|
16982
|
-
latencyColor =
|
|
17383
|
+
latencyColor = chalk21.yellow;
|
|
16983
17384
|
} else {
|
|
16984
|
-
latencyColor =
|
|
17385
|
+
latencyColor = chalk21.red;
|
|
16985
17386
|
}
|
|
16986
|
-
return `[${entry.timestamp}] ${
|
|
17387
|
+
return `[${entry.timestamp}] ${chalk21.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes7(entry.request_size)}/${formatBytes7(entry.response_size)} ${chalk21.gray(entry.url)}`;
|
|
16987
17388
|
}
|
|
16988
|
-
function renderAgentEvent(event) {
|
|
16989
|
-
const
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
parsed
|
|
16994
|
-
|
|
17389
|
+
function renderAgentEvent(event, provider) {
|
|
17390
|
+
const eventData = event.eventData;
|
|
17391
|
+
if (provider === "codex") {
|
|
17392
|
+
CodexEventRenderer.render(eventData);
|
|
17393
|
+
} else {
|
|
17394
|
+
const parsed = ClaudeEventParser.parse(eventData);
|
|
17395
|
+
if (parsed) {
|
|
17396
|
+
parsed.timestamp = new Date(event.createdAt);
|
|
17397
|
+
EventRenderer.render(parsed, { showTimestamp: true });
|
|
17398
|
+
}
|
|
16995
17399
|
}
|
|
16996
17400
|
}
|
|
16997
17401
|
function getLogType(options) {
|
|
@@ -17003,7 +17407,7 @@ function getLogType(options) {
|
|
|
17003
17407
|
].filter(Boolean).length;
|
|
17004
17408
|
if (selected > 1) {
|
|
17005
17409
|
console.error(
|
|
17006
|
-
|
|
17410
|
+
chalk21.red(
|
|
17007
17411
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
17008
17412
|
)
|
|
17009
17413
|
);
|
|
@@ -17056,16 +17460,16 @@ var logsCommand = new Command19().name("logs").description("View logs for an age
|
|
|
17056
17460
|
async function showAgentEvents(runId, options) {
|
|
17057
17461
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
17058
17462
|
if (response.events.length === 0) {
|
|
17059
|
-
console.log(
|
|
17463
|
+
console.log(chalk21.yellow("No agent events found for this run."));
|
|
17060
17464
|
return;
|
|
17061
17465
|
}
|
|
17062
17466
|
for (const event of response.events) {
|
|
17063
|
-
renderAgentEvent(event);
|
|
17467
|
+
renderAgentEvent(event, response.provider);
|
|
17064
17468
|
}
|
|
17065
17469
|
if (response.hasMore) {
|
|
17066
17470
|
console.log();
|
|
17067
17471
|
console.log(
|
|
17068
|
-
|
|
17472
|
+
chalk21.gray(
|
|
17069
17473
|
`Showing ${response.events.length} events. Use --limit to see more.`
|
|
17070
17474
|
)
|
|
17071
17475
|
);
|
|
@@ -17074,21 +17478,21 @@ async function showAgentEvents(runId, options) {
|
|
|
17074
17478
|
async function showSystemLog(runId, options) {
|
|
17075
17479
|
const response = await apiClient.getSystemLog(runId, options);
|
|
17076
17480
|
if (!response.systemLog) {
|
|
17077
|
-
console.log(
|
|
17481
|
+
console.log(chalk21.yellow("No system log found for this run."));
|
|
17078
17482
|
return;
|
|
17079
17483
|
}
|
|
17080
17484
|
console.log(response.systemLog);
|
|
17081
17485
|
if (response.hasMore) {
|
|
17082
17486
|
console.log();
|
|
17083
17487
|
console.log(
|
|
17084
|
-
|
|
17488
|
+
chalk21.gray("More log entries available. Use --limit to see more.")
|
|
17085
17489
|
);
|
|
17086
17490
|
}
|
|
17087
17491
|
}
|
|
17088
17492
|
async function showMetrics(runId, options) {
|
|
17089
17493
|
const response = await apiClient.getMetrics(runId, options);
|
|
17090
17494
|
if (response.metrics.length === 0) {
|
|
17091
|
-
console.log(
|
|
17495
|
+
console.log(chalk21.yellow("No metrics found for this run."));
|
|
17092
17496
|
return;
|
|
17093
17497
|
}
|
|
17094
17498
|
for (const metric of response.metrics) {
|
|
@@ -17097,7 +17501,7 @@ async function showMetrics(runId, options) {
|
|
|
17097
17501
|
if (response.hasMore) {
|
|
17098
17502
|
console.log();
|
|
17099
17503
|
console.log(
|
|
17100
|
-
|
|
17504
|
+
chalk21.gray(
|
|
17101
17505
|
`Showing ${response.metrics.length} metrics. Use --limit to see more.`
|
|
17102
17506
|
)
|
|
17103
17507
|
);
|
|
@@ -17107,7 +17511,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
17107
17511
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
17108
17512
|
if (response.networkLogs.length === 0) {
|
|
17109
17513
|
console.log(
|
|
17110
|
-
|
|
17514
|
+
chalk21.yellow(
|
|
17111
17515
|
"No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
|
|
17112
17516
|
)
|
|
17113
17517
|
);
|
|
@@ -17119,7 +17523,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
17119
17523
|
if (response.hasMore) {
|
|
17120
17524
|
console.log();
|
|
17121
17525
|
console.log(
|
|
17122
|
-
|
|
17526
|
+
chalk21.gray(
|
|
17123
17527
|
`Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
|
|
17124
17528
|
)
|
|
17125
17529
|
);
|
|
@@ -17128,17 +17532,17 @@ async function showNetworkLogs(runId, options) {
|
|
|
17128
17532
|
function handleError(error43, runId) {
|
|
17129
17533
|
if (error43 instanceof Error) {
|
|
17130
17534
|
if (error43.message.includes("Not authenticated")) {
|
|
17131
|
-
console.error(
|
|
17535
|
+
console.error(chalk21.red("Not authenticated. Run: vm0 auth login"));
|
|
17132
17536
|
} else if (error43.message.includes("not found")) {
|
|
17133
|
-
console.error(
|
|
17537
|
+
console.error(chalk21.red(`Run not found: ${runId}`));
|
|
17134
17538
|
} else if (error43.message.includes("Invalid time format")) {
|
|
17135
|
-
console.error(
|
|
17539
|
+
console.error(chalk21.red(error43.message));
|
|
17136
17540
|
} else {
|
|
17137
|
-
console.error(
|
|
17138
|
-
console.error(
|
|
17541
|
+
console.error(chalk21.red("Failed to fetch logs"));
|
|
17542
|
+
console.error(chalk21.gray(` ${error43.message}`));
|
|
17139
17543
|
}
|
|
17140
17544
|
} else {
|
|
17141
|
-
console.error(
|
|
17545
|
+
console.error(chalk21.red("An unexpected error occurred"));
|
|
17142
17546
|
}
|
|
17143
17547
|
}
|
|
17144
17548
|
|
|
@@ -17147,12 +17551,12 @@ import { Command as Command22 } from "commander";
|
|
|
17147
17551
|
|
|
17148
17552
|
// src/commands/scope/status.ts
|
|
17149
17553
|
import { Command as Command20 } from "commander";
|
|
17150
|
-
import
|
|
17554
|
+
import chalk22 from "chalk";
|
|
17151
17555
|
var statusCommand3 = new Command20().name("status").description("View current scope status").action(async () => {
|
|
17152
17556
|
try {
|
|
17153
17557
|
const scope = await apiClient.getScope();
|
|
17154
|
-
console.log(
|
|
17155
|
-
console.log(` Slug: ${
|
|
17558
|
+
console.log(chalk22.cyan("Scope Information:"));
|
|
17559
|
+
console.log(` Slug: ${chalk22.green(scope.slug)}`);
|
|
17156
17560
|
console.log(` Type: ${scope.type}`);
|
|
17157
17561
|
if (scope.displayName) {
|
|
17158
17562
|
console.log(` Display Name: ${scope.displayName}`);
|
|
@@ -17163,20 +17567,20 @@ var statusCommand3 = new Command20().name("status").description("View current sc
|
|
|
17163
17567
|
} catch (error43) {
|
|
17164
17568
|
if (error43 instanceof Error) {
|
|
17165
17569
|
if (error43.message.includes("Not authenticated")) {
|
|
17166
|
-
console.error(
|
|
17570
|
+
console.error(chalk22.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
17167
17571
|
} else if (error43.message.includes("No scope configured")) {
|
|
17168
|
-
console.log(
|
|
17572
|
+
console.log(chalk22.yellow("No scope configured."));
|
|
17169
17573
|
console.log();
|
|
17170
17574
|
console.log("Set your scope with:");
|
|
17171
|
-
console.log(
|
|
17575
|
+
console.log(chalk22.cyan(" vm0 scope set <slug>"));
|
|
17172
17576
|
console.log();
|
|
17173
17577
|
console.log("Example:");
|
|
17174
|
-
console.log(
|
|
17578
|
+
console.log(chalk22.gray(" vm0 scope set myusername"));
|
|
17175
17579
|
} else {
|
|
17176
|
-
console.error(
|
|
17580
|
+
console.error(chalk22.red(`\u2717 ${error43.message}`));
|
|
17177
17581
|
}
|
|
17178
17582
|
} else {
|
|
17179
|
-
console.error(
|
|
17583
|
+
console.error(chalk22.red("\u2717 An unexpected error occurred"));
|
|
17180
17584
|
}
|
|
17181
17585
|
process.exit(1);
|
|
17182
17586
|
}
|
|
@@ -17184,7 +17588,7 @@ var statusCommand3 = new Command20().name("status").description("View current sc
|
|
|
17184
17588
|
|
|
17185
17589
|
// src/commands/scope/set.ts
|
|
17186
17590
|
import { Command as Command21 } from "commander";
|
|
17187
|
-
import
|
|
17591
|
+
import chalk23 from "chalk";
|
|
17188
17592
|
var setCommand = new Command21().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").option("--display-name <name>", "Display name for the scope").action(
|
|
17189
17593
|
async (slug, options) => {
|
|
17190
17594
|
try {
|
|
@@ -17197,56 +17601,56 @@ var setCommand = new Command21().name("set").description("Set your scope slug").
|
|
|
17197
17601
|
if (existingScope) {
|
|
17198
17602
|
if (!options.force) {
|
|
17199
17603
|
console.error(
|
|
17200
|
-
|
|
17604
|
+
chalk23.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
17201
17605
|
);
|
|
17202
17606
|
console.error();
|
|
17203
17607
|
console.error("To change your scope, use --force:");
|
|
17204
|
-
console.error(
|
|
17608
|
+
console.error(chalk23.cyan(` vm0 scope set ${slug} --force`));
|
|
17205
17609
|
console.error();
|
|
17206
17610
|
console.error(
|
|
17207
|
-
|
|
17611
|
+
chalk23.yellow(
|
|
17208
17612
|
"Warning: Changing your scope may break existing image references."
|
|
17209
17613
|
)
|
|
17210
17614
|
);
|
|
17211
17615
|
process.exit(1);
|
|
17212
17616
|
}
|
|
17213
17617
|
scope = await apiClient.updateScope({ slug, force: true });
|
|
17214
|
-
console.log(
|
|
17618
|
+
console.log(chalk23.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
17215
17619
|
} else {
|
|
17216
17620
|
scope = await apiClient.createScope({
|
|
17217
17621
|
slug,
|
|
17218
17622
|
displayName: options.displayName
|
|
17219
17623
|
});
|
|
17220
|
-
console.log(
|
|
17624
|
+
console.log(chalk23.green(`\u2713 Scope created: ${scope.slug}`));
|
|
17221
17625
|
}
|
|
17222
17626
|
console.log();
|
|
17223
17627
|
console.log("Your images will now be namespaced as:");
|
|
17224
|
-
console.log(
|
|
17628
|
+
console.log(chalk23.cyan(` ${scope.slug}/<image-name>`));
|
|
17225
17629
|
} catch (error43) {
|
|
17226
17630
|
if (error43 instanceof Error) {
|
|
17227
17631
|
if (error43.message.includes("Not authenticated")) {
|
|
17228
17632
|
console.error(
|
|
17229
|
-
|
|
17633
|
+
chalk23.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
17230
17634
|
);
|
|
17231
17635
|
} else if (error43.message.includes("already exists")) {
|
|
17232
17636
|
console.error(
|
|
17233
|
-
|
|
17637
|
+
chalk23.red(
|
|
17234
17638
|
`\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
|
|
17235
17639
|
)
|
|
17236
17640
|
);
|
|
17237
17641
|
} else if (error43.message.includes("reserved")) {
|
|
17238
|
-
console.error(
|
|
17642
|
+
console.error(chalk23.red(`\u2717 ${error43.message}`));
|
|
17239
17643
|
} else if (error43.message.includes("vm0")) {
|
|
17240
17644
|
console.error(
|
|
17241
|
-
|
|
17645
|
+
chalk23.red(
|
|
17242
17646
|
"\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
|
|
17243
17647
|
)
|
|
17244
17648
|
);
|
|
17245
17649
|
} else {
|
|
17246
|
-
console.error(
|
|
17650
|
+
console.error(chalk23.red(`\u2717 ${error43.message}`));
|
|
17247
17651
|
}
|
|
17248
17652
|
} else {
|
|
17249
|
-
console.error(
|
|
17653
|
+
console.error(chalk23.red("\u2717 An unexpected error occurred"));
|
|
17250
17654
|
}
|
|
17251
17655
|
process.exit(1);
|
|
17252
17656
|
}
|
|
@@ -17258,9 +17662,9 @@ var scopeCommand = new Command22().name("scope").description("Manage your scope
|
|
|
17258
17662
|
|
|
17259
17663
|
// src/index.ts
|
|
17260
17664
|
var program = new Command23();
|
|
17261
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
17665
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.21.1");
|
|
17262
17666
|
program.command("info").description("Display environment information").action(async () => {
|
|
17263
|
-
console.log(
|
|
17667
|
+
console.log(chalk24.cyan("System Information:"));
|
|
17264
17668
|
console.log(`Node Version: ${process.version}`);
|
|
17265
17669
|
console.log(`Platform: ${process.platform}`);
|
|
17266
17670
|
console.log(`Architecture: ${process.arch}`);
|