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