@vm0/cli 4.8.1 → 4.10.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 +248 -163
- 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 Command17 } from "commander";
|
|
10
|
-
import
|
|
10
|
+
import chalk17 from "chalk";
|
|
11
11
|
|
|
12
12
|
// src/lib/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -1200,10 +1200,13 @@ var EventRenderer = class {
|
|
|
1200
1200
|
* Render run failed state
|
|
1201
1201
|
* Note: This is run lifecycle status, not an event
|
|
1202
1202
|
*/
|
|
1203
|
-
static renderRunFailed(error43) {
|
|
1203
|
+
static renderRunFailed(error43, runId) {
|
|
1204
1204
|
console.log("");
|
|
1205
1205
|
console.log(chalk3.red("\u2717 Run failed"));
|
|
1206
1206
|
console.log(` Error: ${chalk3.red(error43 || "Unknown error")}`);
|
|
1207
|
+
console.log(
|
|
1208
|
+
chalk3.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
1209
|
+
);
|
|
1207
1210
|
}
|
|
1208
1211
|
static renderInit(event, prefix, suffix) {
|
|
1209
1212
|
console.log(
|
|
@@ -14596,11 +14599,14 @@ async function pollEvents(runId, options) {
|
|
|
14596
14599
|
};
|
|
14597
14600
|
} else if (runStatus === "failed") {
|
|
14598
14601
|
complete = true;
|
|
14599
|
-
EventRenderer.renderRunFailed(response.run.error);
|
|
14602
|
+
EventRenderer.renderRunFailed(response.run.error, runId);
|
|
14600
14603
|
result = { succeeded: false, runId };
|
|
14601
14604
|
} else if (runStatus === "timeout") {
|
|
14602
14605
|
complete = true;
|
|
14603
14606
|
console.error(chalk4.red("\n\u2717 Run timed out"));
|
|
14607
|
+
console.error(
|
|
14608
|
+
chalk4.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
14609
|
+
);
|
|
14604
14610
|
result = { succeeded: false, runId };
|
|
14605
14611
|
}
|
|
14606
14612
|
if (!complete) {
|
|
@@ -15303,11 +15309,25 @@ var pushCommand = new Command4().name("push").description("Push local files to c
|
|
|
15303
15309
|
|
|
15304
15310
|
// src/commands/volume/pull.ts
|
|
15305
15311
|
import { Command as Command5 } from "commander";
|
|
15306
|
-
import
|
|
15312
|
+
import chalk8 from "chalk";
|
|
15307
15313
|
import path8 from "path";
|
|
15308
15314
|
import * as fs6 from "fs";
|
|
15309
15315
|
import * as os4 from "os";
|
|
15310
15316
|
import * as tar4 from "tar";
|
|
15317
|
+
|
|
15318
|
+
// src/lib/pull-utils.ts
|
|
15319
|
+
import chalk7 from "chalk";
|
|
15320
|
+
async function handleEmptyStorageResponse(cwd) {
|
|
15321
|
+
console.log(chalk7.gray("Syncing local files..."));
|
|
15322
|
+
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
15323
|
+
if (removedCount > 0) {
|
|
15324
|
+
console.log(chalk7.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
15325
|
+
}
|
|
15326
|
+
console.log(chalk7.green("\u2713 Synced (0 files)"));
|
|
15327
|
+
return { removedCount };
|
|
15328
|
+
}
|
|
15329
|
+
|
|
15330
|
+
// src/commands/volume/pull.ts
|
|
15311
15331
|
function formatBytes2(bytes) {
|
|
15312
15332
|
if (bytes === 0) return "0 B";
|
|
15313
15333
|
const k = 1024;
|
|
@@ -15320,18 +15340,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15320
15340
|
const cwd = process.cwd();
|
|
15321
15341
|
const config2 = await readStorageConfig(cwd);
|
|
15322
15342
|
if (!config2) {
|
|
15323
|
-
console.error(
|
|
15324
|
-
console.error(
|
|
15343
|
+
console.error(chalk8.red("\u2717 No volume initialized in this directory"));
|
|
15344
|
+
console.error(chalk8.gray(" Run: vm0 volume init"));
|
|
15325
15345
|
process.exit(1);
|
|
15326
15346
|
}
|
|
15327
15347
|
if (versionId) {
|
|
15328
15348
|
console.log(
|
|
15329
|
-
|
|
15349
|
+
chalk8.cyan(`Pulling volume: ${config2.name} (version: ${versionId})`)
|
|
15330
15350
|
);
|
|
15331
15351
|
} else {
|
|
15332
|
-
console.log(
|
|
15352
|
+
console.log(chalk8.cyan(`Pulling volume: ${config2.name}`));
|
|
15333
15353
|
}
|
|
15334
|
-
console.log(
|
|
15354
|
+
console.log(chalk8.gray("Downloading..."));
|
|
15335
15355
|
let url2 = `/api/storages?name=${encodeURIComponent(config2.name)}&type=volume`;
|
|
15336
15356
|
if (versionId) {
|
|
15337
15357
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15339,14 +15359,14 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15339
15359
|
const response = await apiClient.get(url2);
|
|
15340
15360
|
if (!response.ok) {
|
|
15341
15361
|
if (response.status === 404) {
|
|
15342
|
-
console.error(
|
|
15362
|
+
console.error(chalk8.red(`\u2717 Volume "${config2.name}" not found`));
|
|
15343
15363
|
console.error(
|
|
15344
|
-
|
|
15364
|
+
chalk8.gray(
|
|
15345
15365
|
" Make sure the volume name is correct in .vm0/storage.yaml"
|
|
15346
15366
|
)
|
|
15347
15367
|
);
|
|
15348
15368
|
console.error(
|
|
15349
|
-
|
|
15369
|
+
chalk8.gray(" Or push the volume first with: vm0 volume push")
|
|
15350
15370
|
);
|
|
15351
15371
|
} else {
|
|
15352
15372
|
const error43 = await response.json();
|
|
@@ -15354,13 +15374,17 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15354
15374
|
}
|
|
15355
15375
|
process.exit(1);
|
|
15356
15376
|
}
|
|
15377
|
+
if (response.status === 204) {
|
|
15378
|
+
await handleEmptyStorageResponse(cwd);
|
|
15379
|
+
return;
|
|
15380
|
+
}
|
|
15357
15381
|
const arrayBuffer = await response.arrayBuffer();
|
|
15358
15382
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15359
|
-
console.log(
|
|
15383
|
+
console.log(chalk8.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
|
|
15360
15384
|
const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
|
|
15361
15385
|
const tarPath = path8.join(tmpDir, "volume.tar.gz");
|
|
15362
15386
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
15363
|
-
console.log(
|
|
15387
|
+
console.log(chalk8.gray("Syncing local files..."));
|
|
15364
15388
|
const remoteFiles = await listTarFiles(tarPath);
|
|
15365
15389
|
const remoteFilesSet = new Set(
|
|
15366
15390
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -15368,10 +15392,10 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15368
15392
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
15369
15393
|
if (removedCount > 0) {
|
|
15370
15394
|
console.log(
|
|
15371
|
-
|
|
15395
|
+
chalk8.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
15372
15396
|
);
|
|
15373
15397
|
}
|
|
15374
|
-
console.log(
|
|
15398
|
+
console.log(chalk8.gray("Extracting files..."));
|
|
15375
15399
|
await tar4.extract({
|
|
15376
15400
|
file: tarPath,
|
|
15377
15401
|
cwd,
|
|
@@ -15379,11 +15403,11 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
|
|
|
15379
15403
|
});
|
|
15380
15404
|
await fs6.promises.unlink(tarPath);
|
|
15381
15405
|
await fs6.promises.rmdir(tmpDir);
|
|
15382
|
-
console.log(
|
|
15406
|
+
console.log(chalk8.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
15383
15407
|
} catch (error43) {
|
|
15384
|
-
console.error(
|
|
15408
|
+
console.error(chalk8.red("\u2717 Pull failed"));
|
|
15385
15409
|
if (error43 instanceof Error) {
|
|
15386
|
-
console.error(
|
|
15410
|
+
console.error(chalk8.gray(` ${error43.message}`));
|
|
15387
15411
|
}
|
|
15388
15412
|
process.exit(1);
|
|
15389
15413
|
}
|
|
@@ -15397,7 +15421,7 @@ import { Command as Command10 } from "commander";
|
|
|
15397
15421
|
|
|
15398
15422
|
// src/commands/artifact/init.ts
|
|
15399
15423
|
import { Command as Command7 } from "commander";
|
|
15400
|
-
import
|
|
15424
|
+
import chalk9 from "chalk";
|
|
15401
15425
|
import path9 from "path";
|
|
15402
15426
|
var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
|
|
15403
15427
|
try {
|
|
@@ -15407,51 +15431,51 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
|
|
|
15407
15431
|
if (existingConfig) {
|
|
15408
15432
|
if (existingConfig.type === "artifact") {
|
|
15409
15433
|
console.log(
|
|
15410
|
-
|
|
15434
|
+
chalk9.yellow(
|
|
15411
15435
|
`Artifact already initialized: ${existingConfig.name}`
|
|
15412
15436
|
)
|
|
15413
15437
|
);
|
|
15414
15438
|
} else {
|
|
15415
15439
|
console.log(
|
|
15416
|
-
|
|
15440
|
+
chalk9.yellow(
|
|
15417
15441
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
15418
15442
|
)
|
|
15419
15443
|
);
|
|
15420
15444
|
console.log(
|
|
15421
|
-
|
|
15445
|
+
chalk9.gray(
|
|
15422
15446
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
15423
15447
|
)
|
|
15424
15448
|
);
|
|
15425
15449
|
}
|
|
15426
15450
|
console.log(
|
|
15427
|
-
|
|
15451
|
+
chalk9.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
15428
15452
|
);
|
|
15429
15453
|
return;
|
|
15430
15454
|
}
|
|
15431
15455
|
const artifactName = dirName;
|
|
15432
15456
|
if (!isValidStorageName(artifactName)) {
|
|
15433
|
-
console.error(
|
|
15457
|
+
console.error(chalk9.red(`\u2717 Invalid artifact name: "${dirName}"`));
|
|
15434
15458
|
console.error(
|
|
15435
|
-
|
|
15459
|
+
chalk9.gray(
|
|
15436
15460
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
15437
15461
|
)
|
|
15438
15462
|
);
|
|
15439
15463
|
console.error(
|
|
15440
|
-
|
|
15464
|
+
chalk9.gray(" Example: my-project, user-workspace, code-artifact")
|
|
15441
15465
|
);
|
|
15442
15466
|
process.exit(1);
|
|
15443
15467
|
}
|
|
15444
15468
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
15445
|
-
console.log(
|
|
15469
|
+
console.log(chalk9.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
15446
15470
|
console.log(
|
|
15447
|
-
|
|
15471
|
+
chalk9.gray(
|
|
15448
15472
|
`\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
15449
15473
|
)
|
|
15450
15474
|
);
|
|
15451
15475
|
} catch (error43) {
|
|
15452
|
-
console.error(
|
|
15476
|
+
console.error(chalk9.red("\u2717 Failed to initialize artifact"));
|
|
15453
15477
|
if (error43 instanceof Error) {
|
|
15454
|
-
console.error(
|
|
15478
|
+
console.error(chalk9.gray(` ${error43.message}`));
|
|
15455
15479
|
}
|
|
15456
15480
|
process.exit(1);
|
|
15457
15481
|
}
|
|
@@ -15459,7 +15483,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
|
|
|
15459
15483
|
|
|
15460
15484
|
// src/commands/artifact/push.ts
|
|
15461
15485
|
import { Command as Command8 } from "commander";
|
|
15462
|
-
import
|
|
15486
|
+
import chalk10 from "chalk";
|
|
15463
15487
|
import path10 from "path";
|
|
15464
15488
|
import * as fs7 from "fs";
|
|
15465
15489
|
import * as os5 from "os";
|
|
@@ -15497,21 +15521,21 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
15497
15521
|
const cwd = process.cwd();
|
|
15498
15522
|
const config2 = await readStorageConfig(cwd);
|
|
15499
15523
|
if (!config2) {
|
|
15500
|
-
console.error(
|
|
15501
|
-
console.error(
|
|
15524
|
+
console.error(chalk10.red("\u2717 No artifact initialized in this directory"));
|
|
15525
|
+
console.error(chalk10.gray(" Run: vm0 artifact init"));
|
|
15502
15526
|
process.exit(1);
|
|
15503
15527
|
}
|
|
15504
15528
|
if (config2.type !== "artifact") {
|
|
15505
15529
|
console.error(
|
|
15506
|
-
|
|
15530
|
+
chalk10.red(
|
|
15507
15531
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15508
15532
|
)
|
|
15509
15533
|
);
|
|
15510
|
-
console.error(
|
|
15534
|
+
console.error(chalk10.gray(" Use: vm0 volume push"));
|
|
15511
15535
|
process.exit(1);
|
|
15512
15536
|
}
|
|
15513
|
-
console.log(
|
|
15514
|
-
console.log(
|
|
15537
|
+
console.log(chalk10.cyan(`Pushing artifact: ${config2.name}`));
|
|
15538
|
+
console.log(chalk10.gray("Collecting files..."));
|
|
15515
15539
|
const files = await getAllFiles2(cwd);
|
|
15516
15540
|
let totalSize = 0;
|
|
15517
15541
|
for (const file2 of files) {
|
|
@@ -15519,13 +15543,13 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
15519
15543
|
totalSize += stats.size;
|
|
15520
15544
|
}
|
|
15521
15545
|
if (files.length === 0) {
|
|
15522
|
-
console.log(
|
|
15546
|
+
console.log(chalk10.gray("No files found (empty artifact)"));
|
|
15523
15547
|
} else {
|
|
15524
15548
|
console.log(
|
|
15525
|
-
|
|
15549
|
+
chalk10.gray(`Found ${files.length} files (${formatBytes3(totalSize)})`)
|
|
15526
15550
|
);
|
|
15527
15551
|
}
|
|
15528
|
-
console.log(
|
|
15552
|
+
console.log(chalk10.gray("Compressing files..."));
|
|
15529
15553
|
const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
|
|
15530
15554
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
15531
15555
|
const relativePaths = files.map((file2) => path10.relative(cwd, file2));
|
|
@@ -15553,9 +15577,9 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
15553
15577
|
await fs7.promises.unlink(tarPath);
|
|
15554
15578
|
await fs7.promises.rmdir(tmpDir);
|
|
15555
15579
|
console.log(
|
|
15556
|
-
|
|
15580
|
+
chalk10.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
|
|
15557
15581
|
);
|
|
15558
|
-
console.log(
|
|
15582
|
+
console.log(chalk10.gray("Uploading..."));
|
|
15559
15583
|
const formData = new FormData();
|
|
15560
15584
|
formData.append("name", config2.name);
|
|
15561
15585
|
formData.append("type", "artifact");
|
|
@@ -15577,17 +15601,17 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
15577
15601
|
const result = await response.json();
|
|
15578
15602
|
const shortVersion = result.versionId.slice(0, 8);
|
|
15579
15603
|
if (result.deduplicated) {
|
|
15580
|
-
console.log(
|
|
15604
|
+
console.log(chalk10.green("\u2713 Content unchanged (deduplicated)"));
|
|
15581
15605
|
} else {
|
|
15582
|
-
console.log(
|
|
15606
|
+
console.log(chalk10.green("\u2713 Upload complete"));
|
|
15583
15607
|
}
|
|
15584
|
-
console.log(
|
|
15585
|
-
console.log(
|
|
15586
|
-
console.log(
|
|
15608
|
+
console.log(chalk10.gray(` Version: ${shortVersion}`));
|
|
15609
|
+
console.log(chalk10.gray(` Files: ${result.fileCount.toLocaleString()}`));
|
|
15610
|
+
console.log(chalk10.gray(` Size: ${formatBytes3(result.size)}`));
|
|
15587
15611
|
} catch (error43) {
|
|
15588
|
-
console.error(
|
|
15612
|
+
console.error(chalk10.red("\u2717 Push failed"));
|
|
15589
15613
|
if (error43 instanceof Error) {
|
|
15590
|
-
console.error(
|
|
15614
|
+
console.error(chalk10.gray(` ${error43.message}`));
|
|
15591
15615
|
}
|
|
15592
15616
|
process.exit(1);
|
|
15593
15617
|
}
|
|
@@ -15595,7 +15619,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
|
|
|
15595
15619
|
|
|
15596
15620
|
// src/commands/artifact/pull.ts
|
|
15597
15621
|
import { Command as Command9 } from "commander";
|
|
15598
|
-
import
|
|
15622
|
+
import chalk11 from "chalk";
|
|
15599
15623
|
import path11 from "path";
|
|
15600
15624
|
import * as fs8 from "fs";
|
|
15601
15625
|
import * as os6 from "os";
|
|
@@ -15612,29 +15636,29 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
15612
15636
|
const cwd = process.cwd();
|
|
15613
15637
|
const config2 = await readStorageConfig(cwd);
|
|
15614
15638
|
if (!config2) {
|
|
15615
|
-
console.error(
|
|
15616
|
-
console.error(
|
|
15639
|
+
console.error(chalk11.red("\u2717 No artifact initialized in this directory"));
|
|
15640
|
+
console.error(chalk11.gray(" Run: vm0 artifact init"));
|
|
15617
15641
|
process.exit(1);
|
|
15618
15642
|
}
|
|
15619
15643
|
if (config2.type !== "artifact") {
|
|
15620
15644
|
console.error(
|
|
15621
|
-
|
|
15645
|
+
chalk11.red(
|
|
15622
15646
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
15623
15647
|
)
|
|
15624
15648
|
);
|
|
15625
|
-
console.error(
|
|
15649
|
+
console.error(chalk11.gray(" Use: vm0 volume pull"));
|
|
15626
15650
|
process.exit(1);
|
|
15627
15651
|
}
|
|
15628
15652
|
if (versionId) {
|
|
15629
15653
|
console.log(
|
|
15630
|
-
|
|
15654
|
+
chalk11.cyan(
|
|
15631
15655
|
`Pulling artifact: ${config2.name} (version: ${versionId})`
|
|
15632
15656
|
)
|
|
15633
15657
|
);
|
|
15634
15658
|
} else {
|
|
15635
|
-
console.log(
|
|
15659
|
+
console.log(chalk11.cyan(`Pulling artifact: ${config2.name}`));
|
|
15636
15660
|
}
|
|
15637
|
-
console.log(
|
|
15661
|
+
console.log(chalk11.gray("Downloading..."));
|
|
15638
15662
|
let url2 = `/api/storages?name=${encodeURIComponent(config2.name)}&type=artifact`;
|
|
15639
15663
|
if (versionId) {
|
|
15640
15664
|
url2 += `&version=${encodeURIComponent(versionId)}`;
|
|
@@ -15642,14 +15666,14 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
15642
15666
|
const response = await apiClient.get(url2);
|
|
15643
15667
|
if (!response.ok) {
|
|
15644
15668
|
if (response.status === 404) {
|
|
15645
|
-
console.error(
|
|
15669
|
+
console.error(chalk11.red(`\u2717 Artifact "${config2.name}" not found`));
|
|
15646
15670
|
console.error(
|
|
15647
|
-
|
|
15671
|
+
chalk11.gray(
|
|
15648
15672
|
" Make sure the artifact name is correct in .vm0/storage.yaml"
|
|
15649
15673
|
)
|
|
15650
15674
|
);
|
|
15651
15675
|
console.error(
|
|
15652
|
-
|
|
15676
|
+
chalk11.gray(" Or push the artifact first with: vm0 artifact push")
|
|
15653
15677
|
);
|
|
15654
15678
|
} else {
|
|
15655
15679
|
const error43 = await response.json();
|
|
@@ -15657,13 +15681,17 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
15657
15681
|
}
|
|
15658
15682
|
process.exit(1);
|
|
15659
15683
|
}
|
|
15684
|
+
if (response.status === 204) {
|
|
15685
|
+
await handleEmptyStorageResponse(cwd);
|
|
15686
|
+
return;
|
|
15687
|
+
}
|
|
15660
15688
|
const arrayBuffer = await response.arrayBuffer();
|
|
15661
15689
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
15662
|
-
console.log(
|
|
15690
|
+
console.log(chalk11.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
|
|
15663
15691
|
const tmpDir = fs8.mkdtempSync(path11.join(os6.tmpdir(), "vm0-"));
|
|
15664
15692
|
const tarPath = path11.join(tmpDir, "artifact.tar.gz");
|
|
15665
15693
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
15666
|
-
console.log(
|
|
15694
|
+
console.log(chalk11.gray("Syncing local files..."));
|
|
15667
15695
|
const remoteFiles = await listTarFiles(tarPath);
|
|
15668
15696
|
const remoteFilesSet = new Set(
|
|
15669
15697
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -15671,10 +15699,10 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
15671
15699
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
15672
15700
|
if (removedCount > 0) {
|
|
15673
15701
|
console.log(
|
|
15674
|
-
|
|
15702
|
+
chalk11.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
15675
15703
|
);
|
|
15676
15704
|
}
|
|
15677
|
-
console.log(
|
|
15705
|
+
console.log(chalk11.gray("Extracting files..."));
|
|
15678
15706
|
await tar6.extract({
|
|
15679
15707
|
file: tarPath,
|
|
15680
15708
|
cwd,
|
|
@@ -15682,11 +15710,11 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
15682
15710
|
});
|
|
15683
15711
|
await fs8.promises.unlink(tarPath);
|
|
15684
15712
|
await fs8.promises.rmdir(tmpDir);
|
|
15685
|
-
console.log(
|
|
15713
|
+
console.log(chalk11.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
15686
15714
|
} catch (error43) {
|
|
15687
|
-
console.error(
|
|
15715
|
+
console.error(chalk11.red("\u2717 Pull failed"));
|
|
15688
15716
|
if (error43 instanceof Error) {
|
|
15689
|
-
console.error(
|
|
15717
|
+
console.error(chalk11.gray(` ${error43.message}`));
|
|
15690
15718
|
}
|
|
15691
15719
|
process.exit(1);
|
|
15692
15720
|
}
|
|
@@ -15697,12 +15725,13 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
|
|
|
15697
15725
|
|
|
15698
15726
|
// src/commands/cook.ts
|
|
15699
15727
|
import { Command as Command11 } from "commander";
|
|
15700
|
-
import
|
|
15701
|
-
import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
|
|
15702
|
-
import { existsSync as existsSync5 } from "fs";
|
|
15728
|
+
import chalk12 from "chalk";
|
|
15729
|
+
import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
15730
|
+
import { existsSync as existsSync5, readFileSync } from "fs";
|
|
15703
15731
|
import path12 from "path";
|
|
15704
15732
|
import { spawn } from "child_process";
|
|
15705
15733
|
import { parse as parseYaml3 } from "yaml";
|
|
15734
|
+
import { config as dotenvConfig2 } from "dotenv";
|
|
15706
15735
|
var CONFIG_FILE3 = "vm0.yaml";
|
|
15707
15736
|
var ARTIFACT_DIR = "artifact";
|
|
15708
15737
|
function execVm0Command(args, options = {}) {
|
|
@@ -15780,11 +15809,49 @@ function parseArtifactVersionFromCompletion(output, artifactName) {
|
|
|
15780
15809
|
function escapeRegExp(str) {
|
|
15781
15810
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15782
15811
|
}
|
|
15812
|
+
function extractRequiredVarNames(config2) {
|
|
15813
|
+
const refs = extractVariableReferences(config2);
|
|
15814
|
+
const grouped = groupVariablesBySource(refs);
|
|
15815
|
+
const varNames = grouped.vars.map((r) => r.name);
|
|
15816
|
+
const secretNames = grouped.secrets.map((r) => r.name);
|
|
15817
|
+
return [.../* @__PURE__ */ new Set([...varNames, ...secretNames])];
|
|
15818
|
+
}
|
|
15819
|
+
function checkMissingVariables(varNames, envFilePath) {
|
|
15820
|
+
let dotenvValues = {};
|
|
15821
|
+
if (existsSync5(envFilePath)) {
|
|
15822
|
+
const result = dotenvConfig2({ path: envFilePath });
|
|
15823
|
+
if (result.parsed) {
|
|
15824
|
+
dotenvValues = result.parsed;
|
|
15825
|
+
}
|
|
15826
|
+
}
|
|
15827
|
+
const missing = [];
|
|
15828
|
+
for (const name of varNames) {
|
|
15829
|
+
const inEnv = process.env[name] !== void 0;
|
|
15830
|
+
const inDotenv = dotenvValues[name] !== void 0;
|
|
15831
|
+
if (!inEnv && !inDotenv) {
|
|
15832
|
+
missing.push(name);
|
|
15833
|
+
}
|
|
15834
|
+
}
|
|
15835
|
+
return missing;
|
|
15836
|
+
}
|
|
15837
|
+
async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
15838
|
+
const placeholders = missingVars.map((name) => `${name}=`).join("\n");
|
|
15839
|
+
if (existsSync5(envFilePath)) {
|
|
15840
|
+
const existingContent = readFileSync(envFilePath, "utf8");
|
|
15841
|
+
const needsNewline = existingContent.length > 0 && !existingContent.endsWith("\n");
|
|
15842
|
+
const prefix = needsNewline ? "\n" : "";
|
|
15843
|
+
await appendFile(envFilePath, `${prefix}${placeholders}
|
|
15844
|
+
`);
|
|
15845
|
+
} else {
|
|
15846
|
+
await writeFile5(envFilePath, `${placeholders}
|
|
15847
|
+
`);
|
|
15848
|
+
}
|
|
15849
|
+
}
|
|
15783
15850
|
var cookCommand = new Command11().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
15784
15851
|
const cwd = process.cwd();
|
|
15785
|
-
console.log(
|
|
15852
|
+
console.log(chalk12.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
15786
15853
|
if (!existsSync5(CONFIG_FILE3)) {
|
|
15787
|
-
console.error(
|
|
15854
|
+
console.error(chalk12.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
15788
15855
|
process.exit(1);
|
|
15789
15856
|
}
|
|
15790
15857
|
let config2;
|
|
@@ -15792,32 +15859,50 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15792
15859
|
const content = await readFile5(CONFIG_FILE3, "utf8");
|
|
15793
15860
|
config2 = parseYaml3(content);
|
|
15794
15861
|
} catch (error43) {
|
|
15795
|
-
console.error(
|
|
15862
|
+
console.error(chalk12.red("\u2717 Invalid YAML format"));
|
|
15796
15863
|
if (error43 instanceof Error) {
|
|
15797
|
-
console.error(
|
|
15864
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15798
15865
|
}
|
|
15799
15866
|
process.exit(1);
|
|
15800
15867
|
}
|
|
15801
15868
|
const validation = validateAgentCompose(config2);
|
|
15802
15869
|
if (!validation.valid) {
|
|
15803
|
-
console.error(
|
|
15870
|
+
console.error(chalk12.red(`\u2717 ${validation.error}`));
|
|
15804
15871
|
process.exit(1);
|
|
15805
15872
|
}
|
|
15806
15873
|
const agentNames = Object.keys(config2.agents);
|
|
15807
15874
|
const agentName = agentNames[0];
|
|
15808
15875
|
const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
|
|
15809
15876
|
console.log(
|
|
15810
|
-
|
|
15877
|
+
chalk12.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
15811
15878
|
);
|
|
15879
|
+
const requiredVarNames = extractRequiredVarNames(config2);
|
|
15880
|
+
if (requiredVarNames.length > 0) {
|
|
15881
|
+
const envFilePath = path12.join(cwd, ".env");
|
|
15882
|
+
const missingVars = checkMissingVariables(requiredVarNames, envFilePath);
|
|
15883
|
+
if (missingVars.length > 0) {
|
|
15884
|
+
await generateEnvPlaceholders(missingVars, envFilePath);
|
|
15885
|
+
console.log();
|
|
15886
|
+
console.log(
|
|
15887
|
+
chalk12.yellow(
|
|
15888
|
+
`\u26A0 Missing environment variables. Please fill in values in .env file:`
|
|
15889
|
+
)
|
|
15890
|
+
);
|
|
15891
|
+
for (const varName of missingVars) {
|
|
15892
|
+
console.log(chalk12.yellow(` ${varName}`));
|
|
15893
|
+
}
|
|
15894
|
+
process.exit(1);
|
|
15895
|
+
}
|
|
15896
|
+
}
|
|
15812
15897
|
if (config2.volumes && Object.keys(config2.volumes).length > 0) {
|
|
15813
15898
|
console.log();
|
|
15814
|
-
console.log(
|
|
15899
|
+
console.log(chalk12.blue("Processing volumes..."));
|
|
15815
15900
|
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
15816
15901
|
const volumeDir = path12.join(cwd, volumeConfig.name);
|
|
15817
|
-
console.log(
|
|
15902
|
+
console.log(chalk12.gray(` ${volumeConfig.name}/`));
|
|
15818
15903
|
if (!existsSync5(volumeDir)) {
|
|
15819
15904
|
console.error(
|
|
15820
|
-
|
|
15905
|
+
chalk12.red(
|
|
15821
15906
|
` \u2717 Directory not found. Create the directory and add files first.`
|
|
15822
15907
|
)
|
|
15823
15908
|
);
|
|
@@ -15830,30 +15915,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15830
15915
|
cwd: volumeDir,
|
|
15831
15916
|
silent: true
|
|
15832
15917
|
});
|
|
15833
|
-
console.log(
|
|
15918
|
+
console.log(chalk12.green(` \u2713 Initialized`));
|
|
15834
15919
|
}
|
|
15835
15920
|
await execVm0Command(["volume", "push"], {
|
|
15836
15921
|
cwd: volumeDir,
|
|
15837
15922
|
silent: true
|
|
15838
15923
|
});
|
|
15839
|
-
console.log(
|
|
15924
|
+
console.log(chalk12.green(` \u2713 Pushed`));
|
|
15840
15925
|
} catch (error43) {
|
|
15841
|
-
console.error(
|
|
15926
|
+
console.error(chalk12.red(` \u2717 Failed`));
|
|
15842
15927
|
if (error43 instanceof Error) {
|
|
15843
|
-
console.error(
|
|
15928
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15844
15929
|
}
|
|
15845
15930
|
process.exit(1);
|
|
15846
15931
|
}
|
|
15847
15932
|
}
|
|
15848
15933
|
}
|
|
15849
15934
|
console.log();
|
|
15850
|
-
console.log(
|
|
15935
|
+
console.log(chalk12.blue("Processing artifact..."));
|
|
15851
15936
|
const artifactDir = path12.join(cwd, ARTIFACT_DIR);
|
|
15852
|
-
console.log(
|
|
15937
|
+
console.log(chalk12.gray(` ${ARTIFACT_DIR}/`));
|
|
15853
15938
|
try {
|
|
15854
15939
|
if (!existsSync5(artifactDir)) {
|
|
15855
15940
|
await mkdir5(artifactDir, { recursive: true });
|
|
15856
|
-
console.log(
|
|
15941
|
+
console.log(chalk12.green(` \u2713 Created directory`));
|
|
15857
15942
|
}
|
|
15858
15943
|
const existingConfig = await readStorageConfig(artifactDir);
|
|
15859
15944
|
if (!existingConfig) {
|
|
@@ -15861,38 +15946,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15861
15946
|
cwd: artifactDir,
|
|
15862
15947
|
silent: true
|
|
15863
15948
|
});
|
|
15864
|
-
console.log(
|
|
15949
|
+
console.log(chalk12.green(` \u2713 Initialized`));
|
|
15865
15950
|
}
|
|
15866
15951
|
await execVm0Command(["artifact", "push"], {
|
|
15867
15952
|
cwd: artifactDir,
|
|
15868
15953
|
silent: true
|
|
15869
15954
|
});
|
|
15870
|
-
console.log(
|
|
15955
|
+
console.log(chalk12.green(` \u2713 Pushed`));
|
|
15871
15956
|
} catch (error43) {
|
|
15872
|
-
console.error(
|
|
15957
|
+
console.error(chalk12.red(` \u2717 Failed`));
|
|
15873
15958
|
if (error43 instanceof Error) {
|
|
15874
|
-
console.error(
|
|
15959
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15875
15960
|
}
|
|
15876
15961
|
process.exit(1);
|
|
15877
15962
|
}
|
|
15878
15963
|
console.log();
|
|
15879
|
-
console.log(
|
|
15964
|
+
console.log(chalk12.blue("Uploading compose..."));
|
|
15880
15965
|
try {
|
|
15881
15966
|
await execVm0Command(["compose", CONFIG_FILE3], {
|
|
15882
15967
|
cwd,
|
|
15883
15968
|
silent: true
|
|
15884
15969
|
});
|
|
15885
|
-
console.log(
|
|
15970
|
+
console.log(chalk12.green(`\u2713 Compose uploaded: ${agentName}`));
|
|
15886
15971
|
} catch (error43) {
|
|
15887
|
-
console.error(
|
|
15972
|
+
console.error(chalk12.red(`\u2717 Compose failed`));
|
|
15888
15973
|
if (error43 instanceof Error) {
|
|
15889
|
-
console.error(
|
|
15974
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15890
15975
|
}
|
|
15891
15976
|
process.exit(1);
|
|
15892
15977
|
}
|
|
15893
15978
|
if (prompt) {
|
|
15894
15979
|
console.log();
|
|
15895
|
-
console.log(
|
|
15980
|
+
console.log(chalk12.blue(`Running agent: ${agentName}`));
|
|
15896
15981
|
console.log();
|
|
15897
15982
|
let runOutput;
|
|
15898
15983
|
try {
|
|
@@ -15913,17 +15998,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15913
15998
|
);
|
|
15914
15999
|
if (serverVersion) {
|
|
15915
16000
|
console.log();
|
|
15916
|
-
console.log(
|
|
16001
|
+
console.log(chalk12.blue("Pulling updated artifact..."));
|
|
15917
16002
|
try {
|
|
15918
16003
|
await execVm0Command(["artifact", "pull"], {
|
|
15919
16004
|
cwd: artifactDir,
|
|
15920
16005
|
silent: true
|
|
15921
16006
|
});
|
|
15922
|
-
console.log(
|
|
16007
|
+
console.log(chalk12.green(`\u2713 Artifact pulled (${serverVersion})`));
|
|
15923
16008
|
} catch (error43) {
|
|
15924
|
-
console.error(
|
|
16009
|
+
console.error(chalk12.red(`\u2717 Artifact pull failed`));
|
|
15925
16010
|
if (error43 instanceof Error) {
|
|
15926
|
-
console.error(
|
|
16011
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
15927
16012
|
}
|
|
15928
16013
|
}
|
|
15929
16014
|
}
|
|
@@ -15931,7 +16016,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15931
16016
|
console.log();
|
|
15932
16017
|
console.log(" Run your agent:");
|
|
15933
16018
|
console.log(
|
|
15934
|
-
|
|
16019
|
+
chalk12.cyan(
|
|
15935
16020
|
` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
|
|
15936
16021
|
)
|
|
15937
16022
|
);
|
|
@@ -15943,7 +16028,7 @@ import { Command as Command15 } from "commander";
|
|
|
15943
16028
|
|
|
15944
16029
|
// src/commands/image/build.ts
|
|
15945
16030
|
import { Command as Command12 } from "commander";
|
|
15946
|
-
import
|
|
16031
|
+
import chalk13 from "chalk";
|
|
15947
16032
|
import { readFile as readFile6 } from "fs/promises";
|
|
15948
16033
|
import { existsSync as existsSync6 } from "fs";
|
|
15949
16034
|
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
@@ -15951,13 +16036,13 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15951
16036
|
async (options) => {
|
|
15952
16037
|
const { file: file2, name, deleteExisting } = options;
|
|
15953
16038
|
if (!existsSync6(file2)) {
|
|
15954
|
-
console.error(
|
|
16039
|
+
console.error(chalk13.red(`\u2717 Dockerfile not found: ${file2}`));
|
|
15955
16040
|
process.exit(1);
|
|
15956
16041
|
}
|
|
15957
16042
|
const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
|
|
15958
16043
|
if (!nameRegex.test(name)) {
|
|
15959
16044
|
console.error(
|
|
15960
|
-
|
|
16045
|
+
chalk13.red(
|
|
15961
16046
|
"\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
|
|
15962
16047
|
)
|
|
15963
16048
|
);
|
|
@@ -15965,7 +16050,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15965
16050
|
}
|
|
15966
16051
|
if (name.startsWith("vm0-")) {
|
|
15967
16052
|
console.error(
|
|
15968
|
-
|
|
16053
|
+
chalk13.red(
|
|
15969
16054
|
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
15970
16055
|
)
|
|
15971
16056
|
);
|
|
@@ -15973,8 +16058,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15973
16058
|
}
|
|
15974
16059
|
try {
|
|
15975
16060
|
const dockerfile = await readFile6(file2, "utf8");
|
|
15976
|
-
console.log(
|
|
15977
|
-
console.log(
|
|
16061
|
+
console.log(chalk13.blue(`Building image: ${name}`));
|
|
16062
|
+
console.log(chalk13.gray(` Dockerfile: ${file2}`));
|
|
15978
16063
|
console.log();
|
|
15979
16064
|
const buildInfo = await apiClient.createImage({
|
|
15980
16065
|
dockerfile,
|
|
@@ -15982,7 +16067,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15982
16067
|
deleteExisting
|
|
15983
16068
|
});
|
|
15984
16069
|
const { imageId, buildId } = buildInfo;
|
|
15985
|
-
console.log(
|
|
16070
|
+
console.log(chalk13.gray(` Build ID: ${buildId}`));
|
|
15986
16071
|
console.log();
|
|
15987
16072
|
let logsOffset = 0;
|
|
15988
16073
|
let status = "building";
|
|
@@ -15998,7 +16083,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15998
16083
|
}
|
|
15999
16084
|
const statusData = await statusResponse.json();
|
|
16000
16085
|
for (const log of statusData.logs) {
|
|
16001
|
-
console.log(
|
|
16086
|
+
console.log(chalk13.gray(` ${log}`));
|
|
16002
16087
|
}
|
|
16003
16088
|
logsOffset = statusData.logsOffset;
|
|
16004
16089
|
status = statusData.status;
|
|
@@ -16008,27 +16093,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16008
16093
|
}
|
|
16009
16094
|
console.log();
|
|
16010
16095
|
if (status === "ready") {
|
|
16011
|
-
console.log(
|
|
16096
|
+
console.log(chalk13.green(`\u2713 Image built: ${name}`));
|
|
16012
16097
|
console.log();
|
|
16013
16098
|
console.log("Use in vm0.yaml:");
|
|
16014
|
-
console.log(
|
|
16015
|
-
console.log(
|
|
16016
|
-
console.log(
|
|
16099
|
+
console.log(chalk13.cyan(` agents:`));
|
|
16100
|
+
console.log(chalk13.cyan(` your-agent:`));
|
|
16101
|
+
console.log(chalk13.cyan(` image: "${name}"`));
|
|
16017
16102
|
} else {
|
|
16018
|
-
console.error(
|
|
16103
|
+
console.error(chalk13.red(`\u2717 Build failed`));
|
|
16019
16104
|
process.exit(1);
|
|
16020
16105
|
}
|
|
16021
16106
|
} catch (error43) {
|
|
16022
16107
|
if (error43 instanceof Error) {
|
|
16023
16108
|
if (error43.message.includes("Not authenticated")) {
|
|
16024
16109
|
console.error(
|
|
16025
|
-
|
|
16110
|
+
chalk13.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
16026
16111
|
);
|
|
16027
16112
|
} else {
|
|
16028
|
-
console.error(
|
|
16113
|
+
console.error(chalk13.red(`\u2717 ${error43.message}`));
|
|
16029
16114
|
}
|
|
16030
16115
|
} else {
|
|
16031
|
-
console.error(
|
|
16116
|
+
console.error(chalk13.red("\u2717 An unexpected error occurred"));
|
|
16032
16117
|
}
|
|
16033
16118
|
process.exit(1);
|
|
16034
16119
|
}
|
|
@@ -16037,7 +16122,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16037
16122
|
|
|
16038
16123
|
// src/commands/image/list.ts
|
|
16039
16124
|
import { Command as Command13 } from "commander";
|
|
16040
|
-
import
|
|
16125
|
+
import chalk14 from "chalk";
|
|
16041
16126
|
var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
|
|
16042
16127
|
try {
|
|
16043
16128
|
const response = await apiClient.get("/api/images");
|
|
@@ -16050,43 +16135,43 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
|
|
|
16050
16135
|
const data = await response.json();
|
|
16051
16136
|
const { images } = data;
|
|
16052
16137
|
if (images.length === 0) {
|
|
16053
|
-
console.log(
|
|
16138
|
+
console.log(chalk14.gray("No images found."));
|
|
16054
16139
|
console.log();
|
|
16055
16140
|
console.log("Build your first image:");
|
|
16056
16141
|
console.log(
|
|
16057
|
-
|
|
16142
|
+
chalk14.cyan(" vm0 image build --file Dockerfile --name my-image")
|
|
16058
16143
|
);
|
|
16059
16144
|
return;
|
|
16060
16145
|
}
|
|
16061
|
-
console.log(
|
|
16146
|
+
console.log(chalk14.bold("Your images:"));
|
|
16062
16147
|
console.log();
|
|
16063
16148
|
console.log(
|
|
16064
|
-
|
|
16149
|
+
chalk14.gray(
|
|
16065
16150
|
`${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
|
|
16066
16151
|
)
|
|
16067
16152
|
);
|
|
16068
|
-
console.log(
|
|
16153
|
+
console.log(chalk14.gray("-".repeat(62)));
|
|
16069
16154
|
for (const image of images) {
|
|
16070
|
-
const statusColor = image.status === "ready" ?
|
|
16155
|
+
const statusColor = image.status === "ready" ? chalk14.green : image.status === "building" ? chalk14.yellow : chalk14.red;
|
|
16071
16156
|
const createdAt = new Date(image.createdAt).toLocaleString();
|
|
16072
16157
|
console.log(
|
|
16073
16158
|
`${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
|
|
16074
16159
|
);
|
|
16075
16160
|
if (image.status === "error" && image.errorMessage) {
|
|
16076
|
-
console.log(
|
|
16161
|
+
console.log(chalk14.red(` Error: ${image.errorMessage}`));
|
|
16077
16162
|
}
|
|
16078
16163
|
}
|
|
16079
16164
|
console.log();
|
|
16080
|
-
console.log(
|
|
16165
|
+
console.log(chalk14.gray(`Total: ${images.length} image(s)`));
|
|
16081
16166
|
} catch (error43) {
|
|
16082
16167
|
if (error43 instanceof Error) {
|
|
16083
16168
|
if (error43.message.includes("Not authenticated")) {
|
|
16084
|
-
console.error(
|
|
16169
|
+
console.error(chalk14.red("Not authenticated. Run: vm0 auth login"));
|
|
16085
16170
|
} else {
|
|
16086
|
-
console.error(
|
|
16171
|
+
console.error(chalk14.red(`Error: ${error43.message}`));
|
|
16087
16172
|
}
|
|
16088
16173
|
} else {
|
|
16089
|
-
console.error(
|
|
16174
|
+
console.error(chalk14.red("An unexpected error occurred"));
|
|
16090
16175
|
}
|
|
16091
16176
|
process.exit(1);
|
|
16092
16177
|
}
|
|
@@ -16094,7 +16179,7 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
|
|
|
16094
16179
|
|
|
16095
16180
|
// src/commands/image/delete.ts
|
|
16096
16181
|
import { Command as Command14 } from "commander";
|
|
16097
|
-
import
|
|
16182
|
+
import chalk15 from "chalk";
|
|
16098
16183
|
import * as readline from "readline";
|
|
16099
16184
|
var deleteCommand = new Command14().name("delete").alias("rm").description("Delete a custom image").argument("<name>", "Name of the image to delete").option("-f, --force", "Skip confirmation prompt").action(async (name, options) => {
|
|
16100
16185
|
try {
|
|
@@ -16108,7 +16193,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16108
16193
|
const data = await listResponse.json();
|
|
16109
16194
|
const image = data.images.find((img) => img.alias === name);
|
|
16110
16195
|
if (!image) {
|
|
16111
|
-
console.error(
|
|
16196
|
+
console.error(chalk15.red(`Image not found: ${name}`));
|
|
16112
16197
|
process.exit(1);
|
|
16113
16198
|
}
|
|
16114
16199
|
if (!options.force) {
|
|
@@ -16118,7 +16203,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16118
16203
|
});
|
|
16119
16204
|
const answer = await new Promise((resolve2) => {
|
|
16120
16205
|
rl.question(
|
|
16121
|
-
|
|
16206
|
+
chalk15.yellow(`Delete image "${name}"? [y/N] `),
|
|
16122
16207
|
(answer2) => {
|
|
16123
16208
|
rl.close();
|
|
16124
16209
|
resolve2(answer2);
|
|
@@ -16126,7 +16211,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16126
16211
|
);
|
|
16127
16212
|
});
|
|
16128
16213
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
16129
|
-
console.log(
|
|
16214
|
+
console.log(chalk15.gray("Cancelled."));
|
|
16130
16215
|
return;
|
|
16131
16216
|
}
|
|
16132
16217
|
}
|
|
@@ -16137,16 +16222,16 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16137
16222
|
error43.error?.message || "Failed to delete image"
|
|
16138
16223
|
);
|
|
16139
16224
|
}
|
|
16140
|
-
console.log(
|
|
16225
|
+
console.log(chalk15.green(`Deleted image: ${name}`));
|
|
16141
16226
|
} catch (error43) {
|
|
16142
16227
|
if (error43 instanceof Error) {
|
|
16143
16228
|
if (error43.message.includes("Not authenticated")) {
|
|
16144
|
-
console.error(
|
|
16229
|
+
console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
|
|
16145
16230
|
} else {
|
|
16146
|
-
console.error(
|
|
16231
|
+
console.error(chalk15.red(`Error: ${error43.message}`));
|
|
16147
16232
|
}
|
|
16148
16233
|
} else {
|
|
16149
|
-
console.error(
|
|
16234
|
+
console.error(chalk15.red("An unexpected error occurred"));
|
|
16150
16235
|
}
|
|
16151
16236
|
process.exit(1);
|
|
16152
16237
|
}
|
|
@@ -16157,7 +16242,7 @@ var imageCommand = new Command15().name("image").description("Manage custom imag
|
|
|
16157
16242
|
|
|
16158
16243
|
// src/commands/logs/index.ts
|
|
16159
16244
|
import { Command as Command16 } from "commander";
|
|
16160
|
-
import
|
|
16245
|
+
import chalk16 from "chalk";
|
|
16161
16246
|
|
|
16162
16247
|
// src/lib/time-parser.ts
|
|
16163
16248
|
function parseTime(timeStr) {
|
|
@@ -16219,23 +16304,23 @@ function formatMetric(metric) {
|
|
|
16219
16304
|
function formatNetworkLog(entry) {
|
|
16220
16305
|
let statusColor;
|
|
16221
16306
|
if (entry.status >= 200 && entry.status < 300) {
|
|
16222
|
-
statusColor =
|
|
16307
|
+
statusColor = chalk16.green;
|
|
16223
16308
|
} else if (entry.status >= 300 && entry.status < 400) {
|
|
16224
|
-
statusColor =
|
|
16309
|
+
statusColor = chalk16.yellow;
|
|
16225
16310
|
} else if (entry.status >= 400) {
|
|
16226
|
-
statusColor =
|
|
16311
|
+
statusColor = chalk16.red;
|
|
16227
16312
|
} else {
|
|
16228
|
-
statusColor =
|
|
16313
|
+
statusColor = chalk16.gray;
|
|
16229
16314
|
}
|
|
16230
16315
|
let latencyColor;
|
|
16231
16316
|
if (entry.latency_ms < 500) {
|
|
16232
|
-
latencyColor =
|
|
16317
|
+
latencyColor = chalk16.green;
|
|
16233
16318
|
} else if (entry.latency_ms < 2e3) {
|
|
16234
|
-
latencyColor =
|
|
16319
|
+
latencyColor = chalk16.yellow;
|
|
16235
16320
|
} else {
|
|
16236
|
-
latencyColor =
|
|
16321
|
+
latencyColor = chalk16.red;
|
|
16237
16322
|
}
|
|
16238
|
-
return `[${entry.timestamp}] ${
|
|
16323
|
+
return `[${entry.timestamp}] ${chalk16.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk16.gray(entry.url)}`;
|
|
16239
16324
|
}
|
|
16240
16325
|
function renderAgentEvent(event) {
|
|
16241
16326
|
const parsed = ClaudeEventParser.parse(
|
|
@@ -16255,7 +16340,7 @@ function getLogType(options) {
|
|
|
16255
16340
|
].filter(Boolean).length;
|
|
16256
16341
|
if (selected > 1) {
|
|
16257
16342
|
console.error(
|
|
16258
|
-
|
|
16343
|
+
chalk16.red(
|
|
16259
16344
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
16260
16345
|
)
|
|
16261
16346
|
);
|
|
@@ -16308,7 +16393,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
|
|
|
16308
16393
|
async function showAgentEvents(runId, options) {
|
|
16309
16394
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
16310
16395
|
if (response.events.length === 0) {
|
|
16311
|
-
console.log(
|
|
16396
|
+
console.log(chalk16.yellow("No agent events found for this run."));
|
|
16312
16397
|
return;
|
|
16313
16398
|
}
|
|
16314
16399
|
for (const event of response.events) {
|
|
@@ -16317,7 +16402,7 @@ async function showAgentEvents(runId, options) {
|
|
|
16317
16402
|
if (response.hasMore) {
|
|
16318
16403
|
console.log();
|
|
16319
16404
|
console.log(
|
|
16320
|
-
|
|
16405
|
+
chalk16.gray(
|
|
16321
16406
|
`Showing ${response.events.length} events. Use --limit to see more.`
|
|
16322
16407
|
)
|
|
16323
16408
|
);
|
|
@@ -16326,21 +16411,21 @@ async function showAgentEvents(runId, options) {
|
|
|
16326
16411
|
async function showSystemLog(runId, options) {
|
|
16327
16412
|
const response = await apiClient.getSystemLog(runId, options);
|
|
16328
16413
|
if (!response.systemLog) {
|
|
16329
|
-
console.log(
|
|
16414
|
+
console.log(chalk16.yellow("No system log found for this run."));
|
|
16330
16415
|
return;
|
|
16331
16416
|
}
|
|
16332
16417
|
console.log(response.systemLog);
|
|
16333
16418
|
if (response.hasMore) {
|
|
16334
16419
|
console.log();
|
|
16335
16420
|
console.log(
|
|
16336
|
-
|
|
16421
|
+
chalk16.gray("More log entries available. Use --limit to see more.")
|
|
16337
16422
|
);
|
|
16338
16423
|
}
|
|
16339
16424
|
}
|
|
16340
16425
|
async function showMetrics(runId, options) {
|
|
16341
16426
|
const response = await apiClient.getMetrics(runId, options);
|
|
16342
16427
|
if (response.metrics.length === 0) {
|
|
16343
|
-
console.log(
|
|
16428
|
+
console.log(chalk16.yellow("No metrics found for this run."));
|
|
16344
16429
|
return;
|
|
16345
16430
|
}
|
|
16346
16431
|
for (const metric of response.metrics) {
|
|
@@ -16349,7 +16434,7 @@ async function showMetrics(runId, options) {
|
|
|
16349
16434
|
if (response.hasMore) {
|
|
16350
16435
|
console.log();
|
|
16351
16436
|
console.log(
|
|
16352
|
-
|
|
16437
|
+
chalk16.gray(
|
|
16353
16438
|
`Showing ${response.metrics.length} metrics. Use --limit to see more.`
|
|
16354
16439
|
)
|
|
16355
16440
|
);
|
|
@@ -16359,7 +16444,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
16359
16444
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
16360
16445
|
if (response.networkLogs.length === 0) {
|
|
16361
16446
|
console.log(
|
|
16362
|
-
|
|
16447
|
+
chalk16.yellow(
|
|
16363
16448
|
"No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
|
|
16364
16449
|
)
|
|
16365
16450
|
);
|
|
@@ -16371,7 +16456,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
16371
16456
|
if (response.hasMore) {
|
|
16372
16457
|
console.log();
|
|
16373
16458
|
console.log(
|
|
16374
|
-
|
|
16459
|
+
chalk16.gray(
|
|
16375
16460
|
`Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
|
|
16376
16461
|
)
|
|
16377
16462
|
);
|
|
@@ -16380,25 +16465,25 @@ async function showNetworkLogs(runId, options) {
|
|
|
16380
16465
|
function handleError(error43, runId) {
|
|
16381
16466
|
if (error43 instanceof Error) {
|
|
16382
16467
|
if (error43.message.includes("Not authenticated")) {
|
|
16383
|
-
console.error(
|
|
16468
|
+
console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
|
|
16384
16469
|
} else if (error43.message.includes("not found")) {
|
|
16385
|
-
console.error(
|
|
16470
|
+
console.error(chalk16.red(`Run not found: ${runId}`));
|
|
16386
16471
|
} else if (error43.message.includes("Invalid time format")) {
|
|
16387
|
-
console.error(
|
|
16472
|
+
console.error(chalk16.red(error43.message));
|
|
16388
16473
|
} else {
|
|
16389
|
-
console.error(
|
|
16390
|
-
console.error(
|
|
16474
|
+
console.error(chalk16.red("Failed to fetch logs"));
|
|
16475
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16391
16476
|
}
|
|
16392
16477
|
} else {
|
|
16393
|
-
console.error(
|
|
16478
|
+
console.error(chalk16.red("An unexpected error occurred"));
|
|
16394
16479
|
}
|
|
16395
16480
|
}
|
|
16396
16481
|
|
|
16397
16482
|
// src/index.ts
|
|
16398
16483
|
var program = new Command17();
|
|
16399
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
16484
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.10.0");
|
|
16400
16485
|
program.command("info").description("Display environment information").action(async () => {
|
|
16401
|
-
console.log(
|
|
16486
|
+
console.log(chalk17.cyan("System Information:"));
|
|
16402
16487
|
console.log(`Node Version: ${process.version}`);
|
|
16403
16488
|
console.log(`Platform: ${process.platform}`);
|
|
16404
16489
|
console.log(`Architecture: ${process.arch}`);
|