@vm0/cli 9.3.0 → 9.4.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.
Files changed (2) hide show
  1. package/index.js +956 -1160
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command48 } from "commander";
5
- import chalk50 from "chalk";
4
+ import { Command as Command50 } from "commander";
5
+ import chalk53 from "chalk";
6
6
 
7
7
  // src/lib/api/auth.ts
8
8
  import chalk from "chalk";
@@ -354,7 +354,9 @@ var storedExecutionContextSchema = z3.object({
354
354
  cliAgentType: z3.string(),
355
355
  experimentalFirewall: experimentalFirewallSchema.optional(),
356
356
  // Debug flag to force real Claude in mock environments (internal use only)
357
- debugNoMockClaude: z3.boolean().optional()
357
+ debugNoMockClaude: z3.boolean().optional(),
358
+ // Dispatch timestamp for E2E timing metrics
359
+ apiStartTime: z3.number().optional()
358
360
  });
359
361
  var executionContextSchema = z3.object({
360
362
  runId: z3.string().uuid(),
@@ -374,7 +376,9 @@ var executionContextSchema = z3.object({
374
376
  // Experimental firewall configuration
375
377
  experimentalFirewall: experimentalFirewallSchema.optional(),
376
378
  // Debug flag to force real Claude in mock environments (internal use only)
377
- debugNoMockClaude: z3.boolean().optional()
379
+ debugNoMockClaude: z3.boolean().optional(),
380
+ // Dispatch timestamp for E2E timing metrics
381
+ apiStartTime: z3.number().optional()
378
382
  });
379
383
  var runnersJobClaimContract = c.router({
380
384
  claim: {
@@ -711,7 +715,36 @@ var eventsResponseSchema = z5.object({
711
715
  run: runStateSchema,
712
716
  framework: z5.string()
713
717
  });
718
+ var runListItemSchema = z5.object({
719
+ id: z5.string(),
720
+ agentName: z5.string(),
721
+ status: runStatusSchema,
722
+ prompt: z5.string(),
723
+ createdAt: z5.string(),
724
+ startedAt: z5.string().nullable()
725
+ });
726
+ var runsListResponseSchema = z5.object({
727
+ runs: z5.array(runListItemSchema)
728
+ });
714
729
  var runsMainContract = c3.router({
730
+ /**
731
+ * GET /api/agent/runs
732
+ * List agent runs (pending and running by default)
733
+ */
734
+ list: {
735
+ method: "GET",
736
+ path: "/api/agent/runs",
737
+ headers: authHeadersSchema,
738
+ query: z5.object({
739
+ status: runStatusSchema.optional(),
740
+ limit: z5.coerce.number().min(1).max(100).default(50)
741
+ }),
742
+ responses: {
743
+ 200: runsListResponseSchema,
744
+ 401: apiErrorSchema
745
+ },
746
+ summary: "List agent runs"
747
+ },
715
748
  /**
716
749
  * POST /api/agent/runs
717
750
  * Create and execute a new agent run
@@ -752,6 +785,33 @@ var runsByIdContract = c3.router({
752
785
  summary: "Get agent run by ID"
753
786
  }
754
787
  });
788
+ var cancelRunResponseSchema = z5.object({
789
+ id: z5.string(),
790
+ status: z5.literal("cancelled"),
791
+ message: z5.string()
792
+ });
793
+ var runsCancelContract = c3.router({
794
+ /**
795
+ * POST /api/agent/runs/:id/cancel
796
+ * Cancel a pending or running run
797
+ */
798
+ cancel: {
799
+ method: "POST",
800
+ path: "/api/agent/runs/:id/cancel",
801
+ headers: authHeadersSchema,
802
+ pathParams: z5.object({
803
+ id: z5.string().min(1, "Run ID is required")
804
+ }),
805
+ body: z5.undefined(),
806
+ responses: {
807
+ 200: cancelRunResponseSchema,
808
+ 400: apiErrorSchema,
809
+ 401: apiErrorSchema,
810
+ 404: apiErrorSchema
811
+ },
812
+ summary: "Cancel a pending or running run"
813
+ }
814
+ });
755
815
  var runEventsContract = c3.router({
756
816
  /**
757
817
  * GET /api/agent/runs/:id/events
@@ -3149,10 +3209,10 @@ async function getRawHeaders() {
3149
3209
  }
3150
3210
  return headers;
3151
3211
  }
3152
- async function httpGet(path16) {
3212
+ async function httpGet(path15) {
3153
3213
  const baseUrl = await getBaseUrl();
3154
3214
  const headers = await getRawHeaders();
3155
- return fetch(`${baseUrl}${path16}`, {
3215
+ return fetch(`${baseUrl}${path15}`, {
3156
3216
  method: "GET",
3157
3217
  headers
3158
3218
  });
@@ -3234,6 +3294,31 @@ async function getEvents(runId, options) {
3234
3294
  }
3235
3295
  handleError(result, "Failed to fetch events");
3236
3296
  }
3297
+ async function listRuns(params) {
3298
+ const config = await getClientConfig();
3299
+ const client = initClient2(runsMainContract, config);
3300
+ const result = await client.list({
3301
+ query: {
3302
+ status: params?.status,
3303
+ limit: params?.limit ?? 50
3304
+ }
3305
+ });
3306
+ if (result.status === 200) {
3307
+ return result.body;
3308
+ }
3309
+ handleError(result, "Failed to list runs");
3310
+ }
3311
+ async function cancelRun(runId) {
3312
+ const config = await getClientConfig();
3313
+ const client = initClient2(runsCancelContract, config);
3314
+ const result = await client.cancel({
3315
+ params: { id: runId }
3316
+ });
3317
+ if (result.status === 200) {
3318
+ return result.body;
3319
+ }
3320
+ handleError(result, "Failed to cancel run");
3321
+ }
3237
3322
 
3238
3323
  // src/lib/api/domains/sessions.ts
3239
3324
  import { initClient as initClient3 } from "@ts-rest/core";
@@ -3632,49 +3717,49 @@ var cliComposeSchema = z24.object({
3632
3717
  function formatZodError(error) {
3633
3718
  const issue = error.issues[0];
3634
3719
  if (!issue) return "Validation failed";
3635
- const path16 = issue.path.join(".");
3720
+ const path15 = issue.path.join(".");
3636
3721
  const message = issue.message;
3637
- if (!path16) return message;
3722
+ if (!path15) return message;
3638
3723
  if (issue.code === "invalid_type") {
3639
3724
  const received = issue.received;
3640
3725
  const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
3641
- if (path16 === "version" && isMissing) {
3726
+ if (path15 === "version" && isMissing) {
3642
3727
  return "Missing config.version";
3643
3728
  }
3644
- if (path16 === "agents" && isMissing) {
3729
+ if (path15 === "agents" && isMissing) {
3645
3730
  return "Missing agents object in config";
3646
3731
  }
3647
- if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
3648
- const volumeKey = path16.split(".")[1];
3732
+ if (path15.startsWith("volumes.") && path15.endsWith(".name")) {
3733
+ const volumeKey = path15.split(".")[1];
3649
3734
  return `Volume "${volumeKey}" must have a 'name' field (string)`;
3650
3735
  }
3651
- if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
3652
- const volumeKey = path16.split(".")[1];
3736
+ if (path15.startsWith("volumes.") && path15.endsWith(".version")) {
3737
+ const volumeKey = path15.split(".")[1];
3653
3738
  return `Volume "${volumeKey}" must have a 'version' field (string)`;
3654
3739
  }
3655
3740
  if (issue.expected === "array") {
3656
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
3741
+ const fieldName = path15.replace(/^agents\.[^.]+\./, "agent.");
3657
3742
  return `${fieldName} must be an array`;
3658
3743
  }
3659
3744
  if (issue.expected === "string" && received === "number") {
3660
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
3745
+ const fieldName = path15.replace(/^agents\.[^.]+\./, "agent.");
3661
3746
  const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
3662
3747
  if (match) {
3663
3748
  return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
3664
3749
  }
3665
3750
  }
3666
3751
  }
3667
- if (issue.code === "invalid_key" && path16.startsWith("agents.")) {
3752
+ if (issue.code === "invalid_key" && path15.startsWith("agents.")) {
3668
3753
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
3669
3754
  }
3670
- if (message === "Invalid key in record" && path16.startsWith("agents.")) {
3755
+ if (message === "Invalid key in record" && path15.startsWith("agents.")) {
3671
3756
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
3672
3757
  }
3673
3758
  if (issue.code === "custom") {
3674
3759
  return message;
3675
3760
  }
3676
- if (path16.startsWith("agents.")) {
3677
- const cleanPath = path16.replace(/^agents\.[^.]+\./, "agent.");
3761
+ if (path15.startsWith("agents.")) {
3762
+ const cleanPath = path15.replace(/^agents\.[^.]+\./, "agent.");
3678
3763
  if (message.startsWith("Invalid input:")) {
3679
3764
  const match = message.match(/expected (\w+), received (\w+)/);
3680
3765
  if (match && match[1] === "string" && match[2] === "number") {
@@ -3686,7 +3771,7 @@ function formatZodError(error) {
3686
3771
  }
3687
3772
  return `${cleanPath}: ${message}`;
3688
3773
  }
3689
- return `${path16}: ${message}`;
3774
+ return `${path15}: ${message}`;
3690
3775
  }
3691
3776
  function validateAgentName(name) {
3692
3777
  return cliAgentNameSchema.safeParse(name).success;
@@ -5862,7 +5947,7 @@ var ApiClient = class {
5862
5947
  /**
5863
5948
  * Generic GET request
5864
5949
  */
5865
- async get(path16) {
5950
+ async get(path15) {
5866
5951
  const baseUrl = await this.getBaseUrl();
5867
5952
  const token = await getToken();
5868
5953
  if (!token) {
@@ -5875,7 +5960,7 @@ var ApiClient = class {
5875
5960
  if (bypassSecret) {
5876
5961
  headers["x-vercel-protection-bypass"] = bypassSecret;
5877
5962
  }
5878
- return fetch(`${baseUrl}${path16}`, {
5963
+ return fetch(`${baseUrl}${path15}`, {
5879
5964
  method: "GET",
5880
5965
  headers
5881
5966
  });
@@ -5883,7 +5968,7 @@ var ApiClient = class {
5883
5968
  /**
5884
5969
  * Generic POST request
5885
5970
  */
5886
- async post(path16, options) {
5971
+ async post(path15, options) {
5887
5972
  const baseUrl = await this.getBaseUrl();
5888
5973
  const token = await getToken();
5889
5974
  if (!token) {
@@ -5899,7 +5984,7 @@ var ApiClient = class {
5899
5984
  if (bypassSecret) {
5900
5985
  headers["x-vercel-protection-bypass"] = bypassSecret;
5901
5986
  }
5902
- return fetch(`${baseUrl}${path16}`, {
5987
+ return fetch(`${baseUrl}${path15}`, {
5903
5988
  method: "POST",
5904
5989
  headers,
5905
5990
  body: options?.body
@@ -5908,7 +5993,7 @@ var ApiClient = class {
5908
5993
  /**
5909
5994
  * Generic DELETE request
5910
5995
  */
5911
- async delete(path16) {
5996
+ async delete(path15) {
5912
5997
  const baseUrl = await this.getBaseUrl();
5913
5998
  const token = await getToken();
5914
5999
  if (!token) {
@@ -5921,7 +6006,7 @@ var ApiClient = class {
5921
6006
  if (bypassSecret) {
5922
6007
  headers["x-vercel-protection-bypass"] = bypassSecret;
5923
6008
  }
5924
- return fetch(`${baseUrl}${path16}`, {
6009
+ return fetch(`${baseUrl}${path15}`, {
5925
6010
  method: "DELETE",
5926
6011
  headers
5927
6012
  });
@@ -6198,6 +6283,20 @@ function showNextSteps(result) {
6198
6283
  );
6199
6284
  }
6200
6285
  }
6286
+ function handleGenericRunError(error, commandLabel) {
6287
+ if (error instanceof ApiRequestError && error.code === "concurrent_run_limit_exceeded") {
6288
+ console.error(chalk5.red(`\u2717 ${commandLabel} failed`));
6289
+ console.error(chalk5.dim(` ${error.message}`));
6290
+ console.log();
6291
+ console.log(" To view active runs:");
6292
+ console.log(chalk5.cyan(" vm0 run list"));
6293
+ console.log(" To cancel a run:");
6294
+ console.log(chalk5.cyan(" vm0 run kill <run-id>"));
6295
+ } else {
6296
+ console.error(chalk5.red(`\u2717 ${commandLabel} failed`));
6297
+ console.error(chalk5.dim(` ${error.message}`));
6298
+ }
6299
+ }
6201
6300
 
6202
6301
  // src/commands/run/run.ts
6203
6302
  var mainRunCommand = new Command3().name("run").description("Run an agent").argument(
@@ -6328,8 +6427,7 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
6328
6427
  )
6329
6428
  );
6330
6429
  } else {
6331
- console.error(chalk6.red("\u2717 Run failed"));
6332
- console.error(chalk6.dim(` ${error.message}`));
6430
+ handleGenericRunError(error, "Run");
6333
6431
  }
6334
6432
  } else {
6335
6433
  console.error(chalk6.red("\u2717 An unexpected error occurred"));
@@ -6426,8 +6524,7 @@ var resumeCommand = new Command4().name("resume").description("Resume an agent r
6426
6524
  } else if (error.message.includes("not found")) {
6427
6525
  console.error(chalk7.red(`\u2717 Checkpoint not found: ${checkpointId}`));
6428
6526
  } else {
6429
- console.error(chalk7.red("\u2717 Resume failed"));
6430
- console.error(chalk7.dim(` ${error.message}`));
6527
+ handleGenericRunError(error, "Resume");
6431
6528
  }
6432
6529
  } else {
6433
6530
  console.error(chalk7.red("\u2717 An unexpected error occurred"));
@@ -6528,8 +6625,7 @@ var continueCommand = new Command5().name("continue").description(
6528
6625
  chalk8.red(`\u2717 Agent session not found: ${agentSessionId}`)
6529
6626
  );
6530
6627
  } else {
6531
- console.error(chalk8.red("\u2717 Continue failed"));
6532
- console.error(chalk8.dim(` ${error.message}`));
6628
+ handleGenericRunError(error, "Continue");
6533
6629
  }
6534
6630
  } else {
6535
6631
  console.error(chalk8.red("\u2717 An unexpected error occurred"));
@@ -6539,17 +6635,105 @@ var continueCommand = new Command5().name("continue").description(
6539
6635
  }
6540
6636
  );
6541
6637
 
6638
+ // src/commands/run/list.ts
6639
+ import { Command as Command6 } from "commander";
6640
+ import chalk9 from "chalk";
6641
+ var UUID_LENGTH = 36;
6642
+ function formatRunStatus(status, width) {
6643
+ const paddedStatus = width ? status.padEnd(width) : status;
6644
+ switch (status) {
6645
+ case "running":
6646
+ return chalk9.green(paddedStatus);
6647
+ case "pending":
6648
+ return chalk9.yellow(paddedStatus);
6649
+ case "completed":
6650
+ return chalk9.blue(paddedStatus);
6651
+ case "failed":
6652
+ case "timeout":
6653
+ return chalk9.red(paddedStatus);
6654
+ default:
6655
+ return paddedStatus;
6656
+ }
6657
+ }
6658
+ var listCommand = new Command6().name("list").alias("ls").description("List active runs (pending and running)").action(async () => {
6659
+ try {
6660
+ const response = await listRuns({ limit: 100 });
6661
+ const activeRuns = response.runs;
6662
+ if (activeRuns.length === 0) {
6663
+ console.log(chalk9.dim("No active runs"));
6664
+ return;
6665
+ }
6666
+ const agentWidth = Math.max(
6667
+ 5,
6668
+ ...activeRuns.map((r) => r.agentName.length)
6669
+ );
6670
+ const statusWidth = 7;
6671
+ const header = [
6672
+ "ID".padEnd(UUID_LENGTH),
6673
+ "AGENT".padEnd(agentWidth),
6674
+ "STATUS".padEnd(statusWidth),
6675
+ "CREATED"
6676
+ ].join(" ");
6677
+ console.log(chalk9.dim(header));
6678
+ for (const run of activeRuns) {
6679
+ const row = [
6680
+ run.id.padEnd(UUID_LENGTH),
6681
+ run.agentName.padEnd(agentWidth),
6682
+ formatRunStatus(run.status, statusWidth),
6683
+ formatRelativeTime(run.createdAt)
6684
+ ].join(" ");
6685
+ console.log(row);
6686
+ }
6687
+ } catch (error) {
6688
+ console.error(chalk9.red("\u2717 Failed to list runs"));
6689
+ if (error instanceof Error) {
6690
+ if (error.message.includes("Not authenticated")) {
6691
+ console.error(chalk9.dim(" Run: vm0 auth login"));
6692
+ } else {
6693
+ console.error(chalk9.dim(` ${error.message}`));
6694
+ }
6695
+ }
6696
+ process.exit(1);
6697
+ }
6698
+ });
6699
+
6700
+ // src/commands/run/kill.ts
6701
+ import { Command as Command7 } from "commander";
6702
+ import chalk10 from "chalk";
6703
+ var killCommand = new Command7().name("kill").description("Kill (cancel) a pending or running run").argument("<run-id>", "Run ID to kill").action(async (runId) => {
6704
+ try {
6705
+ await cancelRun(runId);
6706
+ console.log(chalk10.green(`\u2713 Run ${runId} cancelled`));
6707
+ } catch (error) {
6708
+ console.error(chalk10.red("\u2717 Failed to kill run"));
6709
+ if (error instanceof Error) {
6710
+ if (error.message.includes("Not authenticated")) {
6711
+ console.error(chalk10.dim(" Run: vm0 auth login"));
6712
+ } else if (error.message.includes("not found") || error.message.includes("No such run")) {
6713
+ console.error(chalk10.dim(` Run not found: ${runId}`));
6714
+ } else if (error.message.includes("cannot be cancelled")) {
6715
+ console.error(chalk10.dim(` ${error.message}`));
6716
+ } else {
6717
+ console.error(chalk10.dim(` ${error.message}`));
6718
+ }
6719
+ }
6720
+ process.exit(1);
6721
+ }
6722
+ });
6723
+
6542
6724
  // src/commands/run/index.ts
6543
6725
  mainRunCommand.addCommand(resumeCommand);
6544
6726
  mainRunCommand.addCommand(continueCommand);
6727
+ mainRunCommand.addCommand(listCommand);
6728
+ mainRunCommand.addCommand(killCommand);
6545
6729
  var runCommand = mainRunCommand;
6546
6730
 
6547
6731
  // src/commands/volume/index.ts
6548
- import { Command as Command12 } from "commander";
6732
+ import { Command as Command14 } from "commander";
6549
6733
 
6550
6734
  // src/commands/volume/init.ts
6551
- import { Command as Command6 } from "commander";
6552
- import chalk9 from "chalk";
6735
+ import { Command as Command8 } from "commander";
6736
+ import chalk11 from "chalk";
6553
6737
  import path6 from "path";
6554
6738
 
6555
6739
  // src/lib/storage/storage-utils.ts
@@ -6600,17 +6784,17 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type =
6600
6784
  }
6601
6785
 
6602
6786
  // src/commands/volume/init.ts
6603
- var initCommand = new Command6().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
6787
+ var initCommand = new Command8().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
6604
6788
  try {
6605
6789
  const cwd = process.cwd();
6606
6790
  const dirName = path6.basename(cwd);
6607
6791
  const existingConfig = await readStorageConfig(cwd);
6608
6792
  if (existingConfig) {
6609
6793
  console.log(
6610
- chalk9.yellow(`Volume already initialized: ${existingConfig.name}`)
6794
+ chalk11.yellow(`Volume already initialized: ${existingConfig.name}`)
6611
6795
  );
6612
6796
  console.log(
6613
- chalk9.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
6797
+ chalk11.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
6614
6798
  );
6615
6799
  return;
6616
6800
  }
@@ -6619,10 +6803,10 @@ var initCommand = new Command6().name("init").description("Initialize a volume i
6619
6803
  volumeName = options.name;
6620
6804
  } else if (!isInteractive()) {
6621
6805
  console.error(
6622
- chalk9.red("\u2717 --name flag is required in non-interactive mode")
6806
+ chalk11.red("\u2717 --name flag is required in non-interactive mode")
6623
6807
  );
6624
6808
  console.error(
6625
- chalk9.dim(" Usage: vm0 volume init --name <volume-name>")
6809
+ chalk11.dim(" Usage: vm0 volume init --name <volume-name>")
6626
6810
  );
6627
6811
  process.exit(1);
6628
6812
  } else {
@@ -6638,43 +6822,43 @@ var initCommand = new Command6().name("init").description("Initialize a volume i
6638
6822
  }
6639
6823
  );
6640
6824
  if (name === void 0) {
6641
- console.log(chalk9.dim("Cancelled"));
6825
+ console.log(chalk11.dim("Cancelled"));
6642
6826
  return;
6643
6827
  }
6644
6828
  volumeName = name;
6645
6829
  }
6646
6830
  if (!isValidStorageName(volumeName)) {
6647
- console.error(chalk9.red(`\u2717 Invalid volume name: "${volumeName}"`));
6831
+ console.error(chalk11.red(`\u2717 Invalid volume name: "${volumeName}"`));
6648
6832
  console.error(
6649
- chalk9.dim(
6833
+ chalk11.dim(
6650
6834
  " Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
6651
6835
  )
6652
6836
  );
6653
6837
  console.error(
6654
- chalk9.dim(" Example: my-dataset, user-data-v2, training-set-2024")
6838
+ chalk11.dim(" Example: my-dataset, user-data-v2, training-set-2024")
6655
6839
  );
6656
6840
  process.exit(1);
6657
6841
  }
6658
6842
  await writeStorageConfig(volumeName, cwd);
6659
- console.log(chalk9.green(`\u2713 Initialized volume: ${volumeName}`));
6843
+ console.log(chalk11.green(`\u2713 Initialized volume: ${volumeName}`));
6660
6844
  console.log(
6661
- chalk9.dim(
6845
+ chalk11.dim(
6662
6846
  ` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
6663
6847
  )
6664
6848
  );
6665
6849
  } catch (error) {
6666
- console.error(chalk9.red("\u2717 Failed to initialize volume"));
6850
+ console.error(chalk11.red("\u2717 Failed to initialize volume"));
6667
6851
  if (error instanceof Error) {
6668
- console.error(chalk9.dim(` ${error.message}`));
6852
+ console.error(chalk11.dim(` ${error.message}`));
6669
6853
  }
6670
6854
  process.exit(1);
6671
6855
  }
6672
6856
  });
6673
6857
 
6674
6858
  // src/commands/volume/push.ts
6675
- import { Command as Command7 } from "commander";
6676
- import chalk10 from "chalk";
6677
- var pushCommand = new Command7().name("push").description("Push local files to cloud volume").option(
6859
+ import { Command as Command9 } from "commander";
6860
+ import chalk12 from "chalk";
6861
+ var pushCommand = new Command9().name("push").description("Push local files to cloud volume").option(
6678
6862
  "-f, --force",
6679
6863
  "Force upload even if content unchanged (recreate archive)"
6680
6864
  ).action(async (options) => {
@@ -6682,35 +6866,35 @@ var pushCommand = new Command7().name("push").description("Push local files to c
6682
6866
  const cwd = process.cwd();
6683
6867
  const config = await readStorageConfig(cwd);
6684
6868
  if (!config) {
6685
- console.error(chalk10.red("\u2717 No volume initialized in this directory"));
6686
- console.error(chalk10.dim(" Run: vm0 volume init"));
6869
+ console.error(chalk12.red("\u2717 No volume initialized in this directory"));
6870
+ console.error(chalk12.dim(" Run: vm0 volume init"));
6687
6871
  process.exit(1);
6688
6872
  }
6689
6873
  console.log(`Pushing volume: ${config.name}`);
6690
6874
  const result = await directUpload(config.name, "volume", cwd, {
6691
6875
  onProgress: (message) => {
6692
- console.log(chalk10.dim(message));
6876
+ console.log(chalk12.dim(message));
6693
6877
  },
6694
6878
  force: options.force
6695
6879
  });
6696
6880
  const shortVersion = result.versionId.slice(0, 8);
6697
6881
  if (result.empty) {
6698
- console.log(chalk10.dim("No files found (empty volume)"));
6882
+ console.log(chalk12.dim("No files found (empty volume)"));
6699
6883
  } else if (result.deduplicated) {
6700
- console.log(chalk10.green("\u2713 Content unchanged (deduplicated)"));
6884
+ console.log(chalk12.green("\u2713 Content unchanged (deduplicated)"));
6701
6885
  } else {
6702
- console.log(chalk10.green("\u2713 Upload complete"));
6886
+ console.log(chalk12.green("\u2713 Upload complete"));
6703
6887
  }
6704
- console.log(chalk10.dim(` Version: ${shortVersion}`));
6705
- console.log(chalk10.dim(` Files: ${result.fileCount.toLocaleString()}`));
6706
- console.log(chalk10.dim(` Size: ${formatBytes(result.size)}`));
6888
+ console.log(chalk12.dim(` Version: ${shortVersion}`));
6889
+ console.log(chalk12.dim(` Files: ${result.fileCount.toLocaleString()}`));
6890
+ console.log(chalk12.dim(` Size: ${formatBytes(result.size)}`));
6707
6891
  } catch (error) {
6708
- console.error(chalk10.red("\u2717 Push failed"));
6892
+ console.error(chalk12.red("\u2717 Push failed"));
6709
6893
  if (error instanceof Error) {
6710
6894
  if (error.message.includes("Not authenticated")) {
6711
- console.error(chalk10.dim(" Run: vm0 auth login"));
6895
+ console.error(chalk12.dim(" Run: vm0 auth login"));
6712
6896
  } else {
6713
- console.error(chalk10.dim(` ${error.message}`));
6897
+ console.error(chalk12.dim(` ${error.message}`));
6714
6898
  }
6715
6899
  }
6716
6900
  process.exit(1);
@@ -6718,33 +6902,33 @@ var pushCommand = new Command7().name("push").description("Push local files to c
6718
6902
  });
6719
6903
 
6720
6904
  // src/commands/volume/pull.ts
6721
- import { Command as Command8 } from "commander";
6722
- import chalk12 from "chalk";
6905
+ import { Command as Command10 } from "commander";
6906
+ import chalk14 from "chalk";
6723
6907
  import path7 from "path";
6724
6908
  import * as fs6 from "fs";
6725
6909
  import * as os4 from "os";
6726
6910
  import * as tar3 from "tar";
6727
6911
 
6728
6912
  // src/lib/storage/pull-utils.ts
6729
- import chalk11 from "chalk";
6913
+ import chalk13 from "chalk";
6730
6914
  async function handleEmptyStorageResponse(cwd) {
6731
- console.log(chalk11.dim("Syncing local files..."));
6915
+ console.log(chalk13.dim("Syncing local files..."));
6732
6916
  const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
6733
6917
  if (removedCount > 0) {
6734
- console.log(chalk11.green(`\u2713 Removed ${removedCount} files not in remote`));
6918
+ console.log(chalk13.green(`\u2713 Removed ${removedCount} files not in remote`));
6735
6919
  }
6736
- console.log(chalk11.green("\u2713 Synced (0 files)"));
6920
+ console.log(chalk13.green("\u2713 Synced (0 files)"));
6737
6921
  return { removedCount };
6738
6922
  }
6739
6923
 
6740
6924
  // src/commands/volume/pull.ts
6741
- var pullCommand = new Command8().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
6925
+ var pullCommand = new Command10().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
6742
6926
  try {
6743
6927
  const cwd = process.cwd();
6744
6928
  const config = await readStorageConfig(cwd);
6745
6929
  if (!config) {
6746
- console.error(chalk12.red("\u2717 No volume initialized in this directory"));
6747
- console.error(chalk12.dim(" Run: vm0 volume init"));
6930
+ console.error(chalk14.red("\u2717 No volume initialized in this directory"));
6931
+ console.error(chalk14.dim(" Run: vm0 volume init"));
6748
6932
  process.exit(1);
6749
6933
  }
6750
6934
  if (versionId) {
@@ -6752,7 +6936,7 @@ var pullCommand = new Command8().name("pull").description("Pull cloud files to l
6752
6936
  } else {
6753
6937
  console.log(`Pulling volume: ${config.name}`);
6754
6938
  }
6755
- console.log(chalk12.dim("Getting download URL..."));
6939
+ console.log(chalk14.dim("Getting download URL..."));
6756
6940
  const downloadInfo = await getStorageDownload({
6757
6941
  name: config.name,
6758
6942
  type: "volume",
@@ -6766,18 +6950,18 @@ var pullCommand = new Command8().name("pull").description("Pull cloud files to l
6766
6950
  if (!downloadUrl) {
6767
6951
  throw new Error("No download URL returned");
6768
6952
  }
6769
- console.log(chalk12.dim("Downloading from S3..."));
6953
+ console.log(chalk14.dim("Downloading from S3..."));
6770
6954
  const s3Response = await fetch(downloadUrl);
6771
6955
  if (!s3Response.ok) {
6772
6956
  throw new Error(`S3 download failed: ${s3Response.status}`);
6773
6957
  }
6774
6958
  const arrayBuffer = await s3Response.arrayBuffer();
6775
6959
  const tarBuffer = Buffer.from(arrayBuffer);
6776
- console.log(chalk12.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
6960
+ console.log(chalk14.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
6777
6961
  const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
6778
6962
  const tarPath = path7.join(tmpDir, "volume.tar.gz");
6779
6963
  await fs6.promises.writeFile(tarPath, tarBuffer);
6780
- console.log(chalk12.dim("Syncing local files..."));
6964
+ console.log(chalk14.dim("Syncing local files..."));
6781
6965
  const remoteFiles = await listTarFiles(tarPath);
6782
6966
  const remoteFilesSet = new Set(
6783
6967
  remoteFiles.map((f) => f.replace(/\\/g, "/"))
@@ -6785,10 +6969,10 @@ var pullCommand = new Command8().name("pull").description("Pull cloud files to l
6785
6969
  const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
6786
6970
  if (removedCount > 0) {
6787
6971
  console.log(
6788
- chalk12.green(`\u2713 Removed ${removedCount} files not in remote`)
6972
+ chalk14.green(`\u2713 Removed ${removedCount} files not in remote`)
6789
6973
  );
6790
6974
  }
6791
- console.log(chalk12.dim("Extracting files..."));
6975
+ console.log(chalk14.dim("Extracting files..."));
6792
6976
  await tar3.extract({
6793
6977
  file: tarPath,
6794
6978
  cwd,
@@ -6796,14 +6980,14 @@ var pullCommand = new Command8().name("pull").description("Pull cloud files to l
6796
6980
  });
6797
6981
  await fs6.promises.unlink(tarPath);
6798
6982
  await fs6.promises.rmdir(tmpDir);
6799
- console.log(chalk12.green(`\u2713 Extracted ${remoteFiles.length} files`));
6983
+ console.log(chalk14.green(`\u2713 Extracted ${remoteFiles.length} files`));
6800
6984
  } catch (error) {
6801
- console.error(chalk12.red("\u2717 Pull failed"));
6985
+ console.error(chalk14.red("\u2717 Pull failed"));
6802
6986
  if (error instanceof Error) {
6803
6987
  if (error.message.includes("Not authenticated")) {
6804
- console.error(chalk12.dim(" Run: vm0 auth login"));
6988
+ console.error(chalk14.dim(" Run: vm0 auth login"));
6805
6989
  } else {
6806
- console.error(chalk12.dim(` ${error.message}`));
6990
+ console.error(chalk14.dim(` ${error.message}`));
6807
6991
  }
6808
6992
  }
6809
6993
  process.exit(1);
@@ -6811,24 +6995,24 @@ var pullCommand = new Command8().name("pull").description("Pull cloud files to l
6811
6995
  });
6812
6996
 
6813
6997
  // src/commands/volume/status.ts
6814
- import { Command as Command9 } from "commander";
6815
- import chalk13 from "chalk";
6816
- var statusCommand = new Command9().name("status").description("Show status of cloud volume").action(async () => {
6998
+ import { Command as Command11 } from "commander";
6999
+ import chalk15 from "chalk";
7000
+ var statusCommand = new Command11().name("status").description("Show status of cloud volume").action(async () => {
6817
7001
  try {
6818
7002
  const cwd = process.cwd();
6819
7003
  const config = await readStorageConfig(cwd);
6820
7004
  if (!config) {
6821
- console.error(chalk13.red("\u2717 No volume initialized in this directory"));
6822
- console.error(chalk13.dim(" Run: vm0 volume init"));
7005
+ console.error(chalk15.red("\u2717 No volume initialized in this directory"));
7006
+ console.error(chalk15.dim(" Run: vm0 volume init"));
6823
7007
  process.exit(1);
6824
7008
  }
6825
7009
  if (config.type !== "volume") {
6826
7010
  console.error(
6827
- chalk13.red(
7011
+ chalk15.red(
6828
7012
  "\u2717 This directory is initialized as an artifact, not a volume"
6829
7013
  )
6830
7014
  );
6831
- console.error(chalk13.dim(" Use: vm0 artifact status"));
7015
+ console.error(chalk15.dim(" Use: vm0 artifact status"));
6832
7016
  process.exit(1);
6833
7017
  }
6834
7018
  console.log(`Checking volume: ${config.name}`);
@@ -6838,25 +7022,25 @@ var statusCommand = new Command9().name("status").description("Show status of cl
6838
7022
  });
6839
7023
  const shortVersion = info.versionId.slice(0, 8);
6840
7024
  if ("empty" in info) {
6841
- console.log(chalk13.green("\u2713 Found (empty)"));
6842
- console.log(chalk13.dim(` Version: ${shortVersion}`));
7025
+ console.log(chalk15.green("\u2713 Found (empty)"));
7026
+ console.log(chalk15.dim(` Version: ${shortVersion}`));
6843
7027
  } else {
6844
- console.log(chalk13.green("\u2713 Found"));
6845
- console.log(chalk13.dim(` Version: ${shortVersion}`));
6846
- console.log(chalk13.dim(` Files: ${info.fileCount.toLocaleString()}`));
6847
- console.log(chalk13.dim(` Size: ${formatBytes(info.size)}`));
7028
+ console.log(chalk15.green("\u2713 Found"));
7029
+ console.log(chalk15.dim(` Version: ${shortVersion}`));
7030
+ console.log(chalk15.dim(` Files: ${info.fileCount.toLocaleString()}`));
7031
+ console.log(chalk15.dim(` Size: ${formatBytes(info.size)}`));
6848
7032
  }
6849
7033
  } catch (error) {
6850
7034
  if (error instanceof Error && error.message.includes("not found")) {
6851
- console.error(chalk13.red("\u2717 Not found on remote"));
6852
- console.error(chalk13.dim(" Run: vm0 volume push"));
7035
+ console.error(chalk15.red("\u2717 Not found on remote"));
7036
+ console.error(chalk15.dim(" Run: vm0 volume push"));
6853
7037
  } else {
6854
- console.error(chalk13.red("\u2717 Status check failed"));
7038
+ console.error(chalk15.red("\u2717 Status check failed"));
6855
7039
  if (error instanceof Error) {
6856
7040
  if (error.message.includes("Not authenticated")) {
6857
- console.error(chalk13.dim(" Run: vm0 auth login"));
7041
+ console.error(chalk15.dim(" Run: vm0 auth login"));
6858
7042
  } else {
6859
- console.error(chalk13.dim(` ${error.message}`));
7043
+ console.error(chalk15.dim(` ${error.message}`));
6860
7044
  }
6861
7045
  }
6862
7046
  }
@@ -6865,15 +7049,15 @@ var statusCommand = new Command9().name("status").description("Show status of cl
6865
7049
  });
6866
7050
 
6867
7051
  // src/commands/volume/list.ts
6868
- import { Command as Command10 } from "commander";
6869
- import chalk14 from "chalk";
6870
- var listCommand = new Command10().name("list").alias("ls").description("List all remote volumes").action(async () => {
7052
+ import { Command as Command12 } from "commander";
7053
+ import chalk16 from "chalk";
7054
+ var listCommand2 = new Command12().name("list").alias("ls").description("List all remote volumes").action(async () => {
6871
7055
  try {
6872
7056
  const items = await listStorages({ type: "volume" });
6873
7057
  if (items.length === 0) {
6874
- console.log(chalk14.dim("No volumes found"));
7058
+ console.log(chalk16.dim("No volumes found"));
6875
7059
  console.log(
6876
- chalk14.dim(" Create one with: vm0 volume init && vm0 volume push")
7060
+ chalk16.dim(" Create one with: vm0 volume init && vm0 volume push")
6877
7061
  );
6878
7062
  return;
6879
7063
  }
@@ -6892,7 +7076,7 @@ var listCommand = new Command10().name("list").alias("ls").description("List all
6892
7076
  "FILES".padStart(filesWidth),
6893
7077
  "UPDATED"
6894
7078
  ].join(" ");
6895
- console.log(chalk14.dim(header));
7079
+ console.log(chalk16.dim(header));
6896
7080
  for (const item of items) {
6897
7081
  const row = [
6898
7082
  item.name.padEnd(nameWidth),
@@ -6903,12 +7087,12 @@ var listCommand = new Command10().name("list").alias("ls").description("List all
6903
7087
  console.log(row);
6904
7088
  }
6905
7089
  } catch (error) {
6906
- console.error(chalk14.red("\u2717 Failed to list volumes"));
7090
+ console.error(chalk16.red("\u2717 Failed to list volumes"));
6907
7091
  if (error instanceof Error) {
6908
7092
  if (error.message.includes("Not authenticated")) {
6909
- console.error(chalk14.dim(" Run: vm0 auth login"));
7093
+ console.error(chalk16.dim(" Run: vm0 auth login"));
6910
7094
  } else {
6911
- console.error(chalk14.dim(` ${error.message}`));
7095
+ console.error(chalk16.dim(` ${error.message}`));
6912
7096
  }
6913
7097
  }
6914
7098
  process.exit(1);
@@ -6916,11 +7100,11 @@ var listCommand = new Command10().name("list").alias("ls").description("List all
6916
7100
  });
6917
7101
 
6918
7102
  // src/commands/volume/clone.ts
6919
- import { Command as Command11 } from "commander";
6920
- import chalk16 from "chalk";
7103
+ import { Command as Command13 } from "commander";
7104
+ import chalk18 from "chalk";
6921
7105
 
6922
7106
  // src/lib/storage/clone-utils.ts
6923
- import chalk15 from "chalk";
7107
+ import chalk17 from "chalk";
6924
7108
  import path8 from "path";
6925
7109
  import * as fs7 from "fs";
6926
7110
  import * as os5 from "os";
@@ -6930,18 +7114,18 @@ async function cloneStorage(name, type, destination, options = {}) {
6930
7114
  if (fs7.existsSync(destination)) {
6931
7115
  throw new Error(`Directory "${destination}" already exists`);
6932
7116
  }
6933
- console.log(chalk15.dim(`Checking remote ${typeLabel}...`));
7117
+ console.log(chalk17.dim(`Checking remote ${typeLabel}...`));
6934
7118
  const downloadInfo = await getStorageDownload({
6935
7119
  name,
6936
7120
  type,
6937
7121
  version: options.version
6938
7122
  });
6939
- console.log(chalk15.dim(`Creating directory: ${destination}/`));
7123
+ console.log(chalk17.dim(`Creating directory: ${destination}/`));
6940
7124
  await fs7.promises.mkdir(destination, { recursive: true });
6941
7125
  if ("empty" in downloadInfo) {
6942
7126
  await writeStorageConfig(name, destination, type);
6943
- console.log(chalk15.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
6944
- console.log(chalk15.dim(`\u2713 Initialized .vm0/storage.yaml`));
7127
+ console.log(chalk17.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
7128
+ console.log(chalk17.dim(`\u2713 Initialized .vm0/storage.yaml`));
6945
7129
  return {
6946
7130
  success: true,
6947
7131
  fileCount: 0,
@@ -6953,7 +7137,7 @@ async function cloneStorage(name, type, destination, options = {}) {
6953
7137
  if (!downloadUrl) {
6954
7138
  throw new Error("No download URL returned");
6955
7139
  }
6956
- console.log(chalk15.dim("Downloading from S3..."));
7140
+ console.log(chalk17.dim("Downloading from S3..."));
6957
7141
  const s3Response = await fetch(downloadUrl);
6958
7142
  if (!s3Response.ok) {
6959
7143
  await fs7.promises.rm(destination, { recursive: true, force: true });
@@ -6961,12 +7145,12 @@ async function cloneStorage(name, type, destination, options = {}) {
6961
7145
  }
6962
7146
  const arrayBuffer = await s3Response.arrayBuffer();
6963
7147
  const tarBuffer = Buffer.from(arrayBuffer);
6964
- console.log(chalk15.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
7148
+ console.log(chalk17.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
6965
7149
  const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-clone-"));
6966
7150
  const tarPath = path8.join(tmpDir, "archive.tar.gz");
6967
7151
  await fs7.promises.writeFile(tarPath, tarBuffer);
6968
7152
  const files = await listTarFiles(tarPath);
6969
- console.log(chalk15.dim("Extracting files..."));
7153
+ console.log(chalk17.dim("Extracting files..."));
6970
7154
  await tar4.extract({
6971
7155
  file: tarPath,
6972
7156
  cwd: destination,
@@ -6974,9 +7158,9 @@ async function cloneStorage(name, type, destination, options = {}) {
6974
7158
  });
6975
7159
  await fs7.promises.unlink(tarPath);
6976
7160
  await fs7.promises.rmdir(tmpDir);
6977
- console.log(chalk15.green(`\u2713 Extracted ${files.length} files`));
7161
+ console.log(chalk17.green(`\u2713 Extracted ${files.length} files`));
6978
7162
  await writeStorageConfig(name, destination, type);
6979
- console.log(chalk15.green(`\u2713 Initialized .vm0/storage.yaml`));
7163
+ console.log(chalk17.green(`\u2713 Initialized .vm0/storage.yaml`));
6980
7164
  return {
6981
7165
  success: true,
6982
7166
  fileCount: downloadInfo.fileCount,
@@ -6986,22 +7170,22 @@ async function cloneStorage(name, type, destination, options = {}) {
6986
7170
  }
6987
7171
 
6988
7172
  // src/commands/volume/clone.ts
6989
- var cloneCommand = new Command11().name("clone").description("Clone a remote volume to local directory (latest version)").argument("<name>", "Volume name to clone").argument("[destination]", "Destination directory (default: volume name)").action(async (name, destination) => {
7173
+ var cloneCommand = new Command13().name("clone").description("Clone a remote volume to local directory (latest version)").argument("<name>", "Volume name to clone").argument("[destination]", "Destination directory (default: volume name)").action(async (name, destination) => {
6990
7174
  try {
6991
7175
  const targetDir = destination || name;
6992
7176
  console.log(`Cloning volume: ${name}`);
6993
7177
  const result = await cloneStorage(name, "volume", targetDir);
6994
- console.log(chalk16.green(`
7178
+ console.log(chalk18.green(`
6995
7179
  \u2713 Successfully cloned volume: ${name}`));
6996
- console.log(chalk16.dim(` Location: ${targetDir}/`));
6997
- console.log(chalk16.dim(` Version: ${result.versionId.slice(0, 8)}`));
7180
+ console.log(chalk18.dim(` Location: ${targetDir}/`));
7181
+ console.log(chalk18.dim(` Version: ${result.versionId.slice(0, 8)}`));
6998
7182
  } catch (error) {
6999
- console.error(chalk16.red("\u2717 Clone failed"));
7183
+ console.error(chalk18.red("\u2717 Clone failed"));
7000
7184
  if (error instanceof Error) {
7001
7185
  if (error.message.includes("Not authenticated")) {
7002
- console.error(chalk16.dim(" Run: vm0 auth login"));
7186
+ console.error(chalk18.dim(" Run: vm0 auth login"));
7003
7187
  } else {
7004
- console.error(chalk16.dim(` ${error.message}`));
7188
+ console.error(chalk18.dim(` ${error.message}`));
7005
7189
  }
7006
7190
  }
7007
7191
  process.exit(1);
@@ -7009,16 +7193,16 @@ var cloneCommand = new Command11().name("clone").description("Clone a remote vol
7009
7193
  });
7010
7194
 
7011
7195
  // src/commands/volume/index.ts
7012
- var volumeCommand = new Command12().name("volume").description("Manage volumes (defined in compose, not versioned after run)").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand).addCommand(listCommand).addCommand(cloneCommand);
7196
+ var volumeCommand = new Command14().name("volume").description("Manage volumes (defined in compose, not versioned after run)").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand).addCommand(listCommand2).addCommand(cloneCommand);
7013
7197
 
7014
7198
  // src/commands/artifact/index.ts
7015
- import { Command as Command19 } from "commander";
7199
+ import { Command as Command21 } from "commander";
7016
7200
 
7017
7201
  // src/commands/artifact/init.ts
7018
- import { Command as Command13 } from "commander";
7019
- import chalk17 from "chalk";
7202
+ import { Command as Command15 } from "commander";
7203
+ import chalk19 from "chalk";
7020
7204
  import path9 from "path";
7021
- var initCommand2 = new Command13().name("init").description("Initialize an artifact in the current directory").option(
7205
+ var initCommand2 = new Command15().name("init").description("Initialize an artifact in the current directory").option(
7022
7206
  "-n, --name <name>",
7023
7207
  "Artifact name (required in non-interactive mode)"
7024
7208
  ).action(async (options) => {
@@ -7029,24 +7213,24 @@ var initCommand2 = new Command13().name("init").description("Initialize an artif
7029
7213
  if (existingConfig) {
7030
7214
  if (existingConfig.type === "artifact") {
7031
7215
  console.log(
7032
- chalk17.yellow(
7216
+ chalk19.yellow(
7033
7217
  `Artifact already initialized: ${existingConfig.name}`
7034
7218
  )
7035
7219
  );
7036
7220
  } else {
7037
7221
  console.log(
7038
- chalk17.yellow(
7222
+ chalk19.yellow(
7039
7223
  `Directory already initialized as volume: ${existingConfig.name}`
7040
7224
  )
7041
7225
  );
7042
7226
  console.log(
7043
- chalk17.dim(
7227
+ chalk19.dim(
7044
7228
  " To change type, delete .vm0/storage.yaml and reinitialize"
7045
7229
  )
7046
7230
  );
7047
7231
  }
7048
7232
  console.log(
7049
- chalk17.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
7233
+ chalk19.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
7050
7234
  );
7051
7235
  return;
7052
7236
  }
@@ -7055,10 +7239,10 @@ var initCommand2 = new Command13().name("init").description("Initialize an artif
7055
7239
  artifactName = options.name;
7056
7240
  } else if (!isInteractive()) {
7057
7241
  console.error(
7058
- chalk17.red("\u2717 --name flag is required in non-interactive mode")
7242
+ chalk19.red("\u2717 --name flag is required in non-interactive mode")
7059
7243
  );
7060
7244
  console.error(
7061
- chalk17.dim(" Usage: vm0 artifact init --name <artifact-name>")
7245
+ chalk19.dim(" Usage: vm0 artifact init --name <artifact-name>")
7062
7246
  );
7063
7247
  process.exit(1);
7064
7248
  } else {
@@ -7074,43 +7258,43 @@ var initCommand2 = new Command13().name("init").description("Initialize an artif
7074
7258
  }
7075
7259
  );
7076
7260
  if (name === void 0) {
7077
- console.log(chalk17.dim("Cancelled"));
7261
+ console.log(chalk19.dim("Cancelled"));
7078
7262
  return;
7079
7263
  }
7080
7264
  artifactName = name;
7081
7265
  }
7082
7266
  if (!isValidStorageName(artifactName)) {
7083
- console.error(chalk17.red(`\u2717 Invalid artifact name: "${artifactName}"`));
7267
+ console.error(chalk19.red(`\u2717 Invalid artifact name: "${artifactName}"`));
7084
7268
  console.error(
7085
- chalk17.dim(
7269
+ chalk19.dim(
7086
7270
  " Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
7087
7271
  )
7088
7272
  );
7089
7273
  console.error(
7090
- chalk17.dim(" Example: my-project, user-workspace, code-artifact")
7274
+ chalk19.dim(" Example: my-project, user-workspace, code-artifact")
7091
7275
  );
7092
7276
  process.exit(1);
7093
7277
  }
7094
7278
  await writeStorageConfig(artifactName, cwd, "artifact");
7095
- console.log(chalk17.green(`\u2713 Initialized artifact: ${artifactName}`));
7279
+ console.log(chalk19.green(`\u2713 Initialized artifact: ${artifactName}`));
7096
7280
  console.log(
7097
- chalk17.dim(
7281
+ chalk19.dim(
7098
7282
  ` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
7099
7283
  )
7100
7284
  );
7101
7285
  } catch (error) {
7102
- console.error(chalk17.red("\u2717 Failed to initialize artifact"));
7286
+ console.error(chalk19.red("\u2717 Failed to initialize artifact"));
7103
7287
  if (error instanceof Error) {
7104
- console.error(chalk17.dim(` ${error.message}`));
7288
+ console.error(chalk19.dim(` ${error.message}`));
7105
7289
  }
7106
7290
  process.exit(1);
7107
7291
  }
7108
7292
  });
7109
7293
 
7110
7294
  // src/commands/artifact/push.ts
7111
- import { Command as Command14 } from "commander";
7112
- import chalk18 from "chalk";
7113
- var pushCommand2 = new Command14().name("push").description("Push local files to cloud artifact").option(
7295
+ import { Command as Command16 } from "commander";
7296
+ import chalk20 from "chalk";
7297
+ var pushCommand2 = new Command16().name("push").description("Push local files to cloud artifact").option(
7114
7298
  "-f, --force",
7115
7299
  "Force upload even if content unchanged (recreate archive)"
7116
7300
  ).action(async (options) => {
@@ -7118,69 +7302,69 @@ var pushCommand2 = new Command14().name("push").description("Push local files to
7118
7302
  const cwd = process.cwd();
7119
7303
  const config = await readStorageConfig(cwd);
7120
7304
  if (!config) {
7121
- console.error(chalk18.red("\u2717 No artifact initialized in this directory"));
7122
- console.error(chalk18.dim(" Run: vm0 artifact init"));
7305
+ console.error(chalk20.red("\u2717 No artifact initialized in this directory"));
7306
+ console.error(chalk20.dim(" Run: vm0 artifact init"));
7123
7307
  process.exit(1);
7124
7308
  }
7125
7309
  if (config.type !== "artifact") {
7126
7310
  console.error(
7127
- chalk18.red(
7311
+ chalk20.red(
7128
7312
  `\u2717 This directory is initialized as a volume, not an artifact`
7129
7313
  )
7130
7314
  );
7131
- console.error(chalk18.dim(" Use: vm0 volume push"));
7315
+ console.error(chalk20.dim(" Use: vm0 volume push"));
7132
7316
  process.exit(1);
7133
7317
  }
7134
7318
  console.log(`Pushing artifact: ${config.name}`);
7135
7319
  const result = await directUpload(config.name, "artifact", cwd, {
7136
7320
  onProgress: (message) => {
7137
- console.log(chalk18.dim(message));
7321
+ console.log(chalk20.dim(message));
7138
7322
  },
7139
7323
  force: options.force
7140
7324
  });
7141
7325
  const shortVersion = result.versionId.slice(0, 8);
7142
7326
  if (result.empty) {
7143
- console.log(chalk18.dim("No files found (empty artifact)"));
7327
+ console.log(chalk20.dim("No files found (empty artifact)"));
7144
7328
  } else if (result.deduplicated) {
7145
- console.log(chalk18.green("\u2713 Content unchanged (deduplicated)"));
7329
+ console.log(chalk20.green("\u2713 Content unchanged (deduplicated)"));
7146
7330
  } else {
7147
- console.log(chalk18.green("\u2713 Upload complete"));
7331
+ console.log(chalk20.green("\u2713 Upload complete"));
7148
7332
  }
7149
- console.log(chalk18.dim(` Version: ${shortVersion}`));
7150
- console.log(chalk18.dim(` Files: ${result.fileCount.toLocaleString()}`));
7151
- console.log(chalk18.dim(` Size: ${formatBytes(result.size)}`));
7333
+ console.log(chalk20.dim(` Version: ${shortVersion}`));
7334
+ console.log(chalk20.dim(` Files: ${result.fileCount.toLocaleString()}`));
7335
+ console.log(chalk20.dim(` Size: ${formatBytes(result.size)}`));
7152
7336
  } catch (error) {
7153
- console.error(chalk18.red("\u2717 Push failed"));
7337
+ console.error(chalk20.red("\u2717 Push failed"));
7154
7338
  if (error instanceof Error) {
7155
- console.error(chalk18.dim(` ${error.message}`));
7339
+ console.error(chalk20.dim(` ${error.message}`));
7156
7340
  }
7157
7341
  process.exit(1);
7158
7342
  }
7159
7343
  });
7160
7344
 
7161
7345
  // src/commands/artifact/pull.ts
7162
- import { Command as Command15 } from "commander";
7163
- import chalk19 from "chalk";
7346
+ import { Command as Command17 } from "commander";
7347
+ import chalk21 from "chalk";
7164
7348
  import path10 from "path";
7165
7349
  import * as fs8 from "fs";
7166
7350
  import * as os6 from "os";
7167
7351
  import * as tar5 from "tar";
7168
- var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
7352
+ var pullCommand2 = new Command17().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
7169
7353
  try {
7170
7354
  const cwd = process.cwd();
7171
7355
  const config = await readStorageConfig(cwd);
7172
7356
  if (!config) {
7173
- console.error(chalk19.red("\u2717 No artifact initialized in this directory"));
7174
- console.error(chalk19.dim(" Run: vm0 artifact init"));
7357
+ console.error(chalk21.red("\u2717 No artifact initialized in this directory"));
7358
+ console.error(chalk21.dim(" Run: vm0 artifact init"));
7175
7359
  process.exit(1);
7176
7360
  }
7177
7361
  if (config.type !== "artifact") {
7178
7362
  console.error(
7179
- chalk19.red(
7363
+ chalk21.red(
7180
7364
  `\u2717 This directory is initialized as a volume, not an artifact`
7181
7365
  )
7182
7366
  );
7183
- console.error(chalk19.dim(" Use: vm0 volume pull"));
7367
+ console.error(chalk21.dim(" Use: vm0 volume pull"));
7184
7368
  process.exit(1);
7185
7369
  }
7186
7370
  if (versionId) {
@@ -7188,7 +7372,7 @@ var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact
7188
7372
  } else {
7189
7373
  console.log(`Pulling artifact: ${config.name}`);
7190
7374
  }
7191
- console.log(chalk19.dim("Getting download URL..."));
7375
+ console.log(chalk21.dim("Getting download URL..."));
7192
7376
  const downloadInfo = await getStorageDownload({
7193
7377
  name: config.name,
7194
7378
  type: "artifact",
@@ -7202,18 +7386,18 @@ var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact
7202
7386
  if (!downloadUrl) {
7203
7387
  throw new Error("No download URL returned");
7204
7388
  }
7205
- console.log(chalk19.dim("Downloading from S3..."));
7389
+ console.log(chalk21.dim("Downloading from S3..."));
7206
7390
  const s3Response = await fetch(downloadUrl);
7207
7391
  if (!s3Response.ok) {
7208
7392
  throw new Error(`S3 download failed: ${s3Response.status}`);
7209
7393
  }
7210
7394
  const arrayBuffer = await s3Response.arrayBuffer();
7211
7395
  const tarBuffer = Buffer.from(arrayBuffer);
7212
- console.log(chalk19.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
7396
+ console.log(chalk21.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
7213
7397
  const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
7214
7398
  const tarPath = path10.join(tmpDir, "artifact.tar.gz");
7215
7399
  await fs8.promises.writeFile(tarPath, tarBuffer);
7216
- console.log(chalk19.dim("Syncing local files..."));
7400
+ console.log(chalk21.dim("Syncing local files..."));
7217
7401
  const remoteFiles = await listTarFiles(tarPath);
7218
7402
  const remoteFilesSet = new Set(
7219
7403
  remoteFiles.map((f) => f.replace(/\\/g, "/"))
@@ -7221,10 +7405,10 @@ var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact
7221
7405
  const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
7222
7406
  if (removedCount > 0) {
7223
7407
  console.log(
7224
- chalk19.green(`\u2713 Removed ${removedCount} files not in remote`)
7408
+ chalk21.green(`\u2713 Removed ${removedCount} files not in remote`)
7225
7409
  );
7226
7410
  }
7227
- console.log(chalk19.dim("Extracting files..."));
7411
+ console.log(chalk21.dim("Extracting files..."));
7228
7412
  await tar5.extract({
7229
7413
  file: tarPath,
7230
7414
  cwd,
@@ -7232,35 +7416,35 @@ var pullCommand2 = new Command15().name("pull").description("Pull cloud artifact
7232
7416
  });
7233
7417
  await fs8.promises.unlink(tarPath);
7234
7418
  await fs8.promises.rmdir(tmpDir);
7235
- console.log(chalk19.green(`\u2713 Extracted ${remoteFiles.length} files`));
7419
+ console.log(chalk21.green(`\u2713 Extracted ${remoteFiles.length} files`));
7236
7420
  } catch (error) {
7237
- console.error(chalk19.red("\u2717 Pull failed"));
7421
+ console.error(chalk21.red("\u2717 Pull failed"));
7238
7422
  if (error instanceof Error) {
7239
- console.error(chalk19.dim(` ${error.message}`));
7423
+ console.error(chalk21.dim(` ${error.message}`));
7240
7424
  }
7241
7425
  process.exit(1);
7242
7426
  }
7243
7427
  });
7244
7428
 
7245
7429
  // src/commands/artifact/status.ts
7246
- import { Command as Command16 } from "commander";
7247
- import chalk20 from "chalk";
7248
- var statusCommand2 = new Command16().name("status").description("Show status of cloud artifact").action(async () => {
7430
+ import { Command as Command18 } from "commander";
7431
+ import chalk22 from "chalk";
7432
+ var statusCommand2 = new Command18().name("status").description("Show status of cloud artifact").action(async () => {
7249
7433
  try {
7250
7434
  const cwd = process.cwd();
7251
7435
  const config = await readStorageConfig(cwd);
7252
7436
  if (!config) {
7253
- console.error(chalk20.red("\u2717 No artifact initialized in this directory"));
7254
- console.error(chalk20.dim(" Run: vm0 artifact init"));
7437
+ console.error(chalk22.red("\u2717 No artifact initialized in this directory"));
7438
+ console.error(chalk22.dim(" Run: vm0 artifact init"));
7255
7439
  process.exit(1);
7256
7440
  }
7257
7441
  if (config.type !== "artifact") {
7258
7442
  console.error(
7259
- chalk20.red(
7443
+ chalk22.red(
7260
7444
  "\u2717 This directory is initialized as a volume, not an artifact"
7261
7445
  )
7262
7446
  );
7263
- console.error(chalk20.dim(" Use: vm0 volume status"));
7447
+ console.error(chalk22.dim(" Use: vm0 volume status"));
7264
7448
  process.exit(1);
7265
7449
  }
7266
7450
  console.log(`Checking artifact: ${config.name}`);
@@ -7270,22 +7454,22 @@ var statusCommand2 = new Command16().name("status").description("Show status of
7270
7454
  });
7271
7455
  const shortVersion = info.versionId.slice(0, 8);
7272
7456
  if ("empty" in info) {
7273
- console.log(chalk20.green("\u2713 Found (empty)"));
7274
- console.log(chalk20.dim(` Version: ${shortVersion}`));
7457
+ console.log(chalk22.green("\u2713 Found (empty)"));
7458
+ console.log(chalk22.dim(` Version: ${shortVersion}`));
7275
7459
  } else {
7276
- console.log(chalk20.green("\u2713 Found"));
7277
- console.log(chalk20.dim(` Version: ${shortVersion}`));
7278
- console.log(chalk20.dim(` Files: ${info.fileCount.toLocaleString()}`));
7279
- console.log(chalk20.dim(` Size: ${formatBytes(info.size)}`));
7460
+ console.log(chalk22.green("\u2713 Found"));
7461
+ console.log(chalk22.dim(` Version: ${shortVersion}`));
7462
+ console.log(chalk22.dim(` Files: ${info.fileCount.toLocaleString()}`));
7463
+ console.log(chalk22.dim(` Size: ${formatBytes(info.size)}`));
7280
7464
  }
7281
7465
  } catch (error) {
7282
7466
  if (error instanceof Error && error.message.includes("not found")) {
7283
- console.error(chalk20.red("\u2717 Not found on remote"));
7284
- console.error(chalk20.dim(" Run: vm0 artifact push"));
7467
+ console.error(chalk22.red("\u2717 Not found on remote"));
7468
+ console.error(chalk22.dim(" Run: vm0 artifact push"));
7285
7469
  } else {
7286
- console.error(chalk20.red("\u2717 Status check failed"));
7470
+ console.error(chalk22.red("\u2717 Status check failed"));
7287
7471
  if (error instanceof Error) {
7288
- console.error(chalk20.dim(` ${error.message}`));
7472
+ console.error(chalk22.dim(` ${error.message}`));
7289
7473
  }
7290
7474
  }
7291
7475
  process.exit(1);
@@ -7293,15 +7477,15 @@ var statusCommand2 = new Command16().name("status").description("Show status of
7293
7477
  });
7294
7478
 
7295
7479
  // src/commands/artifact/list.ts
7296
- import { Command as Command17 } from "commander";
7297
- import chalk21 from "chalk";
7298
- var listCommand2 = new Command17().name("list").alias("ls").description("List all remote artifacts").action(async () => {
7480
+ import { Command as Command19 } from "commander";
7481
+ import chalk23 from "chalk";
7482
+ var listCommand3 = new Command19().name("list").alias("ls").description("List all remote artifacts").action(async () => {
7299
7483
  try {
7300
7484
  const items = await listStorages({ type: "artifact" });
7301
7485
  if (items.length === 0) {
7302
- console.log(chalk21.dim("No artifacts found"));
7486
+ console.log(chalk23.dim("No artifacts found"));
7303
7487
  console.log(
7304
- chalk21.dim(
7488
+ chalk23.dim(
7305
7489
  " Create one with: vm0 artifact init && vm0 artifact push"
7306
7490
  )
7307
7491
  );
@@ -7322,7 +7506,7 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
7322
7506
  "FILES".padStart(filesWidth),
7323
7507
  "UPDATED"
7324
7508
  ].join(" ");
7325
- console.log(chalk21.dim(header));
7509
+ console.log(chalk23.dim(header));
7326
7510
  for (const item of items) {
7327
7511
  const row = [
7328
7512
  item.name.padEnd(nameWidth),
@@ -7333,12 +7517,12 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
7333
7517
  console.log(row);
7334
7518
  }
7335
7519
  } catch (error) {
7336
- console.error(chalk21.red("\u2717 Failed to list artifacts"));
7520
+ console.error(chalk23.red("\u2717 Failed to list artifacts"));
7337
7521
  if (error instanceof Error) {
7338
7522
  if (error.message.includes("Not authenticated")) {
7339
- console.error(chalk21.dim(" Run: vm0 auth login"));
7523
+ console.error(chalk23.dim(" Run: vm0 auth login"));
7340
7524
  } else {
7341
- console.error(chalk21.dim(` ${error.message}`));
7525
+ console.error(chalk23.dim(` ${error.message}`));
7342
7526
  }
7343
7527
  }
7344
7528
  process.exit(1);
@@ -7346,24 +7530,24 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
7346
7530
  });
7347
7531
 
7348
7532
  // src/commands/artifact/clone.ts
7349
- import { Command as Command18 } from "commander";
7350
- import chalk22 from "chalk";
7351
- var cloneCommand2 = new Command18().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
7533
+ import { Command as Command20 } from "commander";
7534
+ import chalk24 from "chalk";
7535
+ var cloneCommand2 = new Command20().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
7352
7536
  try {
7353
7537
  const targetDir = destination || name;
7354
7538
  console.log(`Cloning artifact: ${name}`);
7355
7539
  const result = await cloneStorage(name, "artifact", targetDir);
7356
- console.log(chalk22.green(`
7540
+ console.log(chalk24.green(`
7357
7541
  \u2713 Successfully cloned artifact: ${name}`));
7358
- console.log(chalk22.dim(` Location: ${targetDir}/`));
7359
- console.log(chalk22.dim(` Version: ${result.versionId.slice(0, 8)}`));
7542
+ console.log(chalk24.dim(` Location: ${targetDir}/`));
7543
+ console.log(chalk24.dim(` Version: ${result.versionId.slice(0, 8)}`));
7360
7544
  } catch (error) {
7361
- console.error(chalk22.red("\u2717 Clone failed"));
7545
+ console.error(chalk24.red("\u2717 Clone failed"));
7362
7546
  if (error instanceof Error) {
7363
7547
  if (error.message.includes("Not authenticated")) {
7364
- console.error(chalk22.dim(" Run: vm0 auth login"));
7548
+ console.error(chalk24.dim(" Run: vm0 auth login"));
7365
7549
  } else {
7366
- console.error(chalk22.dim(` ${error.message}`));
7550
+ console.error(chalk24.dim(` ${error.message}`));
7367
7551
  }
7368
7552
  }
7369
7553
  process.exit(1);
@@ -7371,11 +7555,11 @@ var cloneCommand2 = new Command18().name("clone").description("Clone a remote ar
7371
7555
  });
7372
7556
 
7373
7557
  // src/commands/artifact/index.ts
7374
- var artifactCommand = new Command19().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand2).addCommand(listCommand2).addCommand(cloneCommand2);
7558
+ var artifactCommand = new Command21().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand2).addCommand(listCommand3).addCommand(cloneCommand2);
7375
7559
 
7376
7560
  // src/commands/cook.ts
7377
- import { Command as Command20, Option as Option4 } from "commander";
7378
- import chalk24 from "chalk";
7561
+ import { Command as Command22, Option as Option4 } from "commander";
7562
+ import chalk26 from "chalk";
7379
7563
  import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
7380
7564
  import { existsSync as existsSync8 } from "fs";
7381
7565
  import path11 from "path";
@@ -7385,7 +7569,7 @@ import { config as dotenvConfig2 } from "dotenv";
7385
7569
 
7386
7570
  // src/lib/utils/update-checker.ts
7387
7571
  import { spawn } from "child_process";
7388
- import chalk23 from "chalk";
7572
+ import chalk25 from "chalk";
7389
7573
  var PACKAGE_NAME = "@vm0/cli";
7390
7574
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
7391
7575
  var TIMEOUT_MS = 5e3;
@@ -7469,21 +7653,21 @@ function performUpgrade(packageManager) {
7469
7653
  async function checkAndUpgrade(currentVersion, prompt) {
7470
7654
  const latestVersion = await getLatestVersion();
7471
7655
  if (latestVersion === null) {
7472
- console.log(chalk23.yellow("Warning: Could not check for updates"));
7656
+ console.log(chalk25.yellow("Warning: Could not check for updates"));
7473
7657
  console.log();
7474
7658
  return false;
7475
7659
  }
7476
7660
  if (latestVersion === currentVersion) {
7477
7661
  return false;
7478
7662
  }
7479
- console.log(chalk23.yellow("vm0 is currently in Early Access (EA)."));
7663
+ console.log(chalk25.yellow("vm0 is currently in Early Access (EA)."));
7480
7664
  console.log(
7481
- chalk23.yellow(
7665
+ chalk25.yellow(
7482
7666
  `Current version: ${currentVersion} -> Latest version: ${latestVersion}`
7483
7667
  )
7484
7668
  );
7485
7669
  console.log(
7486
- chalk23.yellow(
7670
+ chalk25.yellow(
7487
7671
  "Please always use the latest version for best compatibility."
7488
7672
  )
7489
7673
  );
@@ -7492,33 +7676,33 @@ async function checkAndUpgrade(currentVersion, prompt) {
7492
7676
  if (!isAutoUpgradeSupported(packageManager)) {
7493
7677
  if (packageManager === "unknown") {
7494
7678
  console.log(
7495
- chalk23.yellow("Could not detect your package manager for auto-upgrade.")
7679
+ chalk25.yellow("Could not detect your package manager for auto-upgrade.")
7496
7680
  );
7497
7681
  } else {
7498
7682
  console.log(
7499
- chalk23.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
7683
+ chalk25.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
7500
7684
  );
7501
7685
  }
7502
- console.log(chalk23.yellow("Please upgrade manually:"));
7503
- console.log(chalk23.cyan(` ${getManualUpgradeCommand(packageManager)}`));
7686
+ console.log(chalk25.yellow("Please upgrade manually:"));
7687
+ console.log(chalk25.cyan(` ${getManualUpgradeCommand(packageManager)}`));
7504
7688
  console.log();
7505
7689
  return false;
7506
7690
  }
7507
7691
  console.log(`Upgrading via ${packageManager}...`);
7508
7692
  const success = await performUpgrade(packageManager);
7509
7693
  if (success) {
7510
- console.log(chalk23.green(`Upgraded to ${latestVersion}`));
7694
+ console.log(chalk25.green(`Upgraded to ${latestVersion}`));
7511
7695
  console.log();
7512
7696
  console.log("To continue, run:");
7513
- console.log(chalk23.cyan(` ${buildRerunCommand(prompt)}`));
7697
+ console.log(chalk25.cyan(` ${buildRerunCommand(prompt)}`));
7514
7698
  return true;
7515
7699
  }
7516
7700
  console.log();
7517
- console.log(chalk23.red("Upgrade failed. Please run manually:"));
7518
- console.log(chalk23.cyan(` ${getManualUpgradeCommand(packageManager)}`));
7701
+ console.log(chalk25.red("Upgrade failed. Please run manually:"));
7702
+ console.log(chalk25.cyan(` ${getManualUpgradeCommand(packageManager)}`));
7519
7703
  console.log();
7520
7704
  console.log("Then re-run:");
7521
- console.log(chalk23.cyan(` ${buildRerunCommand(prompt)}`));
7705
+ console.log(chalk25.cyan(` ${buildRerunCommand(prompt)}`));
7522
7706
  return true;
7523
7707
  }
7524
7708
 
@@ -7591,7 +7775,7 @@ async function saveCookState(state) {
7591
7775
  var CONFIG_FILE2 = "vm0.yaml";
7592
7776
  var ARTIFACT_DIR = "artifact";
7593
7777
  function printCommand(cmd) {
7594
- console.log(chalk24.dim(`> ${cmd}`));
7778
+ console.log(chalk26.dim(`> ${cmd}`));
7595
7779
  }
7596
7780
  function execVm0Command(args, options = {}) {
7597
7781
  return new Promise((resolve, reject) => {
@@ -7718,7 +7902,7 @@ async function autoPullArtifact(runOutput, artifactDir) {
7718
7902
  );
7719
7903
  if (serverVersion && existsSync8(artifactDir)) {
7720
7904
  console.log();
7721
- console.log(chalk24.bold("Pulling updated artifact:"));
7905
+ console.log(chalk26.bold("Pulling updated artifact:"));
7722
7906
  printCommand(`cd ${ARTIFACT_DIR}`);
7723
7907
  printCommand(`vm0 artifact pull ${serverVersion}`);
7724
7908
  try {
@@ -7728,14 +7912,14 @@ async function autoPullArtifact(runOutput, artifactDir) {
7728
7912
  });
7729
7913
  printCommand("cd ..");
7730
7914
  } catch (error) {
7731
- console.error(chalk24.red(`\u2717 Artifact pull failed`));
7915
+ console.error(chalk26.red(`\u2717 Artifact pull failed`));
7732
7916
  if (error instanceof Error) {
7733
- console.error(chalk24.dim(` ${error.message}`));
7917
+ console.error(chalk26.dim(` ${error.message}`));
7734
7918
  }
7735
7919
  }
7736
7920
  }
7737
7921
  }
7738
- var cookCmd = new Command20().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml");
7922
+ var cookCmd = new Command22().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml");
7739
7923
  cookCmd.argument("[prompt]", "Prompt for the agent").option(
7740
7924
  "--env-file <path>",
7741
7925
  "Load environment variables from file (priority: CLI flags > file > env vars)"
@@ -7743,15 +7927,15 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7743
7927
  // eslint-disable-next-line complexity -- TODO: refactor complex function
7744
7928
  async (prompt, options) => {
7745
7929
  if (!options.noAutoUpdate) {
7746
- const shouldExit = await checkAndUpgrade("9.3.0", prompt);
7930
+ const shouldExit = await checkAndUpgrade("9.4.0", prompt);
7747
7931
  if (shouldExit) {
7748
7932
  process.exit(0);
7749
7933
  }
7750
7934
  }
7751
7935
  const cwd = process.cwd();
7752
- console.log(chalk24.bold(`Reading config: ${CONFIG_FILE2}`));
7936
+ console.log(chalk26.bold(`Reading config: ${CONFIG_FILE2}`));
7753
7937
  if (!existsSync8(CONFIG_FILE2)) {
7754
- console.error(chalk24.red(`\u2717 Config file not found: ${CONFIG_FILE2}`));
7938
+ console.error(chalk26.red(`\u2717 Config file not found: ${CONFIG_FILE2}`));
7755
7939
  process.exit(1);
7756
7940
  }
7757
7941
  let config;
@@ -7759,22 +7943,22 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7759
7943
  const content = await readFile7(CONFIG_FILE2, "utf8");
7760
7944
  config = parseYaml4(content);
7761
7945
  } catch (error) {
7762
- console.error(chalk24.red("\u2717 Invalid YAML format"));
7946
+ console.error(chalk26.red("\u2717 Invalid YAML format"));
7763
7947
  if (error instanceof Error) {
7764
- console.error(chalk24.dim(` ${error.message}`));
7948
+ console.error(chalk26.dim(` ${error.message}`));
7765
7949
  }
7766
7950
  process.exit(1);
7767
7951
  }
7768
7952
  const validation = validateAgentCompose(config);
7769
7953
  if (!validation.valid) {
7770
- console.error(chalk24.red(`\u2717 ${validation.error}`));
7954
+ console.error(chalk26.red(`\u2717 ${validation.error}`));
7771
7955
  process.exit(1);
7772
7956
  }
7773
7957
  const agentNames = Object.keys(config.agents);
7774
7958
  const agentName = agentNames[0];
7775
7959
  const volumeCount = config.volumes ? Object.keys(config.volumes).length : 0;
7776
7960
  console.log(
7777
- chalk24.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
7961
+ chalk26.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
7778
7962
  );
7779
7963
  const requiredVarNames = extractRequiredVarNames(config);
7780
7964
  if (requiredVarNames.length > 0) {
@@ -7785,12 +7969,12 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7785
7969
  );
7786
7970
  if (missingVars.length > 0) {
7787
7971
  console.log();
7788
- console.error(chalk24.red("\u2717 Missing required variables:"));
7972
+ console.error(chalk26.red("\u2717 Missing required variables:"));
7789
7973
  for (const varName of missingVars) {
7790
- console.error(chalk24.red(` ${varName}`));
7974
+ console.error(chalk26.red(` ${varName}`));
7791
7975
  }
7792
7976
  console.error(
7793
- chalk24.dim(
7977
+ chalk26.dim(
7794
7978
  "\n Provide via --env-file, or set as environment variables"
7795
7979
  )
7796
7980
  );
@@ -7798,22 +7982,22 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7798
7982
  }
7799
7983
  } catch (error) {
7800
7984
  if (error instanceof Error) {
7801
- console.error(chalk24.red(`\u2717 ${error.message}`));
7985
+ console.error(chalk26.red(`\u2717 ${error.message}`));
7802
7986
  }
7803
7987
  process.exit(1);
7804
7988
  }
7805
7989
  }
7806
7990
  if (config.volumes && Object.keys(config.volumes).length > 0) {
7807
7991
  console.log();
7808
- console.log(chalk24.bold("Processing volumes:"));
7992
+ console.log(chalk26.bold("Processing volumes:"));
7809
7993
  for (const volumeConfig of Object.values(config.volumes)) {
7810
7994
  const volumeDir = path11.join(cwd, volumeConfig.name);
7811
7995
  if (!existsSync8(volumeDir)) {
7812
7996
  console.error(
7813
- chalk24.red(`\u2717 Directory not found: ${volumeConfig.name}`)
7997
+ chalk26.red(`\u2717 Directory not found: ${volumeConfig.name}`)
7814
7998
  );
7815
7999
  console.error(
7816
- chalk24.dim(" Create the directory and add files first")
8000
+ chalk26.dim(" Create the directory and add files first")
7817
8001
  );
7818
8002
  process.exit(1);
7819
8003
  }
@@ -7837,16 +8021,16 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7837
8021
  });
7838
8022
  printCommand("cd ..");
7839
8023
  } catch (error) {
7840
- console.error(chalk24.red(`\u2717 Failed`));
8024
+ console.error(chalk26.red(`\u2717 Failed`));
7841
8025
  if (error instanceof Error) {
7842
- console.error(chalk24.dim(` ${error.message}`));
8026
+ console.error(chalk26.dim(` ${error.message}`));
7843
8027
  }
7844
8028
  process.exit(1);
7845
8029
  }
7846
8030
  }
7847
8031
  }
7848
8032
  console.log();
7849
- console.log(chalk24.bold("Processing artifact:"));
8033
+ console.log(chalk26.bold("Processing artifact:"));
7850
8034
  const artifactDir = path11.join(cwd, ARTIFACT_DIR);
7851
8035
  try {
7852
8036
  if (!existsSync8(artifactDir)) {
@@ -7869,14 +8053,14 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7869
8053
  });
7870
8054
  printCommand("cd ..");
7871
8055
  } catch (error) {
7872
- console.error(chalk24.red(`\u2717 Failed`));
8056
+ console.error(chalk26.red(`\u2717 Failed`));
7873
8057
  if (error instanceof Error) {
7874
- console.error(chalk24.dim(` ${error.message}`));
8058
+ console.error(chalk26.dim(` ${error.message}`));
7875
8059
  }
7876
8060
  process.exit(1);
7877
8061
  }
7878
8062
  console.log();
7879
- console.log(chalk24.bold("Composing agent:"));
8063
+ console.log(chalk26.bold("Composing agent:"));
7880
8064
  const composeArgs = options.yes ? ["compose", "--yes", CONFIG_FILE2] : ["compose", CONFIG_FILE2];
7881
8065
  printCommand(`vm0 ${composeArgs.join(" ")}`);
7882
8066
  try {
@@ -7884,15 +8068,15 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
7884
8068
  cwd
7885
8069
  });
7886
8070
  } catch (error) {
7887
- console.error(chalk24.red(`\u2717 Compose failed`));
8071
+ console.error(chalk26.red(`\u2717 Compose failed`));
7888
8072
  if (error instanceof Error) {
7889
- console.error(chalk24.dim(` ${error.message}`));
8073
+ console.error(chalk26.dim(` ${error.message}`));
7890
8074
  }
7891
8075
  process.exit(1);
7892
8076
  }
7893
8077
  if (prompt) {
7894
8078
  console.log();
7895
- console.log(chalk24.bold("Running agent:"));
8079
+ console.log(chalk26.bold("Running agent:"));
7896
8080
  printCommand(
7897
8081
  `vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "${prompt}"`
7898
8082
  );
@@ -7936,8 +8120,8 @@ cookCmd.command("logs").description("View logs from the last cook run").option("
7936
8120
  async (options) => {
7937
8121
  const state = await loadCookState();
7938
8122
  if (!state.lastRunId) {
7939
- console.error(chalk24.red("\u2717 No previous run found"));
7940
- console.error(chalk24.dim(" Run 'vm0 cook <prompt>' first"));
8123
+ console.error(chalk26.red("\u2717 No previous run found"));
8124
+ console.error(chalk26.dim(" Run 'vm0 cook <prompt>' first"));
7941
8125
  process.exit(1);
7942
8126
  }
7943
8127
  const args = ["logs", state.lastRunId];
@@ -7983,8 +8167,8 @@ cookCmd.command("continue").description(
7983
8167
  async (prompt, options) => {
7984
8168
  const state = await loadCookState();
7985
8169
  if (!state.lastSessionId) {
7986
- console.error(chalk24.red("\u2717 No previous session found"));
7987
- console.error(chalk24.dim(" Run 'vm0 cook <prompt>' first"));
8170
+ console.error(chalk26.red("\u2717 No previous session found"));
8171
+ console.error(chalk26.dim(" Run 'vm0 cook <prompt>' first"));
7988
8172
  process.exit(1);
7989
8173
  }
7990
8174
  const cwd = process.cwd();
@@ -8030,8 +8214,8 @@ cookCmd.command("resume").description(
8030
8214
  async (prompt, options) => {
8031
8215
  const state = await loadCookState();
8032
8216
  if (!state.lastCheckpointId) {
8033
- console.error(chalk24.red("\u2717 No previous checkpoint found"));
8034
- console.error(chalk24.dim(" Run 'vm0 cook <prompt>' first"));
8217
+ console.error(chalk26.red("\u2717 No previous checkpoint found"));
8218
+ console.error(chalk26.dim(" Run 'vm0 cook <prompt>' first"));
8035
8219
  process.exit(1);
8036
8220
  }
8037
8221
  const cwd = process.cwd();
@@ -8071,8 +8255,8 @@ cookCmd.command("resume").description(
8071
8255
  var cookCommand = cookCmd;
8072
8256
 
8073
8257
  // src/commands/logs/index.ts
8074
- import { Command as Command21 } from "commander";
8075
- import chalk25 from "chalk";
8258
+ import { Command as Command23 } from "commander";
8259
+ import chalk27 from "chalk";
8076
8260
 
8077
8261
  // src/lib/utils/time-parser.ts
8078
8262
  function parseTime(timeStr) {
@@ -8126,36 +8310,36 @@ function formatMetric(metric) {
8126
8310
  }
8127
8311
  function formatNetworkLog(entry) {
8128
8312
  if (entry.mode === "sni" || !entry.method) {
8129
- const actionColor = entry.action === "ALLOW" ? chalk25.green : chalk25.red;
8313
+ const actionColor = entry.action === "ALLOW" ? chalk27.green : chalk27.red;
8130
8314
  const host = entry.host || "unknown";
8131
8315
  const port = entry.port || 443;
8132
- return `[${entry.timestamp}] ${chalk25.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk25.dim(entry.rule_matched || "")}`;
8316
+ return `[${entry.timestamp}] ${chalk27.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk27.dim(entry.rule_matched || "")}`;
8133
8317
  }
8134
8318
  let statusColor;
8135
8319
  const status = entry.status || 0;
8136
8320
  if (status >= 200 && status < 300) {
8137
- statusColor = chalk25.green;
8321
+ statusColor = chalk27.green;
8138
8322
  } else if (status >= 300 && status < 400) {
8139
- statusColor = chalk25.yellow;
8323
+ statusColor = chalk27.yellow;
8140
8324
  } else if (status >= 400) {
8141
- statusColor = chalk25.red;
8325
+ statusColor = chalk27.red;
8142
8326
  } else {
8143
- statusColor = chalk25.gray;
8327
+ statusColor = chalk27.gray;
8144
8328
  }
8145
8329
  let latencyColor;
8146
8330
  const latencyMs = entry.latency_ms || 0;
8147
8331
  if (latencyMs < 500) {
8148
- latencyColor = chalk25.green;
8332
+ latencyColor = chalk27.green;
8149
8333
  } else if (latencyMs < 2e3) {
8150
- latencyColor = chalk25.yellow;
8334
+ latencyColor = chalk27.yellow;
8151
8335
  } else {
8152
- latencyColor = chalk25.red;
8336
+ latencyColor = chalk27.red;
8153
8337
  }
8154
8338
  const method = entry.method || "???";
8155
8339
  const requestSize = entry.request_size || 0;
8156
8340
  const responseSize = entry.response_size || 0;
8157
8341
  const url = entry.url || entry.host || "unknown";
8158
- return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk25.dim(url)}`;
8342
+ return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk27.dim(url)}`;
8159
8343
  }
8160
8344
  function renderAgentEvent(event, provider) {
8161
8345
  const eventData = event.eventData;
@@ -8178,7 +8362,7 @@ function getLogType(options) {
8178
8362
  ].filter(Boolean).length;
8179
8363
  if (selected > 1) {
8180
8364
  console.error(
8181
- chalk25.red(
8365
+ chalk27.red(
8182
8366
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
8183
8367
  )
8184
8368
  );
@@ -8189,7 +8373,7 @@ function getLogType(options) {
8189
8373
  if (options.network) return "network";
8190
8374
  return "agent";
8191
8375
  }
8192
- var logsCommand = new Command21().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
8376
+ var logsCommand = new Command23().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
8193
8377
  "--since <time>",
8194
8378
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
8195
8379
  ).option("--tail <n>", "Show last N entries (default: 5, max: 100)").option("--head <n>", "Show first N entries (max: 100)").action(
@@ -8198,7 +8382,7 @@ var logsCommand = new Command21().name("logs").description("View logs for an age
8198
8382
  const logType = getLogType(options);
8199
8383
  if (options.tail !== void 0 && options.head !== void 0) {
8200
8384
  console.error(
8201
- chalk25.red("Options --tail and --head are mutually exclusive")
8385
+ chalk27.red("Options --tail and --head are mutually exclusive")
8202
8386
  );
8203
8387
  process.exit(1);
8204
8388
  }
@@ -8235,7 +8419,7 @@ var logsCommand = new Command21().name("logs").description("View logs for an age
8235
8419
  async function showAgentEvents(runId, options) {
8236
8420
  const response = await apiClient.getAgentEvents(runId, options);
8237
8421
  if (response.events.length === 0) {
8238
- console.log(chalk25.yellow("No agent events found for this run"));
8422
+ console.log(chalk27.yellow("No agent events found for this run"));
8239
8423
  return;
8240
8424
  }
8241
8425
  const events = options.order === "desc" ? [...response.events].reverse() : response.events;
@@ -8245,7 +8429,7 @@ async function showAgentEvents(runId, options) {
8245
8429
  if (response.hasMore) {
8246
8430
  console.log();
8247
8431
  console.log(
8248
- chalk25.dim(
8432
+ chalk27.dim(
8249
8433
  `Showing ${response.events.length} events. Use --tail to see more.`
8250
8434
  )
8251
8435
  );
@@ -8254,21 +8438,21 @@ async function showAgentEvents(runId, options) {
8254
8438
  async function showSystemLog(runId, options) {
8255
8439
  const response = await apiClient.getSystemLog(runId, options);
8256
8440
  if (!response.systemLog) {
8257
- console.log(chalk25.yellow("No system log found for this run"));
8441
+ console.log(chalk27.yellow("No system log found for this run"));
8258
8442
  return;
8259
8443
  }
8260
8444
  console.log(response.systemLog);
8261
8445
  if (response.hasMore) {
8262
8446
  console.log();
8263
8447
  console.log(
8264
- chalk25.dim("More log entries available. Use --tail to see more.")
8448
+ chalk27.dim("More log entries available. Use --tail to see more.")
8265
8449
  );
8266
8450
  }
8267
8451
  }
8268
8452
  async function showMetrics(runId, options) {
8269
8453
  const response = await apiClient.getMetrics(runId, options);
8270
8454
  if (response.metrics.length === 0) {
8271
- console.log(chalk25.yellow("No metrics found for this run"));
8455
+ console.log(chalk27.yellow("No metrics found for this run"));
8272
8456
  return;
8273
8457
  }
8274
8458
  const metrics = options.order === "desc" ? [...response.metrics].reverse() : response.metrics;
@@ -8278,7 +8462,7 @@ async function showMetrics(runId, options) {
8278
8462
  if (response.hasMore) {
8279
8463
  console.log();
8280
8464
  console.log(
8281
- chalk25.dim(
8465
+ chalk27.dim(
8282
8466
  `Showing ${response.metrics.length} metrics. Use --tail to see more.`
8283
8467
  )
8284
8468
  );
@@ -8288,7 +8472,7 @@ async function showNetworkLogs(runId, options) {
8288
8472
  const response = await apiClient.getNetworkLogs(runId, options);
8289
8473
  if (response.networkLogs.length === 0) {
8290
8474
  console.log(
8291
- chalk25.yellow(
8475
+ chalk27.yellow(
8292
8476
  "No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner"
8293
8477
  )
8294
8478
  );
@@ -8301,7 +8485,7 @@ async function showNetworkLogs(runId, options) {
8301
8485
  if (response.hasMore) {
8302
8486
  console.log();
8303
8487
  console.log(
8304
- chalk25.dim(
8488
+ chalk27.dim(
8305
8489
  `Showing ${response.networkLogs.length} network logs. Use --tail to see more.`
8306
8490
  )
8307
8491
  );
@@ -8310,31 +8494,31 @@ async function showNetworkLogs(runId, options) {
8310
8494
  function handleError2(error, runId) {
8311
8495
  if (error instanceof Error) {
8312
8496
  if (error.message.includes("Not authenticated")) {
8313
- console.error(chalk25.red("Not authenticated. Run: vm0 auth login"));
8497
+ console.error(chalk27.red("Not authenticated. Run: vm0 auth login"));
8314
8498
  } else if (error.message.includes("not found")) {
8315
- console.error(chalk25.red(`Run not found: ${runId}`));
8499
+ console.error(chalk27.red(`Run not found: ${runId}`));
8316
8500
  } else if (error.message.includes("Invalid time format")) {
8317
- console.error(chalk25.red(error.message));
8501
+ console.error(chalk27.red(error.message));
8318
8502
  } else {
8319
- console.error(chalk25.red("Failed to fetch logs"));
8320
- console.error(chalk25.dim(` ${error.message}`));
8503
+ console.error(chalk27.red("Failed to fetch logs"));
8504
+ console.error(chalk27.dim(` ${error.message}`));
8321
8505
  }
8322
8506
  } else {
8323
- console.error(chalk25.red("An unexpected error occurred"));
8507
+ console.error(chalk27.red("An unexpected error occurred"));
8324
8508
  }
8325
8509
  }
8326
8510
 
8327
8511
  // src/commands/scope/index.ts
8328
- import { Command as Command24 } from "commander";
8512
+ import { Command as Command26 } from "commander";
8329
8513
 
8330
8514
  // src/commands/scope/status.ts
8331
- import { Command as Command22 } from "commander";
8332
- import chalk26 from "chalk";
8333
- var statusCommand3 = new Command22().name("status").description("View current scope status").action(async () => {
8515
+ import { Command as Command24 } from "commander";
8516
+ import chalk28 from "chalk";
8517
+ var statusCommand3 = new Command24().name("status").description("View current scope status").action(async () => {
8334
8518
  try {
8335
8519
  const scope = await getScope();
8336
- console.log(chalk26.bold("Scope Information:"));
8337
- console.log(` Slug: ${chalk26.green(scope.slug)}`);
8520
+ console.log(chalk28.bold("Scope Information:"));
8521
+ console.log(` Slug: ${chalk28.green(scope.slug)}`);
8338
8522
  console.log(` Type: ${scope.type}`);
8339
8523
  console.log(
8340
8524
  ` Created: ${new Date(scope.createdAt).toLocaleDateString()}`
@@ -8342,29 +8526,29 @@ var statusCommand3 = new Command22().name("status").description("View current sc
8342
8526
  } catch (error) {
8343
8527
  if (error instanceof Error) {
8344
8528
  if (error.message.includes("Not authenticated")) {
8345
- console.error(chalk26.red("\u2717 Not authenticated. Run: vm0 auth login"));
8529
+ console.error(chalk28.red("\u2717 Not authenticated. Run: vm0 auth login"));
8346
8530
  } else if (error.message.includes("No scope configured")) {
8347
- console.log(chalk26.yellow("No scope configured"));
8531
+ console.log(chalk28.yellow("No scope configured"));
8348
8532
  console.log();
8349
8533
  console.log("Set your scope with:");
8350
- console.log(chalk26.cyan(" vm0 scope set <slug>"));
8534
+ console.log(chalk28.cyan(" vm0 scope set <slug>"));
8351
8535
  console.log();
8352
8536
  console.log("Example:");
8353
- console.log(chalk26.dim(" vm0 scope set myusername"));
8537
+ console.log(chalk28.dim(" vm0 scope set myusername"));
8354
8538
  } else {
8355
- console.error(chalk26.red(`\u2717 ${error.message}`));
8539
+ console.error(chalk28.red(`\u2717 ${error.message}`));
8356
8540
  }
8357
8541
  } else {
8358
- console.error(chalk26.red("\u2717 An unexpected error occurred"));
8542
+ console.error(chalk28.red("\u2717 An unexpected error occurred"));
8359
8543
  }
8360
8544
  process.exit(1);
8361
8545
  }
8362
8546
  });
8363
8547
 
8364
8548
  // src/commands/scope/set.ts
8365
- import { Command as Command23 } from "commander";
8366
- import chalk27 from "chalk";
8367
- var setCommand = new Command23().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)").action(async (slug, options) => {
8549
+ import { Command as Command25 } from "commander";
8550
+ import chalk29 from "chalk";
8551
+ var setCommand = new Command25().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)").action(async (slug, options) => {
8368
8552
  try {
8369
8553
  let existingScope;
8370
8554
  try {
@@ -8378,66 +8562,66 @@ var setCommand = new Command23().name("set").description("Set your scope slug").
8378
8562
  if (existingScope) {
8379
8563
  if (!options.force) {
8380
8564
  console.error(
8381
- chalk27.yellow(`You already have a scope: ${existingScope.slug}`)
8565
+ chalk29.yellow(`You already have a scope: ${existingScope.slug}`)
8382
8566
  );
8383
8567
  console.error();
8384
8568
  console.error("To change your scope, use --force:");
8385
- console.error(chalk27.cyan(` vm0 scope set ${slug} --force`));
8569
+ console.error(chalk29.cyan(` vm0 scope set ${slug} --force`));
8386
8570
  console.error();
8387
8571
  console.error(
8388
- chalk27.yellow(
8572
+ chalk29.yellow(
8389
8573
  "Warning: Changing your scope may break existing agent references."
8390
8574
  )
8391
8575
  );
8392
8576
  process.exit(1);
8393
8577
  }
8394
8578
  scope = await updateScope({ slug, force: true });
8395
- console.log(chalk27.green(`\u2713 Scope updated to ${scope.slug}`));
8579
+ console.log(chalk29.green(`\u2713 Scope updated to ${scope.slug}`));
8396
8580
  } else {
8397
8581
  scope = await createScope({ slug });
8398
- console.log(chalk27.green(`\u2713 Scope created: ${scope.slug}`));
8582
+ console.log(chalk29.green(`\u2713 Scope created: ${scope.slug}`));
8399
8583
  }
8400
8584
  console.log();
8401
8585
  console.log("Your agents will now be namespaced as:");
8402
- console.log(chalk27.cyan(` ${scope.slug}/<agent-name>`));
8586
+ console.log(chalk29.cyan(` ${scope.slug}/<agent-name>`));
8403
8587
  } catch (error) {
8404
8588
  if (error instanceof Error) {
8405
8589
  if (error.message.includes("Not authenticated")) {
8406
- console.error(chalk27.red("\u2717 Not authenticated. Run: vm0 auth login"));
8590
+ console.error(chalk29.red("\u2717 Not authenticated. Run: vm0 auth login"));
8407
8591
  } else if (error.message.includes("already exists")) {
8408
8592
  console.error(
8409
- chalk27.red(
8593
+ chalk29.red(
8410
8594
  `\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
8411
8595
  )
8412
8596
  );
8413
8597
  } else if (error.message.includes("reserved")) {
8414
- console.error(chalk27.red(`\u2717 ${error.message}`));
8598
+ console.error(chalk29.red(`\u2717 ${error.message}`));
8415
8599
  } else if (error.message.includes("vm0")) {
8416
8600
  console.error(
8417
- chalk27.red(
8601
+ chalk29.red(
8418
8602
  "\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
8419
8603
  )
8420
8604
  );
8421
8605
  } else {
8422
- console.error(chalk27.red(`\u2717 ${error.message}`));
8606
+ console.error(chalk29.red(`\u2717 ${error.message}`));
8423
8607
  }
8424
8608
  } else {
8425
- console.error(chalk27.red("\u2717 An unexpected error occurred"));
8609
+ console.error(chalk29.red("\u2717 An unexpected error occurred"));
8426
8610
  }
8427
8611
  process.exit(1);
8428
8612
  }
8429
8613
  });
8430
8614
 
8431
8615
  // src/commands/scope/index.ts
8432
- var scopeCommand = new Command24().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand3).addCommand(setCommand);
8616
+ var scopeCommand = new Command26().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand3).addCommand(setCommand);
8433
8617
 
8434
8618
  // src/commands/agent/index.ts
8435
- import { Command as Command27 } from "commander";
8619
+ import { Command as Command29 } from "commander";
8436
8620
 
8437
8621
  // src/commands/agent/list.ts
8438
- import { Command as Command25 } from "commander";
8439
- import chalk28 from "chalk";
8440
- var listCommand3 = new Command25().name("list").alias("ls").description("List all agent composes").action(async () => {
8622
+ import { Command as Command27 } from "commander";
8623
+ import chalk30 from "chalk";
8624
+ var listCommand4 = new Command27().name("list").alias("ls").description("List all agent composes").action(async () => {
8441
8625
  try {
8442
8626
  const response = await httpGet("/api/agent/composes/list");
8443
8627
  if (!response.ok) {
@@ -8446,9 +8630,9 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
8446
8630
  }
8447
8631
  const data = await response.json();
8448
8632
  if (data.composes.length === 0) {
8449
- console.log(chalk28.dim("No agent composes found"));
8633
+ console.log(chalk30.dim("No agent composes found"));
8450
8634
  console.log(
8451
- chalk28.dim(" Create one with: vm0 compose <agent-compose.yaml>")
8635
+ chalk30.dim(" Create one with: vm0 compose <agent-compose.yaml>")
8452
8636
  );
8453
8637
  return;
8454
8638
  }
@@ -8456,9 +8640,9 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
8456
8640
  const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
8457
8641
  " "
8458
8642
  );
8459
- console.log(chalk28.dim(header));
8643
+ console.log(chalk30.dim(header));
8460
8644
  for (const compose of data.composes) {
8461
- const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk28.dim("-");
8645
+ const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk30.dim("-");
8462
8646
  const row = [
8463
8647
  compose.name.padEnd(nameWidth),
8464
8648
  versionShort,
@@ -8467,12 +8651,12 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
8467
8651
  console.log(row);
8468
8652
  }
8469
8653
  } catch (error) {
8470
- console.error(chalk28.red("\u2717 Failed to list agent composes"));
8654
+ console.error(chalk30.red("\u2717 Failed to list agent composes"));
8471
8655
  if (error instanceof Error) {
8472
8656
  if (error.message.includes("Not authenticated")) {
8473
- console.error(chalk28.dim(" Run: vm0 auth login"));
8657
+ console.error(chalk30.dim(" Run: vm0 auth login"));
8474
8658
  } else {
8475
- console.error(chalk28.dim(` ${error.message}`));
8659
+ console.error(chalk30.dim(` ${error.message}`));
8476
8660
  }
8477
8661
  }
8478
8662
  process.exit(1);
@@ -8480,8 +8664,8 @@ var listCommand3 = new Command25().name("list").alias("ls").description("List al
8480
8664
  });
8481
8665
 
8482
8666
  // src/commands/agent/status.ts
8483
- import { Command as Command26 } from "commander";
8484
- import chalk29 from "chalk";
8667
+ import { Command as Command28 } from "commander";
8668
+ import chalk31 from "chalk";
8485
8669
 
8486
8670
  // src/lib/domain/source-derivation.ts
8487
8671
  import * as fs9 from "fs/promises";
@@ -8605,27 +8789,27 @@ function formatVariableSources(sources) {
8605
8789
  if (sources.secrets.length > 0) {
8606
8790
  console.log(` Secrets:`);
8607
8791
  for (const secret of sources.secrets) {
8608
- const sourceInfo = chalk29.dim(`(${secret.source})`);
8792
+ const sourceInfo = chalk31.dim(`(${secret.source})`);
8609
8793
  console.log(` - ${secret.name.padEnd(20)} ${sourceInfo}`);
8610
8794
  }
8611
8795
  }
8612
8796
  if (sources.vars.length > 0) {
8613
8797
  console.log(` Vars:`);
8614
8798
  for (const v of sources.vars) {
8615
- const sourceInfo = chalk29.dim(`(${v.source})`);
8799
+ const sourceInfo = chalk31.dim(`(${v.source})`);
8616
8800
  console.log(` - ${v.name.padEnd(20)} ${sourceInfo}`);
8617
8801
  }
8618
8802
  }
8619
8803
  if (sources.credentials.length > 0) {
8620
8804
  console.log(` Credentials:`);
8621
8805
  for (const cred of sources.credentials) {
8622
- const sourceInfo = chalk29.dim(`(${cred.source})`);
8806
+ const sourceInfo = chalk31.dim(`(${cred.source})`);
8623
8807
  console.log(` - ${cred.name.padEnd(20)} ${sourceInfo}`);
8624
8808
  }
8625
8809
  }
8626
8810
  }
8627
8811
  function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
8628
- console.log(` ${chalk29.cyan(agentName)}:`);
8812
+ console.log(` ${chalk31.cyan(agentName)}:`);
8629
8813
  console.log(` Framework: ${agent.framework}`);
8630
8814
  if (agent.image) {
8631
8815
  console.log(` Image: ${agent.image}`);
@@ -8644,16 +8828,16 @@ function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
8644
8828
  }
8645
8829
  }
8646
8830
  function formatComposeOutput(name, versionId, content, variableSources) {
8647
- console.log(chalk29.bold("Name:") + ` ${name}`);
8648
- console.log(chalk29.bold("Version:") + ` ${versionId}`);
8831
+ console.log(chalk31.bold("Name:") + ` ${name}`);
8832
+ console.log(chalk31.bold("Version:") + ` ${versionId}`);
8649
8833
  console.log();
8650
- console.log(chalk29.bold("Agents:"));
8834
+ console.log(chalk31.bold("Agents:"));
8651
8835
  for (const [agentName, agent] of Object.entries(content.agents)) {
8652
8836
  const agentSources = variableSources?.get(agentName);
8653
8837
  formatAgentDetails(agentName, agent, agentSources, content.volumes);
8654
8838
  }
8655
8839
  }
8656
- var statusCommand4 = new Command26().name("status").description("Show status of agent compose").argument(
8840
+ var statusCommand4 = new Command28().name("status").description("Show status of agent compose").argument(
8657
8841
  "<name[:version]>",
8658
8842
  "Agent name with optional version (e.g., my-agent:latest or my-agent:a1b2c3d4)"
8659
8843
  ).option("--no-sources", "Skip fetching skills to determine variable sources").action(async (argument, options) => {
@@ -8670,8 +8854,8 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8670
8854
  }
8671
8855
  const compose = await getComposeByName(name);
8672
8856
  if (!compose) {
8673
- console.error(chalk29.red(`\u2717 Agent compose not found: ${name}`));
8674
- console.error(chalk29.dim(" Run: vm0 agent list"));
8857
+ console.error(chalk31.red(`\u2717 Agent compose not found: ${name}`));
8858
+ console.error(chalk31.dim(" Run: vm0 agent list"));
8675
8859
  process.exit(1);
8676
8860
  }
8677
8861
  let resolvedVersionId = compose.headVersionId;
@@ -8682,9 +8866,9 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8682
8866
  resolvedVersionId = versionInfo.versionId;
8683
8867
  } catch (error) {
8684
8868
  if (error instanceof Error && error.message.includes("not found")) {
8685
- console.error(chalk29.red(`\u2717 Version not found: ${version}`));
8869
+ console.error(chalk31.red(`\u2717 Version not found: ${version}`));
8686
8870
  console.error(
8687
- chalk29.dim(
8871
+ chalk31.dim(
8688
8872
  ` HEAD version: ${compose.headVersionId?.slice(0, 8)}`
8689
8873
  )
8690
8874
  );
@@ -8697,7 +8881,7 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8697
8881
  }
8698
8882
  }
8699
8883
  if (!resolvedVersionId || !compose.content) {
8700
- console.error(chalk29.red(`\u2717 No version found for: ${name}`));
8884
+ console.error(chalk31.red(`\u2717 No version found for: ${name}`));
8701
8885
  process.exit(1);
8702
8886
  }
8703
8887
  const content = compose.content;
@@ -8708,7 +8892,7 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8708
8892
  });
8709
8893
  } catch {
8710
8894
  console.error(
8711
- chalk29.yellow(
8895
+ chalk31.yellow(
8712
8896
  "\u26A0 Warning: Failed to fetch skill sources, showing basic info"
8713
8897
  )
8714
8898
  );
@@ -8720,12 +8904,12 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8720
8904
  variableSources
8721
8905
  );
8722
8906
  } catch (error) {
8723
- console.error(chalk29.red("\u2717 Failed to get agent compose status"));
8907
+ console.error(chalk31.red("\u2717 Failed to get agent compose status"));
8724
8908
  if (error instanceof Error) {
8725
8909
  if (error.message.includes("Not authenticated")) {
8726
- console.error(chalk29.dim(" Run: vm0 auth login"));
8910
+ console.error(chalk31.dim(" Run: vm0 auth login"));
8727
8911
  } else {
8728
- console.error(chalk29.dim(` ${error.message}`));
8912
+ console.error(chalk31.dim(` ${error.message}`));
8729
8913
  }
8730
8914
  }
8731
8915
  process.exit(1);
@@ -8733,11 +8917,11 @@ var statusCommand4 = new Command26().name("status").description("Show status of
8733
8917
  });
8734
8918
 
8735
8919
  // src/commands/agent/index.ts
8736
- var agentCommand = new Command27().name("agent").description("Manage agent composes").addCommand(listCommand3).addCommand(statusCommand4);
8920
+ var agentCommand = new Command29().name("agent").description("Manage agent composes").addCommand(listCommand4).addCommand(statusCommand4);
8737
8921
 
8738
8922
  // src/commands/init.ts
8739
- import { Command as Command28 } from "commander";
8740
- import chalk30 from "chalk";
8923
+ import { Command as Command30 } from "commander";
8924
+ import chalk32 from "chalk";
8741
8925
  import path13 from "path";
8742
8926
  import { existsSync as existsSync9 } from "fs";
8743
8927
  import { writeFile as writeFile6 } from "fs/promises";
@@ -8775,14 +8959,14 @@ function checkExistingFiles() {
8775
8959
  if (existsSync9(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
8776
8960
  return existingFiles;
8777
8961
  }
8778
- var initCommand3 = new Command28().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
8962
+ var initCommand3 = new Command30().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
8779
8963
  const existingFiles = checkExistingFiles();
8780
8964
  if (existingFiles.length > 0 && !options.force) {
8781
8965
  for (const file of existingFiles) {
8782
- console.log(chalk30.red(`\u2717 ${file} already exists`));
8966
+ console.log(chalk32.red(`\u2717 ${file} already exists`));
8783
8967
  }
8784
8968
  console.log();
8785
- console.log(`To overwrite: ${chalk30.cyan("vm0 init --force")}`);
8969
+ console.log(`To overwrite: ${chalk32.cyan("vm0 init --force")}`);
8786
8970
  process.exit(1);
8787
8971
  }
8788
8972
  let agentName;
@@ -8790,9 +8974,9 @@ var initCommand3 = new Command28().name("init").description("Initialize a new VM
8790
8974
  agentName = options.name.trim();
8791
8975
  } else if (!isInteractive()) {
8792
8976
  console.error(
8793
- chalk30.red("\u2717 --name flag is required in non-interactive mode")
8977
+ chalk32.red("\u2717 --name flag is required in non-interactive mode")
8794
8978
  );
8795
- console.error(chalk30.dim(" Usage: vm0 init --name <agent-name>"));
8979
+ console.error(chalk32.dim(" Usage: vm0 init --name <agent-name>"));
8796
8980
  process.exit(1);
8797
8981
  } else {
8798
8982
  const dirName = path13.basename(process.cwd());
@@ -8808,44 +8992,44 @@ var initCommand3 = new Command28().name("init").description("Initialize a new VM
8808
8992
  }
8809
8993
  );
8810
8994
  if (name === void 0) {
8811
- console.log(chalk30.dim("Cancelled"));
8995
+ console.log(chalk32.dim("Cancelled"));
8812
8996
  return;
8813
8997
  }
8814
8998
  agentName = name;
8815
8999
  }
8816
9000
  if (!agentName || !validateAgentName(agentName)) {
8817
- console.log(chalk30.red("\u2717 Invalid agent name"));
9001
+ console.log(chalk32.red("\u2717 Invalid agent name"));
8818
9002
  console.log(
8819
- chalk30.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
9003
+ chalk32.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
8820
9004
  );
8821
- console.log(chalk30.dim(" Must start and end with letter or number"));
9005
+ console.log(chalk32.dim(" Must start and end with letter or number"));
8822
9006
  process.exit(1);
8823
9007
  }
8824
9008
  await writeFile6(VM0_YAML_FILE, generateVm0Yaml(agentName));
8825
9009
  const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
8826
- console.log(chalk30.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
9010
+ console.log(chalk32.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
8827
9011
  await writeFile6(AGENTS_MD_FILE, generateAgentsMd());
8828
9012
  const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
8829
- console.log(chalk30.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
9013
+ console.log(chalk32.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
8830
9014
  console.log();
8831
9015
  console.log("Next steps:");
8832
9016
  console.log(
8833
- ` 1. Set model provider (one-time): ${chalk30.cyan("vm0 model-provider setup")}`
9017
+ ` 1. Set model provider (one-time): ${chalk32.cyan("vm0 model-provider setup")}`
8834
9018
  );
8835
9019
  console.log(
8836
- ` 2. Edit ${chalk30.cyan("AGENTS.md")} to customize your agent's workflow`
9020
+ ` 2. Edit ${chalk32.cyan("AGENTS.md")} to customize your agent's workflow`
8837
9021
  );
8838
9022
  console.log(
8839
- ` 3. Run your agent: ${chalk30.cyan(`vm0 cook "let's start working."`)}`
9023
+ ` 3. Run your agent: ${chalk32.cyan(`vm0 cook "let's start working."`)}`
8840
9024
  );
8841
9025
  });
8842
9026
 
8843
9027
  // src/commands/schedule/index.ts
8844
- import { Command as Command35 } from "commander";
9028
+ import { Command as Command37 } from "commander";
8845
9029
 
8846
9030
  // src/commands/schedule/setup.ts
8847
- import { Command as Command29 } from "commander";
8848
- import chalk32 from "chalk";
9031
+ import { Command as Command31 } from "commander";
9032
+ import chalk34 from "chalk";
8849
9033
 
8850
9034
  // src/lib/domain/schedule-utils.ts
8851
9035
  import { parse as parseYaml5 } from "yaml";
@@ -8987,7 +9171,7 @@ async function resolveScheduleByAgent(agentName) {
8987
9171
  }
8988
9172
 
8989
9173
  // src/commands/schedule/gather-configuration.ts
8990
- import chalk31 from "chalk";
9174
+ import chalk33 from "chalk";
8991
9175
  var defaultPromptDeps = {
8992
9176
  isInteractive,
8993
9177
  promptConfirm,
@@ -9021,7 +9205,7 @@ async function handleSecrets(optionSecrets, existingSecretNames, deps) {
9021
9205
  if (keepSecrets) {
9022
9206
  return { secrets: {}, preserveExistingSecrets: true };
9023
9207
  }
9024
- console.log(chalk31.dim(" Note: You'll need to provide new secret values"));
9208
+ console.log(chalk33.dim(" Note: You'll need to provide new secret values"));
9025
9209
  return { secrets: {}, preserveExistingSecrets: false };
9026
9210
  }
9027
9211
  return { secrets: {}, preserveExistingSecrets: false };
@@ -9042,17 +9226,17 @@ async function handleVars(optionVars, existingVars, deps) {
9042
9226
  return {};
9043
9227
  }
9044
9228
  function displayMissingRequirements(missingSecrets, missingVars) {
9045
- console.log(chalk31.yellow("\nAgent requires the following configuration:"));
9229
+ console.log(chalk33.yellow("\nAgent requires the following configuration:"));
9046
9230
  if (missingSecrets.length > 0) {
9047
- console.log(chalk31.dim(" Secrets:"));
9231
+ console.log(chalk33.dim(" Secrets:"));
9048
9232
  for (const name of missingSecrets) {
9049
- console.log(chalk31.dim(` ${name}`));
9233
+ console.log(chalk33.dim(` ${name}`));
9050
9234
  }
9051
9235
  }
9052
9236
  if (missingVars.length > 0) {
9053
- console.log(chalk31.dim(" Vars:"));
9237
+ console.log(chalk33.dim(" Vars:"));
9054
9238
  for (const name of missingVars) {
9055
- console.log(chalk31.dim(` ${name}`));
9239
+ console.log(chalk33.dim(` ${name}`));
9056
9240
  }
9057
9241
  }
9058
9242
  console.log("");
@@ -9060,7 +9244,7 @@ function displayMissingRequirements(missingSecrets, missingVars) {
9060
9244
  async function promptForMissingSecrets(missingSecrets, secrets, deps) {
9061
9245
  for (const name of missingSecrets) {
9062
9246
  const value = await deps.promptPassword(
9063
- `Enter value for secret ${chalk31.cyan(name)}`
9247
+ `Enter value for secret ${chalk33.cyan(name)}`
9064
9248
  );
9065
9249
  if (value) {
9066
9250
  secrets[name] = value;
@@ -9070,7 +9254,7 @@ async function promptForMissingSecrets(missingSecrets, secrets, deps) {
9070
9254
  async function promptForMissingVars(missingVars, vars, deps) {
9071
9255
  for (const name of missingVars) {
9072
9256
  const value = await deps.promptText(
9073
- `Enter value for var ${chalk31.cyan(name)}`,
9257
+ `Enter value for var ${chalk33.cyan(name)}`,
9074
9258
  ""
9075
9259
  );
9076
9260
  if (value) {
@@ -9160,7 +9344,7 @@ function expandEnvVars(value) {
9160
9344
  const envValue = process.env[varName];
9161
9345
  if (envValue === void 0) {
9162
9346
  console.warn(
9163
- chalk32.yellow(` Warning: Environment variable ${varName} not set`)
9347
+ chalk34.yellow(` Warning: Environment variable ${varName} not set`)
9164
9348
  );
9165
9349
  return match;
9166
9350
  }
@@ -9227,7 +9411,7 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
9227
9411
  }
9228
9412
  if (!isInteractive()) {
9229
9413
  console.error(
9230
- chalk32.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
9414
+ chalk34.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
9231
9415
  );
9232
9416
  process.exit(1);
9233
9417
  }
@@ -9247,7 +9431,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
9247
9431
  const day2 = parseDayOption(optionDay, frequency);
9248
9432
  if (day2 === void 0) {
9249
9433
  console.error(
9250
- chalk32.red(
9434
+ chalk34.red(
9251
9435
  `\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
9252
9436
  )
9253
9437
  );
@@ -9256,7 +9440,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
9256
9440
  return day2;
9257
9441
  }
9258
9442
  if (!isInteractive()) {
9259
- console.error(chalk32.red("\u2717 --day is required for weekly/monthly"));
9443
+ console.error(chalk34.red("\u2717 --day is required for weekly/monthly"));
9260
9444
  process.exit(1);
9261
9445
  }
9262
9446
  if (frequency === "weekly") {
@@ -9275,7 +9459,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
9275
9459
  if (!dayStr) return null;
9276
9460
  const day = parseInt(dayStr, 10);
9277
9461
  if (isNaN(day) || day < 1 || day > 31) {
9278
- console.error(chalk32.red("\u2717 Day must be between 1 and 31"));
9462
+ console.error(chalk34.red("\u2717 Day must be between 1 and 31"));
9279
9463
  process.exit(1);
9280
9464
  }
9281
9465
  return day;
@@ -9284,13 +9468,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
9284
9468
  if (optionTime) {
9285
9469
  const validation = validateTimeFormat(optionTime);
9286
9470
  if (validation !== true) {
9287
- console.error(chalk32.red(`\u2717 Invalid time: ${validation}`));
9471
+ console.error(chalk34.red(`\u2717 Invalid time: ${validation}`));
9288
9472
  process.exit(1);
9289
9473
  }
9290
9474
  return optionTime;
9291
9475
  }
9292
9476
  if (!isInteractive()) {
9293
- console.error(chalk32.red("\u2717 --time is required (HH:MM format)"));
9477
+ console.error(chalk34.red("\u2717 --time is required (HH:MM format)"));
9294
9478
  process.exit(1);
9295
9479
  }
9296
9480
  return await promptText(
@@ -9303,7 +9487,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
9303
9487
  if (optionDay && optionTime) {
9304
9488
  if (!validateDateFormat(optionDay)) {
9305
9489
  console.error(
9306
- chalk32.red(
9490
+ chalk34.red(
9307
9491
  `\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
9308
9492
  )
9309
9493
  );
@@ -9311,16 +9495,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
9311
9495
  }
9312
9496
  if (!validateTimeFormat(optionTime)) {
9313
9497
  console.error(
9314
- chalk32.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
9498
+ chalk34.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
9315
9499
  );
9316
9500
  process.exit(1);
9317
9501
  }
9318
9502
  return `${optionDay} ${optionTime}`;
9319
9503
  }
9320
9504
  if (!isInteractive()) {
9321
- console.error(chalk32.red("\u2717 One-time schedules require interactive mode"));
9505
+ console.error(chalk34.red("\u2717 One-time schedules require interactive mode"));
9322
9506
  console.error(
9323
- chalk32.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
9507
+ chalk34.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
9324
9508
  );
9325
9509
  process.exit(1);
9326
9510
  }
@@ -9351,7 +9535,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
9351
9535
  async function gatherPromptText(optionPrompt, existingPrompt) {
9352
9536
  if (optionPrompt) return optionPrompt;
9353
9537
  if (!isInteractive()) {
9354
- console.error(chalk32.red("\u2717 --prompt is required"));
9538
+ console.error(chalk34.red("\u2717 --prompt is required"));
9355
9539
  process.exit(1);
9356
9540
  }
9357
9541
  return await promptText(
@@ -9362,8 +9546,8 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
9362
9546
  async function resolveAgent(agentName) {
9363
9547
  const compose = await getComposeByName(agentName);
9364
9548
  if (!compose) {
9365
- console.error(chalk32.red(`\u2717 Agent not found: ${agentName}`));
9366
- console.error(chalk32.dim(" Make sure the agent is composed first"));
9549
+ console.error(chalk34.red(`\u2717 Agent not found: ${agentName}`));
9550
+ console.error(chalk34.dim(" Make sure the agent is composed first"));
9367
9551
  process.exit(1);
9368
9552
  }
9369
9553
  return {
@@ -9410,7 +9594,7 @@ async function buildAndDeploy(params) {
9410
9594
  const expandedSecrets = expandEnvVarsInObject(params.secrets);
9411
9595
  console.log(
9412
9596
  `
9413
- Deploying schedule for agent ${chalk32.cyan(params.agentName)}...`
9597
+ Deploying schedule for agent ${chalk34.cyan(params.agentName)}...`
9414
9598
  );
9415
9599
  const deployResult = await deploySchedule({
9416
9600
  name: params.scheduleName,
@@ -9426,12 +9610,12 @@ Deploying schedule for agent ${chalk32.cyan(params.agentName)}...`
9426
9610
  return deployResult;
9427
9611
  }
9428
9612
  function handleSetupError(error) {
9429
- console.error(chalk32.red("\u2717 Failed to setup schedule"));
9613
+ console.error(chalk34.red("\u2717 Failed to setup schedule"));
9430
9614
  if (error instanceof Error) {
9431
9615
  if (error.message.includes("Not authenticated")) {
9432
- console.error(chalk32.dim(" Run: vm0 auth login"));
9616
+ console.error(chalk34.dim(" Run: vm0 auth login"));
9433
9617
  } else {
9434
- console.error(chalk32.dim(` ${error.message}`));
9618
+ console.error(chalk34.dim(` ${error.message}`));
9435
9619
  }
9436
9620
  }
9437
9621
  process.exit(1);
@@ -9439,56 +9623,56 @@ function handleSetupError(error) {
9439
9623
  function displayDeployResult(agentName, deployResult) {
9440
9624
  if (deployResult.created) {
9441
9625
  console.log(
9442
- chalk32.green(`\u2713 Created schedule for agent ${chalk32.cyan(agentName)}`)
9626
+ chalk34.green(`\u2713 Created schedule for agent ${chalk34.cyan(agentName)}`)
9443
9627
  );
9444
9628
  } else {
9445
9629
  console.log(
9446
- chalk32.green(`\u2713 Updated schedule for agent ${chalk32.cyan(agentName)}`)
9630
+ chalk34.green(`\u2713 Updated schedule for agent ${chalk34.cyan(agentName)}`)
9447
9631
  );
9448
9632
  }
9449
- console.log(chalk32.dim(` Timezone: ${deployResult.schedule.timezone}`));
9633
+ console.log(chalk34.dim(` Timezone: ${deployResult.schedule.timezone}`));
9450
9634
  if (deployResult.schedule.cronExpression) {
9451
- console.log(chalk32.dim(` Cron: ${deployResult.schedule.cronExpression}`));
9635
+ console.log(chalk34.dim(` Cron: ${deployResult.schedule.cronExpression}`));
9452
9636
  if (deployResult.schedule.nextRunAt) {
9453
9637
  const nextRun = formatInTimezone(
9454
9638
  deployResult.schedule.nextRunAt,
9455
9639
  deployResult.schedule.timezone
9456
9640
  );
9457
- console.log(chalk32.dim(` Next run: ${nextRun}`));
9641
+ console.log(chalk34.dim(` Next run: ${nextRun}`));
9458
9642
  }
9459
9643
  } else if (deployResult.schedule.atTime) {
9460
9644
  const atTimeFormatted = formatInTimezone(
9461
9645
  deployResult.schedule.atTime,
9462
9646
  deployResult.schedule.timezone
9463
9647
  );
9464
- console.log(chalk32.dim(` At: ${atTimeFormatted}`));
9648
+ console.log(chalk34.dim(` At: ${atTimeFormatted}`));
9465
9649
  }
9466
9650
  }
9467
9651
  async function tryEnableSchedule(scheduleName, composeId, agentName) {
9468
9652
  try {
9469
9653
  await enableSchedule({ name: scheduleName, composeId });
9470
9654
  console.log(
9471
- chalk32.green(`\u2713 Enabled schedule for agent ${chalk32.cyan(agentName)}`)
9655
+ chalk34.green(`\u2713 Enabled schedule for agent ${chalk34.cyan(agentName)}`)
9472
9656
  );
9473
9657
  } catch (error) {
9474
- console.error(chalk32.yellow("\u26A0 Failed to enable schedule"));
9658
+ console.error(chalk34.yellow("\u26A0 Failed to enable schedule"));
9475
9659
  if (error instanceof ApiRequestError) {
9476
9660
  if (error.code === "SCHEDULE_PAST") {
9477
- console.error(chalk32.dim(" Scheduled time has already passed"));
9661
+ console.error(chalk34.dim(" Scheduled time has already passed"));
9478
9662
  } else {
9479
- console.error(chalk32.dim(` ${error.message}`));
9663
+ console.error(chalk34.dim(` ${error.message}`));
9480
9664
  }
9481
9665
  } else if (error instanceof Error) {
9482
- console.error(chalk32.dim(` ${error.message}`));
9666
+ console.error(chalk34.dim(` ${error.message}`));
9483
9667
  }
9484
9668
  console.log(
9485
- ` To enable manually: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`
9669
+ ` To enable manually: ${chalk34.cyan(`vm0 schedule enable ${agentName}`)}`
9486
9670
  );
9487
9671
  }
9488
9672
  }
9489
9673
  function showEnableHint(agentName) {
9490
9674
  console.log();
9491
- console.log(` To enable: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`);
9675
+ console.log(` To enable: ${chalk34.cyan(`vm0 schedule enable ${agentName}`)}`);
9492
9676
  }
9493
9677
  async function handleScheduleEnabling(params) {
9494
9678
  const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
@@ -9509,13 +9693,13 @@ async function handleScheduleEnabling(params) {
9509
9693
  showEnableHint(agentName);
9510
9694
  }
9511
9695
  }
9512
- var setupCommand = new Command29().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
9696
+ var setupCommand = new Command31().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
9513
9697
  try {
9514
9698
  const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
9515
9699
  const requiredConfig = extractRequiredConfiguration(composeContent);
9516
9700
  const existingSchedule = await findExistingSchedule(agentName);
9517
9701
  console.log(
9518
- chalk32.dim(
9702
+ chalk34.dim(
9519
9703
  existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
9520
9704
  )
9521
9705
  );
@@ -9525,12 +9709,12 @@ var setupCommand = new Command29().name("setup").description("Create or edit a s
9525
9709
  defaults.frequency
9526
9710
  );
9527
9711
  if (!frequency) {
9528
- console.log(chalk32.dim("Cancelled"));
9712
+ console.log(chalk34.dim("Cancelled"));
9529
9713
  return;
9530
9714
  }
9531
9715
  const timing = await gatherTiming(frequency, options, defaults);
9532
9716
  if (!timing) {
9533
- console.log(chalk32.dim("Cancelled"));
9717
+ console.log(chalk34.dim("Cancelled"));
9534
9718
  return;
9535
9719
  }
9536
9720
  const { day, time, atTime } = timing;
@@ -9539,7 +9723,7 @@ var setupCommand = new Command29().name("setup").description("Create or edit a s
9539
9723
  existingSchedule?.timezone
9540
9724
  );
9541
9725
  if (!timezone) {
9542
- console.log(chalk32.dim("Cancelled"));
9726
+ console.log(chalk34.dim("Cancelled"));
9543
9727
  return;
9544
9728
  }
9545
9729
  const promptText_ = await gatherPromptText(
@@ -9547,7 +9731,7 @@ var setupCommand = new Command29().name("setup").description("Create or edit a s
9547
9731
  existingSchedule?.prompt
9548
9732
  );
9549
9733
  if (!promptText_) {
9550
- console.log(chalk32.dim("Cancelled"));
9734
+ console.log(chalk34.dim("Cancelled"));
9551
9735
  return;
9552
9736
  }
9553
9737
  const config = await gatherConfiguration({
@@ -9585,15 +9769,15 @@ var setupCommand = new Command29().name("setup").description("Create or edit a s
9585
9769
  });
9586
9770
 
9587
9771
  // src/commands/schedule/list.ts
9588
- import { Command as Command30 } from "commander";
9589
- import chalk33 from "chalk";
9590
- var listCommand4 = new Command30().name("list").alias("ls").description("List all schedules").action(async () => {
9772
+ import { Command as Command32 } from "commander";
9773
+ import chalk35 from "chalk";
9774
+ var listCommand5 = new Command32().name("list").alias("ls").description("List all schedules").action(async () => {
9591
9775
  try {
9592
9776
  const result = await listSchedules();
9593
9777
  if (result.schedules.length === 0) {
9594
- console.log(chalk33.dim("No schedules found"));
9778
+ console.log(chalk35.dim("No schedules found"));
9595
9779
  console.log(
9596
- chalk33.dim(" Create one with: vm0 schedule setup <agent-name>")
9780
+ chalk35.dim(" Create one with: vm0 schedule setup <agent-name>")
9597
9781
  );
9598
9782
  return;
9599
9783
  }
@@ -9613,10 +9797,10 @@ var listCommand4 = new Command30().name("list").alias("ls").description("List al
9613
9797
  "STATUS".padEnd(8),
9614
9798
  "NEXT RUN"
9615
9799
  ].join(" ");
9616
- console.log(chalk33.dim(header));
9800
+ console.log(chalk35.dim(header));
9617
9801
  for (const schedule of result.schedules) {
9618
9802
  const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
9619
- const status = schedule.enabled ? chalk33.green("enabled") : chalk33.yellow("disabled");
9803
+ const status = schedule.enabled ? chalk35.green("enabled") : chalk35.yellow("disabled");
9620
9804
  const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
9621
9805
  const row = [
9622
9806
  schedule.composeName.padEnd(agentWidth),
@@ -9628,12 +9812,12 @@ var listCommand4 = new Command30().name("list").alias("ls").description("List al
9628
9812
  console.log(row);
9629
9813
  }
9630
9814
  } catch (error) {
9631
- console.error(chalk33.red("\u2717 Failed to list schedules"));
9815
+ console.error(chalk35.red("\u2717 Failed to list schedules"));
9632
9816
  if (error instanceof Error) {
9633
9817
  if (error.message.includes("Not authenticated")) {
9634
- console.error(chalk33.dim(" Run: vm0 auth login"));
9818
+ console.error(chalk35.dim(" Run: vm0 auth login"));
9635
9819
  } else {
9636
- console.error(chalk33.dim(` ${error.message}`));
9820
+ console.error(chalk35.dim(` ${error.message}`));
9637
9821
  }
9638
9822
  }
9639
9823
  process.exit(1);
@@ -9641,45 +9825,45 @@ var listCommand4 = new Command30().name("list").alias("ls").description("List al
9641
9825
  });
9642
9826
 
9643
9827
  // src/commands/schedule/status.ts
9644
- import { Command as Command31 } from "commander";
9645
- import chalk34 from "chalk";
9828
+ import { Command as Command33 } from "commander";
9829
+ import chalk36 from "chalk";
9646
9830
  function formatDateTimeStyled(dateStr) {
9647
- if (!dateStr) return chalk34.dim("-");
9831
+ if (!dateStr) return chalk36.dim("-");
9648
9832
  const formatted = formatDateTime(dateStr);
9649
- return formatted.replace(/\(([^)]+)\)$/, chalk34.dim("($1)"));
9833
+ return formatted.replace(/\(([^)]+)\)$/, chalk36.dim("($1)"));
9650
9834
  }
9651
9835
  function formatTrigger(schedule) {
9652
9836
  if (schedule.cronExpression) {
9653
9837
  return schedule.cronExpression;
9654
9838
  }
9655
9839
  if (schedule.atTime) {
9656
- return `${schedule.atTime} ${chalk34.dim("(one-time)")}`;
9840
+ return `${schedule.atTime} ${chalk36.dim("(one-time)")}`;
9657
9841
  }
9658
- return chalk34.dim("-");
9842
+ return chalk36.dim("-");
9659
9843
  }
9660
- function formatRunStatus(status) {
9844
+ function formatRunStatus2(status) {
9661
9845
  switch (status) {
9662
9846
  case "completed":
9663
- return chalk34.green(status);
9847
+ return chalk36.green(status);
9664
9848
  case "failed":
9665
9849
  case "timeout":
9666
- return chalk34.red(status);
9850
+ return chalk36.red(status);
9667
9851
  case "running":
9668
- return chalk34.blue(status);
9852
+ return chalk36.blue(status);
9669
9853
  case "pending":
9670
- return chalk34.yellow(status);
9854
+ return chalk36.yellow(status);
9671
9855
  default:
9672
9856
  return status;
9673
9857
  }
9674
9858
  }
9675
9859
  function printRunConfiguration(schedule) {
9676
- const statusText = schedule.enabled ? chalk34.green("enabled") : chalk34.yellow("disabled");
9860
+ const statusText = schedule.enabled ? chalk36.green("enabled") : chalk36.yellow("disabled");
9677
9861
  console.log(`${"Status:".padEnd(16)}${statusText}`);
9678
9862
  console.log(
9679
- `${"Agent:".padEnd(16)}${schedule.composeName} ${chalk34.dim(`(${schedule.scopeSlug})`)}`
9863
+ `${"Agent:".padEnd(16)}${schedule.composeName} ${chalk36.dim(`(${schedule.scopeSlug})`)}`
9680
9864
  );
9681
9865
  const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
9682
- console.log(`${"Prompt:".padEnd(16)}${chalk34.dim(promptPreview)}`);
9866
+ console.log(`${"Prompt:".padEnd(16)}${chalk36.dim(promptPreview)}`);
9683
9867
  if (schedule.vars && Object.keys(schedule.vars).length > 0) {
9684
9868
  console.log(
9685
9869
  `${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
@@ -9716,35 +9900,35 @@ async function printRecentRuns(name, composeId, limit) {
9716
9900
  console.log();
9717
9901
  console.log("Recent Runs:");
9718
9902
  console.log(
9719
- chalk34.dim("RUN ID STATUS CREATED")
9903
+ chalk36.dim("RUN ID STATUS CREATED")
9720
9904
  );
9721
9905
  for (const run of runs) {
9722
9906
  const id = run.id;
9723
- const status = formatRunStatus(run.status).padEnd(10);
9907
+ const status = formatRunStatus2(run.status).padEnd(10);
9724
9908
  const created = formatDateTimeStyled(run.createdAt);
9725
9909
  console.log(`${id} ${status} ${created}`);
9726
9910
  }
9727
9911
  }
9728
9912
  } catch {
9729
9913
  console.log();
9730
- console.log(chalk34.dim("Recent Runs: (unable to fetch)"));
9914
+ console.log(chalk36.dim("Recent Runs: (unable to fetch)"));
9731
9915
  }
9732
9916
  }
9733
9917
  function handleStatusError(error, agentName) {
9734
- console.error(chalk34.red("\u2717 Failed to get schedule status"));
9918
+ console.error(chalk36.red("\u2717 Failed to get schedule status"));
9735
9919
  if (error instanceof Error) {
9736
9920
  if (error.message.includes("Not authenticated")) {
9737
- console.error(chalk34.dim(" Run: vm0 auth login"));
9921
+ console.error(chalk36.dim(" Run: vm0 auth login"));
9738
9922
  } else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
9739
- console.error(chalk34.dim(` No schedule found for agent "${agentName}"`));
9740
- console.error(chalk34.dim(" Run: vm0 schedule list"));
9923
+ console.error(chalk36.dim(` No schedule found for agent "${agentName}"`));
9924
+ console.error(chalk36.dim(" Run: vm0 schedule list"));
9741
9925
  } else {
9742
- console.error(chalk34.dim(` ${error.message}`));
9926
+ console.error(chalk36.dim(` ${error.message}`));
9743
9927
  }
9744
9928
  }
9745
9929
  process.exit(1);
9746
9930
  }
9747
- var statusCommand5 = new Command31().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
9931
+ var statusCommand5 = new Command33().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
9748
9932
  "-l, --limit <number>",
9749
9933
  "Number of recent runs to show (0 to hide)",
9750
9934
  "5"
@@ -9754,8 +9938,8 @@ var statusCommand5 = new Command31().name("status").description("Show detailed s
9754
9938
  const { name, composeId } = resolved;
9755
9939
  const schedule = await getScheduleByName({ name, composeId });
9756
9940
  console.log();
9757
- console.log(`Schedule for agent: ${chalk34.cyan(agentName)}`);
9758
- console.log(chalk34.dim("\u2501".repeat(50)));
9941
+ console.log(`Schedule for agent: ${chalk36.cyan(agentName)}`);
9942
+ console.log(chalk36.dim("\u2501".repeat(50)));
9759
9943
  printRunConfiguration(schedule);
9760
9944
  printTimeSchedule(schedule);
9761
9945
  const limit = Math.min(
@@ -9770,24 +9954,24 @@ var statusCommand5 = new Command31().name("status").description("Show detailed s
9770
9954
  });
9771
9955
 
9772
9956
  // src/commands/schedule/delete.ts
9773
- import { Command as Command32 } from "commander";
9774
- import chalk35 from "chalk";
9775
- var deleteCommand = new Command32().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
9957
+ import { Command as Command34 } from "commander";
9958
+ import chalk37 from "chalk";
9959
+ var deleteCommand = new Command34().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
9776
9960
  try {
9777
9961
  const resolved = await resolveScheduleByAgent(agentName);
9778
9962
  if (!options.force) {
9779
9963
  if (!isInteractive()) {
9780
9964
  console.error(
9781
- chalk35.red("\u2717 --force required in non-interactive mode")
9965
+ chalk37.red("\u2717 --force required in non-interactive mode")
9782
9966
  );
9783
9967
  process.exit(1);
9784
9968
  }
9785
9969
  const confirmed = await promptConfirm(
9786
- `Delete schedule for agent ${chalk35.cyan(agentName)}?`,
9970
+ `Delete schedule for agent ${chalk37.cyan(agentName)}?`,
9787
9971
  false
9788
9972
  );
9789
9973
  if (!confirmed) {
9790
- console.log(chalk35.dim("Cancelled"));
9974
+ console.log(chalk37.dim("Cancelled"));
9791
9975
  return;
9792
9976
  }
9793
9977
  }
@@ -9796,20 +9980,20 @@ var deleteCommand = new Command32().name("delete").alias("rm").description("Dele
9796
9980
  composeId: resolved.composeId
9797
9981
  });
9798
9982
  console.log(
9799
- chalk35.green(`\u2713 Deleted schedule for agent ${chalk35.cyan(agentName)}`)
9983
+ chalk37.green(`\u2713 Deleted schedule for agent ${chalk37.cyan(agentName)}`)
9800
9984
  );
9801
9985
  } catch (error) {
9802
- console.error(chalk35.red("\u2717 Failed to delete schedule"));
9986
+ console.error(chalk37.red("\u2717 Failed to delete schedule"));
9803
9987
  if (error instanceof Error) {
9804
9988
  if (error.message.includes("Not authenticated")) {
9805
- console.error(chalk35.dim(" Run: vm0 auth login"));
9989
+ console.error(chalk37.dim(" Run: vm0 auth login"));
9806
9990
  } else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
9807
9991
  console.error(
9808
- chalk35.dim(` No schedule found for agent "${agentName}"`)
9992
+ chalk37.dim(` No schedule found for agent "${agentName}"`)
9809
9993
  );
9810
- console.error(chalk35.dim(" Run: vm0 schedule list"));
9994
+ console.error(chalk37.dim(" Run: vm0 schedule list"));
9811
9995
  } else {
9812
- console.error(chalk35.dim(` ${error.message}`));
9996
+ console.error(chalk37.dim(` ${error.message}`));
9813
9997
  }
9814
9998
  }
9815
9999
  process.exit(1);
@@ -9817,9 +10001,9 @@ var deleteCommand = new Command32().name("delete").alias("rm").description("Dele
9817
10001
  });
9818
10002
 
9819
10003
  // src/commands/schedule/enable.ts
9820
- import { Command as Command33 } from "commander";
9821
- import chalk36 from "chalk";
9822
- var enableCommand = new Command33().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
10004
+ import { Command as Command35 } from "commander";
10005
+ import chalk38 from "chalk";
10006
+ var enableCommand = new Command35().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9823
10007
  try {
9824
10008
  const resolved = await resolveScheduleByAgent(agentName);
9825
10009
  await enableSchedule({
@@ -9827,34 +10011,34 @@ var enableCommand = new Command33().name("enable").description("Enable a schedul
9827
10011
  composeId: resolved.composeId
9828
10012
  });
9829
10013
  console.log(
9830
- chalk36.green(`\u2713 Enabled schedule for agent ${chalk36.cyan(agentName)}`)
10014
+ chalk38.green(`\u2713 Enabled schedule for agent ${chalk38.cyan(agentName)}`)
9831
10015
  );
9832
10016
  } catch (error) {
9833
- console.error(chalk36.red("\u2717 Failed to enable schedule"));
10017
+ console.error(chalk38.red("\u2717 Failed to enable schedule"));
9834
10018
  if (error instanceof ApiRequestError) {
9835
10019
  if (error.code === "SCHEDULE_PAST") {
9836
- console.error(chalk36.dim(" Scheduled time has already passed"));
9837
- console.error(chalk36.dim(` Run: vm0 schedule setup ${agentName}`));
10020
+ console.error(chalk38.dim(" Scheduled time has already passed"));
10021
+ console.error(chalk38.dim(` Run: vm0 schedule setup ${agentName}`));
9838
10022
  } else if (error.code === "NOT_FOUND") {
9839
10023
  console.error(
9840
- chalk36.dim(` No schedule found for agent "${agentName}"`)
10024
+ chalk38.dim(` No schedule found for agent "${agentName}"`)
9841
10025
  );
9842
- console.error(chalk36.dim(" Run: vm0 schedule list"));
10026
+ console.error(chalk38.dim(" Run: vm0 schedule list"));
9843
10027
  } else if (error.code === "UNAUTHORIZED") {
9844
- console.error(chalk36.dim(" Run: vm0 auth login"));
10028
+ console.error(chalk38.dim(" Run: vm0 auth login"));
9845
10029
  } else {
9846
- console.error(chalk36.dim(` ${error.message}`));
10030
+ console.error(chalk38.dim(` ${error.message}`));
9847
10031
  }
9848
10032
  } else if (error instanceof Error) {
9849
10033
  if (error.message.includes("Not authenticated")) {
9850
- console.error(chalk36.dim(" Run: vm0 auth login"));
10034
+ console.error(chalk38.dim(" Run: vm0 auth login"));
9851
10035
  } else if (error.message.includes("No schedule found")) {
9852
10036
  console.error(
9853
- chalk36.dim(` No schedule found for agent "${agentName}"`)
10037
+ chalk38.dim(` No schedule found for agent "${agentName}"`)
9854
10038
  );
9855
- console.error(chalk36.dim(" Run: vm0 schedule list"));
10039
+ console.error(chalk38.dim(" Run: vm0 schedule list"));
9856
10040
  } else {
9857
- console.error(chalk36.dim(` ${error.message}`));
10041
+ console.error(chalk38.dim(` ${error.message}`));
9858
10042
  }
9859
10043
  }
9860
10044
  process.exit(1);
@@ -9862,9 +10046,9 @@ var enableCommand = new Command33().name("enable").description("Enable a schedul
9862
10046
  });
9863
10047
 
9864
10048
  // src/commands/schedule/disable.ts
9865
- import { Command as Command34 } from "commander";
9866
- import chalk37 from "chalk";
9867
- var disableCommand = new Command34().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
10049
+ import { Command as Command36 } from "commander";
10050
+ import chalk39 from "chalk";
10051
+ var disableCommand = new Command36().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
9868
10052
  try {
9869
10053
  const resolved = await resolveScheduleByAgent(agentName);
9870
10054
  await disableSchedule({
@@ -9872,20 +10056,20 @@ var disableCommand = new Command34().name("disable").description("Disable a sche
9872
10056
  composeId: resolved.composeId
9873
10057
  });
9874
10058
  console.log(
9875
- chalk37.green(`\u2713 Disabled schedule for agent ${chalk37.cyan(agentName)}`)
10059
+ chalk39.green(`\u2713 Disabled schedule for agent ${chalk39.cyan(agentName)}`)
9876
10060
  );
9877
10061
  } catch (error) {
9878
- console.error(chalk37.red("\u2717 Failed to disable schedule"));
10062
+ console.error(chalk39.red("\u2717 Failed to disable schedule"));
9879
10063
  if (error instanceof Error) {
9880
10064
  if (error.message.includes("Not authenticated")) {
9881
- console.error(chalk37.dim(" Run: vm0 auth login"));
10065
+ console.error(chalk39.dim(" Run: vm0 auth login"));
9882
10066
  } else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
9883
10067
  console.error(
9884
- chalk37.dim(` No schedule found for agent "${agentName}"`)
10068
+ chalk39.dim(` No schedule found for agent "${agentName}"`)
9885
10069
  );
9886
- console.error(chalk37.dim(" Run: vm0 schedule list"));
10070
+ console.error(chalk39.dim(" Run: vm0 schedule list"));
9887
10071
  } else {
9888
- console.error(chalk37.dim(` ${error.message}`));
10072
+ console.error(chalk39.dim(` ${error.message}`));
9889
10073
  }
9890
10074
  }
9891
10075
  process.exit(1);
@@ -9893,11 +10077,11 @@ var disableCommand = new Command34().name("disable").description("Disable a sche
9893
10077
  });
9894
10078
 
9895
10079
  // src/commands/schedule/index.ts
9896
- var scheduleCommand = new Command35().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand4).addCommand(statusCommand5).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
10080
+ var scheduleCommand = new Command37().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand5).addCommand(statusCommand5).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
9897
10081
 
9898
10082
  // src/commands/usage.ts
9899
- import { Command as Command36 } from "commander";
9900
- import chalk38 from "chalk";
10083
+ import { Command as Command38 } from "commander";
10084
+ import chalk40 from "chalk";
9901
10085
 
9902
10086
  // src/lib/utils/duration-formatter.ts
9903
10087
  function formatDuration(ms) {
@@ -9970,7 +10154,7 @@ function fillMissingDates(daily, startDate, endDate) {
9970
10154
  result.sort((a, b) => b.date.localeCompare(a.date));
9971
10155
  return result;
9972
10156
  }
9973
- var usageCommand = new Command36().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
10157
+ var usageCommand = new Command38().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
9974
10158
  "--until <date>",
9975
10159
  "End date (ISO format or relative, defaults to now)"
9976
10160
  ).action(async (options) => {
@@ -9984,7 +10168,7 @@ var usageCommand = new Command36().name("usage").description("View usage statist
9984
10168
  endDate = new Date(untilMs);
9985
10169
  } catch {
9986
10170
  console.error(
9987
- chalk38.red(
10171
+ chalk40.red(
9988
10172
  "\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
9989
10173
  )
9990
10174
  );
@@ -9999,7 +10183,7 @@ var usageCommand = new Command36().name("usage").description("View usage statist
9999
10183
  startDate = new Date(sinceMs);
10000
10184
  } catch {
10001
10185
  console.error(
10002
- chalk38.red(
10186
+ chalk40.red(
10003
10187
  "\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
10004
10188
  )
10005
10189
  );
@@ -10009,13 +10193,13 @@ var usageCommand = new Command36().name("usage").description("View usage statist
10009
10193
  startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
10010
10194
  }
10011
10195
  if (startDate >= endDate) {
10012
- console.error(chalk38.red("\u2717 --since must be before --until"));
10196
+ console.error(chalk40.red("\u2717 --since must be before --until"));
10013
10197
  process.exit(1);
10014
10198
  }
10015
10199
  const rangeMs = endDate.getTime() - startDate.getTime();
10016
10200
  if (rangeMs > MAX_RANGE_MS) {
10017
10201
  console.error(
10018
- chalk38.red(
10202
+ chalk40.red(
10019
10203
  "\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
10020
10204
  )
10021
10205
  );
@@ -10032,19 +10216,19 @@ var usageCommand = new Command36().name("usage").description("View usage statist
10032
10216
  );
10033
10217
  console.log();
10034
10218
  console.log(
10035
- chalk38.bold(
10219
+ chalk40.bold(
10036
10220
  `Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
10037
10221
  )
10038
10222
  );
10039
10223
  console.log();
10040
- console.log(chalk38.dim("DATE RUNS RUN TIME"));
10224
+ console.log(chalk40.dim("DATE RUNS RUN TIME"));
10041
10225
  for (const day of filledDaily) {
10042
10226
  const dateDisplay = formatDateDisplay(day.date).padEnd(10);
10043
10227
  const runsDisplay = String(day.run_count).padStart(6);
10044
10228
  const timeDisplay = formatDuration(day.run_time_ms);
10045
10229
  console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
10046
10230
  }
10047
- console.log(chalk38.dim("\u2500".repeat(29)));
10231
+ console.log(chalk40.dim("\u2500".repeat(29)));
10048
10232
  const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
10049
10233
  const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
10050
10234
  console.log(
@@ -10054,68 +10238,68 @@ var usageCommand = new Command36().name("usage").description("View usage statist
10054
10238
  } catch (error) {
10055
10239
  if (error instanceof Error) {
10056
10240
  if (error.message.includes("Not authenticated")) {
10057
- console.error(chalk38.red("\u2717 Not authenticated"));
10058
- console.error(chalk38.dim(" Run: vm0 auth login"));
10241
+ console.error(chalk40.red("\u2717 Not authenticated"));
10242
+ console.error(chalk40.dim(" Run: vm0 auth login"));
10059
10243
  } else {
10060
- console.error(chalk38.red(`\u2717 ${error.message}`));
10244
+ console.error(chalk40.red(`\u2717 ${error.message}`));
10061
10245
  }
10062
10246
  } else {
10063
- console.error(chalk38.red("\u2717 An unexpected error occurred"));
10247
+ console.error(chalk40.red("\u2717 An unexpected error occurred"));
10064
10248
  }
10065
10249
  process.exit(1);
10066
10250
  }
10067
10251
  });
10068
10252
 
10069
10253
  // src/commands/credential/index.ts
10070
- import { Command as Command40 } from "commander";
10254
+ import { Command as Command42 } from "commander";
10071
10255
 
10072
10256
  // src/commands/credential/list.ts
10073
- import { Command as Command37 } from "commander";
10074
- import chalk39 from "chalk";
10075
- var listCommand5 = new Command37().name("list").alias("ls").description("List all credentials").action(async () => {
10257
+ import { Command as Command39 } from "commander";
10258
+ import chalk41 from "chalk";
10259
+ var listCommand6 = new Command39().name("list").alias("ls").description("List all credentials").action(async () => {
10076
10260
  try {
10077
10261
  const result = await listCredentials();
10078
10262
  if (result.credentials.length === 0) {
10079
- console.log(chalk39.dim("No credentials found"));
10263
+ console.log(chalk41.dim("No credentials found"));
10080
10264
  console.log();
10081
10265
  console.log("To add a credential:");
10082
- console.log(chalk39.cyan(" vm0 credential set MY_API_KEY <value>"));
10266
+ console.log(chalk41.cyan(" vm0 credential set MY_API_KEY <value>"));
10083
10267
  return;
10084
10268
  }
10085
- console.log(chalk39.bold("Credentials:"));
10269
+ console.log(chalk41.bold("Credentials:"));
10086
10270
  console.log();
10087
10271
  for (const credential of result.credentials) {
10088
- const typeIndicator = credential.type === "model-provider" ? chalk39.dim(" [model-provider]") : "";
10089
- console.log(` ${chalk39.cyan(credential.name)}${typeIndicator}`);
10272
+ const typeIndicator = credential.type === "model-provider" ? chalk41.dim(" [model-provider]") : "";
10273
+ console.log(` ${chalk41.cyan(credential.name)}${typeIndicator}`);
10090
10274
  if (credential.description) {
10091
- console.log(` ${chalk39.dim(credential.description)}`);
10275
+ console.log(` ${chalk41.dim(credential.description)}`);
10092
10276
  }
10093
10277
  console.log(
10094
- ` ${chalk39.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
10278
+ ` ${chalk41.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
10095
10279
  );
10096
10280
  console.log();
10097
10281
  }
10098
10282
  console.log(
10099
- chalk39.dim(`Total: ${result.credentials.length} credential(s)`)
10283
+ chalk41.dim(`Total: ${result.credentials.length} credential(s)`)
10100
10284
  );
10101
10285
  } catch (error) {
10102
10286
  if (error instanceof Error) {
10103
10287
  if (error.message.includes("Not authenticated")) {
10104
- console.error(chalk39.red("\u2717 Not authenticated. Run: vm0 auth login"));
10288
+ console.error(chalk41.red("\u2717 Not authenticated. Run: vm0 auth login"));
10105
10289
  } else {
10106
- console.error(chalk39.red(`\u2717 ${error.message}`));
10290
+ console.error(chalk41.red(`\u2717 ${error.message}`));
10107
10291
  }
10108
10292
  } else {
10109
- console.error(chalk39.red("\u2717 An unexpected error occurred"));
10293
+ console.error(chalk41.red("\u2717 An unexpected error occurred"));
10110
10294
  }
10111
10295
  process.exit(1);
10112
10296
  }
10113
10297
  });
10114
10298
 
10115
10299
  // src/commands/credential/set.ts
10116
- import { Command as Command38 } from "commander";
10117
- import chalk40 from "chalk";
10118
- var setCommand2 = new Command38().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
10300
+ import { Command as Command40 } from "commander";
10301
+ import chalk42 from "chalk";
10302
+ var setCommand2 = new Command40().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
10119
10303
  async (name, value, options) => {
10120
10304
  try {
10121
10305
  const credential = await setCredential({
@@ -10123,29 +10307,29 @@ var setCommand2 = new Command38().name("set").description("Create or update a cr
10123
10307
  value,
10124
10308
  description: options.description
10125
10309
  });
10126
- console.log(chalk40.green(`\u2713 Credential "${credential.name}" saved`));
10310
+ console.log(chalk42.green(`\u2713 Credential "${credential.name}" saved`));
10127
10311
  console.log();
10128
10312
  console.log("Use in vm0.yaml:");
10129
- console.log(chalk40.cyan(` environment:`));
10130
- console.log(chalk40.cyan(` ${name}: \${{ credentials.${name} }}`));
10313
+ console.log(chalk42.cyan(` environment:`));
10314
+ console.log(chalk42.cyan(` ${name}: \${{ credentials.${name} }}`));
10131
10315
  } catch (error) {
10132
10316
  if (error instanceof Error) {
10133
10317
  if (error.message.includes("Not authenticated")) {
10134
10318
  console.error(
10135
- chalk40.red("\u2717 Not authenticated. Run: vm0 auth login")
10319
+ chalk42.red("\u2717 Not authenticated. Run: vm0 auth login")
10136
10320
  );
10137
10321
  } else if (error.message.includes("must contain only uppercase")) {
10138
- console.error(chalk40.red(`\u2717 ${error.message}`));
10322
+ console.error(chalk42.red(`\u2717 ${error.message}`));
10139
10323
  console.log();
10140
10324
  console.log("Examples of valid credential names:");
10141
- console.log(chalk40.dim(" MY_API_KEY"));
10142
- console.log(chalk40.dim(" GITHUB_TOKEN"));
10143
- console.log(chalk40.dim(" AWS_ACCESS_KEY_ID"));
10325
+ console.log(chalk42.dim(" MY_API_KEY"));
10326
+ console.log(chalk42.dim(" GITHUB_TOKEN"));
10327
+ console.log(chalk42.dim(" AWS_ACCESS_KEY_ID"));
10144
10328
  } else {
10145
- console.error(chalk40.red(`\u2717 ${error.message}`));
10329
+ console.error(chalk42.red(`\u2717 ${error.message}`));
10146
10330
  }
10147
10331
  } else {
10148
- console.error(chalk40.red("\u2717 An unexpected error occurred"));
10332
+ console.error(chalk42.red("\u2717 An unexpected error occurred"));
10149
10333
  }
10150
10334
  process.exit(1);
10151
10335
  }
@@ -10153,20 +10337,20 @@ var setCommand2 = new Command38().name("set").description("Create or update a cr
10153
10337
  );
10154
10338
 
10155
10339
  // src/commands/credential/delete.ts
10156
- import { Command as Command39 } from "commander";
10157
- import chalk41 from "chalk";
10158
- var deleteCommand2 = new Command39().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
10340
+ import { Command as Command41 } from "commander";
10341
+ import chalk43 from "chalk";
10342
+ var deleteCommand2 = new Command41().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
10159
10343
  try {
10160
10344
  try {
10161
10345
  await getCredential(name);
10162
10346
  } catch {
10163
- console.error(chalk41.red(`\u2717 Credential "${name}" not found`));
10347
+ console.error(chalk43.red(`\u2717 Credential "${name}" not found`));
10164
10348
  process.exit(1);
10165
10349
  }
10166
10350
  if (!options.yes) {
10167
10351
  if (!isInteractive()) {
10168
10352
  console.error(
10169
- chalk41.red("\u2717 --yes flag is required in non-interactive mode")
10353
+ chalk43.red("\u2717 --yes flag is required in non-interactive mode")
10170
10354
  );
10171
10355
  process.exit(1);
10172
10356
  }
@@ -10175,43 +10359,43 @@ var deleteCommand2 = new Command39().name("delete").description("Delete a creden
10175
10359
  false
10176
10360
  );
10177
10361
  if (!confirmed) {
10178
- console.log(chalk41.dim("Cancelled"));
10362
+ console.log(chalk43.dim("Cancelled"));
10179
10363
  return;
10180
10364
  }
10181
10365
  }
10182
10366
  await deleteCredential(name);
10183
- console.log(chalk41.green(`\u2713 Credential "${name}" deleted`));
10367
+ console.log(chalk43.green(`\u2713 Credential "${name}" deleted`));
10184
10368
  } catch (error) {
10185
10369
  if (error instanceof Error) {
10186
10370
  if (error.message.includes("Not authenticated")) {
10187
- console.error(chalk41.red("\u2717 Not authenticated. Run: vm0 auth login"));
10371
+ console.error(chalk43.red("\u2717 Not authenticated. Run: vm0 auth login"));
10188
10372
  } else {
10189
- console.error(chalk41.red(`\u2717 ${error.message}`));
10373
+ console.error(chalk43.red(`\u2717 ${error.message}`));
10190
10374
  }
10191
10375
  } else {
10192
- console.error(chalk41.red("\u2717 An unexpected error occurred"));
10376
+ console.error(chalk43.red("\u2717 An unexpected error occurred"));
10193
10377
  }
10194
10378
  process.exit(1);
10195
10379
  }
10196
10380
  });
10197
10381
 
10198
10382
  // src/commands/credential/index.ts
10199
- var credentialCommand = new Command40().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand5).addCommand(setCommand2).addCommand(deleteCommand2);
10383
+ var credentialCommand = new Command42().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand6).addCommand(setCommand2).addCommand(deleteCommand2);
10200
10384
 
10201
10385
  // src/commands/model-provider/index.ts
10202
- import { Command as Command45 } from "commander";
10386
+ import { Command as Command47 } from "commander";
10203
10387
 
10204
10388
  // src/commands/model-provider/list.ts
10205
- import { Command as Command41 } from "commander";
10206
- import chalk42 from "chalk";
10207
- var listCommand6 = new Command41().name("list").alias("ls").description("List all model providers").action(async () => {
10389
+ import { Command as Command43 } from "commander";
10390
+ import chalk44 from "chalk";
10391
+ var listCommand7 = new Command43().name("list").alias("ls").description("List all model providers").action(async () => {
10208
10392
  try {
10209
10393
  const result = await listModelProviders();
10210
10394
  if (result.modelProviders.length === 0) {
10211
- console.log(chalk42.dim("No model providers configured"));
10395
+ console.log(chalk44.dim("No model providers configured"));
10212
10396
  console.log();
10213
10397
  console.log("To add a model provider:");
10214
- console.log(chalk42.cyan(" vm0 model-provider setup"));
10398
+ console.log(chalk44.cyan(" vm0 model-provider setup"));
10215
10399
  return;
10216
10400
  }
10217
10401
  const byFramework = result.modelProviders.reduce(
@@ -10225,15 +10409,15 @@ var listCommand6 = new Command41().name("list").alias("ls").description("List al
10225
10409
  },
10226
10410
  {}
10227
10411
  );
10228
- console.log(chalk42.bold("Model Providers:"));
10412
+ console.log(chalk44.bold("Model Providers:"));
10229
10413
  console.log();
10230
10414
  for (const [framework, providers] of Object.entries(byFramework)) {
10231
- console.log(` ${chalk42.cyan(framework)}:`);
10415
+ console.log(` ${chalk44.cyan(framework)}:`);
10232
10416
  for (const provider of providers) {
10233
- const defaultTag = provider.isDefault ? chalk42.green(" (default)") : "";
10417
+ const defaultTag = provider.isDefault ? chalk44.green(" (default)") : "";
10234
10418
  console.log(` ${provider.type}${defaultTag}`);
10235
10419
  console.log(
10236
- chalk42.dim(
10420
+ chalk44.dim(
10237
10421
  ` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
10238
10422
  )
10239
10423
  );
@@ -10241,25 +10425,25 @@ var listCommand6 = new Command41().name("list").alias("ls").description("List al
10241
10425
  console.log();
10242
10426
  }
10243
10427
  console.log(
10244
- chalk42.dim(`Total: ${result.modelProviders.length} provider(s)`)
10428
+ chalk44.dim(`Total: ${result.modelProviders.length} provider(s)`)
10245
10429
  );
10246
10430
  } catch (error) {
10247
10431
  if (error instanceof Error) {
10248
10432
  if (error.message.includes("Not authenticated")) {
10249
- console.error(chalk42.red("\u2717 Not authenticated. Run: vm0 auth login"));
10433
+ console.error(chalk44.red("\u2717 Not authenticated. Run: vm0 auth login"));
10250
10434
  } else {
10251
- console.error(chalk42.red(`\u2717 ${error.message}`));
10435
+ console.error(chalk44.red(`\u2717 ${error.message}`));
10252
10436
  }
10253
10437
  } else {
10254
- console.error(chalk42.red("\u2717 An unexpected error occurred"));
10438
+ console.error(chalk44.red("\u2717 An unexpected error occurred"));
10255
10439
  }
10256
10440
  process.exit(1);
10257
10441
  }
10258
10442
  });
10259
10443
 
10260
10444
  // src/commands/model-provider/setup.ts
10261
- import { Command as Command42 } from "commander";
10262
- import chalk43 from "chalk";
10445
+ import { Command as Command44 } from "commander";
10446
+ import chalk45 from "chalk";
10263
10447
  import prompts2 from "prompts";
10264
10448
  var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
10265
10449
  ([type, config]) => ({
@@ -10267,7 +10451,7 @@ var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
10267
10451
  value: type
10268
10452
  })
10269
10453
  );
10270
- var setupCommand2 = new Command42().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
10454
+ var setupCommand2 = new Command44().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
10271
10455
  "-c, --credential <credential>",
10272
10456
  "Credential value (for non-interactive mode)"
10273
10457
  ).option("--convert", "Convert existing user credential to model provider").action(
@@ -10278,11 +10462,11 @@ var setupCommand2 = new Command42().name("setup").description("Configure a model
10278
10462
  const shouldConvert = options.convert ?? false;
10279
10463
  if (options.type && options.credential) {
10280
10464
  if (!Object.keys(MODEL_PROVIDER_TYPES).includes(options.type)) {
10281
- console.error(chalk43.red(`\u2717 Invalid type "${options.type}"`));
10465
+ console.error(chalk45.red(`\u2717 Invalid type "${options.type}"`));
10282
10466
  console.log();
10283
10467
  console.log("Valid types:");
10284
10468
  for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
10285
- console.log(` ${chalk43.cyan(t)} - ${config.label}`);
10469
+ console.log(` ${chalk45.cyan(t)} - ${config.label}`);
10286
10470
  }
10287
10471
  process.exit(1);
10288
10472
  }
@@ -10290,16 +10474,16 @@ var setupCommand2 = new Command42().name("setup").description("Configure a model
10290
10474
  credential = options.credential;
10291
10475
  } else if (options.type || options.credential) {
10292
10476
  console.error(
10293
- chalk43.red("\u2717 Both --type and --credential are required")
10477
+ chalk45.red("\u2717 Both --type and --credential are required")
10294
10478
  );
10295
10479
  process.exit(1);
10296
10480
  } else {
10297
10481
  if (!isInteractive()) {
10298
- console.error(chalk43.red("\u2717 Interactive mode requires a TTY"));
10482
+ console.error(chalk45.red("\u2717 Interactive mode requires a TTY"));
10299
10483
  console.log();
10300
10484
  console.log("Use non-interactive mode:");
10301
10485
  console.log(
10302
- chalk43.cyan(
10486
+ chalk45.cyan(
10303
10487
  ' vm0 model-provider setup --type <type> --credential "<value>"'
10304
10488
  )
10305
10489
  );
@@ -10330,19 +10514,19 @@ var setupCommand2 = new Command42().name("setup").description("Configure a model
10330
10514
  const provider2 = await convertModelProviderCredential(type);
10331
10515
  const defaultNote2 = provider2.isDefault ? ` (default for ${provider2.framework})` : "";
10332
10516
  console.log(
10333
- chalk43.green(
10517
+ chalk45.green(
10334
10518
  `\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote2}`
10335
10519
  )
10336
10520
  );
10337
10521
  return;
10338
10522
  } else {
10339
- console.log(chalk43.dim("Aborted"));
10523
+ console.log(chalk45.dim("Aborted"));
10340
10524
  process.exit(0);
10341
10525
  }
10342
10526
  }
10343
10527
  const config = MODEL_PROVIDER_TYPES[type];
10344
10528
  console.log();
10345
- console.log(chalk43.dim(config.helpText));
10529
+ console.log(chalk45.dim(config.helpText));
10346
10530
  console.log();
10347
10531
  const credentialResponse = await prompts2(
10348
10532
  {
@@ -10363,24 +10547,24 @@ var setupCommand2 = new Command42().name("setup").description("Configure a model
10363
10547
  const action = created ? "created" : "updated";
10364
10548
  const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
10365
10549
  console.log(
10366
- chalk43.green(`\u2713 Model provider "${type}" ${action}${defaultNote}`)
10550
+ chalk45.green(`\u2713 Model provider "${type}" ${action}${defaultNote}`)
10367
10551
  );
10368
10552
  } catch (error) {
10369
10553
  if (error instanceof Error) {
10370
10554
  if (error.message.includes("already exists")) {
10371
- console.error(chalk43.red(`\u2717 ${error.message}`));
10555
+ console.error(chalk45.red(`\u2717 ${error.message}`));
10372
10556
  console.log();
10373
10557
  console.log("To convert the existing credential, run:");
10374
- console.log(chalk43.cyan(" vm0 model-provider setup --convert"));
10558
+ console.log(chalk45.cyan(" vm0 model-provider setup --convert"));
10375
10559
  } else if (error.message.includes("Not authenticated")) {
10376
10560
  console.error(
10377
- chalk43.red("\u2717 Not authenticated. Run: vm0 auth login")
10561
+ chalk45.red("\u2717 Not authenticated. Run: vm0 auth login")
10378
10562
  );
10379
10563
  } else {
10380
- console.error(chalk43.red(`\u2717 ${error.message}`));
10564
+ console.error(chalk45.red(`\u2717 ${error.message}`));
10381
10565
  }
10382
10566
  } else {
10383
- console.error(chalk43.red("\u2717 An unexpected error occurred"));
10567
+ console.error(chalk45.red("\u2717 An unexpected error occurred"));
10384
10568
  }
10385
10569
  process.exit(1);
10386
10570
  }
@@ -10388,84 +10572,85 @@ var setupCommand2 = new Command42().name("setup").description("Configure a model
10388
10572
  );
10389
10573
 
10390
10574
  // src/commands/model-provider/delete.ts
10391
- import { Command as Command43 } from "commander";
10392
- import chalk44 from "chalk";
10393
- var deleteCommand3 = new Command43().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
10575
+ import { Command as Command45 } from "commander";
10576
+ import chalk46 from "chalk";
10577
+ var deleteCommand3 = new Command45().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
10394
10578
  try {
10395
10579
  if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
10396
- console.error(chalk44.red(`\u2717 Invalid type "${type}"`));
10580
+ console.error(chalk46.red(`\u2717 Invalid type "${type}"`));
10397
10581
  console.log();
10398
10582
  console.log("Valid types:");
10399
10583
  for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
10400
- console.log(` ${chalk44.cyan(t)} - ${config.label}`);
10584
+ console.log(` ${chalk46.cyan(t)} - ${config.label}`);
10401
10585
  }
10402
10586
  process.exit(1);
10403
10587
  }
10404
10588
  await deleteModelProvider(type);
10405
- console.log(chalk44.green(`\u2713 Model provider "${type}" deleted`));
10589
+ console.log(chalk46.green(`\u2713 Model provider "${type}" deleted`));
10406
10590
  } catch (error) {
10407
10591
  if (error instanceof Error) {
10408
10592
  if (error.message.includes("not found")) {
10409
- console.error(chalk44.red(`\u2717 Model provider "${type}" not found`));
10593
+ console.error(chalk46.red(`\u2717 Model provider "${type}" not found`));
10410
10594
  } else if (error.message.includes("Not authenticated")) {
10411
- console.error(chalk44.red("\u2717 Not authenticated. Run: vm0 auth login"));
10595
+ console.error(chalk46.red("\u2717 Not authenticated. Run: vm0 auth login"));
10412
10596
  } else {
10413
- console.error(chalk44.red(`\u2717 ${error.message}`));
10597
+ console.error(chalk46.red(`\u2717 ${error.message}`));
10414
10598
  }
10415
10599
  } else {
10416
- console.error(chalk44.red("\u2717 An unexpected error occurred"));
10600
+ console.error(chalk46.red("\u2717 An unexpected error occurred"));
10417
10601
  }
10418
10602
  process.exit(1);
10419
10603
  }
10420
10604
  });
10421
10605
 
10422
10606
  // src/commands/model-provider/set-default.ts
10423
- import { Command as Command44 } from "commander";
10424
- import chalk45 from "chalk";
10425
- var setDefaultCommand = new Command44().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
10607
+ import { Command as Command46 } from "commander";
10608
+ import chalk47 from "chalk";
10609
+ var setDefaultCommand = new Command46().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
10426
10610
  try {
10427
10611
  if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
10428
- console.error(chalk45.red(`\u2717 Invalid type "${type}"`));
10612
+ console.error(chalk47.red(`\u2717 Invalid type "${type}"`));
10429
10613
  console.log();
10430
10614
  console.log("Valid types:");
10431
10615
  for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
10432
- console.log(` ${chalk45.cyan(t)} - ${config.label}`);
10616
+ console.log(` ${chalk47.cyan(t)} - ${config.label}`);
10433
10617
  }
10434
10618
  process.exit(1);
10435
10619
  }
10436
10620
  const provider = await setModelProviderDefault(type);
10437
10621
  console.log(
10438
- chalk45.green(
10622
+ chalk47.green(
10439
10623
  `\u2713 Default for ${provider.framework} set to "${provider.type}"`
10440
10624
  )
10441
10625
  );
10442
10626
  } catch (error) {
10443
10627
  if (error instanceof Error) {
10444
10628
  if (error.message.includes("not found")) {
10445
- console.error(chalk45.red(`\u2717 Model provider "${type}" not found`));
10629
+ console.error(chalk47.red(`\u2717 Model provider "${type}" not found`));
10446
10630
  } else if (error.message.includes("Not authenticated")) {
10447
- console.error(chalk45.red("\u2717 Not authenticated. Run: vm0 auth login"));
10631
+ console.error(chalk47.red("\u2717 Not authenticated. Run: vm0 auth login"));
10448
10632
  } else {
10449
- console.error(chalk45.red(`\u2717 ${error.message}`));
10633
+ console.error(chalk47.red(`\u2717 ${error.message}`));
10450
10634
  }
10451
10635
  } else {
10452
- console.error(chalk45.red("\u2717 An unexpected error occurred"));
10636
+ console.error(chalk47.red("\u2717 An unexpected error occurred"));
10453
10637
  }
10454
10638
  process.exit(1);
10455
10639
  }
10456
10640
  });
10457
10641
 
10458
10642
  // src/commands/model-provider/index.ts
10459
- var modelProviderCommand = new Command45().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand6).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
10643
+ var modelProviderCommand = new Command47().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand7).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
10460
10644
 
10461
10645
  // src/commands/onboard.ts
10462
- import { Command as Command46 } from "commander";
10463
- import chalk48 from "chalk";
10464
- import { mkdir as mkdir8 } from "fs/promises";
10646
+ import { Command as Command48 } from "commander";
10647
+ import chalk51 from "chalk";
10648
+ import { mkdir as mkdir7 } from "fs/promises";
10465
10649
  import { existsSync as existsSync10 } from "fs";
10650
+ import path14 from "path";
10466
10651
 
10467
10652
  // src/lib/ui/welcome-box.ts
10468
- import chalk46 from "chalk";
10653
+ import chalk48 from "chalk";
10469
10654
  function renderWelcomeBox(lines, width) {
10470
10655
  const maxLineLength = Math.max(...lines.map((line) => line.length));
10471
10656
  const boxWidth = width ?? maxLineLength + 4;
@@ -10473,28 +10658,28 @@ function renderWelcomeBox(lines, width) {
10473
10658
  const horizontalLine = "\u2500".repeat(innerWidth);
10474
10659
  const topBorder = `\u250C${horizontalLine}\u2510`;
10475
10660
  const bottomBorder = `\u2514${horizontalLine}\u2518`;
10476
- console.log(chalk46.cyan(topBorder));
10661
+ console.log(chalk48.cyan(topBorder));
10477
10662
  for (const line of lines) {
10478
10663
  const padding = innerWidth - line.length;
10479
10664
  const leftPad = Math.floor(padding / 2);
10480
10665
  const rightPad = padding - leftPad;
10481
10666
  const centeredLine = " ".repeat(leftPad) + line + " ".repeat(rightPad);
10482
- console.log(chalk46.cyan("\u2502") + centeredLine + chalk46.cyan("\u2502"));
10667
+ console.log(chalk48.cyan("\u2502") + centeredLine + chalk48.cyan("\u2502"));
10483
10668
  }
10484
- console.log(chalk46.cyan(bottomBorder));
10669
+ console.log(chalk48.cyan(bottomBorder));
10485
10670
  }
10486
10671
  function renderOnboardWelcome() {
10487
10672
  renderWelcomeBox([
10488
10673
  "",
10489
10674
  "Welcome to VM0!",
10490
10675
  "",
10491
- "Let's set up your first agent.",
10676
+ "Let's create your first agent.",
10492
10677
  ""
10493
10678
  ]);
10494
10679
  }
10495
10680
 
10496
10681
  // src/lib/ui/progress-line.ts
10497
- import chalk47 from "chalk";
10682
+ import chalk49 from "chalk";
10498
10683
  var STATUS_SYMBOLS = {
10499
10684
  completed: "\u25CF",
10500
10685
  "in-progress": "\u25D0",
@@ -10504,14 +10689,14 @@ var STATUS_SYMBOLS = {
10504
10689
  function getStatusColor(status) {
10505
10690
  switch (status) {
10506
10691
  case "completed":
10507
- return chalk47.green;
10692
+ return chalk49.green;
10508
10693
  case "in-progress":
10509
- return chalk47.yellow;
10694
+ return chalk49.yellow;
10510
10695
  case "failed":
10511
- return chalk47.red;
10696
+ return chalk49.red;
10512
10697
  case "pending":
10513
10698
  default:
10514
- return chalk47.dim;
10699
+ return chalk49.dim;
10515
10700
  }
10516
10701
  }
10517
10702
  function renderProgressLine(steps) {
@@ -10522,7 +10707,7 @@ function renderProgressLine(steps) {
10522
10707
  const color = getStatusColor(step.status);
10523
10708
  console.log(color(`${symbol} ${step.label}`));
10524
10709
  if (i < steps.length - 1) {
10525
- console.log(chalk47.dim("\u2502"));
10710
+ console.log(chalk49.dim("\u2502"));
10526
10711
  }
10527
10712
  }
10528
10713
  }
@@ -10531,6 +10716,7 @@ function createOnboardProgress() {
10531
10716
  { label: "Authentication", status: "pending" },
10532
10717
  { label: "Model Provider Setup", status: "pending" },
10533
10718
  { label: "Create Agent", status: "pending" },
10719
+ { label: "Claude Plugin Install", status: "pending" },
10534
10720
  { label: "Complete", status: "pending" }
10535
10721
  ];
10536
10722
  return {
@@ -10675,295 +10861,102 @@ async function setupModelProvider(type, credential, options) {
10675
10861
  }
10676
10862
 
10677
10863
  // src/lib/domain/onboard/claude-setup.ts
10678
- import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
10679
- import path14 from "path";
10680
- var SKILL_DIR = ".claude/skills/vm0-agent-builder";
10681
- var SKILL_FILE = "SKILL.md";
10682
- function getSkillContent() {
10683
- return `---
10684
- name: vm0-agent-builder
10685
- description: Build VM0 agents by creating AGENTS.md and vm0.yaml. Use when users describe what agent they want to build.
10686
- ---
10687
-
10688
- # VM0 Agent Builder
10689
-
10690
- Build AI agents that run in VM0's secure sandbox environment. This skill helps you create the two essential files: \`AGENTS.md\` (agent instructions) and \`vm0.yaml\` (configuration).
10691
-
10692
- ## Workflow
10693
-
10694
- ### Step 1: Understand the Goal
10695
-
10696
- First, clarify what the user wants their agent to do:
10697
- - What task should the agent accomplish?
10698
- - What inputs does it need? (files, APIs, websites)
10699
- - What outputs should it produce? (reports, files, notifications)
10700
- - Should it run once or on a schedule?
10701
-
10702
- ### Step 2: Create AGENTS.md
10703
-
10704
- Write clear, step-by-step instructions. The agent will follow these exactly.
10705
-
10706
- **Template:**
10707
-
10708
- \`\`\`markdown
10709
- # [Agent Name]
10710
-
10711
- You are a [role description].
10712
-
10713
- ## Workflow
10714
-
10715
- 1. [First action - be specific]
10716
- 2. [Second action - include details]
10717
- 3. [Continue with clear steps...]
10718
-
10719
- ## Output
10720
-
10721
- Write results to \`[filename]\` in the current directory.
10722
- \`\`\`
10723
-
10724
- **Writing Tips:**
10725
- - Be specific: "Read the top 10 stories" not "Read some stories"
10726
- - One action per step: Keep steps focused and atomic
10727
- - Specify output: Exact filenames and formats
10728
- - Use active voice: "Create a file" not "A file should be created"
10729
-
10730
- ### Step 3: Create vm0.yaml
10731
-
10732
- Configure the agent with required skills and environment variables.
10733
-
10734
- \`\`\`yaml
10735
- version: "1.0"
10736
-
10737
- agents:
10738
- [agent-name]:
10739
- framework: claude-code
10740
- instructions: AGENTS.md
10741
- # Pre-install GitHub CLI (optional)
10742
- apps:
10743
- - github
10744
- # Add skills the agent needs (optional)
10745
- skills:
10746
- - https://github.com/vm0-ai/vm0-skills/tree/main/[skill-name]
10747
- # Mount volumes for input files (optional)
10748
- volumes:
10749
- - my-volume:/home/user/input
10750
- # Environment variables (optional)
10751
- environment:
10752
- API_KEY: "\${{ secrets.API_KEY }}"
10753
- \`\`\`
10754
-
10755
- ### Step 4: Test the Agent
10756
-
10757
- After creating both files, the user runs:
10758
-
10759
- \`\`\`bash
10760
- vm0 cook "start working"
10761
- \`\`\`
10762
-
10763
- This command:
10764
- 1. Uploads the configuration to VM0
10765
- 2. Runs the agent in a secure sandbox
10766
- 3. Downloads results to the \`artifact/\` directory
10767
-
10768
- ## Available Skills
10769
-
10770
- Skills give agents access to external services. Add them to vm0.yaml when needed.
10771
-
10772
- **Popular Skills:**
10773
-
10774
- | Skill | Use Case |
10775
- |-------|----------|
10776
- | \`github\` | Read/write issues, PRs, files |
10777
- | \`slack\` | Send messages to channels |
10778
- | \`notion\` | Access Notion pages/databases |
10779
- | \`firecrawl\` | Scrape and extract web content |
10780
- | \`supabase\` | Database operations |
10781
- | \`google-sheets\` | Read/write spreadsheets |
10782
- | \`linear\` | Project management |
10783
- | \`discord\` | Send Discord messages |
10784
- | \`gmail\` | Send emails |
10785
- | \`openai\` | Embeddings, additional AI calls |
10786
-
10787
- **All 79 skills:** https://github.com/vm0-ai/vm0-skills
10788
-
10789
- **Skill URL format:**
10790
- \`\`\`
10791
- https://github.com/vm0-ai/vm0-skills/tree/main/[skill-name]
10792
- \`\`\`
10793
-
10794
- ## Examples
10795
-
10796
- ### HackerNews Curator
10797
-
10798
- **AGENTS.md:**
10799
- \`\`\`markdown
10800
- # HackerNews AI Curator
10801
-
10802
- You are a content curator that finds AI-related articles on HackerNews.
10803
-
10804
- ## Workflow
10805
-
10806
- 1. Go to https://news.ycombinator.com
10807
- 2. Read the top 30 stories
10808
- 3. Filter for AI, ML, and LLM related content
10809
- 4. For each relevant article, extract:
10810
- - Title and URL
10811
- - 2-3 sentence summary
10812
- - Why it matters
10813
- 5. Write findings to \`daily-digest.md\`
10814
-
10815
- ## Output
10816
-
10817
- Create \`daily-digest.md\` with today's date as the header.
10818
- Format as a bulleted list with links.
10819
- \`\`\`
10820
-
10821
- **vm0.yaml:**
10822
- \`\`\`yaml
10823
- version: "1.0"
10824
-
10825
- agents:
10826
- hn-curator:
10827
- framework: claude-code
10828
- instructions: AGENTS.md
10829
- \`\`\`
10830
-
10831
- ### GitHub Issue Reporter
10832
-
10833
- **AGENTS.md:**
10834
- \`\`\`markdown
10835
- # GitHub Issue Reporter
10836
-
10837
- You are a GitHub analyst that creates issue summary reports.
10838
-
10839
- ## Workflow
10840
-
10841
- 1. List all open issues in the repository
10842
- 2. Group by labels: bug, feature, documentation, other
10843
- 3. For each group, report:
10844
- - Total count
10845
- - Oldest issue (with age in days)
10846
- - Most commented issue
10847
- 4. Write report to \`issue-report.md\`
10848
-
10849
- ## Output
10850
-
10851
- Create \`issue-report.md\` with sections for each label group.
10852
- Include links to referenced issues.
10853
- \`\`\`
10854
-
10855
- **vm0.yaml:**
10856
- \`\`\`yaml
10857
- version: "1.0"
10858
-
10859
- agents:
10860
- issue-reporter:
10861
- framework: claude-code
10862
- instructions: AGENTS.md
10863
- skills:
10864
- - https://github.com/vm0-ai/vm0-skills/tree/main/github
10865
- environment:
10866
- GITHUB_REPO: "\${{ vars.GITHUB_REPO }}"
10867
- \`\`\`
10868
-
10869
- ### Slack Daily Digest
10870
-
10871
- **AGENTS.md:**
10872
- \`\`\`markdown
10873
- # Slack Daily Digest
10874
-
10875
- You are an assistant that posts daily summaries to Slack.
10876
-
10877
- ## Workflow
10878
-
10879
- 1. Read the contents of \`updates.md\` from the input volume
10880
- 2. Summarize the key points (max 5 bullets)
10881
- 3. Format as a Slack message with emoji headers
10882
- 4. Post to the #daily-updates channel
10883
-
10884
- ## Output
10885
-
10886
- Post the summary to Slack. Write a copy to \`sent-message.md\`.
10887
- \`\`\`
10888
-
10889
- **vm0.yaml:**
10890
- \`\`\`yaml
10891
- version: "1.0"
10892
-
10893
- agents:
10894
- slack-digest:
10895
- framework: claude-code
10896
- instructions: AGENTS.md
10897
- skills:
10898
- - https://github.com/vm0-ai/vm0-skills/tree/main/slack
10899
- environment:
10900
- SLACK_CHANNEL: "\${{ vars.SLACK_CHANNEL }}"
10901
- \`\`\`
10902
-
10903
- ## Environment Variables
10904
-
10905
- Use environment variables for sensitive data and configuration:
10906
-
10907
- \`\`\`yaml
10908
- environment:
10909
- # Secrets (encrypted, for API keys)
10910
- API_KEY: "\${{ secrets.API_KEY }}"
10911
-
10912
- # Variables (plain text, for config)
10913
- REPO_NAME: "\${{ vars.REPO_NAME }}"
10914
-
10915
- # Credentials (from vm0 credential storage)
10916
- MY_TOKEN: "\${{ credentials.MY_TOKEN }}"
10917
- \`\`\`
10918
-
10919
- Set credentials with (names must be UPPERCASE):
10920
- \`\`\`bash
10921
- vm0 credential set API_KEY "your-api-key"
10922
- \`\`\`
10923
-
10924
- ## Troubleshooting
10925
-
10926
- **Agent doesn't follow instructions:**
10927
- - Make steps more specific and explicit
10928
- - Add "Do not..." constraints for unwanted behavior
10929
- - Break complex steps into smaller sub-steps
10930
-
10931
- **Agent can't access a service:**
10932
- - Add the required skill to vm0.yaml
10933
- - Set up credentials with \`vm0 credential set\`
10934
-
10935
- **Output is in wrong format:**
10936
- - Provide an exact template in the instructions
10937
- - Include a small example of expected output
10938
-
10939
- ## Next Steps After Creating Files
10940
-
10941
- \`\`\`bash
10942
- # Run your agent
10943
- vm0 cook "start working"
10944
-
10945
- # View logs if needed
10946
- vm0 logs [run-id]
10947
-
10948
- # Results are in artifact/ directory
10949
- ls artifact/
10950
-
10951
- # Continue from where agent left off
10952
- vm0 cook continue "keep going"
10953
-
10954
- # Resume from a checkpoint
10955
- vm0 cook resume "try again"
10956
- \`\`\`
10957
- `;
10864
+ import { spawn as spawn3 } from "child_process";
10865
+ import chalk50 from "chalk";
10866
+ var MARKETPLACE_NAME = "vm0-skills";
10867
+ var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
10868
+ var PLUGIN_ID = "vm0@vm0-skills";
10869
+ var PRIMARY_SKILL_NAME = "vm0-agent";
10870
+ async function runClaudeCommand(args, cwd) {
10871
+ return new Promise((resolve) => {
10872
+ const child = spawn3("claude", args, {
10873
+ shell: true,
10874
+ stdio: ["inherit", "pipe", "pipe"],
10875
+ cwd
10876
+ });
10877
+ let stdout = "";
10878
+ let stderr = "";
10879
+ child.stdout?.on("data", (data) => {
10880
+ stdout += data.toString();
10881
+ });
10882
+ child.stderr?.on("data", (data) => {
10883
+ stderr += data.toString();
10884
+ });
10885
+ child.on("error", (err) => {
10886
+ resolve({
10887
+ success: false,
10888
+ output: stdout,
10889
+ error: err.message
10890
+ });
10891
+ });
10892
+ child.on("close", (code) => {
10893
+ resolve({
10894
+ success: code === 0,
10895
+ output: stdout,
10896
+ error: stderr || void 0
10897
+ });
10898
+ });
10899
+ });
10900
+ }
10901
+ function handlePluginError(error, context) {
10902
+ const displayContext = context ?? "Claude plugin";
10903
+ console.error(chalk50.red(`Failed to install ${displayContext}`));
10904
+ if (error instanceof Error) {
10905
+ console.error(chalk50.red(error.message));
10906
+ }
10907
+ console.error(
10908
+ chalk50.dim("Please ensure Claude CLI is installed and accessible.")
10909
+ );
10910
+ process.exit(1);
10911
+ }
10912
+ async function isMarketplaceInstalled() {
10913
+ const result = await runClaudeCommand([
10914
+ "plugin",
10915
+ "marketplace",
10916
+ "list",
10917
+ "--json"
10918
+ ]);
10919
+ if (!result.success) {
10920
+ return false;
10921
+ }
10922
+ try {
10923
+ const marketplaces = JSON.parse(result.output);
10924
+ return marketplaces.some((m) => m.name === MARKETPLACE_NAME);
10925
+ } catch {
10926
+ return false;
10927
+ }
10928
+ }
10929
+ async function addMarketplace() {
10930
+ const result = await runClaudeCommand([
10931
+ "plugin",
10932
+ "marketplace",
10933
+ "add",
10934
+ MARKETPLACE_REPO
10935
+ ]);
10936
+ if (!result.success) {
10937
+ throw new Error(
10938
+ `Failed to add marketplace ${MARKETPLACE_REPO}: ${result.error ?? "unknown error"}`
10939
+ );
10940
+ }
10958
10941
  }
10959
- async function installClaudeSkill(targetDir = process.cwd()) {
10960
- const skillDirPath = path14.join(targetDir, SKILL_DIR);
10961
- const skillFilePath = path14.join(skillDirPath, SKILL_FILE);
10962
- await mkdir7(skillDirPath, { recursive: true });
10963
- await writeFile7(skillFilePath, getSkillContent());
10942
+ async function ensureMarketplace() {
10943
+ const installed = await isMarketplaceInstalled();
10944
+ if (!installed) {
10945
+ await addMarketplace();
10946
+ }
10947
+ }
10948
+ async function installVm0Plugin(scope = "user", cwd) {
10949
+ await ensureMarketplace();
10950
+ const args = ["plugin", "install", PLUGIN_ID, "--scope", scope];
10951
+ const result = await runClaudeCommand(args, cwd);
10952
+ if (!result.success) {
10953
+ throw new Error(
10954
+ `Failed to install plugin ${PLUGIN_ID}: ${result.error ?? "unknown error"}`
10955
+ );
10956
+ }
10964
10957
  return {
10965
- skillDir: skillDirPath,
10966
- skillFile: skillFilePath
10958
+ pluginId: PLUGIN_ID,
10959
+ scope
10967
10960
  };
10968
10961
  }
10969
10962
 
@@ -10977,34 +10970,34 @@ async function handleAuthentication(ctx) {
10977
10970
  return;
10978
10971
  }
10979
10972
  if (!ctx.interactive) {
10980
- console.error(chalk48.red("Error: Not authenticated"));
10973
+ console.error(chalk51.red("Error: Not authenticated"));
10981
10974
  console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
10982
10975
  process.exit(1);
10983
10976
  }
10984
- console.log(chalk48.dim("Authentication required..."));
10977
+ console.log(chalk51.dim("Authentication required..."));
10985
10978
  console.log();
10986
10979
  await runAuthFlow({
10987
10980
  onInitiating: () => {
10988
10981
  console.log("Initiating authentication...");
10989
10982
  },
10990
10983
  onDeviceCodeReady: (url, code, expiresIn) => {
10991
- console.log(chalk48.green("\nDevice code generated"));
10992
- console.log(chalk48.cyan(`
10984
+ console.log(chalk51.green("\nDevice code generated"));
10985
+ console.log(chalk51.cyan(`
10993
10986
  To authenticate, visit: ${url}`));
10994
- console.log(`And enter this code: ${chalk48.bold(code)}`);
10987
+ console.log(`And enter this code: ${chalk51.bold(code)}`);
10995
10988
  console.log(`
10996
10989
  The code expires in ${expiresIn} minutes.`);
10997
10990
  console.log("\nWaiting for authentication...");
10998
10991
  },
10999
10992
  onPolling: () => {
11000
- process.stdout.write(chalk48.dim("."));
10993
+ process.stdout.write(chalk51.dim("."));
11001
10994
  },
11002
10995
  onSuccess: () => {
11003
- console.log(chalk48.green("\nAuthentication successful!"));
10996
+ console.log(chalk51.green("\nAuthentication successful!"));
11004
10997
  console.log("Your credentials have been saved.");
11005
10998
  },
11006
10999
  onError: (error) => {
11007
- console.error(chalk48.red(`
11000
+ console.error(chalk51.red(`
11008
11001
  ${error.message}`));
11009
11002
  process.exit(1);
11010
11003
  }
@@ -11019,11 +11012,11 @@ async function handleModelProvider(ctx) {
11019
11012
  return;
11020
11013
  }
11021
11014
  if (!ctx.interactive) {
11022
- console.error(chalk48.red("Error: No model provider configured"));
11015
+ console.error(chalk51.red("Error: No model provider configured"));
11023
11016
  console.error("Run 'vm0 model-provider setup' first");
11024
11017
  process.exit(1);
11025
11018
  }
11026
- console.log(chalk48.dim("Model provider setup required..."));
11019
+ console.log(chalk51.dim("Model provider setup required..."));
11027
11020
  console.log();
11028
11021
  const choices = getProviderChoices();
11029
11022
  const providerType = await promptSelect(
@@ -11040,19 +11033,19 @@ async function handleModelProvider(ctx) {
11040
11033
  const selectedChoice = choices.find((c20) => c20.type === providerType);
11041
11034
  if (selectedChoice) {
11042
11035
  console.log();
11043
- console.log(chalk48.dim(selectedChoice.helpText));
11036
+ console.log(chalk51.dim(selectedChoice.helpText));
11044
11037
  console.log();
11045
11038
  }
11046
11039
  const credential = await promptPassword(
11047
11040
  `Enter your ${selectedChoice?.credentialLabel ?? "credential"}:`
11048
11041
  );
11049
11042
  if (!credential) {
11050
- console.log(chalk48.dim("Cancelled"));
11043
+ console.log(chalk51.dim("Cancelled"));
11051
11044
  process.exit(0);
11052
11045
  }
11053
11046
  const result = await setupModelProvider(providerType, credential);
11054
11047
  console.log(
11055
- chalk48.green(
11048
+ chalk51.green(
11056
11049
  `
11057
11050
  \u2713 Model provider "${providerType}" ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}`
11058
11051
  )
@@ -11080,52 +11073,63 @@ async function handleAgentCreation(ctx) {
11080
11073
  }
11081
11074
  if (!validateAgentName(agentName)) {
11082
11075
  console.error(
11083
- chalk48.red(
11076
+ chalk51.red(
11084
11077
  "Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
11085
11078
  )
11086
11079
  );
11087
11080
  process.exit(1);
11088
11081
  }
11089
11082
  if (existsSync10(agentName)) {
11090
- console.error(chalk48.red(`
11083
+ console.error(chalk51.red(`
11091
11084
  \u2717 ${agentName}/ already exists`));
11092
11085
  console.log();
11093
11086
  console.log("Remove it first or choose a different name:");
11094
- console.log(chalk48.cyan(` rm -rf ${agentName}`));
11087
+ console.log(chalk51.cyan(` rm -rf ${agentName}`));
11095
11088
  process.exit(1);
11096
11089
  }
11097
- if (!ctx.options.yes && ctx.interactive) {
11098
- const confirmed = await promptConfirm(`Create ${agentName}/?`, true);
11099
- if (!confirmed) {
11100
- console.log(chalk48.dim("Cancelled"));
11101
- process.exit(0);
11102
- }
11103
- }
11104
- await mkdir8(agentName, { recursive: true });
11105
- console.log(chalk48.green(`\u2713 Created ${agentName}/`));
11090
+ await mkdir7(agentName, { recursive: true });
11091
+ console.log(chalk51.green(`\u2713 Created ${agentName}/`));
11106
11092
  ctx.updateProgress(2, "completed");
11107
11093
  return agentName;
11108
11094
  }
11109
- async function handleSkillInstallation(ctx, agentName) {
11095
+ async function handlePluginInstallation(ctx, agentName) {
11110
11096
  ctx.updateProgress(3, "in-progress");
11111
- const skillResult = await installClaudeSkill(agentName);
11112
- console.log(
11113
- chalk48.green(
11114
- `\u2713 Installed vm0-agent-builder skill to ${skillResult.skillDir}`
11115
- )
11116
- );
11097
+ let shouldInstall = true;
11098
+ if (!ctx.options.yes && ctx.interactive) {
11099
+ const confirmed = await promptConfirm(
11100
+ "Install VM0 Claude Plugin?",
11101
+ true
11102
+ // default: Yes
11103
+ );
11104
+ shouldInstall = confirmed ?? true;
11105
+ }
11106
+ if (!shouldInstall) {
11107
+ console.log(chalk51.dim("Skipped plugin installation"));
11108
+ ctx.updateProgress(3, "completed");
11109
+ return;
11110
+ }
11111
+ const scope = "project";
11112
+ try {
11113
+ const agentDir = path14.resolve(process.cwd(), agentName);
11114
+ const result = await installVm0Plugin(scope, agentDir);
11115
+ console.log(
11116
+ chalk51.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
11117
+ );
11118
+ } catch (error) {
11119
+ handlePluginError(error);
11120
+ }
11117
11121
  ctx.updateProgress(3, "completed");
11118
11122
  }
11119
11123
  function printNextSteps(agentName) {
11120
11124
  console.log();
11121
- console.log(chalk48.bold("Next step:"));
11125
+ console.log(chalk51.bold("Next step:"));
11122
11126
  console.log();
11123
11127
  console.log(
11124
- ` ${chalk48.cyan(`cd ${agentName} && claude "/vm0-agent-builder I want to build an agent that..."`)}`
11128
+ ` ${chalk51.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`)}`
11125
11129
  );
11126
11130
  console.log();
11127
11131
  }
11128
- var onboardCommand = new Command46().name("onboard").description("Guided setup for new VM0 users").option("-y, --yes", "Skip confirmation prompts").option("--name <name>", `Agent name (default: ${DEFAULT_AGENT_NAME})`).action(async (options) => {
11132
+ var onboardCommand = new Command48().name("onboard").description("Guided setup for new VM0 users").option("-y, --yes", "Skip confirmation prompts").option("--name <name>", `Agent name (default: ${DEFAULT_AGENT_NAME})`).action(async (options) => {
11129
11133
  const interactive = isInteractive();
11130
11134
  if (interactive) {
11131
11135
  console.log();
@@ -11151,248 +11155,40 @@ var onboardCommand = new Command46().name("onboard").description("Guided setup f
11151
11155
  await handleAuthentication(ctx);
11152
11156
  await handleModelProvider(ctx);
11153
11157
  const agentName = await handleAgentCreation(ctx);
11154
- await handleSkillInstallation(ctx, agentName);
11158
+ await handlePluginInstallation(ctx, agentName);
11159
+ ctx.updateProgress(4, "completed");
11155
11160
  printNextSteps(agentName);
11156
11161
  });
11157
11162
 
11158
11163
  // src/commands/setup-claude.ts
11159
- import { Command as Command47 } from "commander";
11160
- import chalk49 from "chalk";
11161
- import { mkdir as mkdir9, writeFile as writeFile8 } from "fs/promises";
11162
- import path15 from "path";
11163
- var SKILL_DIR2 = ".claude/skills/vm0-agent-builder";
11164
- var SKILL_CONTENT = `---
11165
- name: vm0-agent-builder
11166
- description: Guide for building VM0 agents with Claude's help. Use this skill when users want to create or improve their agent's AGENTS.md and vm0.yaml configuration.
11167
- ---
11168
-
11169
- # VM0 Agent Builder
11170
-
11171
- Help users create effective AI agents using the VM0 platform. This skill guides the process of designing agent workflows, writing AGENTS.md instructions, and configuring vm0.yaml.
11172
-
11173
- ## When to Use
11174
-
11175
- - User wants to create a new VM0 agent from scratch
11176
- - User wants to improve an existing agent's instructions
11177
- - User needs help configuring vm0.yaml with skills
11178
- - User is unsure how to structure their agent's workflow
11179
-
11180
- ## Workflow
11181
-
11182
- ### Step 1: Understand the Goal
11183
-
11184
- Ask the user what they want their agent to accomplish:
11185
- - What is the main task or problem to solve?
11186
- - What inputs will the agent receive?
11187
- - What outputs should the agent produce?
11188
- - Are there any constraints or requirements?
11189
-
11190
- ### Step 2: Design the Workflow
11191
-
11192
- Break down the task into clear, sequential steps:
11193
- 1. Each step should be a single, focused action
11194
- 2. Steps should build on each other logically
11195
- 3. Include error handling and edge cases
11196
- 4. Consider what tools/skills the agent will need
11197
-
11198
- ### Step 3: Write AGENTS.md
11199
-
11200
- Create the agent instructions file with:
11201
-
11202
- \`\`\`markdown
11203
- # Agent Instructions
11204
-
11205
- You are a [role description].
11206
-
11207
- ## Goal
11208
-
11209
- [Clear statement of what the agent should accomplish]
11210
-
11211
- ## Workflow
11212
-
11213
- 1. [First step with specific instructions]
11214
- 2. [Second step with specific instructions]
11215
- 3. [Continue with remaining steps...]
11216
-
11217
- ## Output
11218
-
11219
- [Describe the expected output format and location]
11220
-
11221
- ## Constraints
11222
-
11223
- [Any limitations or rules the agent should follow]
11224
- \`\`\`
11225
-
11226
- ### Step 4: Configure vm0.yaml
11227
-
11228
- Update the vm0.yaml to include necessary skills:
11229
-
11230
- \`\`\`yaml
11231
- version: "1.0"
11232
-
11233
- agents:
11234
- agent-name:
11235
- framework: claude-code
11236
- instructions: AGENTS.md
11237
- skills:
11238
- - https://github.com/vm0-ai/vm0-skills/tree/main/skill-name
11239
- environment:
11240
- # Add any required environment variables
11241
- API_KEY: "\${{ secrets.API_KEY }}"
11242
- \`\`\`
11243
-
11244
- ### Step 5: Test the Agent
11245
-
11246
- Guide the user to test their agent:
11247
-
11248
- \`\`\`bash
11249
- # Deploy the agent configuration
11250
- vm0 compose vm0.yaml
11251
-
11252
- # Run the agent with a test prompt
11253
- vm0 cook "start working on the task"
11254
-
11255
- # Check the logs if needed
11256
- vm0 logs <run-id>
11257
- \`\`\`
11258
-
11259
- ## Available Skills
11260
-
11261
- Common skills from vm0-skills repository:
11262
-
11263
- | Skill | Purpose |
11264
- |-------|---------|
11265
- | \`github\` | GitHub API operations (issues, PRs, repos) |
11266
- | \`slack\` | Send messages to Slack channels |
11267
- | \`notion\` | Read/write Notion pages and databases |
11268
- | \`firecrawl\` | Web scraping and content extraction |
11269
- | \`browserbase\` | Browser automation |
11270
- | \`openai\` | OpenAI API for embeddings, completions |
11271
- | \`supabase\` | Database operations with Supabase |
11272
-
11273
- Browse all skills: https://github.com/vm0-ai/vm0-skills
11274
-
11275
- ## Example Agents
11276
-
11277
- ### Content Curator Agent
11278
-
11279
- \`\`\`markdown
11280
- # Agent Instructions
11281
-
11282
- You are a content curator that monitors HackerNews for AI-related articles.
11283
-
11284
- ## Workflow
11285
-
11286
- 1. Go to HackerNews and read the top 30 stories
11287
- 2. Filter for AI, ML, and LLM related content
11288
- 3. For each relevant article, extract:
11289
- - Title and URL
11290
- - Key points (2-3 sentences)
11291
- - Why it's interesting
11292
- 4. Write a summary to \`daily-digest.md\`
11293
-
11294
- ## Output
11295
-
11296
- Create \`daily-digest.md\` with today's date as the header.
11297
- \`\`\`
11298
-
11299
- ### GitHub Issue Tracker Agent
11300
-
11301
- \`\`\`markdown
11302
- # Agent Instructions
11303
-
11304
- You are a GitHub issue tracker that summarizes open issues.
11305
-
11306
- ## Workflow
11307
-
11308
- 1. List all open issues in the repository
11309
- 2. Group issues by labels (bug, feature, docs)
11310
- 3. For each group, summarize:
11311
- - Number of issues
11312
- - Oldest issue age
11313
- - Most discussed issues
11314
- 4. Create a report in \`issue-report.md\`
11315
-
11316
- ## Skills Required
11317
-
11318
- - github (for API access)
11319
- \`\`\`
11320
-
11321
- ### Data Pipeline Agent
11322
-
11323
- \`\`\`markdown
11324
- # Agent Instructions
11325
-
11326
- You are a data pipeline agent that processes CSV files.
11327
-
11328
- ## Workflow
11329
-
11330
- 1. Read all CSV files from the input volume
11331
- 2. For each file:
11332
- - Validate the schema
11333
- - Clean missing values
11334
- - Transform dates to ISO format
11335
- 3. Merge all files into \`combined.csv\`
11336
- 4. Generate a summary report
11337
-
11338
- ## Input
11339
-
11340
- Files are provided via volume mount.
11341
-
11342
- ## Output
11343
-
11344
- Write results to the artifact directory.
11345
- \`\`\`
11346
-
11347
- ## Best Practices
11348
-
11349
- 1. **Be Specific**: Vague instructions lead to unpredictable results
11350
- 2. **One Task Per Step**: Keep workflow steps focused and atomic
11351
- 3. **Define Output Clearly**: Specify exact file names and formats
11352
- 4. **Handle Errors**: Include what to do when things go wrong
11353
- 5. **Test Incrementally**: Start with simple workflows, add complexity
11354
- 6. **Use Skills Wisely**: Only include skills the agent actually needs
11355
-
11356
- ## Troubleshooting
11357
-
11358
- ### Agent doesn't follow instructions
11359
- - Make instructions more specific and explicit
11360
- - Add examples of expected behavior
11361
- - Break complex steps into smaller sub-steps
11362
-
11363
- ### Agent uses wrong tools
11364
- - Specify which tools/skills to use for each step
11365
- - Add constraints about what NOT to do
11366
-
11367
- ### Output format is wrong
11368
- - Provide exact templates for output files
11369
- - Include example output in the instructions
11370
- `;
11371
- var setupClaudeCommand = new Command47().name("setup-claude").description("Add/update Claude skill for agent building").option(
11372
- "--agent-dir <dir>",
11373
- "Agent directory (shown in next step instructions)"
11374
- ).action(async (options) => {
11375
- console.log(chalk49.dim("Installing vm0-agent-builder skill..."));
11376
- await mkdir9(SKILL_DIR2, { recursive: true });
11377
- await writeFile8(path15.join(SKILL_DIR2, "SKILL.md"), SKILL_CONTENT);
11378
- console.log(
11379
- chalk49.green(`Done Installed vm0-agent-builder skill to ${SKILL_DIR2}`)
11380
- );
11164
+ import { Command as Command49 } from "commander";
11165
+ import chalk52 from "chalk";
11166
+ var setupClaudeCommand = new Command49().name("setup-claude").description("Install VM0 Claude Plugin").option("--agent-dir <dir>", "Agent directory to run install in").option("--scope <scope>", "Installation scope (user or project)", "project").action(async (options) => {
11167
+ console.log(chalk52.dim("Installing VM0 Claude Plugin..."));
11168
+ const scope = options.scope === "user" ? "user" : "project";
11169
+ try {
11170
+ const result = await installVm0Plugin(scope, options.agentDir);
11171
+ console.log(
11172
+ chalk52.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
11173
+ );
11174
+ } catch (error) {
11175
+ handlePluginError(error);
11176
+ }
11381
11177
  console.log();
11382
11178
  console.log("Next step:");
11383
11179
  const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
11384
11180
  console.log(
11385
- chalk49.cyan(
11386
- ` ${cdPrefix}claude "/vm0-agent-builder I want to build an agent that..."`
11181
+ chalk52.cyan(
11182
+ ` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
11387
11183
  )
11388
11184
  );
11389
11185
  });
11390
11186
 
11391
11187
  // src/index.ts
11392
- var program = new Command48();
11393
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.3.0");
11188
+ var program = new Command50();
11189
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.4.0");
11394
11190
  program.command("info").description("Display environment information").action(async () => {
11395
- console.log(chalk50.bold("System Information:"));
11191
+ console.log(chalk53.bold("System Information:"));
11396
11192
  console.log(`Node Version: ${process.version}`);
11397
11193
  console.log(`Platform: ${process.platform}`);
11398
11194
  console.log(`Architecture: ${process.arch}`);