@vm0/cli 9.35.0 → 9.36.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 +117 -53
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -45,7 +45,7 @@ if (DSN) {
45
45
  Sentry.init({
46
46
  dsn: DSN,
47
47
  environment: process.env.SENTRY_ENVIRONMENT ?? "production",
48
- release: "9.35.0",
48
+ release: "9.36.0",
49
49
  sendDefaultPii: false,
50
50
  tracesSampleRate: 0,
51
51
  shutdownTimeout: 500,
@@ -64,7 +64,7 @@ if (DSN) {
64
64
  }
65
65
  });
66
66
  Sentry.setContext("cli", {
67
- version: "9.35.0",
67
+ version: "9.36.0",
68
68
  command: process.argv.slice(2).join(" ")
69
69
  });
70
70
  Sentry.setContext("runtime", {
@@ -605,7 +605,7 @@ async function waitForSilentUpgrade(timeout = TIMEOUT_MS) {
605
605
  // src/commands/info/index.ts
606
606
  var CONFIG_PATH = join2(homedir2(), ".vm0", "config.json");
607
607
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
608
- console.log(chalk7.bold(`VM0 CLI v${"9.35.0"}`));
608
+ console.log(chalk7.bold(`VM0 CLI v${"9.36.0"}`));
609
609
  console.log();
610
610
  const config = await loadConfig();
611
611
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -858,7 +858,9 @@ var agentNameSchema = z4.string().min(3, "Agent name must be at least 3 characte
858
858
  );
859
859
  var volumeConfigSchema = z4.object({
860
860
  name: z4.string().min(1, "Volume name is required"),
861
- version: z4.string().min(1, "Volume version is required")
861
+ version: z4.string().min(1, "Volume version is required"),
862
+ /** When true, skip mounting without error if volume doesn't exist */
863
+ optional: z4.boolean().optional()
862
864
  });
863
865
  var SUPPORTED_APPS = ["github"];
864
866
  var SUPPORTED_APP_TAGS = ["latest", "dev"];
@@ -3783,11 +3785,18 @@ var connectorSessionByIdContract = c19.router({
3783
3785
  import { z as z24 } from "zod";
3784
3786
  var c20 = initContract();
3785
3787
  var userPreferencesResponseSchema = z24.object({
3786
- timezone: z24.string().nullable()
3788
+ timezone: z24.string().nullable(),
3789
+ notifyEmail: z24.boolean()
3787
3790
  });
3788
3791
  var updateUserPreferencesRequestSchema = z24.object({
3789
- timezone: z24.string().min(1, "Timezone is required")
3790
- });
3792
+ timezone: z24.string().min(1).optional(),
3793
+ notifyEmail: z24.boolean().optional()
3794
+ }).refine(
3795
+ (data) => data.timezone !== void 0 || data.notifyEmail !== void 0,
3796
+ {
3797
+ message: "At least one preference must be provided"
3798
+ }
3799
+ );
3791
3800
  var userPreferencesContract = c20.router({
3792
3801
  /**
3793
3802
  * GET /api/user/preferences
@@ -6334,7 +6343,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
6334
6343
  options.autoUpdate = false;
6335
6344
  }
6336
6345
  if (options.autoUpdate !== false) {
6337
- await startSilentUpgrade("9.35.0");
6346
+ await startSilentUpgrade("9.36.0");
6338
6347
  }
6339
6348
  try {
6340
6349
  let result;
@@ -8531,7 +8540,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
8531
8540
  async (identifier, prompt, options) => {
8532
8541
  try {
8533
8542
  if (options.autoUpdate !== false) {
8534
- await startSilentUpgrade("9.35.0");
8543
+ await startSilentUpgrade("9.36.0");
8535
8544
  }
8536
8545
  const { scope, name, version } = parseIdentifier(identifier);
8537
8546
  if (scope && !options.experimentalSharedAgent) {
@@ -10107,7 +10116,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
10107
10116
  ).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option5("--debug-no-mock-claude").hideHelp()).addOption(new Option5("--no-auto-update").hideHelp()).action(
10108
10117
  async (prompt, options) => {
10109
10118
  if (options.autoUpdate !== false) {
10110
- const shouldExit = await checkAndUpgrade("9.35.0", prompt);
10119
+ const shouldExit = await checkAndUpgrade("9.36.0", prompt);
10111
10120
  if (shouldExit) {
10112
10121
  process.exit(0);
10113
10122
  }
@@ -14678,7 +14687,7 @@ function displayResult(job) {
14678
14687
  // src/commands/dev-tool/index.ts
14679
14688
  var devToolCommand = new Command76().name("dev-tool").description("Developer tools for testing and debugging").addCommand(composeCommand2);
14680
14689
 
14681
- // src/commands/timezone/index.ts
14690
+ // src/commands/preference/index.ts
14682
14691
  import { Command as Command77 } from "commander";
14683
14692
  import chalk78 from "chalk";
14684
14693
  function detectTimezone2() {
@@ -14692,60 +14701,115 @@ function isValidTimezone(timezone) {
14692
14701
  return false;
14693
14702
  }
14694
14703
  }
14695
- var timezoneCommand = new Command77().name("timezone").description("View or set your timezone preference").argument("[timezone]", "IANA timezone to set (e.g., America/New_York)").action(
14696
- withErrorHandler(async (timezone) => {
14697
- if (timezone) {
14698
- if (!isValidTimezone(timezone)) {
14699
- console.error(chalk78.red(`\u2717 Invalid timezone: ${timezone}`));
14700
- console.error(
14701
- chalk78.dim(
14702
- " Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
14703
- )
14704
- );
14705
- process.exit(1);
14706
- }
14707
- const result = await updateUserPreferences({ timezone });
14708
- console.log(chalk78.green(`\u2713 Timezone set to ${chalk78.cyan(timezone)}`));
14709
- if (result.timezone !== timezone) {
14710
- console.log(chalk78.dim(` (Server returned: ${result.timezone})`));
14704
+ function parseNotifyEmail(value) {
14705
+ const lower = value.toLowerCase();
14706
+ if (lower === "on" || lower === "true" || lower === "1") return true;
14707
+ if (lower === "off" || lower === "false" || lower === "0") return false;
14708
+ throw new Error(
14709
+ `Invalid value for --notify-email: "${value}". Use "on" or "off".`
14710
+ );
14711
+ }
14712
+ function displayPreferences(prefs) {
14713
+ console.log(chalk78.bold("Current preferences:"));
14714
+ console.log(
14715
+ ` Timezone: ${prefs.timezone ? chalk78.cyan(prefs.timezone) : chalk78.dim("not set")}`
14716
+ );
14717
+ console.log(
14718
+ ` Email notify: ${prefs.notifyEmail ? chalk78.green("on") : chalk78.dim("off")}`
14719
+ );
14720
+ }
14721
+ var preferenceCommand = new Command77().name("preference").description("View or update your preferences").option("--timezone <timezone>", "IANA timezone (e.g., America/New_York)").option("--notify-email <on|off>", "Enable or disable email notifications").action(
14722
+ withErrorHandler(
14723
+ async (opts) => {
14724
+ const hasTimezone = opts.timezone !== void 0;
14725
+ const hasNotifyEmail = opts.notifyEmail !== void 0;
14726
+ if (hasTimezone || hasNotifyEmail) {
14727
+ const updates = {};
14728
+ if (hasTimezone) {
14729
+ if (!isValidTimezone(opts.timezone)) {
14730
+ console.error(chalk78.red(`Invalid timezone: ${opts.timezone}`));
14731
+ console.error(
14732
+ chalk78.dim(
14733
+ " Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
14734
+ )
14735
+ );
14736
+ process.exit(1);
14737
+ }
14738
+ updates.timezone = opts.timezone;
14739
+ }
14740
+ if (hasNotifyEmail) {
14741
+ try {
14742
+ updates.notifyEmail = parseNotifyEmail(opts.notifyEmail);
14743
+ } catch (err) {
14744
+ console.error(chalk78.red(err.message));
14745
+ process.exit(1);
14746
+ }
14747
+ }
14748
+ const result = await updateUserPreferences(updates);
14749
+ if (updates.timezone !== void 0) {
14750
+ console.log(
14751
+ chalk78.green(
14752
+ `Timezone set to ${chalk78.cyan(result.timezone ?? updates.timezone)}`
14753
+ )
14754
+ );
14755
+ }
14756
+ if (updates.notifyEmail !== void 0) {
14757
+ console.log(
14758
+ chalk78.green(
14759
+ `Email notifications ${result.notifyEmail ? "enabled" : "disabled"}`
14760
+ )
14761
+ );
14762
+ }
14763
+ return;
14711
14764
  }
14712
- return;
14713
- }
14714
- const prefs = await getUserPreferences();
14715
- if (prefs.timezone) {
14716
- console.log(`Current timezone: ${chalk78.cyan(prefs.timezone)}`);
14717
- } else {
14718
- const detectedTz = detectTimezone2();
14719
- console.log(chalk78.dim("No timezone preference set."));
14720
- console.log(chalk78.dim(`System timezone detected: ${detectedTz}`));
14765
+ const prefs = await getUserPreferences();
14766
+ displayPreferences(prefs);
14721
14767
  if (isInteractive()) {
14722
- const setNow = await promptText(
14723
- "Would you like to set it now? (enter timezone or leave empty to skip)",
14724
- detectedTz
14725
- );
14726
- if (setNow && setNow.trim()) {
14727
- const tz = setNow.trim();
14728
- if (!isValidTimezone(tz)) {
14729
- console.error(chalk78.red(`\u2717 Invalid timezone: ${tz}`));
14730
- process.exit(1);
14768
+ if (!prefs.timezone) {
14769
+ const detectedTz = detectTimezone2();
14770
+ console.log(chalk78.dim(`
14771
+ System timezone detected: ${detectedTz}`));
14772
+ const tz = await promptText(
14773
+ "Set timezone? (enter timezone or leave empty to skip)",
14774
+ detectedTz
14775
+ );
14776
+ if (tz?.trim()) {
14777
+ if (!isValidTimezone(tz.trim())) {
14778
+ console.error(chalk78.red(`Invalid timezone: ${tz.trim()}`));
14779
+ process.exit(1);
14780
+ }
14781
+ await updateUserPreferences({ timezone: tz.trim() });
14782
+ console.log(
14783
+ chalk78.green(`Timezone set to ${chalk78.cyan(tz.trim())}`)
14784
+ );
14731
14785
  }
14732
- await updateUserPreferences({ timezone: tz });
14733
- console.log(chalk78.green(`\u2713 Timezone set to ${chalk78.cyan(tz)}`));
14734
14786
  }
14735
- } else {
14787
+ if (!prefs.notifyEmail) {
14788
+ const enable = await promptConfirm(
14789
+ "\nEnable email notifications for scheduled runs?",
14790
+ false
14791
+ );
14792
+ if (enable) {
14793
+ await updateUserPreferences({ notifyEmail: true });
14794
+ console.log(chalk78.green("Email notifications enabled"));
14795
+ }
14796
+ }
14797
+ } else if (!prefs.timezone) {
14736
14798
  console.log();
14737
14799
  console.log(
14738
- `To set your timezone: ${chalk78.cyan("vm0 timezone <timezone>")}`
14800
+ `To set timezone: ${chalk78.cyan("vm0 preference --timezone <timezone>")}`
14801
+ );
14802
+ console.log(
14803
+ chalk78.dim("Example: vm0 preference --timezone America/New_York")
14739
14804
  );
14740
- console.log(chalk78.dim("Example: vm0 timezone America/New_York"));
14741
14805
  }
14742
14806
  }
14743
- })
14807
+ )
14744
14808
  );
14745
14809
 
14746
14810
  // src/index.ts
14747
14811
  var program = new Command78();
14748
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.35.0");
14812
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.36.0");
14749
14813
  program.addCommand(authCommand);
14750
14814
  program.addCommand(infoCommand);
14751
14815
  program.addCommand(composeCommand);
@@ -14766,7 +14830,7 @@ program.addCommand(connectorCommand);
14766
14830
  program.addCommand(onboardCommand);
14767
14831
  program.addCommand(setupClaudeCommand);
14768
14832
  program.addCommand(dashboardCommand);
14769
- program.addCommand(timezoneCommand);
14833
+ program.addCommand(preferenceCommand);
14770
14834
  program.addCommand(devToolCommand, { hidden: true });
14771
14835
  if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
14772
14836
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.35.0",
3
+ "version": "9.36.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",