@vm0/cli 4.19.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 +833 -405
- 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";
|
|
@@ -12357,7 +12357,8 @@ var volumeConfigSchema = external_exports.object({
|
|
|
12357
12357
|
});
|
|
12358
12358
|
var agentDefinitionSchema = external_exports.object({
|
|
12359
12359
|
description: external_exports.string().optional(),
|
|
12360
|
-
image: external_exports.string().
|
|
12360
|
+
image: external_exports.string().optional(),
|
|
12361
|
+
// Optional when provider supports auto-config
|
|
12361
12362
|
provider: external_exports.string().min(1, "Provider is required"),
|
|
12362
12363
|
volumes: external_exports.array(external_exports.string()).optional(),
|
|
12363
12364
|
working_dir: external_exports.string().optional(),
|
|
@@ -12371,15 +12372,15 @@ var agentDefinitionSchema = external_exports.object({
|
|
|
12371
12372
|
*/
|
|
12372
12373
|
beta_network_security: external_exports.boolean().optional().default(false),
|
|
12373
12374
|
/**
|
|
12374
|
-
* Path to
|
|
12375
|
+
* Path to instructions file (e.g., AGENTS.md).
|
|
12375
12376
|
* Auto-uploaded as volume and mounted at /home/user/.claude/CLAUDE.md
|
|
12376
12377
|
*/
|
|
12377
|
-
|
|
12378
|
+
instructions: external_exports.string().optional(),
|
|
12378
12379
|
/**
|
|
12379
|
-
* Array of GitHub tree URLs for
|
|
12380
|
+
* Array of GitHub tree URLs for agent skills.
|
|
12380
12381
|
* Each skill is auto-downloaded and mounted at /home/user/.claude/skills/{skillName}/
|
|
12381
12382
|
*/
|
|
12382
|
-
|
|
12383
|
+
skills: external_exports.array(external_exports.string()).optional()
|
|
12383
12384
|
});
|
|
12384
12385
|
var agentComposeContentSchema = external_exports.object({
|
|
12385
12386
|
version: external_exports.string().min(1, "Version is required"),
|
|
@@ -13492,6 +13493,12 @@ function getLegacySystemTemplateWarning(legacyFormat) {
|
|
|
13492
13493
|
if (legacyFormat === "vm0-claude-code-dev") {
|
|
13493
13494
|
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/claude-code:dev" instead.`;
|
|
13494
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
|
+
}
|
|
13495
13502
|
if (legacyFormat.startsWith("vm0-github-cli")) {
|
|
13496
13503
|
return `Warning: "${legacyFormat}" is deprecated and will be removed. No replacement available.`;
|
|
13497
13504
|
}
|
|
@@ -13507,6 +13514,69 @@ function formatVersionIdForDisplay(versionId) {
|
|
|
13507
13514
|
return versionId.slice(0, VERSION_ID_DISPLAY_LENGTH);
|
|
13508
13515
|
}
|
|
13509
13516
|
|
|
13517
|
+
// ../../packages/core/src/storage-names.ts
|
|
13518
|
+
function getInstructionsStorageName(agentName) {
|
|
13519
|
+
return `agent-instructions@${agentName}`;
|
|
13520
|
+
}
|
|
13521
|
+
function getSkillStorageName(fullPath) {
|
|
13522
|
+
return `agent-skills@${fullPath}`;
|
|
13523
|
+
}
|
|
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
|
+
|
|
13510
13580
|
// src/lib/api-client.ts
|
|
13511
13581
|
var ApiClient = class {
|
|
13512
13582
|
async getHeaders() {
|
|
@@ -13886,7 +13956,18 @@ var apiClient = new ApiClient();
|
|
|
13886
13956
|
// src/lib/provider-config.ts
|
|
13887
13957
|
var PROVIDER_DEFAULTS = {
|
|
13888
13958
|
"claude-code": {
|
|
13889
|
-
workingDir: "/home/user/workspace"
|
|
13959
|
+
workingDir: "/home/user/workspace",
|
|
13960
|
+
image: {
|
|
13961
|
+
production: "vm0/claude-code:latest",
|
|
13962
|
+
development: "vm0/claude-code:dev"
|
|
13963
|
+
}
|
|
13964
|
+
},
|
|
13965
|
+
codex: {
|
|
13966
|
+
workingDir: "/home/user/workspace",
|
|
13967
|
+
image: {
|
|
13968
|
+
production: "vm0/codex:latest",
|
|
13969
|
+
development: "vm0/codex:dev"
|
|
13970
|
+
}
|
|
13890
13971
|
}
|
|
13891
13972
|
};
|
|
13892
13973
|
function getProviderDefaults(provider) {
|
|
@@ -13895,6 +13976,12 @@ function getProviderDefaults(provider) {
|
|
|
13895
13976
|
function isProviderSupported(provider) {
|
|
13896
13977
|
return provider in PROVIDER_DEFAULTS;
|
|
13897
13978
|
}
|
|
13979
|
+
function getDefaultImage(provider) {
|
|
13980
|
+
const defaults = PROVIDER_DEFAULTS[provider];
|
|
13981
|
+
if (!defaults) return void 0;
|
|
13982
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
13983
|
+
return isProduction ? defaults.image.production : defaults.image.development;
|
|
13984
|
+
}
|
|
13898
13985
|
|
|
13899
13986
|
// src/lib/yaml-validator.ts
|
|
13900
13987
|
function validateAgentName(name) {
|
|
@@ -13967,10 +14054,16 @@ function validateAgentCompose(config2) {
|
|
|
13967
14054
|
};
|
|
13968
14055
|
}
|
|
13969
14056
|
const providerIsSupported = isProviderSupported(agent.provider);
|
|
13970
|
-
if (
|
|
14057
|
+
if (agent.image !== void 0 && typeof agent.image !== "string") {
|
|
13971
14058
|
return {
|
|
13972
14059
|
valid: false,
|
|
13973
|
-
error: "
|
|
14060
|
+
error: "agent.image must be a string if provided"
|
|
14061
|
+
};
|
|
14062
|
+
}
|
|
14063
|
+
if (!agent.image && !providerIsSupported) {
|
|
14064
|
+
return {
|
|
14065
|
+
valid: false,
|
|
14066
|
+
error: "Missing agent.image (required when provider is not auto-configured)"
|
|
13974
14067
|
};
|
|
13975
14068
|
}
|
|
13976
14069
|
if (agent.working_dir !== void 0 && typeof agent.working_dir !== "string") {
|
|
@@ -13985,38 +14078,38 @@ function validateAgentCompose(config2) {
|
|
|
13985
14078
|
error: "Missing agent.working_dir (required when provider is not auto-configured)"
|
|
13986
14079
|
};
|
|
13987
14080
|
}
|
|
13988
|
-
if (agent.
|
|
13989
|
-
if (typeof agent.
|
|
14081
|
+
if (agent.instructions !== void 0) {
|
|
14082
|
+
if (typeof agent.instructions !== "string") {
|
|
13990
14083
|
return {
|
|
13991
14084
|
valid: false,
|
|
13992
|
-
error: "agent.
|
|
14085
|
+
error: "agent.instructions must be a string (path to instructions file)"
|
|
13993
14086
|
};
|
|
13994
14087
|
}
|
|
13995
|
-
if (agent.
|
|
14088
|
+
if (agent.instructions.length === 0) {
|
|
13996
14089
|
return {
|
|
13997
14090
|
valid: false,
|
|
13998
|
-
error: "agent.
|
|
14091
|
+
error: "agent.instructions cannot be empty"
|
|
13999
14092
|
};
|
|
14000
14093
|
}
|
|
14001
14094
|
}
|
|
14002
|
-
if (agent.
|
|
14003
|
-
if (!Array.isArray(agent.
|
|
14095
|
+
if (agent.skills !== void 0) {
|
|
14096
|
+
if (!Array.isArray(agent.skills)) {
|
|
14004
14097
|
return {
|
|
14005
14098
|
valid: false,
|
|
14006
|
-
error: "agent.
|
|
14099
|
+
error: "agent.skills must be an array of GitHub tree URLs"
|
|
14007
14100
|
};
|
|
14008
14101
|
}
|
|
14009
|
-
for (const skillUrl of agent.
|
|
14102
|
+
for (const skillUrl of agent.skills) {
|
|
14010
14103
|
if (typeof skillUrl !== "string") {
|
|
14011
14104
|
return {
|
|
14012
14105
|
valid: false,
|
|
14013
|
-
error: "Each
|
|
14106
|
+
error: "Each skill must be a string URL"
|
|
14014
14107
|
};
|
|
14015
14108
|
}
|
|
14016
14109
|
if (!validateGitHubTreeUrl(skillUrl)) {
|
|
14017
14110
|
return {
|
|
14018
14111
|
valid: false,
|
|
14019
|
-
error: `Invalid
|
|
14112
|
+
error: `Invalid skill URL: ${skillUrl}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
|
|
14020
14113
|
};
|
|
14021
14114
|
}
|
|
14022
14115
|
}
|
|
@@ -14090,38 +14183,17 @@ import * as os from "os";
|
|
|
14090
14183
|
import { exec } from "child_process";
|
|
14091
14184
|
import { promisify } from "util";
|
|
14092
14185
|
var execAsync = promisify(exec);
|
|
14093
|
-
function
|
|
14094
|
-
const
|
|
14095
|
-
if (!
|
|
14096
|
-
throw new Error(
|
|
14097
|
-
`Invalid GitHub URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
|
|
14098
|
-
);
|
|
14099
|
-
}
|
|
14100
|
-
const fullPath = fullPathMatch[1];
|
|
14101
|
-
const regex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
|
|
14102
|
-
const match = url2.match(regex);
|
|
14103
|
-
if (!match) {
|
|
14186
|
+
function parseGitHubTreeUrl2(url2) {
|
|
14187
|
+
const parsed = parseGitHubTreeUrl(url2);
|
|
14188
|
+
if (!parsed) {
|
|
14104
14189
|
throw new Error(
|
|
14105
14190
|
`Invalid GitHub tree URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
|
|
14106
14191
|
);
|
|
14107
14192
|
}
|
|
14108
|
-
|
|
14109
|
-
const pathSegments = pathPart.split("/");
|
|
14110
|
-
const skillName = pathSegments[pathSegments.length - 1];
|
|
14111
|
-
return {
|
|
14112
|
-
owner,
|
|
14113
|
-
repo,
|
|
14114
|
-
branch,
|
|
14115
|
-
path: pathPart,
|
|
14116
|
-
skillName,
|
|
14117
|
-
fullPath
|
|
14118
|
-
};
|
|
14193
|
+
return parsed;
|
|
14119
14194
|
}
|
|
14120
|
-
function
|
|
14121
|
-
return
|
|
14122
|
-
}
|
|
14123
|
-
function getSystemPromptStorageName(composeName) {
|
|
14124
|
-
return `system-prompt@${composeName}`;
|
|
14195
|
+
function getSkillStorageName2(parsed) {
|
|
14196
|
+
return getSkillStorageName(parsed.fullPath);
|
|
14125
14197
|
}
|
|
14126
14198
|
async function downloadGitHubSkill(parsed, destDir) {
|
|
14127
14199
|
const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
|
|
@@ -14457,16 +14529,24 @@ async function directUpload(storageName, storageType, cwd, options) {
|
|
|
14457
14529
|
}
|
|
14458
14530
|
|
|
14459
14531
|
// src/lib/system-storage.ts
|
|
14460
|
-
|
|
14461
|
-
const
|
|
14462
|
-
|
|
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) {
|
|
14540
|
+
const storageName = getInstructionsStorageName(agentName);
|
|
14541
|
+
const absolutePath = path4.isAbsolute(instructionsFilePath) ? instructionsFilePath : path4.join(basePath, instructionsFilePath);
|
|
14463
14542
|
const content = await fs4.readFile(absolutePath, "utf8");
|
|
14464
|
-
const tmpDir = await fs4.mkdtemp(path4.join(os3.tmpdir(), "vm0-
|
|
14465
|
-
const
|
|
14466
|
-
await fs4.mkdir(
|
|
14467
|
-
|
|
14543
|
+
const tmpDir = await fs4.mkdtemp(path4.join(os3.tmpdir(), "vm0-instructions-"));
|
|
14544
|
+
const instructionsDir = path4.join(tmpDir, "instructions");
|
|
14545
|
+
await fs4.mkdir(instructionsDir);
|
|
14546
|
+
const filename = getInstructionsFilename(provider);
|
|
14547
|
+
await fs4.writeFile(path4.join(instructionsDir, filename), content);
|
|
14468
14548
|
try {
|
|
14469
|
-
const result = await directUpload(storageName, "volume",
|
|
14549
|
+
const result = await directUpload(storageName, "volume", instructionsDir);
|
|
14470
14550
|
return {
|
|
14471
14551
|
name: storageName,
|
|
14472
14552
|
versionId: result.versionId,
|
|
@@ -14476,9 +14556,9 @@ async function uploadSystemPrompt(agentName, promptFilePath, basePath) {
|
|
|
14476
14556
|
await fs4.rm(tmpDir, { recursive: true, force: true });
|
|
14477
14557
|
}
|
|
14478
14558
|
}
|
|
14479
|
-
async function
|
|
14480
|
-
const parsed =
|
|
14481
|
-
const storageName =
|
|
14559
|
+
async function uploadSkill(skillUrl) {
|
|
14560
|
+
const parsed = parseGitHubTreeUrl2(skillUrl);
|
|
14561
|
+
const storageName = getSkillStorageName2(parsed);
|
|
14482
14562
|
const tmpDir = await fs4.mkdtemp(path4.join(os3.tmpdir(), "vm0-skill-"));
|
|
14483
14563
|
try {
|
|
14484
14564
|
const skillDir = await downloadGitHubSkill(parsed, tmpDir);
|
|
@@ -14535,6 +14615,15 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
14535
14615
|
if (agent.provider) {
|
|
14536
14616
|
const defaults = getProviderDefaults(agent.provider);
|
|
14537
14617
|
if (defaults) {
|
|
14618
|
+
if (!agent.image) {
|
|
14619
|
+
const defaultImage = getDefaultImage(agent.provider);
|
|
14620
|
+
if (defaultImage) {
|
|
14621
|
+
agent.image = defaultImage;
|
|
14622
|
+
console.log(
|
|
14623
|
+
chalk2.gray(` Auto-configured image: ${defaultImage}`)
|
|
14624
|
+
);
|
|
14625
|
+
}
|
|
14626
|
+
}
|
|
14538
14627
|
if (!agent.working_dir) {
|
|
14539
14628
|
agent.working_dir = defaults.workingDir;
|
|
14540
14629
|
console.log(
|
|
@@ -14545,37 +14634,37 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
14545
14634
|
}
|
|
14546
14635
|
}
|
|
14547
14636
|
}
|
|
14548
|
-
if (agent.
|
|
14549
|
-
const
|
|
14550
|
-
|
|
14637
|
+
if (agent.instructions) {
|
|
14638
|
+
const instructionsPath = agent.instructions;
|
|
14639
|
+
const provider = agent.provider;
|
|
14640
|
+
console.log(chalk2.blue(`Uploading instructions: ${instructionsPath}`));
|
|
14551
14641
|
try {
|
|
14552
|
-
const result = await
|
|
14642
|
+
const result = await uploadInstructions(
|
|
14553
14643
|
agentName,
|
|
14554
|
-
|
|
14555
|
-
basePath
|
|
14644
|
+
instructionsPath,
|
|
14645
|
+
basePath,
|
|
14646
|
+
provider
|
|
14556
14647
|
);
|
|
14557
14648
|
console.log(
|
|
14558
14649
|
chalk2.green(
|
|
14559
|
-
`\u2713
|
|
14650
|
+
`\u2713 Instructions ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
14560
14651
|
)
|
|
14561
14652
|
);
|
|
14562
14653
|
} catch (error43) {
|
|
14563
|
-
console.error(chalk2.red(`\u2717 Failed to upload
|
|
14654
|
+
console.error(chalk2.red(`\u2717 Failed to upload instructions`));
|
|
14564
14655
|
if (error43 instanceof Error) {
|
|
14565
14656
|
console.error(chalk2.gray(` ${error43.message}`));
|
|
14566
14657
|
}
|
|
14567
14658
|
process.exit(1);
|
|
14568
14659
|
}
|
|
14569
14660
|
}
|
|
14570
|
-
if (agent.
|
|
14571
|
-
const skillUrls = agent.
|
|
14572
|
-
console.log(
|
|
14573
|
-
chalk2.blue(`Uploading ${skillUrls.length} system skill(s)...`)
|
|
14574
|
-
);
|
|
14661
|
+
if (agent.skills && Array.isArray(agent.skills)) {
|
|
14662
|
+
const skillUrls = agent.skills;
|
|
14663
|
+
console.log(chalk2.blue(`Uploading ${skillUrls.length} skill(s)...`));
|
|
14575
14664
|
for (const skillUrl of skillUrls) {
|
|
14576
14665
|
try {
|
|
14577
14666
|
console.log(chalk2.gray(` Downloading: ${skillUrl}`));
|
|
14578
|
-
const result = await
|
|
14667
|
+
const result = await uploadSkill(skillUrl);
|
|
14579
14668
|
console.log(
|
|
14580
14669
|
chalk2.green(
|
|
14581
14670
|
` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
@@ -14629,12 +14718,12 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
14629
14718
|
|
|
14630
14719
|
// src/commands/run.ts
|
|
14631
14720
|
import { Command as Command2 } from "commander";
|
|
14632
|
-
import
|
|
14721
|
+
import chalk5 from "chalk";
|
|
14633
14722
|
import * as fs5 from "fs";
|
|
14634
14723
|
import * as path5 from "path";
|
|
14635
14724
|
import { config as dotenvConfig } from "dotenv";
|
|
14636
14725
|
|
|
14637
|
-
// src/lib/event-parser.ts
|
|
14726
|
+
// src/lib/claude-event-parser.ts
|
|
14638
14727
|
var ClaudeEventParser = class {
|
|
14639
14728
|
/**
|
|
14640
14729
|
* Parse a raw Claude Code JSONL event into a simplified format
|
|
@@ -14665,6 +14754,7 @@ var ClaudeEventParser = class {
|
|
|
14665
14754
|
type: "init",
|
|
14666
14755
|
timestamp: /* @__PURE__ */ new Date(),
|
|
14667
14756
|
data: {
|
|
14757
|
+
provider: "claude-code",
|
|
14668
14758
|
sessionId: event.session_id,
|
|
14669
14759
|
model: event.model,
|
|
14670
14760
|
tools: event.tools,
|
|
@@ -14737,6 +14827,222 @@ var ClaudeEventParser = class {
|
|
|
14737
14827
|
}
|
|
14738
14828
|
};
|
|
14739
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
|
+
|
|
14740
15046
|
// src/lib/event-renderer.ts
|
|
14741
15047
|
import chalk3 from "chalk";
|
|
14742
15048
|
var EventRenderer = class {
|
|
@@ -14851,11 +15157,15 @@ var EventRenderer = class {
|
|
|
14851
15157
|
);
|
|
14852
15158
|
}
|
|
14853
15159
|
static renderInit(event, prefix, suffix) {
|
|
15160
|
+
const providerStr = String(event.data.provider || "claude-code");
|
|
15161
|
+
const displayName = isSupportedProvider(providerStr) ? getProviderDisplayName(providerStr) : providerStr;
|
|
14854
15162
|
console.log(
|
|
14855
|
-
prefix + chalk3.cyan("[init]") + suffix +
|
|
15163
|
+
prefix + chalk3.cyan("[init]") + suffix + ` Starting ${displayName} agent`
|
|
14856
15164
|
);
|
|
14857
15165
|
console.log(` Session: ${chalk3.gray(String(event.data.sessionId || ""))}`);
|
|
14858
|
-
|
|
15166
|
+
if (event.data.model) {
|
|
15167
|
+
console.log(` Model: ${chalk3.gray(String(event.data.model))}`);
|
|
15168
|
+
}
|
|
14859
15169
|
console.log(
|
|
14860
15170
|
` Tools: ${chalk3.gray(
|
|
14861
15171
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
@@ -14927,6 +15237,121 @@ var EventRenderer = class {
|
|
|
14927
15237
|
}
|
|
14928
15238
|
};
|
|
14929
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
|
+
|
|
14930
15355
|
// src/commands/run.ts
|
|
14931
15356
|
function collectKeyValue(value, previous) {
|
|
14932
15357
|
const [key, ...valueParts] = value.split("=");
|
|
@@ -15012,16 +15437,19 @@ async function pollEvents(runId, options) {
|
|
|
15012
15437
|
since: nextSequence
|
|
15013
15438
|
});
|
|
15014
15439
|
for (const event of response.events) {
|
|
15015
|
-
const
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
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
|
+
}
|
|
15025
15453
|
}
|
|
15026
15454
|
}
|
|
15027
15455
|
nextSequence = response.nextSequence;
|
|
@@ -15045,9 +15473,9 @@ async function pollEvents(runId, options) {
|
|
|
15045
15473
|
result = { succeeded: false, runId };
|
|
15046
15474
|
} else if (runStatus === "timeout") {
|
|
15047
15475
|
complete = true;
|
|
15048
|
-
console.error(
|
|
15476
|
+
console.error(chalk5.red("\n\u2717 Run timed out"));
|
|
15049
15477
|
console.error(
|
|
15050
|
-
|
|
15478
|
+
chalk5.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
15051
15479
|
);
|
|
15052
15480
|
result = { succeeded: false, runId };
|
|
15053
15481
|
}
|
|
@@ -15058,15 +15486,15 @@ async function pollEvents(runId, options) {
|
|
|
15058
15486
|
return result;
|
|
15059
15487
|
}
|
|
15060
15488
|
function logVerbosePreFlight(action, details) {
|
|
15061
|
-
console.log(
|
|
15489
|
+
console.log(chalk5.blue(`
|
|
15062
15490
|
${action}...`));
|
|
15063
15491
|
for (const { label, value } of details) {
|
|
15064
15492
|
if (value !== void 0) {
|
|
15065
|
-
console.log(
|
|
15493
|
+
console.log(chalk5.gray(` ${label}: ${value}`));
|
|
15066
15494
|
}
|
|
15067
15495
|
}
|
|
15068
15496
|
console.log();
|
|
15069
|
-
console.log(
|
|
15497
|
+
console.log(chalk5.blue("Executing in sandbox..."));
|
|
15070
15498
|
console.log();
|
|
15071
15499
|
}
|
|
15072
15500
|
function showNextSteps(result) {
|
|
@@ -15074,17 +15502,17 @@ function showNextSteps(result) {
|
|
|
15074
15502
|
console.log();
|
|
15075
15503
|
console.log("Next steps:");
|
|
15076
15504
|
console.log(" View telemetry logs:");
|
|
15077
|
-
console.log(
|
|
15505
|
+
console.log(chalk5.cyan(` vm0 logs ${runId}`));
|
|
15078
15506
|
if (sessionId) {
|
|
15079
15507
|
console.log(" Continue with session (latest state):");
|
|
15080
15508
|
console.log(
|
|
15081
|
-
|
|
15509
|
+
chalk5.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
15082
15510
|
);
|
|
15083
15511
|
}
|
|
15084
15512
|
if (checkpointId) {
|
|
15085
15513
|
console.log(" Resume from checkpoint (exact snapshot state):");
|
|
15086
15514
|
console.log(
|
|
15087
|
-
|
|
15515
|
+
chalk5.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
15088
15516
|
);
|
|
15089
15517
|
}
|
|
15090
15518
|
}
|
|
@@ -15122,7 +15550,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15122
15550
|
let composeContent;
|
|
15123
15551
|
if (isUUID(name)) {
|
|
15124
15552
|
if (verbose) {
|
|
15125
|
-
console.log(
|
|
15553
|
+
console.log(chalk5.gray(` Using compose ID: ${identifier}`));
|
|
15126
15554
|
}
|
|
15127
15555
|
try {
|
|
15128
15556
|
const compose = await apiClient.getComposeById(name);
|
|
@@ -15130,26 +15558,26 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15130
15558
|
composeContent = compose.content;
|
|
15131
15559
|
} catch (error43) {
|
|
15132
15560
|
if (error43 instanceof Error) {
|
|
15133
|
-
console.error(
|
|
15561
|
+
console.error(chalk5.red(`\u2717 Compose not found: ${name}`));
|
|
15134
15562
|
}
|
|
15135
15563
|
process.exit(1);
|
|
15136
15564
|
}
|
|
15137
15565
|
} else {
|
|
15138
15566
|
if (verbose) {
|
|
15139
|
-
console.log(
|
|
15567
|
+
console.log(chalk5.gray(` Resolving agent name: ${name}`));
|
|
15140
15568
|
}
|
|
15141
15569
|
try {
|
|
15142
15570
|
const compose = await apiClient.getComposeByName(name);
|
|
15143
15571
|
composeId = compose.id;
|
|
15144
15572
|
composeContent = compose.content;
|
|
15145
15573
|
if (verbose) {
|
|
15146
|
-
console.log(
|
|
15574
|
+
console.log(chalk5.gray(` Resolved to compose ID: ${composeId}`));
|
|
15147
15575
|
}
|
|
15148
15576
|
} catch (error43) {
|
|
15149
15577
|
if (error43 instanceof Error) {
|
|
15150
|
-
console.error(
|
|
15578
|
+
console.error(chalk5.red(`\u2717 Agent not found: ${name}`));
|
|
15151
15579
|
console.error(
|
|
15152
|
-
|
|
15580
|
+
chalk5.gray(
|
|
15153
15581
|
" Make sure you've composed the agent with: vm0 compose"
|
|
15154
15582
|
)
|
|
15155
15583
|
);
|
|
@@ -15160,7 +15588,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15160
15588
|
let agentComposeVersionId;
|
|
15161
15589
|
if (version2 && version2 !== "latest") {
|
|
15162
15590
|
if (verbose) {
|
|
15163
|
-
console.log(
|
|
15591
|
+
console.log(chalk5.gray(` Resolving version: ${version2}`));
|
|
15164
15592
|
}
|
|
15165
15593
|
try {
|
|
15166
15594
|
const versionInfo = await apiClient.getComposeVersion(
|
|
@@ -15170,16 +15598,16 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15170
15598
|
agentComposeVersionId = versionInfo.versionId;
|
|
15171
15599
|
if (verbose) {
|
|
15172
15600
|
console.log(
|
|
15173
|
-
|
|
15601
|
+
chalk5.gray(
|
|
15174
15602
|
` Resolved to version ID: ${agentComposeVersionId.slice(0, 8)}...`
|
|
15175
15603
|
)
|
|
15176
15604
|
);
|
|
15177
15605
|
}
|
|
15178
15606
|
} catch (error43) {
|
|
15179
15607
|
if (error43 instanceof Error) {
|
|
15180
|
-
console.error(
|
|
15608
|
+
console.error(chalk5.red(`\u2717 Version not found: ${version2}`));
|
|
15181
15609
|
console.error(
|
|
15182
|
-
|
|
15610
|
+
chalk5.gray(" Make sure the version hash is correct.")
|
|
15183
15611
|
);
|
|
15184
15612
|
}
|
|
15185
15613
|
process.exit(1);
|
|
@@ -15190,20 +15618,20 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15190
15618
|
const secretNames = extractSecretNames(composeContent);
|
|
15191
15619
|
const secrets = loadValues(options.secrets, secretNames);
|
|
15192
15620
|
if (verbose && varNames.length > 0) {
|
|
15193
|
-
console.log(
|
|
15621
|
+
console.log(chalk5.gray(` Required vars: ${varNames.join(", ")}`));
|
|
15194
15622
|
if (vars) {
|
|
15195
15623
|
console.log(
|
|
15196
|
-
|
|
15624
|
+
chalk5.gray(` Loaded vars: ${Object.keys(vars).join(", ")}`)
|
|
15197
15625
|
);
|
|
15198
15626
|
}
|
|
15199
15627
|
}
|
|
15200
15628
|
if (verbose && secretNames.length > 0) {
|
|
15201
15629
|
console.log(
|
|
15202
|
-
|
|
15630
|
+
chalk5.gray(` Required secrets: ${secretNames.join(", ")}`)
|
|
15203
15631
|
);
|
|
15204
15632
|
if (secrets) {
|
|
15205
15633
|
console.log(
|
|
15206
|
-
|
|
15634
|
+
chalk5.gray(
|
|
15207
15635
|
` Loaded secrets: ${Object.keys(secrets).join(", ")}`
|
|
15208
15636
|
)
|
|
15209
15637
|
);
|
|
@@ -15242,9 +15670,9 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15242
15670
|
conversationId: options.conversation
|
|
15243
15671
|
});
|
|
15244
15672
|
if (response.status === "failed") {
|
|
15245
|
-
console.error(
|
|
15673
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15246
15674
|
if (response.error) {
|
|
15247
|
-
console.error(
|
|
15675
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15248
15676
|
}
|
|
15249
15677
|
process.exit(1);
|
|
15250
15678
|
}
|
|
@@ -15264,21 +15692,21 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
15264
15692
|
if (error43 instanceof Error) {
|
|
15265
15693
|
if (error43.message.includes("Not authenticated")) {
|
|
15266
15694
|
console.error(
|
|
15267
|
-
|
|
15695
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15268
15696
|
);
|
|
15269
15697
|
} else if (error43.message.includes("not found")) {
|
|
15270
|
-
console.error(
|
|
15698
|
+
console.error(chalk5.red(`\u2717 Agent not found: ${identifier}`));
|
|
15271
15699
|
console.error(
|
|
15272
|
-
|
|
15700
|
+
chalk5.gray(
|
|
15273
15701
|
" Make sure you've composed the agent with: vm0 compose"
|
|
15274
15702
|
)
|
|
15275
15703
|
);
|
|
15276
15704
|
} else {
|
|
15277
|
-
console.error(
|
|
15278
|
-
console.error(
|
|
15705
|
+
console.error(chalk5.red("\u2717 Run failed"));
|
|
15706
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15279
15707
|
}
|
|
15280
15708
|
} else {
|
|
15281
|
-
console.error(
|
|
15709
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15282
15710
|
}
|
|
15283
15711
|
process.exit(1);
|
|
15284
15712
|
}
|
|
@@ -15297,9 +15725,9 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15297
15725
|
try {
|
|
15298
15726
|
if (!isUUID(checkpointId)) {
|
|
15299
15727
|
console.error(
|
|
15300
|
-
|
|
15728
|
+
chalk5.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
15301
15729
|
);
|
|
15302
|
-
console.error(
|
|
15730
|
+
console.error(chalk5.gray(" Checkpoint ID must be a valid UUID"));
|
|
15303
15731
|
process.exit(1);
|
|
15304
15732
|
}
|
|
15305
15733
|
if (verbose) {
|
|
@@ -15318,9 +15746,9 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15318
15746
|
volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
|
|
15319
15747
|
});
|
|
15320
15748
|
if (response.status === "failed") {
|
|
15321
|
-
console.error(
|
|
15749
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15322
15750
|
if (response.error) {
|
|
15323
|
-
console.error(
|
|
15751
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15324
15752
|
}
|
|
15325
15753
|
process.exit(1);
|
|
15326
15754
|
}
|
|
@@ -15340,16 +15768,16 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
|
|
|
15340
15768
|
if (error43 instanceof Error) {
|
|
15341
15769
|
if (error43.message.includes("Not authenticated")) {
|
|
15342
15770
|
console.error(
|
|
15343
|
-
|
|
15771
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15344
15772
|
);
|
|
15345
15773
|
} else if (error43.message.includes("not found")) {
|
|
15346
|
-
console.error(
|
|
15774
|
+
console.error(chalk5.red(`\u2717 Checkpoint not found: ${checkpointId}`));
|
|
15347
15775
|
} else {
|
|
15348
|
-
console.error(
|
|
15349
|
-
console.error(
|
|
15776
|
+
console.error(chalk5.red("\u2717 Resume failed"));
|
|
15777
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15350
15778
|
}
|
|
15351
15779
|
} else {
|
|
15352
|
-
console.error(
|
|
15780
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15353
15781
|
}
|
|
15354
15782
|
process.exit(1);
|
|
15355
15783
|
}
|
|
@@ -15370,9 +15798,9 @@ runCmd.command("continue").description(
|
|
|
15370
15798
|
try {
|
|
15371
15799
|
if (!isUUID(agentSessionId)) {
|
|
15372
15800
|
console.error(
|
|
15373
|
-
|
|
15801
|
+
chalk5.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
15374
15802
|
);
|
|
15375
|
-
console.error(
|
|
15803
|
+
console.error(chalk5.gray(" Agent session ID must be a valid UUID"));
|
|
15376
15804
|
process.exit(1);
|
|
15377
15805
|
}
|
|
15378
15806
|
if (verbose) {
|
|
@@ -15392,9 +15820,9 @@ runCmd.command("continue").description(
|
|
|
15392
15820
|
volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
|
|
15393
15821
|
});
|
|
15394
15822
|
if (response.status === "failed") {
|
|
15395
|
-
console.error(
|
|
15823
|
+
console.error(chalk5.red("\u2717 Run preparation failed"));
|
|
15396
15824
|
if (response.error) {
|
|
15397
|
-
console.error(
|
|
15825
|
+
console.error(chalk5.gray(` ${response.error}`));
|
|
15398
15826
|
}
|
|
15399
15827
|
process.exit(1);
|
|
15400
15828
|
}
|
|
@@ -15414,18 +15842,18 @@ runCmd.command("continue").description(
|
|
|
15414
15842
|
if (error43 instanceof Error) {
|
|
15415
15843
|
if (error43.message.includes("Not authenticated")) {
|
|
15416
15844
|
console.error(
|
|
15417
|
-
|
|
15845
|
+
chalk5.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
15418
15846
|
);
|
|
15419
15847
|
} else if (error43.message.includes("not found")) {
|
|
15420
15848
|
console.error(
|
|
15421
|
-
|
|
15849
|
+
chalk5.red(`\u2717 Agent session not found: ${agentSessionId}`)
|
|
15422
15850
|
);
|
|
15423
15851
|
} else {
|
|
15424
|
-
console.error(
|
|
15425
|
-
console.error(
|
|
15852
|
+
console.error(chalk5.red("\u2717 Continue failed"));
|
|
15853
|
+
console.error(chalk5.gray(` ${error43.message}`));
|
|
15426
15854
|
}
|
|
15427
15855
|
} else {
|
|
15428
|
-
console.error(
|
|
15856
|
+
console.error(chalk5.red("\u2717 An unexpected error occurred"));
|
|
15429
15857
|
}
|
|
15430
15858
|
process.exit(1);
|
|
15431
15859
|
}
|
|
@@ -15438,7 +15866,7 @@ import { Command as Command7 } from "commander";
|
|
|
15438
15866
|
|
|
15439
15867
|
// src/commands/volume/init.ts
|
|
15440
15868
|
import { Command as Command3 } from "commander";
|
|
15441
|
-
import
|
|
15869
|
+
import chalk6 from "chalk";
|
|
15442
15870
|
import path7 from "path";
|
|
15443
15871
|
|
|
15444
15872
|
// src/lib/storage-utils.ts
|
|
@@ -15496,37 +15924,37 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
|
|
|
15496
15924
|
const existingConfig = await readStorageConfig(cwd);
|
|
15497
15925
|
if (existingConfig) {
|
|
15498
15926
|
console.log(
|
|
15499
|
-
|
|
15927
|
+
chalk6.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
15500
15928
|
);
|
|
15501
15929
|
console.log(
|
|
15502
|
-
|
|
15930
|
+
chalk6.gray(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
|
|
15503
15931
|
);
|
|
15504
15932
|
return;
|
|
15505
15933
|
}
|
|
15506
15934
|
const volumeName = dirName;
|
|
15507
15935
|
if (!isValidStorageName(volumeName)) {
|
|
15508
|
-
console.error(
|
|
15936
|
+
console.error(chalk6.red(`\u2717 Invalid volume name: "${dirName}"`));
|
|
15509
15937
|
console.error(
|
|
15510
|
-
|
|
15938
|
+
chalk6.gray(
|
|
15511
15939
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
15512
15940
|
)
|
|
15513
15941
|
);
|
|
15514
15942
|
console.error(
|
|
15515
|
-
|
|
15943
|
+
chalk6.gray(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
15516
15944
|
);
|
|
15517
15945
|
process.exit(1);
|
|
15518
15946
|
}
|
|
15519
15947
|
await writeStorageConfig(volumeName, cwd);
|
|
15520
|
-
console.log(
|
|
15948
|
+
console.log(chalk6.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
15521
15949
|
console.log(
|
|
15522
|
-
|
|
15950
|
+
chalk6.gray(
|
|
15523
15951
|
`\u2713 Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
|
|
15524
15952
|
)
|
|
15525
15953
|
);
|
|
15526
15954
|
} catch (error43) {
|
|
15527
|
-
console.error(
|
|
15955
|
+
console.error(chalk6.red("\u2717 Failed to initialize volume"));
|
|
15528
15956
|
if (error43 instanceof Error) {
|
|
15529
|
-
console.error(
|
|
15957
|
+
console.error(chalk6.gray(` ${error43.message}`));
|
|
15530
15958
|
}
|
|
15531
15959
|
process.exit(1);
|
|
15532
15960
|
}
|
|
@@ -15534,7 +15962,7 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
|
|
|
15534
15962
|
|
|
15535
15963
|
// src/commands/volume/push.ts
|
|
15536
15964
|
import { Command as Command4 } from "commander";
|
|
15537
|
-
import
|
|
15965
|
+
import chalk7 from "chalk";
|
|
15538
15966
|
function formatBytes(bytes) {
|
|
15539
15967
|
if (bytes === 0) return "0 B";
|
|
15540
15968
|
const k = 1024;
|
|
@@ -15550,32 +15978,32 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
15550
15978
|
const cwd = process.cwd();
|
|
15551
15979
|
const config2 = await readStorageConfig(cwd);
|
|
15552
15980
|
if (!config2) {
|
|
15553
|
-
console.error(
|
|
15554
|
-
console.error(
|
|
15981
|
+
console.error(chalk7.red("\u2717 No volume initialized in this directory"));
|
|
15982
|
+
console.error(chalk7.gray(" Run: vm0 volume init"));
|
|
15555
15983
|
process.exit(1);
|
|
15556
15984
|
}
|
|
15557
|
-
console.log(
|
|
15985
|
+
console.log(chalk7.cyan(`Pushing volume: ${config2.name}`));
|
|
15558
15986
|
const result = await directUpload(config2.name, "volume", cwd, {
|
|
15559
15987
|
onProgress: (message) => {
|
|
15560
|
-
console.log(
|
|
15988
|
+
console.log(chalk7.gray(message));
|
|
15561
15989
|
},
|
|
15562
15990
|
force: options.force
|
|
15563
15991
|
});
|
|
15564
15992
|
const shortVersion = result.versionId.slice(0, 8);
|
|
15565
15993
|
if (result.empty) {
|
|
15566
|
-
console.log(
|
|
15994
|
+
console.log(chalk7.yellow("No files found (empty volume)"));
|
|
15567
15995
|
} else if (result.deduplicated) {
|
|
15568
|
-
console.log(
|
|
15996
|
+
console.log(chalk7.green("\u2713 Content unchanged (deduplicated)"));
|
|
15569
15997
|
} else {
|
|
15570
|
-
console.log(
|
|
15998
|
+
console.log(chalk7.green("\u2713 Upload complete"));
|
|
15571
15999
|
}
|
|
15572
|
-
console.log(
|
|
15573
|
-
console.log(
|
|
15574
|
-
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)}`));
|
|
15575
16003
|
} catch (error43) {
|
|
15576
|
-
console.error(
|
|
16004
|
+
console.error(chalk7.red("\u2717 Push failed"));
|
|
15577
16005
|
if (error43 instanceof Error) {
|
|
15578
|
-
console.error(
|
|
16006
|
+
console.error(chalk7.gray(` ${error43.message}`));
|
|
15579
16007
|
}
|
|
15580
16008
|
process.exit(1);
|
|
15581
16009
|
}
|
|
@@ -15583,21 +16011,21 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
15583
16011
|
|
|
15584
16012
|
// src/commands/volume/pull.ts
|
|
15585
16013
|
import { Command as Command5 } from "commander";
|
|
15586
|
-
import
|
|
16014
|
+
import chalk9 from "chalk";
|
|
15587
16015
|
import path8 from "path";
|
|
15588
16016
|
import * as fs6 from "fs";
|
|
15589
16017
|
import * as os4 from "os";
|
|
15590
16018
|
import * as tar3 from "tar";
|
|
15591
16019
|
|
|
15592
16020
|
// src/lib/pull-utils.ts
|
|
15593
|
-
import
|
|
16021
|
+
import chalk8 from "chalk";
|
|
15594
16022
|
async function handleEmptyStorageResponse(cwd) {
|
|
15595
|
-
console.log(
|
|
16023
|
+
console.log(chalk8.gray("Syncing local files..."));
|
|
15596
16024
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
15597
16025
|
if (removedCount > 0) {
|
|
15598
|
-
console.log(
|
|
16026
|
+
console.log(chalk8.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
15599
16027
|
}
|
|
15600
|
-
console.log(
|
|
16028
|
+
console.log(chalk8.green("\u2713 Synced (0 files)"));
|
|
15601
16029
|
return { removedCount };
|
|
15602
16030
|
}
|
|
15603
16031
|
|
|
@@ -15614,18 +16042,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15614
16042
|
const cwd = process.cwd();
|
|
15615
16043
|
const config2 = await readStorageConfig(cwd);
|
|
15616
16044
|
if (!config2) {
|
|
15617
|
-
console.error(
|
|
15618
|
-
console.error(
|
|
16045
|
+
console.error(chalk9.red("\u2717 No volume initialized in this directory"));
|
|
16046
|
+
console.error(chalk9.gray(" Run: vm0 volume init"));
|
|
15619
16047
|
process.exit(1);
|
|
15620
16048
|
}
|
|
15621
16049
|
if (versionId) {
|
|
15622
16050
|
console.log(
|
|
15623
|
-
|
|
16051
|
+
chalk9.cyan(`Pulling volume: ${config2.name} (version: ${versionId})`)
|
|
15624
16052
|
);
|
|
15625
16053
|
} else {
|
|
15626
|
-
console.log(
|
|
16054
|
+
console.log(chalk9.cyan(`Pulling volume: ${config2.name}`));
|
|
15627
16055
|
}
|
|
15628
|
-
console.log(
|
|
16056
|
+
console.log(chalk9.gray("Getting download URL..."));
|
|
15629
16057
|
let url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=volume`;
|
|
15630
16058
|
if (versionId) {
|
|
15631
16059
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15633,14 +16061,14 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15633
16061
|
const response = await apiClient.get(url2);
|
|
15634
16062
|
if (!response.ok) {
|
|
15635
16063
|
if (response.status === 404) {
|
|
15636
|
-
console.error(
|
|
16064
|
+
console.error(chalk9.red(`\u2717 Volume "${config2.name}" not found`));
|
|
15637
16065
|
console.error(
|
|
15638
|
-
|
|
16066
|
+
chalk9.gray(
|
|
15639
16067
|
" Make sure the volume name is correct in .vm0/storage.yaml"
|
|
15640
16068
|
)
|
|
15641
16069
|
);
|
|
15642
16070
|
console.error(
|
|
15643
|
-
|
|
16071
|
+
chalk9.gray(" Or push the volume first with: vm0 volume push")
|
|
15644
16072
|
);
|
|
15645
16073
|
} else {
|
|
15646
16074
|
const error43 = await response.json();
|
|
@@ -15656,18 +16084,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15656
16084
|
if (!downloadInfo.url) {
|
|
15657
16085
|
throw new Error("No download URL returned");
|
|
15658
16086
|
}
|
|
15659
|
-
console.log(
|
|
16087
|
+
console.log(chalk9.gray("Downloading from S3..."));
|
|
15660
16088
|
const s3Response = await fetch(downloadInfo.url);
|
|
15661
16089
|
if (!s3Response.ok) {
|
|
15662
16090
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
15663
16091
|
}
|
|
15664
16092
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
15665
16093
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15666
|
-
console.log(
|
|
16094
|
+
console.log(chalk9.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
|
|
15667
16095
|
const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
|
|
15668
16096
|
const tarPath = path8.join(tmpDir, "volume.tar.gz");
|
|
15669
16097
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
15670
|
-
console.log(
|
|
16098
|
+
console.log(chalk9.gray("Syncing local files..."));
|
|
15671
16099
|
const remoteFiles = await listTarFiles(tarPath);
|
|
15672
16100
|
const remoteFilesSet = new Set(
|
|
15673
16101
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -15675,10 +16103,10 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15675
16103
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
15676
16104
|
if (removedCount > 0) {
|
|
15677
16105
|
console.log(
|
|
15678
|
-
|
|
16106
|
+
chalk9.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
15679
16107
|
);
|
|
15680
16108
|
}
|
|
15681
|
-
console.log(
|
|
16109
|
+
console.log(chalk9.gray("Extracting files..."));
|
|
15682
16110
|
await tar3.extract({
|
|
15683
16111
|
file: tarPath,
|
|
15684
16112
|
cwd,
|
|
@@ -15686,11 +16114,11 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15686
16114
|
});
|
|
15687
16115
|
await fs6.promises.unlink(tarPath);
|
|
15688
16116
|
await fs6.promises.rmdir(tmpDir);
|
|
15689
|
-
console.log(
|
|
16117
|
+
console.log(chalk9.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
15690
16118
|
} catch (error43) {
|
|
15691
|
-
console.error(
|
|
16119
|
+
console.error(chalk9.red("\u2717 Pull failed"));
|
|
15692
16120
|
if (error43 instanceof Error) {
|
|
15693
|
-
console.error(
|
|
16121
|
+
console.error(chalk9.gray(` ${error43.message}`));
|
|
15694
16122
|
}
|
|
15695
16123
|
process.exit(1);
|
|
15696
16124
|
}
|
|
@@ -15698,7 +16126,7 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15698
16126
|
|
|
15699
16127
|
// src/commands/volume/status.ts
|
|
15700
16128
|
import { Command as Command6 } from "commander";
|
|
15701
|
-
import
|
|
16129
|
+
import chalk10 from "chalk";
|
|
15702
16130
|
function formatBytes3(bytes) {
|
|
15703
16131
|
if (bytes === 0) return "0 B";
|
|
15704
16132
|
const k = 1024;
|
|
@@ -15711,26 +16139,26 @@ var statusCommand = new Command6().name("status").description("Show status of cl
|
|
|
15711
16139
|
const cwd = process.cwd();
|
|
15712
16140
|
const config2 = await readStorageConfig(cwd);
|
|
15713
16141
|
if (!config2) {
|
|
15714
|
-
console.error(
|
|
15715
|
-
console.error(
|
|
16142
|
+
console.error(chalk10.red("\u2717 No volume initialized in this directory"));
|
|
16143
|
+
console.error(chalk10.gray(" Run: vm0 volume init"));
|
|
15716
16144
|
process.exit(1);
|
|
15717
16145
|
}
|
|
15718
16146
|
if (config2.type !== "volume") {
|
|
15719
16147
|
console.error(
|
|
15720
|
-
|
|
16148
|
+
chalk10.red(
|
|
15721
16149
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
15722
16150
|
)
|
|
15723
16151
|
);
|
|
15724
|
-
console.error(
|
|
16152
|
+
console.error(chalk10.gray(" Use: vm0 artifact status"));
|
|
15725
16153
|
process.exit(1);
|
|
15726
16154
|
}
|
|
15727
|
-
console.log(
|
|
16155
|
+
console.log(chalk10.cyan(`Checking volume: ${config2.name}`));
|
|
15728
16156
|
const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=volume`;
|
|
15729
16157
|
const response = await apiClient.get(url2);
|
|
15730
16158
|
if (!response.ok) {
|
|
15731
16159
|
if (response.status === 404) {
|
|
15732
|
-
console.error(
|
|
15733
|
-
console.error(
|
|
16160
|
+
console.error(chalk10.red("\u2717 Not found on remote"));
|
|
16161
|
+
console.error(chalk10.gray(" Run: vm0 volume push"));
|
|
15734
16162
|
} else {
|
|
15735
16163
|
const error43 = await response.json();
|
|
15736
16164
|
throw new Error(error43.error?.message || "Status check failed");
|
|
@@ -15740,18 +16168,18 @@ var statusCommand = new Command6().name("status").description("Show status of cl
|
|
|
15740
16168
|
const info = await response.json();
|
|
15741
16169
|
const shortVersion = info.versionId.slice(0, 8);
|
|
15742
16170
|
if (info.empty) {
|
|
15743
|
-
console.log(
|
|
15744
|
-
console.log(
|
|
16171
|
+
console.log(chalk10.green("\u2713 Found (empty)"));
|
|
16172
|
+
console.log(chalk10.gray(` Version: ${shortVersion}`));
|
|
15745
16173
|
} else {
|
|
15746
|
-
console.log(
|
|
15747
|
-
console.log(
|
|
15748
|
-
console.log(
|
|
15749
|
-
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)}`));
|
|
15750
16178
|
}
|
|
15751
16179
|
} catch (error43) {
|
|
15752
|
-
console.error(
|
|
16180
|
+
console.error(chalk10.red("\u2717 Status check failed"));
|
|
15753
16181
|
if (error43 instanceof Error) {
|
|
15754
|
-
console.error(
|
|
16182
|
+
console.error(chalk10.gray(` ${error43.message}`));
|
|
15755
16183
|
}
|
|
15756
16184
|
process.exit(1);
|
|
15757
16185
|
}
|
|
@@ -15765,7 +16193,7 @@ import { Command as Command12 } from "commander";
|
|
|
15765
16193
|
|
|
15766
16194
|
// src/commands/artifact/init.ts
|
|
15767
16195
|
import { Command as Command8 } from "commander";
|
|
15768
|
-
import
|
|
16196
|
+
import chalk11 from "chalk";
|
|
15769
16197
|
import path9 from "path";
|
|
15770
16198
|
var initCommand2 = new Command8().name("init").description("Initialize an artifact in the current directory").action(async () => {
|
|
15771
16199
|
try {
|
|
@@ -15775,51 +16203,51 @@ var initCommand2 = new Command8().name("init").description("Initialize an artifa
|
|
|
15775
16203
|
if (existingConfig) {
|
|
15776
16204
|
if (existingConfig.type === "artifact") {
|
|
15777
16205
|
console.log(
|
|
15778
|
-
|
|
16206
|
+
chalk11.yellow(
|
|
15779
16207
|
`Artifact already initialized: ${existingConfig.name}`
|
|
15780
16208
|
)
|
|
15781
16209
|
);
|
|
15782
16210
|
} else {
|
|
15783
16211
|
console.log(
|
|
15784
|
-
|
|
16212
|
+
chalk11.yellow(
|
|
15785
16213
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
15786
16214
|
)
|
|
15787
16215
|
);
|
|
15788
16216
|
console.log(
|
|
15789
|
-
|
|
16217
|
+
chalk11.gray(
|
|
15790
16218
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
15791
16219
|
)
|
|
15792
16220
|
);
|
|
15793
16221
|
}
|
|
15794
16222
|
console.log(
|
|
15795
|
-
|
|
16223
|
+
chalk11.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
15796
16224
|
);
|
|
15797
16225
|
return;
|
|
15798
16226
|
}
|
|
15799
16227
|
const artifactName = dirName;
|
|
15800
16228
|
if (!isValidStorageName(artifactName)) {
|
|
15801
|
-
console.error(
|
|
16229
|
+
console.error(chalk11.red(`\u2717 Invalid artifact name: "${dirName}"`));
|
|
15802
16230
|
console.error(
|
|
15803
|
-
|
|
16231
|
+
chalk11.gray(
|
|
15804
16232
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
15805
16233
|
)
|
|
15806
16234
|
);
|
|
15807
16235
|
console.error(
|
|
15808
|
-
|
|
16236
|
+
chalk11.gray(" Example: my-project, user-workspace, code-artifact")
|
|
15809
16237
|
);
|
|
15810
16238
|
process.exit(1);
|
|
15811
16239
|
}
|
|
15812
16240
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
15813
|
-
console.log(
|
|
16241
|
+
console.log(chalk11.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
15814
16242
|
console.log(
|
|
15815
|
-
|
|
16243
|
+
chalk11.gray(
|
|
15816
16244
|
`\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
15817
16245
|
)
|
|
15818
16246
|
);
|
|
15819
16247
|
} catch (error43) {
|
|
15820
|
-
console.error(
|
|
16248
|
+
console.error(chalk11.red("\u2717 Failed to initialize artifact"));
|
|
15821
16249
|
if (error43 instanceof Error) {
|
|
15822
|
-
console.error(
|
|
16250
|
+
console.error(chalk11.gray(` ${error43.message}`));
|
|
15823
16251
|
}
|
|
15824
16252
|
process.exit(1);
|
|
15825
16253
|
}
|
|
@@ -15827,7 +16255,7 @@ var initCommand2 = new Command8().name("init").description("Initialize an artifa
|
|
|
15827
16255
|
|
|
15828
16256
|
// src/commands/artifact/push.ts
|
|
15829
16257
|
import { Command as Command9 } from "commander";
|
|
15830
|
-
import
|
|
16258
|
+
import chalk12 from "chalk";
|
|
15831
16259
|
function formatBytes4(bytes) {
|
|
15832
16260
|
if (bytes === 0) return "0 B";
|
|
15833
16261
|
const k = 1024;
|
|
@@ -15843,41 +16271,41 @@ var pushCommand2 = new Command9().name("push").description("Push local files to
|
|
|
15843
16271
|
const cwd = process.cwd();
|
|
15844
16272
|
const config2 = await readStorageConfig(cwd);
|
|
15845
16273
|
if (!config2) {
|
|
15846
|
-
console.error(
|
|
15847
|
-
console.error(
|
|
16274
|
+
console.error(chalk12.red("\u2717 No artifact initialized in this directory"));
|
|
16275
|
+
console.error(chalk12.gray(" Run: vm0 artifact init"));
|
|
15848
16276
|
process.exit(1);
|
|
15849
16277
|
}
|
|
15850
16278
|
if (config2.type !== "artifact") {
|
|
15851
16279
|
console.error(
|
|
15852
|
-
|
|
16280
|
+
chalk12.red(
|
|
15853
16281
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15854
16282
|
)
|
|
15855
16283
|
);
|
|
15856
|
-
console.error(
|
|
16284
|
+
console.error(chalk12.gray(" Use: vm0 volume push"));
|
|
15857
16285
|
process.exit(1);
|
|
15858
16286
|
}
|
|
15859
|
-
console.log(
|
|
16287
|
+
console.log(chalk12.cyan(`Pushing artifact: ${config2.name}`));
|
|
15860
16288
|
const result = await directUpload(config2.name, "artifact", cwd, {
|
|
15861
16289
|
onProgress: (message) => {
|
|
15862
|
-
console.log(
|
|
16290
|
+
console.log(chalk12.gray(message));
|
|
15863
16291
|
},
|
|
15864
16292
|
force: options.force
|
|
15865
16293
|
});
|
|
15866
16294
|
const shortVersion = result.versionId.slice(0, 8);
|
|
15867
16295
|
if (result.empty) {
|
|
15868
|
-
console.log(
|
|
16296
|
+
console.log(chalk12.yellow("No files found (empty artifact)"));
|
|
15869
16297
|
} else if (result.deduplicated) {
|
|
15870
|
-
console.log(
|
|
16298
|
+
console.log(chalk12.green("\u2713 Content unchanged (deduplicated)"));
|
|
15871
16299
|
} else {
|
|
15872
|
-
console.log(
|
|
16300
|
+
console.log(chalk12.green("\u2713 Upload complete"));
|
|
15873
16301
|
}
|
|
15874
|
-
console.log(
|
|
15875
|
-
console.log(
|
|
15876
|
-
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)}`));
|
|
15877
16305
|
} catch (error43) {
|
|
15878
|
-
console.error(
|
|
16306
|
+
console.error(chalk12.red("\u2717 Push failed"));
|
|
15879
16307
|
if (error43 instanceof Error) {
|
|
15880
|
-
console.error(
|
|
16308
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15881
16309
|
}
|
|
15882
16310
|
process.exit(1);
|
|
15883
16311
|
}
|
|
@@ -15885,7 +16313,7 @@ var pushCommand2 = new Command9().name("push").description("Push local files to
|
|
|
15885
16313
|
|
|
15886
16314
|
// src/commands/artifact/pull.ts
|
|
15887
16315
|
import { Command as Command10 } from "commander";
|
|
15888
|
-
import
|
|
16316
|
+
import chalk13 from "chalk";
|
|
15889
16317
|
import path10 from "path";
|
|
15890
16318
|
import * as fs7 from "fs";
|
|
15891
16319
|
import * as os5 from "os";
|
|
@@ -15902,29 +16330,29 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15902
16330
|
const cwd = process.cwd();
|
|
15903
16331
|
const config2 = await readStorageConfig(cwd);
|
|
15904
16332
|
if (!config2) {
|
|
15905
|
-
console.error(
|
|
15906
|
-
console.error(
|
|
16333
|
+
console.error(chalk13.red("\u2717 No artifact initialized in this directory"));
|
|
16334
|
+
console.error(chalk13.gray(" Run: vm0 artifact init"));
|
|
15907
16335
|
process.exit(1);
|
|
15908
16336
|
}
|
|
15909
16337
|
if (config2.type !== "artifact") {
|
|
15910
16338
|
console.error(
|
|
15911
|
-
|
|
16339
|
+
chalk13.red(
|
|
15912
16340
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15913
16341
|
)
|
|
15914
16342
|
);
|
|
15915
|
-
console.error(
|
|
16343
|
+
console.error(chalk13.gray(" Use: vm0 volume pull"));
|
|
15916
16344
|
process.exit(1);
|
|
15917
16345
|
}
|
|
15918
16346
|
if (versionId) {
|
|
15919
16347
|
console.log(
|
|
15920
|
-
|
|
16348
|
+
chalk13.cyan(
|
|
15921
16349
|
`Pulling artifact: ${config2.name} (version: ${versionId})`
|
|
15922
16350
|
)
|
|
15923
16351
|
);
|
|
15924
16352
|
} else {
|
|
15925
|
-
console.log(
|
|
16353
|
+
console.log(chalk13.cyan(`Pulling artifact: ${config2.name}`));
|
|
15926
16354
|
}
|
|
15927
|
-
console.log(
|
|
16355
|
+
console.log(chalk13.gray("Getting download URL..."));
|
|
15928
16356
|
let url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
|
|
15929
16357
|
if (versionId) {
|
|
15930
16358
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15932,14 +16360,14 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15932
16360
|
const response = await apiClient.get(url2);
|
|
15933
16361
|
if (!response.ok) {
|
|
15934
16362
|
if (response.status === 404) {
|
|
15935
|
-
console.error(
|
|
16363
|
+
console.error(chalk13.red(`\u2717 Artifact "${config2.name}" not found`));
|
|
15936
16364
|
console.error(
|
|
15937
|
-
|
|
16365
|
+
chalk13.gray(
|
|
15938
16366
|
" Make sure the artifact name is correct in .vm0/storage.yaml"
|
|
15939
16367
|
)
|
|
15940
16368
|
);
|
|
15941
16369
|
console.error(
|
|
15942
|
-
|
|
16370
|
+
chalk13.gray(" Or push the artifact first with: vm0 artifact push")
|
|
15943
16371
|
);
|
|
15944
16372
|
} else {
|
|
15945
16373
|
const error43 = await response.json();
|
|
@@ -15955,18 +16383,18 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15955
16383
|
if (!downloadInfo.url) {
|
|
15956
16384
|
throw new Error("No download URL returned");
|
|
15957
16385
|
}
|
|
15958
|
-
console.log(
|
|
16386
|
+
console.log(chalk13.gray("Downloading from S3..."));
|
|
15959
16387
|
const s3Response = await fetch(downloadInfo.url);
|
|
15960
16388
|
if (!s3Response.ok) {
|
|
15961
16389
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
15962
16390
|
}
|
|
15963
16391
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
15964
16392
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15965
|
-
console.log(
|
|
16393
|
+
console.log(chalk13.green(`\u2713 Downloaded ${formatBytes5(tarBuffer.length)}`));
|
|
15966
16394
|
const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
|
|
15967
16395
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
15968
16396
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
15969
|
-
console.log(
|
|
16397
|
+
console.log(chalk13.gray("Syncing local files..."));
|
|
15970
16398
|
const remoteFiles = await listTarFiles(tarPath);
|
|
15971
16399
|
const remoteFilesSet = new Set(
|
|
15972
16400
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -15974,10 +16402,10 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15974
16402
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
15975
16403
|
if (removedCount > 0) {
|
|
15976
16404
|
console.log(
|
|
15977
|
-
|
|
16405
|
+
chalk13.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
15978
16406
|
);
|
|
15979
16407
|
}
|
|
15980
|
-
console.log(
|
|
16408
|
+
console.log(chalk13.gray("Extracting files..."));
|
|
15981
16409
|
await tar4.extract({
|
|
15982
16410
|
file: tarPath,
|
|
15983
16411
|
cwd,
|
|
@@ -15985,11 +16413,11 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15985
16413
|
});
|
|
15986
16414
|
await fs7.promises.unlink(tarPath);
|
|
15987
16415
|
await fs7.promises.rmdir(tmpDir);
|
|
15988
|
-
console.log(
|
|
16416
|
+
console.log(chalk13.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
15989
16417
|
} catch (error43) {
|
|
15990
|
-
console.error(
|
|
16418
|
+
console.error(chalk13.red("\u2717 Pull failed"));
|
|
15991
16419
|
if (error43 instanceof Error) {
|
|
15992
|
-
console.error(
|
|
16420
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15993
16421
|
}
|
|
15994
16422
|
process.exit(1);
|
|
15995
16423
|
}
|
|
@@ -15997,7 +16425,7 @@ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact
|
|
|
15997
16425
|
|
|
15998
16426
|
// src/commands/artifact/status.ts
|
|
15999
16427
|
import { Command as Command11 } from "commander";
|
|
16000
|
-
import
|
|
16428
|
+
import chalk14 from "chalk";
|
|
16001
16429
|
function formatBytes6(bytes) {
|
|
16002
16430
|
if (bytes === 0) return "0 B";
|
|
16003
16431
|
const k = 1024;
|
|
@@ -16010,26 +16438,26 @@ var statusCommand2 = new Command11().name("status").description("Show status of
|
|
|
16010
16438
|
const cwd = process.cwd();
|
|
16011
16439
|
const config2 = await readStorageConfig(cwd);
|
|
16012
16440
|
if (!config2) {
|
|
16013
|
-
console.error(
|
|
16014
|
-
console.error(
|
|
16441
|
+
console.error(chalk14.red("\u2717 No artifact initialized in this directory"));
|
|
16442
|
+
console.error(chalk14.gray(" Run: vm0 artifact init"));
|
|
16015
16443
|
process.exit(1);
|
|
16016
16444
|
}
|
|
16017
16445
|
if (config2.type !== "artifact") {
|
|
16018
16446
|
console.error(
|
|
16019
|
-
|
|
16447
|
+
chalk14.red(
|
|
16020
16448
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
16021
16449
|
)
|
|
16022
16450
|
);
|
|
16023
|
-
console.error(
|
|
16451
|
+
console.error(chalk14.gray(" Use: vm0 volume status"));
|
|
16024
16452
|
process.exit(1);
|
|
16025
16453
|
}
|
|
16026
|
-
console.log(
|
|
16454
|
+
console.log(chalk14.cyan(`Checking artifact: ${config2.name}`));
|
|
16027
16455
|
const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
|
|
16028
16456
|
const response = await apiClient.get(url2);
|
|
16029
16457
|
if (!response.ok) {
|
|
16030
16458
|
if (response.status === 404) {
|
|
16031
|
-
console.error(
|
|
16032
|
-
console.error(
|
|
16459
|
+
console.error(chalk14.red("\u2717 Not found on remote"));
|
|
16460
|
+
console.error(chalk14.gray(" Run: vm0 artifact push"));
|
|
16033
16461
|
} else {
|
|
16034
16462
|
const error43 = await response.json();
|
|
16035
16463
|
throw new Error(error43.error?.message || "Status check failed");
|
|
@@ -16039,18 +16467,18 @@ var statusCommand2 = new Command11().name("status").description("Show status of
|
|
|
16039
16467
|
const info = await response.json();
|
|
16040
16468
|
const shortVersion = info.versionId.slice(0, 8);
|
|
16041
16469
|
if (info.empty) {
|
|
16042
|
-
console.log(
|
|
16043
|
-
console.log(
|
|
16470
|
+
console.log(chalk14.green("\u2713 Found (empty)"));
|
|
16471
|
+
console.log(chalk14.gray(` Version: ${shortVersion}`));
|
|
16044
16472
|
} else {
|
|
16045
|
-
console.log(
|
|
16046
|
-
console.log(
|
|
16047
|
-
console.log(
|
|
16048
|
-
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)}`));
|
|
16049
16477
|
}
|
|
16050
16478
|
} catch (error43) {
|
|
16051
|
-
console.error(
|
|
16479
|
+
console.error(chalk14.red("\u2717 Status check failed"));
|
|
16052
16480
|
if (error43 instanceof Error) {
|
|
16053
|
-
console.error(
|
|
16481
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
16054
16482
|
}
|
|
16055
16483
|
process.exit(1);
|
|
16056
16484
|
}
|
|
@@ -16061,7 +16489,7 @@ var artifactCommand = new Command12().name("artifact").description("Manage cloud
|
|
|
16061
16489
|
|
|
16062
16490
|
// src/commands/cook.ts
|
|
16063
16491
|
import { Command as Command13 } from "commander";
|
|
16064
|
-
import
|
|
16492
|
+
import chalk16 from "chalk";
|
|
16065
16493
|
import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
16066
16494
|
import { existsSync as existsSync6, readFileSync } from "fs";
|
|
16067
16495
|
import path11 from "path";
|
|
@@ -16072,7 +16500,7 @@ import { config as dotenvConfig2 } from "dotenv";
|
|
|
16072
16500
|
// src/lib/update-checker.ts
|
|
16073
16501
|
import https from "https";
|
|
16074
16502
|
import { spawn } from "child_process";
|
|
16075
|
-
import
|
|
16503
|
+
import chalk15 from "chalk";
|
|
16076
16504
|
var PACKAGE_NAME = "@vm0/cli";
|
|
16077
16505
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
16078
16506
|
var TIMEOUT_MS = 5e3;
|
|
@@ -16137,21 +16565,21 @@ function performUpgrade(packageManager) {
|
|
|
16137
16565
|
async function checkAndUpgrade(currentVersion, prompt) {
|
|
16138
16566
|
const latestVersion = await getLatestVersion();
|
|
16139
16567
|
if (latestVersion === null) {
|
|
16140
|
-
console.log(
|
|
16568
|
+
console.log(chalk15.yellow("Warning: Could not check for updates"));
|
|
16141
16569
|
console.log();
|
|
16142
16570
|
return false;
|
|
16143
16571
|
}
|
|
16144
16572
|
if (latestVersion === currentVersion) {
|
|
16145
16573
|
return false;
|
|
16146
16574
|
}
|
|
16147
|
-
console.log(
|
|
16575
|
+
console.log(chalk15.yellow("vm0 is currently in Early Access (EA)."));
|
|
16148
16576
|
console.log(
|
|
16149
|
-
|
|
16577
|
+
chalk15.yellow(
|
|
16150
16578
|
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
16151
16579
|
)
|
|
16152
16580
|
);
|
|
16153
16581
|
console.log(
|
|
16154
|
-
|
|
16582
|
+
chalk15.yellow(
|
|
16155
16583
|
"Please always use the latest version for best compatibility."
|
|
16156
16584
|
)
|
|
16157
16585
|
);
|
|
@@ -16160,20 +16588,20 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
16160
16588
|
console.log(`Upgrading via ${packageManager}...`);
|
|
16161
16589
|
const success2 = await performUpgrade(packageManager);
|
|
16162
16590
|
if (success2) {
|
|
16163
|
-
console.log(
|
|
16591
|
+
console.log(chalk15.green(`Upgraded to ${latestVersion}`));
|
|
16164
16592
|
console.log();
|
|
16165
16593
|
console.log("To continue, run:");
|
|
16166
|
-
console.log(
|
|
16594
|
+
console.log(chalk15.cyan(` ${buildRerunCommand(prompt)}`));
|
|
16167
16595
|
return true;
|
|
16168
16596
|
}
|
|
16169
16597
|
console.log();
|
|
16170
|
-
console.log(
|
|
16171
|
-
console.log(
|
|
16172
|
-
console.log(
|
|
16173
|
-
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`));
|
|
16174
16602
|
console.log();
|
|
16175
16603
|
console.log("Then re-run:");
|
|
16176
|
-
console.log(
|
|
16604
|
+
console.log(chalk15.cyan(` ${buildRerunCommand(prompt)}`));
|
|
16177
16605
|
return true;
|
|
16178
16606
|
}
|
|
16179
16607
|
|
|
@@ -16294,14 +16722,14 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
|
16294
16722
|
}
|
|
16295
16723
|
}
|
|
16296
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) => {
|
|
16297
|
-
const shouldExit = await checkAndUpgrade("4.
|
|
16725
|
+
const shouldExit = await checkAndUpgrade("4.21.0", prompt);
|
|
16298
16726
|
if (shouldExit) {
|
|
16299
16727
|
process.exit(0);
|
|
16300
16728
|
}
|
|
16301
16729
|
const cwd = process.cwd();
|
|
16302
|
-
console.log(
|
|
16730
|
+
console.log(chalk16.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
16303
16731
|
if (!existsSync6(CONFIG_FILE3)) {
|
|
16304
|
-
console.error(
|
|
16732
|
+
console.error(chalk16.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
16305
16733
|
process.exit(1);
|
|
16306
16734
|
}
|
|
16307
16735
|
let config2;
|
|
@@ -16309,22 +16737,22 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16309
16737
|
const content = await readFile5(CONFIG_FILE3, "utf8");
|
|
16310
16738
|
config2 = parseYaml3(content);
|
|
16311
16739
|
} catch (error43) {
|
|
16312
|
-
console.error(
|
|
16740
|
+
console.error(chalk16.red("\u2717 Invalid YAML format"));
|
|
16313
16741
|
if (error43 instanceof Error) {
|
|
16314
|
-
console.error(
|
|
16742
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16315
16743
|
}
|
|
16316
16744
|
process.exit(1);
|
|
16317
16745
|
}
|
|
16318
16746
|
const validation = validateAgentCompose(config2);
|
|
16319
16747
|
if (!validation.valid) {
|
|
16320
|
-
console.error(
|
|
16748
|
+
console.error(chalk16.red(`\u2717 ${validation.error}`));
|
|
16321
16749
|
process.exit(1);
|
|
16322
16750
|
}
|
|
16323
16751
|
const agentNames = Object.keys(config2.agents);
|
|
16324
16752
|
const agentName = agentNames[0];
|
|
16325
16753
|
const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
|
|
16326
16754
|
console.log(
|
|
16327
|
-
|
|
16755
|
+
chalk16.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
16328
16756
|
);
|
|
16329
16757
|
const requiredVarNames = extractRequiredVarNames(config2);
|
|
16330
16758
|
if (requiredVarNames.length > 0) {
|
|
@@ -16334,25 +16762,25 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16334
16762
|
await generateEnvPlaceholders(missingVars, envFilePath);
|
|
16335
16763
|
console.log();
|
|
16336
16764
|
console.log(
|
|
16337
|
-
|
|
16765
|
+
chalk16.yellow(
|
|
16338
16766
|
`\u26A0 Missing environment variables. Please fill in values in .env file:`
|
|
16339
16767
|
)
|
|
16340
16768
|
);
|
|
16341
16769
|
for (const varName of missingVars) {
|
|
16342
|
-
console.log(
|
|
16770
|
+
console.log(chalk16.yellow(` ${varName}`));
|
|
16343
16771
|
}
|
|
16344
16772
|
process.exit(1);
|
|
16345
16773
|
}
|
|
16346
16774
|
}
|
|
16347
16775
|
if (config2.volumes && Object.keys(config2.volumes).length > 0) {
|
|
16348
16776
|
console.log();
|
|
16349
|
-
console.log(
|
|
16777
|
+
console.log(chalk16.blue("Processing volumes..."));
|
|
16350
16778
|
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
16351
16779
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
16352
|
-
console.log(
|
|
16780
|
+
console.log(chalk16.gray(` ${volumeConfig.name}/`));
|
|
16353
16781
|
if (!existsSync6(volumeDir)) {
|
|
16354
16782
|
console.error(
|
|
16355
|
-
|
|
16783
|
+
chalk16.red(
|
|
16356
16784
|
` \u2717 Directory not found. Create the directory and add files first.`
|
|
16357
16785
|
)
|
|
16358
16786
|
);
|
|
@@ -16365,30 +16793,30 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16365
16793
|
cwd: volumeDir,
|
|
16366
16794
|
silent: true
|
|
16367
16795
|
});
|
|
16368
|
-
console.log(
|
|
16796
|
+
console.log(chalk16.green(` \u2713 Initialized`));
|
|
16369
16797
|
}
|
|
16370
16798
|
await execVm0Command(["volume", "push"], {
|
|
16371
16799
|
cwd: volumeDir,
|
|
16372
16800
|
silent: true
|
|
16373
16801
|
});
|
|
16374
|
-
console.log(
|
|
16802
|
+
console.log(chalk16.green(` \u2713 Pushed`));
|
|
16375
16803
|
} catch (error43) {
|
|
16376
|
-
console.error(
|
|
16804
|
+
console.error(chalk16.red(` \u2717 Failed`));
|
|
16377
16805
|
if (error43 instanceof Error) {
|
|
16378
|
-
console.error(
|
|
16806
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16379
16807
|
}
|
|
16380
16808
|
process.exit(1);
|
|
16381
16809
|
}
|
|
16382
16810
|
}
|
|
16383
16811
|
}
|
|
16384
16812
|
console.log();
|
|
16385
|
-
console.log(
|
|
16813
|
+
console.log(chalk16.blue("Processing artifact..."));
|
|
16386
16814
|
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
16387
|
-
console.log(
|
|
16815
|
+
console.log(chalk16.gray(` ${ARTIFACT_DIR}/`));
|
|
16388
16816
|
try {
|
|
16389
16817
|
if (!existsSync6(artifactDir)) {
|
|
16390
16818
|
await mkdir5(artifactDir, { recursive: true });
|
|
16391
|
-
console.log(
|
|
16819
|
+
console.log(chalk16.green(` \u2713 Created directory`));
|
|
16392
16820
|
}
|
|
16393
16821
|
const existingConfig = await readStorageConfig(artifactDir);
|
|
16394
16822
|
if (!existingConfig) {
|
|
@@ -16396,38 +16824,38 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16396
16824
|
cwd: artifactDir,
|
|
16397
16825
|
silent: true
|
|
16398
16826
|
});
|
|
16399
|
-
console.log(
|
|
16827
|
+
console.log(chalk16.green(` \u2713 Initialized`));
|
|
16400
16828
|
}
|
|
16401
16829
|
await execVm0Command(["artifact", "push"], {
|
|
16402
16830
|
cwd: artifactDir,
|
|
16403
16831
|
silent: true
|
|
16404
16832
|
});
|
|
16405
|
-
console.log(
|
|
16833
|
+
console.log(chalk16.green(` \u2713 Pushed`));
|
|
16406
16834
|
} catch (error43) {
|
|
16407
|
-
console.error(
|
|
16835
|
+
console.error(chalk16.red(` \u2717 Failed`));
|
|
16408
16836
|
if (error43 instanceof Error) {
|
|
16409
|
-
console.error(
|
|
16837
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16410
16838
|
}
|
|
16411
16839
|
process.exit(1);
|
|
16412
16840
|
}
|
|
16413
16841
|
console.log();
|
|
16414
|
-
console.log(
|
|
16842
|
+
console.log(chalk16.blue("Uploading compose..."));
|
|
16415
16843
|
try {
|
|
16416
16844
|
await execVm0Command(["compose", CONFIG_FILE3], {
|
|
16417
16845
|
cwd,
|
|
16418
16846
|
silent: true
|
|
16419
16847
|
});
|
|
16420
|
-
console.log(
|
|
16848
|
+
console.log(chalk16.green(`\u2713 Compose uploaded: ${agentName}`));
|
|
16421
16849
|
} catch (error43) {
|
|
16422
|
-
console.error(
|
|
16850
|
+
console.error(chalk16.red(`\u2717 Compose failed`));
|
|
16423
16851
|
if (error43 instanceof Error) {
|
|
16424
|
-
console.error(
|
|
16852
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16425
16853
|
}
|
|
16426
16854
|
process.exit(1);
|
|
16427
16855
|
}
|
|
16428
16856
|
if (prompt) {
|
|
16429
16857
|
console.log();
|
|
16430
|
-
console.log(
|
|
16858
|
+
console.log(chalk16.blue(`Running agent: ${agentName}`));
|
|
16431
16859
|
console.log();
|
|
16432
16860
|
let runOutput;
|
|
16433
16861
|
try {
|
|
@@ -16448,17 +16876,17 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16448
16876
|
);
|
|
16449
16877
|
if (serverVersion) {
|
|
16450
16878
|
console.log();
|
|
16451
|
-
console.log(
|
|
16879
|
+
console.log(chalk16.blue("Pulling updated artifact..."));
|
|
16452
16880
|
try {
|
|
16453
16881
|
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
16454
16882
|
cwd: artifactDir,
|
|
16455
16883
|
silent: true
|
|
16456
16884
|
});
|
|
16457
|
-
console.log(
|
|
16885
|
+
console.log(chalk16.green(`\u2713 Artifact pulled (${serverVersion})`));
|
|
16458
16886
|
} catch (error43) {
|
|
16459
|
-
console.error(
|
|
16887
|
+
console.error(chalk16.red(`\u2717 Artifact pull failed`));
|
|
16460
16888
|
if (error43 instanceof Error) {
|
|
16461
|
-
console.error(
|
|
16889
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16462
16890
|
}
|
|
16463
16891
|
}
|
|
16464
16892
|
}
|
|
@@ -16466,7 +16894,7 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16466
16894
|
console.log();
|
|
16467
16895
|
console.log(" Run your agent:");
|
|
16468
16896
|
console.log(
|
|
16469
|
-
|
|
16897
|
+
chalk16.cyan(
|
|
16470
16898
|
` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
|
|
16471
16899
|
)
|
|
16472
16900
|
);
|
|
@@ -16478,7 +16906,7 @@ import { Command as Command18 } from "commander";
|
|
|
16478
16906
|
|
|
16479
16907
|
// src/commands/image/build.ts
|
|
16480
16908
|
import { Command as Command14 } from "commander";
|
|
16481
|
-
import
|
|
16909
|
+
import chalk17 from "chalk";
|
|
16482
16910
|
import { readFile as readFile6 } from "fs/promises";
|
|
16483
16911
|
import { existsSync as existsSync7 } from "fs";
|
|
16484
16912
|
|
|
@@ -16518,13 +16946,13 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16518
16946
|
async (options) => {
|
|
16519
16947
|
const { file: file2, name, deleteExisting } = options;
|
|
16520
16948
|
if (!existsSync7(file2)) {
|
|
16521
|
-
console.error(
|
|
16949
|
+
console.error(chalk17.red(`\u2717 Dockerfile not found: ${file2}`));
|
|
16522
16950
|
process.exit(1);
|
|
16523
16951
|
}
|
|
16524
16952
|
const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
|
|
16525
16953
|
if (!nameRegex.test(name)) {
|
|
16526
16954
|
console.error(
|
|
16527
|
-
|
|
16955
|
+
chalk17.red(
|
|
16528
16956
|
"\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
|
|
16529
16957
|
)
|
|
16530
16958
|
);
|
|
@@ -16532,7 +16960,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16532
16960
|
}
|
|
16533
16961
|
if (name.startsWith("vm0-")) {
|
|
16534
16962
|
console.error(
|
|
16535
|
-
|
|
16963
|
+
chalk17.red(
|
|
16536
16964
|
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
16537
16965
|
)
|
|
16538
16966
|
);
|
|
@@ -16543,24 +16971,24 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16543
16971
|
const dockerfile = await readFile6(file2, "utf8");
|
|
16544
16972
|
const validation = validateDockerfile(dockerfile);
|
|
16545
16973
|
if (!validation.valid) {
|
|
16546
|
-
console.error(
|
|
16974
|
+
console.error(chalk17.red("\u2717 Dockerfile validation failed\n"));
|
|
16547
16975
|
for (const error43 of validation.errors) {
|
|
16548
|
-
console.error(
|
|
16976
|
+
console.error(chalk17.red(` ${error43}`));
|
|
16549
16977
|
}
|
|
16550
16978
|
console.error();
|
|
16551
16979
|
console.error(
|
|
16552
|
-
|
|
16980
|
+
chalk17.yellow(
|
|
16553
16981
|
" vm0 image build only supports FROM and RUN instructions."
|
|
16554
16982
|
)
|
|
16555
16983
|
);
|
|
16556
16984
|
console.error(
|
|
16557
|
-
|
|
16985
|
+
chalk17.yellow(
|
|
16558
16986
|
" The purpose is to pre-install environment dependencies."
|
|
16559
16987
|
)
|
|
16560
16988
|
);
|
|
16561
16989
|
process.exit(1);
|
|
16562
16990
|
}
|
|
16563
|
-
console.log(
|
|
16991
|
+
console.log(chalk17.blue(`Building image: ${scope.slug}/${name}`));
|
|
16564
16992
|
console.log();
|
|
16565
16993
|
const buildInfo = await apiClient.createImage({
|
|
16566
16994
|
dockerfile,
|
|
@@ -16568,7 +16996,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16568
16996
|
deleteExisting
|
|
16569
16997
|
});
|
|
16570
16998
|
const { imageId, buildId, versionId } = buildInfo;
|
|
16571
|
-
console.log(
|
|
16999
|
+
console.log(chalk17.gray(` Build ID: ${buildId}`));
|
|
16572
17000
|
console.log();
|
|
16573
17001
|
let logsOffset = 0;
|
|
16574
17002
|
let status = "building";
|
|
@@ -16584,7 +17012,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16584
17012
|
}
|
|
16585
17013
|
const statusData = await statusResponse.json();
|
|
16586
17014
|
for (const log of statusData.logs) {
|
|
16587
|
-
console.log(
|
|
17015
|
+
console.log(chalk17.gray(` ${log}`));
|
|
16588
17016
|
}
|
|
16589
17017
|
logsOffset = statusData.logsOffset;
|
|
16590
17018
|
status = statusData.status;
|
|
@@ -16596,23 +17024,23 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16596
17024
|
if (status === "ready") {
|
|
16597
17025
|
const shortVersion = formatVersionIdForDisplay(versionId);
|
|
16598
17026
|
console.log(
|
|
16599
|
-
|
|
17027
|
+
chalk17.green(`\u2713 Image built: ${scope.slug}/${name}:${shortVersion}`)
|
|
16600
17028
|
);
|
|
16601
17029
|
} else {
|
|
16602
|
-
console.error(
|
|
17030
|
+
console.error(chalk17.red(`\u2717 Build failed`));
|
|
16603
17031
|
process.exit(1);
|
|
16604
17032
|
}
|
|
16605
17033
|
} catch (error43) {
|
|
16606
17034
|
if (error43 instanceof Error) {
|
|
16607
17035
|
if (error43.message.includes("Not authenticated")) {
|
|
16608
17036
|
console.error(
|
|
16609
|
-
|
|
17037
|
+
chalk17.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
16610
17038
|
);
|
|
16611
17039
|
} else {
|
|
16612
|
-
console.error(
|
|
17040
|
+
console.error(chalk17.red(`\u2717 ${error43.message}`));
|
|
16613
17041
|
}
|
|
16614
17042
|
} else {
|
|
16615
|
-
console.error(
|
|
17043
|
+
console.error(chalk17.red("\u2717 An unexpected error occurred"));
|
|
16616
17044
|
}
|
|
16617
17045
|
process.exit(1);
|
|
16618
17046
|
}
|
|
@@ -16621,7 +17049,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16621
17049
|
|
|
16622
17050
|
// src/commands/image/list.ts
|
|
16623
17051
|
import { Command as Command15 } from "commander";
|
|
16624
|
-
import
|
|
17052
|
+
import chalk18 from "chalk";
|
|
16625
17053
|
var listCommand = new Command15().name("list").alias("ls").description("List your custom images").action(async () => {
|
|
16626
17054
|
try {
|
|
16627
17055
|
const response = await apiClient.get("/api/images");
|
|
@@ -16634,15 +17062,15 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16634
17062
|
const data = await response.json();
|
|
16635
17063
|
const { images } = data;
|
|
16636
17064
|
if (images.length === 0) {
|
|
16637
|
-
console.log(
|
|
17065
|
+
console.log(chalk18.gray("No images found."));
|
|
16638
17066
|
console.log();
|
|
16639
17067
|
console.log("Build your first image:");
|
|
16640
17068
|
console.log(
|
|
16641
|
-
|
|
17069
|
+
chalk18.cyan(" vm0 image build --file Dockerfile --name my-image")
|
|
16642
17070
|
);
|
|
16643
17071
|
return;
|
|
16644
17072
|
}
|
|
16645
|
-
console.log(
|
|
17073
|
+
console.log(chalk18.bold("Your images:"));
|
|
16646
17074
|
console.log();
|
|
16647
17075
|
const imagesByAlias = /* @__PURE__ */ new Map();
|
|
16648
17076
|
for (const image of images) {
|
|
@@ -16656,40 +17084,40 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16656
17084
|
latestVersions.set(alias, latestReady?.versionId || null);
|
|
16657
17085
|
}
|
|
16658
17086
|
console.log(
|
|
16659
|
-
|
|
17087
|
+
chalk18.gray(
|
|
16660
17088
|
`${"NAME".padEnd(40)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
|
|
16661
17089
|
)
|
|
16662
17090
|
);
|
|
16663
|
-
console.log(
|
|
17091
|
+
console.log(chalk18.gray("-".repeat(72)));
|
|
16664
17092
|
for (const image of images) {
|
|
16665
|
-
const statusColor = image.status === "ready" ?
|
|
17093
|
+
const statusColor = image.status === "ready" ? chalk18.green : image.status === "building" ? chalk18.yellow : chalk18.red;
|
|
16666
17094
|
const createdAt = new Date(image.createdAt).toLocaleString();
|
|
16667
17095
|
let displayName = image.alias;
|
|
16668
17096
|
if (image.versionId) {
|
|
16669
17097
|
const shortVersion = formatVersionIdForDisplay(image.versionId);
|
|
16670
17098
|
displayName = `${image.alias}:${shortVersion}`;
|
|
16671
17099
|
if (image.status === "ready" && latestVersions.get(image.alias) === image.versionId) {
|
|
16672
|
-
displayName = `${displayName} ${
|
|
17100
|
+
displayName = `${displayName} ${chalk18.cyan("(latest)")}`;
|
|
16673
17101
|
}
|
|
16674
17102
|
}
|
|
16675
17103
|
console.log(
|
|
16676
17104
|
`${displayName.padEnd(40)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
|
|
16677
17105
|
);
|
|
16678
17106
|
if (image.status === "error" && image.errorMessage) {
|
|
16679
|
-
console.log(
|
|
17107
|
+
console.log(chalk18.red(` Error: ${image.errorMessage}`));
|
|
16680
17108
|
}
|
|
16681
17109
|
}
|
|
16682
17110
|
console.log();
|
|
16683
|
-
console.log(
|
|
17111
|
+
console.log(chalk18.gray(`Total: ${images.length} version(s)`));
|
|
16684
17112
|
} catch (error43) {
|
|
16685
17113
|
if (error43 instanceof Error) {
|
|
16686
17114
|
if (error43.message.includes("Not authenticated")) {
|
|
16687
|
-
console.error(
|
|
17115
|
+
console.error(chalk18.red("Not authenticated. Run: vm0 auth login"));
|
|
16688
17116
|
} else {
|
|
16689
|
-
console.error(
|
|
17117
|
+
console.error(chalk18.red(`Error: ${error43.message}`));
|
|
16690
17118
|
}
|
|
16691
17119
|
} else {
|
|
16692
|
-
console.error(
|
|
17120
|
+
console.error(chalk18.red("An unexpected error occurred"));
|
|
16693
17121
|
}
|
|
16694
17122
|
process.exit(1);
|
|
16695
17123
|
}
|
|
@@ -16697,7 +17125,7 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
|
|
|
16697
17125
|
|
|
16698
17126
|
// src/commands/image/delete.ts
|
|
16699
17127
|
import { Command as Command16 } from "commander";
|
|
16700
|
-
import
|
|
17128
|
+
import chalk19 from "chalk";
|
|
16701
17129
|
import * as readline from "readline";
|
|
16702
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(
|
|
16703
17131
|
async (nameArg, options) => {
|
|
@@ -16720,12 +17148,12 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16720
17148
|
(img) => img.alias === name && img.versionId && img.versionId.startsWith(versionId.toLowerCase())
|
|
16721
17149
|
);
|
|
16722
17150
|
if (matchingVersions.length === 0) {
|
|
16723
|
-
console.error(
|
|
17151
|
+
console.error(chalk19.red(`Image version not found: ${nameArg}`));
|
|
16724
17152
|
process.exit(1);
|
|
16725
17153
|
}
|
|
16726
17154
|
if (matchingVersions.length > 1) {
|
|
16727
17155
|
console.error(
|
|
16728
|
-
|
|
17156
|
+
chalk19.red(
|
|
16729
17157
|
`Ambiguous version prefix "${versionId}". Please use more characters.`
|
|
16730
17158
|
)
|
|
16731
17159
|
);
|
|
@@ -16735,7 +17163,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16735
17163
|
} else if (options.all) {
|
|
16736
17164
|
imagesToDelete = data.images.filter((img) => img.alias === name);
|
|
16737
17165
|
if (imagesToDelete.length === 0) {
|
|
16738
|
-
console.error(
|
|
17166
|
+
console.error(chalk19.red(`Image not found: ${name}`));
|
|
16739
17167
|
process.exit(1);
|
|
16740
17168
|
}
|
|
16741
17169
|
} else {
|
|
@@ -16743,7 +17171,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16743
17171
|
(img) => img.alias === name
|
|
16744
17172
|
);
|
|
16745
17173
|
if (matchingImages.length === 0) {
|
|
16746
|
-
console.error(
|
|
17174
|
+
console.error(chalk19.red(`Image not found: ${name}`));
|
|
16747
17175
|
process.exit(1);
|
|
16748
17176
|
}
|
|
16749
17177
|
const latestReady = matchingImages.find(
|
|
@@ -16764,13 +17192,13 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16764
17192
|
output: process.stdout
|
|
16765
17193
|
});
|
|
16766
17194
|
const answer = await new Promise((resolve2) => {
|
|
16767
|
-
rl.question(
|
|
17195
|
+
rl.question(chalk19.yellow(`${confirmMsg} [y/N] `), (answer2) => {
|
|
16768
17196
|
rl.close();
|
|
16769
17197
|
resolve2(answer2);
|
|
16770
17198
|
});
|
|
16771
17199
|
});
|
|
16772
17200
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
16773
|
-
console.log(
|
|
17201
|
+
console.log(chalk19.gray("Cancelled."));
|
|
16774
17202
|
return;
|
|
16775
17203
|
}
|
|
16776
17204
|
}
|
|
@@ -16785,17 +17213,17 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16785
17213
|
);
|
|
16786
17214
|
}
|
|
16787
17215
|
const displayName = image.versionId ? `${image.alias}:${formatVersionIdForDisplay(image.versionId)}` : image.alias;
|
|
16788
|
-
console.log(
|
|
17216
|
+
console.log(chalk19.green(`Deleted image: ${displayName}`));
|
|
16789
17217
|
}
|
|
16790
17218
|
} catch (error43) {
|
|
16791
17219
|
if (error43 instanceof Error) {
|
|
16792
17220
|
if (error43.message.includes("Not authenticated")) {
|
|
16793
|
-
console.error(
|
|
17221
|
+
console.error(chalk19.red("Not authenticated. Run: vm0 auth login"));
|
|
16794
17222
|
} else {
|
|
16795
|
-
console.error(
|
|
17223
|
+
console.error(chalk19.red(`Error: ${error43.message}`));
|
|
16796
17224
|
}
|
|
16797
17225
|
} else {
|
|
16798
|
-
console.error(
|
|
17226
|
+
console.error(chalk19.red("An unexpected error occurred"));
|
|
16799
17227
|
}
|
|
16800
17228
|
process.exit(1);
|
|
16801
17229
|
}
|
|
@@ -16804,7 +17232,7 @@ var deleteCommand = new Command16().name("delete").alias("rm").description("Dele
|
|
|
16804
17232
|
|
|
16805
17233
|
// src/commands/image/versions.ts
|
|
16806
17234
|
import { Command as Command17 } from "commander";
|
|
16807
|
-
import
|
|
17235
|
+
import chalk20 from "chalk";
|
|
16808
17236
|
var versionsCommand = new Command17().name("versions").description("List all versions of an image").argument("<name>", "Name of the image").action(async (name) => {
|
|
16809
17237
|
try {
|
|
16810
17238
|
const response = await apiClient.get("/api/images");
|
|
@@ -16817,42 +17245,42 @@ var versionsCommand = new Command17().name("versions").description("List all ver
|
|
|
16817
17245
|
const data = await response.json();
|
|
16818
17246
|
const versions = data.images.filter((img) => img.alias === name);
|
|
16819
17247
|
if (versions.length === 0) {
|
|
16820
|
-
console.error(
|
|
17248
|
+
console.error(chalk20.red(`Image not found: ${name}`));
|
|
16821
17249
|
process.exit(1);
|
|
16822
17250
|
}
|
|
16823
17251
|
const latestReady = versions.find((v) => v.status === "ready");
|
|
16824
17252
|
const latestVersionId = latestReady?.versionId || null;
|
|
16825
|
-
console.log(
|
|
17253
|
+
console.log(chalk20.bold(`Versions of ${name}:`));
|
|
16826
17254
|
console.log();
|
|
16827
17255
|
console.log(
|
|
16828
|
-
|
|
17256
|
+
chalk20.gray(
|
|
16829
17257
|
`${"VERSION".padEnd(20)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(24)}`
|
|
16830
17258
|
)
|
|
16831
17259
|
);
|
|
16832
|
-
console.log(
|
|
17260
|
+
console.log(chalk20.gray("-".repeat(56)));
|
|
16833
17261
|
for (const version2 of versions) {
|
|
16834
|
-
const statusColor = version2.status === "ready" ?
|
|
17262
|
+
const statusColor = version2.status === "ready" ? chalk20.green : version2.status === "building" ? chalk20.yellow : chalk20.red;
|
|
16835
17263
|
const createdAt = new Date(version2.createdAt).toLocaleString();
|
|
16836
17264
|
let versionDisplay = version2.versionId ? formatVersionIdForDisplay(version2.versionId) : "(legacy)";
|
|
16837
17265
|
if (version2.status === "ready" && version2.versionId === latestVersionId) {
|
|
16838
|
-
versionDisplay = `${versionDisplay} ${
|
|
17266
|
+
versionDisplay = `${versionDisplay} ${chalk20.cyan("(latest)")}`;
|
|
16839
17267
|
}
|
|
16840
17268
|
console.log(
|
|
16841
17269
|
`${versionDisplay.padEnd(20)} ${statusColor(version2.status.padEnd(12))} ${createdAt.padEnd(24)}`
|
|
16842
17270
|
);
|
|
16843
17271
|
if (version2.status === "error" && version2.errorMessage) {
|
|
16844
|
-
console.log(
|
|
17272
|
+
console.log(chalk20.red(` Error: ${version2.errorMessage}`));
|
|
16845
17273
|
}
|
|
16846
17274
|
}
|
|
16847
17275
|
console.log();
|
|
16848
|
-
console.log(
|
|
17276
|
+
console.log(chalk20.gray(`Total: ${versions.length} version(s)`));
|
|
16849
17277
|
console.log();
|
|
16850
|
-
console.log(
|
|
16851
|
-
console.log(
|
|
17278
|
+
console.log(chalk20.gray("Usage:"));
|
|
17279
|
+
console.log(chalk20.gray(` image: "${name}" # uses latest`));
|
|
16852
17280
|
if (latestVersionId) {
|
|
16853
17281
|
const shortVersion = formatVersionIdForDisplay(latestVersionId);
|
|
16854
17282
|
console.log(
|
|
16855
|
-
|
|
17283
|
+
chalk20.gray(
|
|
16856
17284
|
` image: "${name}:${shortVersion}" # pin to specific version`
|
|
16857
17285
|
)
|
|
16858
17286
|
);
|
|
@@ -16860,12 +17288,12 @@ var versionsCommand = new Command17().name("versions").description("List all ver
|
|
|
16860
17288
|
} catch (error43) {
|
|
16861
17289
|
if (error43 instanceof Error) {
|
|
16862
17290
|
if (error43.message.includes("Not authenticated")) {
|
|
16863
|
-
console.error(
|
|
17291
|
+
console.error(chalk20.red("Not authenticated. Run: vm0 auth login"));
|
|
16864
17292
|
} else {
|
|
16865
|
-
console.error(
|
|
17293
|
+
console.error(chalk20.red(`Error: ${error43.message}`));
|
|
16866
17294
|
}
|
|
16867
17295
|
} else {
|
|
16868
|
-
console.error(
|
|
17296
|
+
console.error(chalk20.red("An unexpected error occurred"));
|
|
16869
17297
|
}
|
|
16870
17298
|
process.exit(1);
|
|
16871
17299
|
}
|
|
@@ -16876,7 +17304,7 @@ var imageCommand = new Command18().name("image").description("Manage custom imag
|
|
|
16876
17304
|
|
|
16877
17305
|
// src/commands/logs/index.ts
|
|
16878
17306
|
import { Command as Command19 } from "commander";
|
|
16879
|
-
import
|
|
17307
|
+
import chalk21 from "chalk";
|
|
16880
17308
|
|
|
16881
17309
|
// src/lib/time-parser.ts
|
|
16882
17310
|
function parseTime(timeStr) {
|
|
@@ -16938,23 +17366,23 @@ function formatMetric(metric) {
|
|
|
16938
17366
|
function formatNetworkLog(entry) {
|
|
16939
17367
|
let statusColor;
|
|
16940
17368
|
if (entry.status >= 200 && entry.status < 300) {
|
|
16941
|
-
statusColor =
|
|
17369
|
+
statusColor = chalk21.green;
|
|
16942
17370
|
} else if (entry.status >= 300 && entry.status < 400) {
|
|
16943
|
-
statusColor =
|
|
17371
|
+
statusColor = chalk21.yellow;
|
|
16944
17372
|
} else if (entry.status >= 400) {
|
|
16945
|
-
statusColor =
|
|
17373
|
+
statusColor = chalk21.red;
|
|
16946
17374
|
} else {
|
|
16947
|
-
statusColor =
|
|
17375
|
+
statusColor = chalk21.gray;
|
|
16948
17376
|
}
|
|
16949
17377
|
let latencyColor;
|
|
16950
17378
|
if (entry.latency_ms < 500) {
|
|
16951
|
-
latencyColor =
|
|
17379
|
+
latencyColor = chalk21.green;
|
|
16952
17380
|
} else if (entry.latency_ms < 2e3) {
|
|
16953
|
-
latencyColor =
|
|
17381
|
+
latencyColor = chalk21.yellow;
|
|
16954
17382
|
} else {
|
|
16955
|
-
latencyColor =
|
|
17383
|
+
latencyColor = chalk21.red;
|
|
16956
17384
|
}
|
|
16957
|
-
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)}`;
|
|
16958
17386
|
}
|
|
16959
17387
|
function renderAgentEvent(event) {
|
|
16960
17388
|
const parsed = ClaudeEventParser.parse(
|
|
@@ -16974,7 +17402,7 @@ function getLogType(options) {
|
|
|
16974
17402
|
].filter(Boolean).length;
|
|
16975
17403
|
if (selected > 1) {
|
|
16976
17404
|
console.error(
|
|
16977
|
-
|
|
17405
|
+
chalk21.red(
|
|
16978
17406
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
16979
17407
|
)
|
|
16980
17408
|
);
|
|
@@ -17027,7 +17455,7 @@ var logsCommand = new Command19().name("logs").description("View logs for an age
|
|
|
17027
17455
|
async function showAgentEvents(runId, options) {
|
|
17028
17456
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
17029
17457
|
if (response.events.length === 0) {
|
|
17030
|
-
console.log(
|
|
17458
|
+
console.log(chalk21.yellow("No agent events found for this run."));
|
|
17031
17459
|
return;
|
|
17032
17460
|
}
|
|
17033
17461
|
for (const event of response.events) {
|
|
@@ -17036,7 +17464,7 @@ async function showAgentEvents(runId, options) {
|
|
|
17036
17464
|
if (response.hasMore) {
|
|
17037
17465
|
console.log();
|
|
17038
17466
|
console.log(
|
|
17039
|
-
|
|
17467
|
+
chalk21.gray(
|
|
17040
17468
|
`Showing ${response.events.length} events. Use --limit to see more.`
|
|
17041
17469
|
)
|
|
17042
17470
|
);
|
|
@@ -17045,21 +17473,21 @@ async function showAgentEvents(runId, options) {
|
|
|
17045
17473
|
async function showSystemLog(runId, options) {
|
|
17046
17474
|
const response = await apiClient.getSystemLog(runId, options);
|
|
17047
17475
|
if (!response.systemLog) {
|
|
17048
|
-
console.log(
|
|
17476
|
+
console.log(chalk21.yellow("No system log found for this run."));
|
|
17049
17477
|
return;
|
|
17050
17478
|
}
|
|
17051
17479
|
console.log(response.systemLog);
|
|
17052
17480
|
if (response.hasMore) {
|
|
17053
17481
|
console.log();
|
|
17054
17482
|
console.log(
|
|
17055
|
-
|
|
17483
|
+
chalk21.gray("More log entries available. Use --limit to see more.")
|
|
17056
17484
|
);
|
|
17057
17485
|
}
|
|
17058
17486
|
}
|
|
17059
17487
|
async function showMetrics(runId, options) {
|
|
17060
17488
|
const response = await apiClient.getMetrics(runId, options);
|
|
17061
17489
|
if (response.metrics.length === 0) {
|
|
17062
|
-
console.log(
|
|
17490
|
+
console.log(chalk21.yellow("No metrics found for this run."));
|
|
17063
17491
|
return;
|
|
17064
17492
|
}
|
|
17065
17493
|
for (const metric of response.metrics) {
|
|
@@ -17068,7 +17496,7 @@ async function showMetrics(runId, options) {
|
|
|
17068
17496
|
if (response.hasMore) {
|
|
17069
17497
|
console.log();
|
|
17070
17498
|
console.log(
|
|
17071
|
-
|
|
17499
|
+
chalk21.gray(
|
|
17072
17500
|
`Showing ${response.metrics.length} metrics. Use --limit to see more.`
|
|
17073
17501
|
)
|
|
17074
17502
|
);
|
|
@@ -17078,7 +17506,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
17078
17506
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
17079
17507
|
if (response.networkLogs.length === 0) {
|
|
17080
17508
|
console.log(
|
|
17081
|
-
|
|
17509
|
+
chalk21.yellow(
|
|
17082
17510
|
"No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
|
|
17083
17511
|
)
|
|
17084
17512
|
);
|
|
@@ -17090,7 +17518,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
17090
17518
|
if (response.hasMore) {
|
|
17091
17519
|
console.log();
|
|
17092
17520
|
console.log(
|
|
17093
|
-
|
|
17521
|
+
chalk21.gray(
|
|
17094
17522
|
`Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
|
|
17095
17523
|
)
|
|
17096
17524
|
);
|
|
@@ -17099,17 +17527,17 @@ async function showNetworkLogs(runId, options) {
|
|
|
17099
17527
|
function handleError(error43, runId) {
|
|
17100
17528
|
if (error43 instanceof Error) {
|
|
17101
17529
|
if (error43.message.includes("Not authenticated")) {
|
|
17102
|
-
console.error(
|
|
17530
|
+
console.error(chalk21.red("Not authenticated. Run: vm0 auth login"));
|
|
17103
17531
|
} else if (error43.message.includes("not found")) {
|
|
17104
|
-
console.error(
|
|
17532
|
+
console.error(chalk21.red(`Run not found: ${runId}`));
|
|
17105
17533
|
} else if (error43.message.includes("Invalid time format")) {
|
|
17106
|
-
console.error(
|
|
17534
|
+
console.error(chalk21.red(error43.message));
|
|
17107
17535
|
} else {
|
|
17108
|
-
console.error(
|
|
17109
|
-
console.error(
|
|
17536
|
+
console.error(chalk21.red("Failed to fetch logs"));
|
|
17537
|
+
console.error(chalk21.gray(` ${error43.message}`));
|
|
17110
17538
|
}
|
|
17111
17539
|
} else {
|
|
17112
|
-
console.error(
|
|
17540
|
+
console.error(chalk21.red("An unexpected error occurred"));
|
|
17113
17541
|
}
|
|
17114
17542
|
}
|
|
17115
17543
|
|
|
@@ -17118,12 +17546,12 @@ import { Command as Command22 } from "commander";
|
|
|
17118
17546
|
|
|
17119
17547
|
// src/commands/scope/status.ts
|
|
17120
17548
|
import { Command as Command20 } from "commander";
|
|
17121
|
-
import
|
|
17549
|
+
import chalk22 from "chalk";
|
|
17122
17550
|
var statusCommand3 = new Command20().name("status").description("View current scope status").action(async () => {
|
|
17123
17551
|
try {
|
|
17124
17552
|
const scope = await apiClient.getScope();
|
|
17125
|
-
console.log(
|
|
17126
|
-
console.log(` Slug: ${
|
|
17553
|
+
console.log(chalk22.cyan("Scope Information:"));
|
|
17554
|
+
console.log(` Slug: ${chalk22.green(scope.slug)}`);
|
|
17127
17555
|
console.log(` Type: ${scope.type}`);
|
|
17128
17556
|
if (scope.displayName) {
|
|
17129
17557
|
console.log(` Display Name: ${scope.displayName}`);
|
|
@@ -17134,20 +17562,20 @@ var statusCommand3 = new Command20().name("status").description("View current sc
|
|
|
17134
17562
|
} catch (error43) {
|
|
17135
17563
|
if (error43 instanceof Error) {
|
|
17136
17564
|
if (error43.message.includes("Not authenticated")) {
|
|
17137
|
-
console.error(
|
|
17565
|
+
console.error(chalk22.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
17138
17566
|
} else if (error43.message.includes("No scope configured")) {
|
|
17139
|
-
console.log(
|
|
17567
|
+
console.log(chalk22.yellow("No scope configured."));
|
|
17140
17568
|
console.log();
|
|
17141
17569
|
console.log("Set your scope with:");
|
|
17142
|
-
console.log(
|
|
17570
|
+
console.log(chalk22.cyan(" vm0 scope set <slug>"));
|
|
17143
17571
|
console.log();
|
|
17144
17572
|
console.log("Example:");
|
|
17145
|
-
console.log(
|
|
17573
|
+
console.log(chalk22.gray(" vm0 scope set myusername"));
|
|
17146
17574
|
} else {
|
|
17147
|
-
console.error(
|
|
17575
|
+
console.error(chalk22.red(`\u2717 ${error43.message}`));
|
|
17148
17576
|
}
|
|
17149
17577
|
} else {
|
|
17150
|
-
console.error(
|
|
17578
|
+
console.error(chalk22.red("\u2717 An unexpected error occurred"));
|
|
17151
17579
|
}
|
|
17152
17580
|
process.exit(1);
|
|
17153
17581
|
}
|
|
@@ -17155,7 +17583,7 @@ var statusCommand3 = new Command20().name("status").description("View current sc
|
|
|
17155
17583
|
|
|
17156
17584
|
// src/commands/scope/set.ts
|
|
17157
17585
|
import { Command as Command21 } from "commander";
|
|
17158
|
-
import
|
|
17586
|
+
import chalk23 from "chalk";
|
|
17159
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(
|
|
17160
17588
|
async (slug, options) => {
|
|
17161
17589
|
try {
|
|
@@ -17168,56 +17596,56 @@ var setCommand = new Command21().name("set").description("Set your scope slug").
|
|
|
17168
17596
|
if (existingScope) {
|
|
17169
17597
|
if (!options.force) {
|
|
17170
17598
|
console.error(
|
|
17171
|
-
|
|
17599
|
+
chalk23.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
17172
17600
|
);
|
|
17173
17601
|
console.error();
|
|
17174
17602
|
console.error("To change your scope, use --force:");
|
|
17175
|
-
console.error(
|
|
17603
|
+
console.error(chalk23.cyan(` vm0 scope set ${slug} --force`));
|
|
17176
17604
|
console.error();
|
|
17177
17605
|
console.error(
|
|
17178
|
-
|
|
17606
|
+
chalk23.yellow(
|
|
17179
17607
|
"Warning: Changing your scope may break existing image references."
|
|
17180
17608
|
)
|
|
17181
17609
|
);
|
|
17182
17610
|
process.exit(1);
|
|
17183
17611
|
}
|
|
17184
17612
|
scope = await apiClient.updateScope({ slug, force: true });
|
|
17185
|
-
console.log(
|
|
17613
|
+
console.log(chalk23.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
17186
17614
|
} else {
|
|
17187
17615
|
scope = await apiClient.createScope({
|
|
17188
17616
|
slug,
|
|
17189
17617
|
displayName: options.displayName
|
|
17190
17618
|
});
|
|
17191
|
-
console.log(
|
|
17619
|
+
console.log(chalk23.green(`\u2713 Scope created: ${scope.slug}`));
|
|
17192
17620
|
}
|
|
17193
17621
|
console.log();
|
|
17194
17622
|
console.log("Your images will now be namespaced as:");
|
|
17195
|
-
console.log(
|
|
17623
|
+
console.log(chalk23.cyan(` ${scope.slug}/<image-name>`));
|
|
17196
17624
|
} catch (error43) {
|
|
17197
17625
|
if (error43 instanceof Error) {
|
|
17198
17626
|
if (error43.message.includes("Not authenticated")) {
|
|
17199
17627
|
console.error(
|
|
17200
|
-
|
|
17628
|
+
chalk23.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
17201
17629
|
);
|
|
17202
17630
|
} else if (error43.message.includes("already exists")) {
|
|
17203
17631
|
console.error(
|
|
17204
|
-
|
|
17632
|
+
chalk23.red(
|
|
17205
17633
|
`\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
|
|
17206
17634
|
)
|
|
17207
17635
|
);
|
|
17208
17636
|
} else if (error43.message.includes("reserved")) {
|
|
17209
|
-
console.error(
|
|
17637
|
+
console.error(chalk23.red(`\u2717 ${error43.message}`));
|
|
17210
17638
|
} else if (error43.message.includes("vm0")) {
|
|
17211
17639
|
console.error(
|
|
17212
|
-
|
|
17640
|
+
chalk23.red(
|
|
17213
17641
|
"\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
|
|
17214
17642
|
)
|
|
17215
17643
|
);
|
|
17216
17644
|
} else {
|
|
17217
|
-
console.error(
|
|
17645
|
+
console.error(chalk23.red(`\u2717 ${error43.message}`));
|
|
17218
17646
|
}
|
|
17219
17647
|
} else {
|
|
17220
|
-
console.error(
|
|
17648
|
+
console.error(chalk23.red("\u2717 An unexpected error occurred"));
|
|
17221
17649
|
}
|
|
17222
17650
|
process.exit(1);
|
|
17223
17651
|
}
|
|
@@ -17229,9 +17657,9 @@ var scopeCommand = new Command22().name("scope").description("Manage your scope
|
|
|
17229
17657
|
|
|
17230
17658
|
// src/index.ts
|
|
17231
17659
|
var program = new Command23();
|
|
17232
|
-
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");
|
|
17233
17661
|
program.command("info").description("Display environment information").action(async () => {
|
|
17234
|
-
console.log(
|
|
17662
|
+
console.log(chalk24.cyan("System Information:"));
|
|
17235
17663
|
console.log(`Node Version: ${process.version}`);
|
|
17236
17664
|
console.log(`Platform: ${process.platform}`);
|
|
17237
17665
|
console.log(`Architecture: ${process.arch}`);
|