@vm0/cli 9.104.0 → 9.104.1

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.
@@ -49,7 +49,7 @@ if (DSN) {
49
49
  Sentry.init({
50
50
  dsn: DSN,
51
51
  environment: process.env.SENTRY_ENVIRONMENT ?? "production",
52
- release: "9.104.0",
52
+ release: "9.104.1",
53
53
  sendDefaultPii: false,
54
54
  tracesSampleRate: 0,
55
55
  shutdownTimeout: 500,
@@ -68,7 +68,7 @@ if (DSN) {
68
68
  }
69
69
  });
70
70
  Sentry.setContext("cli", {
71
- version: "9.104.0",
71
+ version: "9.104.1",
72
72
  command: process.argv.slice(2).join(" ")
73
73
  });
74
74
  Sentry.setContext("runtime", {
@@ -32244,4 +32244,4 @@ export {
32244
32244
  parseTime,
32245
32245
  paginate
32246
32246
  };
32247
- //# sourceMappingURL=chunk-FKDGKPGQ.js.map
32247
+ //# sourceMappingURL=chunk-FYV4IKTF.js.map
package/index.js CHANGED
@@ -61,7 +61,7 @@ import {
61
61
  showNextSteps,
62
62
  volumeConfigSchema,
63
63
  withErrorHandler
64
- } from "./chunk-FKDGKPGQ.js";
64
+ } from "./chunk-FYV4IKTF.js";
65
65
 
66
66
  // src/index.ts
67
67
  import { Command as Command44 } from "commander";
@@ -454,7 +454,7 @@ function getConfigPath() {
454
454
  return join(homedir(), ".vm0", "config.json");
455
455
  }
456
456
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
457
- console.log(chalk3.bold(`VM0 CLI v${"9.104.0"}`));
457
+ console.log(chalk3.bold(`VM0 CLI v${"9.104.1"}`));
458
458
  console.log();
459
459
  const config = await loadConfig();
460
460
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -1581,7 +1581,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
1581
1581
  options.autoUpdate = false;
1582
1582
  }
1583
1583
  if (options.autoUpdate !== false) {
1584
- await startSilentUpgrade("9.104.0");
1584
+ await startSilentUpgrade("9.104.1");
1585
1585
  }
1586
1586
  try {
1587
1587
  let result;
@@ -1655,7 +1655,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
1655
1655
  withErrorHandler(
1656
1656
  async (identifier, prompt, options) => {
1657
1657
  if (options.autoUpdate !== false) {
1658
- await startSilentUpgrade("9.104.0");
1658
+ await startSilentUpgrade("9.104.1");
1659
1659
  }
1660
1660
  const { name, version } = parseIdentifier(identifier);
1661
1661
  let composeId;
@@ -3413,7 +3413,7 @@ var cookAction = new Command35().name("cook").description("Quick start: prepare,
3413
3413
  withErrorHandler(
3414
3414
  async (prompt, options) => {
3415
3415
  if (options.autoUpdate !== false) {
3416
- const shouldExit = await checkAndUpgrade("9.104.0", prompt);
3416
+ const shouldExit = await checkAndUpgrade("9.104.1", prompt);
3417
3417
  if (shouldExit) {
3418
3418
  process.exit(0);
3419
3419
  }
@@ -4156,13 +4156,13 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
4156
4156
  if (latestVersion === null) {
4157
4157
  throw new Error("Could not check for updates. Please try again later.");
4158
4158
  }
4159
- if (latestVersion === "9.104.0") {
4160
- console.log(chalk33.green(`\u2713 Already up to date (${"9.104.0"})`));
4159
+ if (latestVersion === "9.104.1") {
4160
+ console.log(chalk33.green(`\u2713 Already up to date (${"9.104.1"})`));
4161
4161
  return;
4162
4162
  }
4163
4163
  console.log(
4164
4164
  chalk33.yellow(
4165
- `Current version: ${"9.104.0"} -> Latest version: ${latestVersion}`
4165
+ `Current version: ${"9.104.1"} -> Latest version: ${latestVersion}`
4166
4166
  )
4167
4167
  );
4168
4168
  console.log();
@@ -4189,7 +4189,7 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
4189
4189
  const success = await performUpgrade(packageManager);
4190
4190
  if (success) {
4191
4191
  console.log(
4192
- chalk33.green(`\u2713 Upgraded from ${"9.104.0"} to ${latestVersion}`)
4192
+ chalk33.green(`\u2713 Upgraded from ${"9.104.1"} to ${latestVersion}`)
4193
4193
  );
4194
4194
  return;
4195
4195
  }
@@ -4257,7 +4257,7 @@ var whoamiCommand = new Command43().name("whoami").description("Show current ide
4257
4257
 
4258
4258
  // src/index.ts
4259
4259
  var program = new Command44();
4260
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.104.0");
4260
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.104.1");
4261
4261
  program.addCommand(authCommand);
4262
4262
  program.addCommand(infoCommand);
4263
4263
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.104.0",
3
+ "version": "9.104.1",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -115,7 +115,7 @@ import {
115
115
  upsertZeroOrgModelProvider,
116
116
  withErrorHandler,
117
117
  zeroAgentCustomSkillNameSchema
118
- } from "./chunk-FKDGKPGQ.js";
118
+ } from "./chunk-FYV4IKTF.js";
119
119
 
120
120
  // src/zero.ts
121
121
  import { Command as Command77 } from "commander";
@@ -4735,8 +4735,19 @@ async function captureScreenshot() {
4735
4735
  const tmpPath = join3(tmpdir(), `vm0-screenshot-${randomUUID()}.jpg`);
4736
4736
  try {
4737
4737
  await execFileAsync("screencapture", ["-x", "-t", "jpg", tmpPath]);
4738
- const buffer = await readFile(tmpPath);
4739
4738
  const info = await getScreenInfo();
4739
+ if (info.scaleFactor > 1) {
4740
+ await execFileAsync("sips", [
4741
+ "-z",
4742
+ String(info.height),
4743
+ String(info.width),
4744
+ "-s",
4745
+ "formatOptions",
4746
+ "80",
4747
+ tmpPath
4748
+ ]);
4749
+ }
4750
+ const buffer = await readFile(tmpPath);
4740
4751
  return {
4741
4752
  image: buffer.toString("base64"),
4742
4753
  width: info.width,
@@ -4761,12 +4772,24 @@ async function captureRegionScreenshot(region) {
4761
4772
  regionArg,
4762
4773
  tmpPath
4763
4774
  ]);
4775
+ const info = await getScreenInfo();
4776
+ if (info.scaleFactor > 1) {
4777
+ await execFileAsync("sips", [
4778
+ "-z",
4779
+ String(region.height),
4780
+ String(region.width),
4781
+ "-s",
4782
+ "formatOptions",
4783
+ "80",
4784
+ tmpPath
4785
+ ]);
4786
+ }
4764
4787
  const buffer = await readFile(tmpPath);
4765
4788
  return {
4766
4789
  image: buffer.toString("base64"),
4767
4790
  width: region.width,
4768
4791
  height: region.height,
4769
- scaleFactor: 1,
4792
+ scaleFactor: info.scaleFactor,
4770
4793
  format: "jpg"
4771
4794
  };
4772
4795
  } finally {
@@ -4786,14 +4809,30 @@ async function getScreenInfo() {
4786
4809
  for (const screen of screens) {
4787
4810
  const pixelStr = screen._spdisplays_pixels;
4788
4811
  if (pixelStr) {
4789
- const match = pixelStr.match(/(\d+)\s*x\s*(\d+)/);
4790
- if (match?.[1] && match[2]) {
4791
- const width = parseInt(match[1], 10);
4792
- const height = parseInt(match[2], 10);
4812
+ const pixelMatch = pixelStr.match(/(\d+)\s*x\s*(\d+)/);
4813
+ if (pixelMatch?.[1] && pixelMatch[2]) {
4814
+ const physicalWidth = parseInt(pixelMatch[1], 10);
4815
+ const physicalHeight = parseInt(pixelMatch[2], 10);
4793
4816
  const resStr = screen._spdisplays_resolution ?? screen.spdisplays_resolution ?? "";
4794
- const isRetina = /retina/i.test(resStr);
4795
- const scaleFactor = isRetina ? 2 : 1;
4796
- return { width, height, scaleFactor };
4817
+ const resMatch = resStr.match(/(\d+)\s*x\s*(\d+)/);
4818
+ let scaleFactor;
4819
+ let logicalWidth;
4820
+ let logicalHeight;
4821
+ if (resMatch?.[1] && resMatch[2]) {
4822
+ logicalWidth = parseInt(resMatch[1], 10);
4823
+ logicalHeight = parseInt(resMatch[2], 10);
4824
+ scaleFactor = Math.round(physicalWidth / logicalWidth);
4825
+ } else {
4826
+ const isRetina = /retina/i.test(resStr);
4827
+ scaleFactor = isRetina ? 2 : 1;
4828
+ logicalWidth = Math.floor(physicalWidth / scaleFactor);
4829
+ logicalHeight = Math.floor(physicalHeight / scaleFactor);
4830
+ }
4831
+ return {
4832
+ width: logicalWidth,
4833
+ height: logicalHeight,
4834
+ scaleFactor
4835
+ };
4797
4836
  }
4798
4837
  }
4799
4838
  }
@@ -4908,17 +4947,20 @@ function parseKeyCombo(keys) {
4908
4947
  }
4909
4948
  return { modifiers, mainKey };
4910
4949
  }
4950
+ function keyAction(key) {
4951
+ return VALID_SPECIAL_KEYS.has(key) ? `kp:${key}` : `t:${key}`;
4952
+ }
4911
4953
  async function pressKey(keys) {
4912
4954
  const { modifiers, mainKey } = parseKeyCombo(keys);
4913
4955
  if (modifiers.length === 0) {
4914
- await execFileAsync2("cliclick", [`kp:${mainKey}`]);
4956
+ await execFileAsync2("cliclick", [keyAction(mainKey)]);
4915
4957
  return;
4916
4958
  }
4917
4959
  const args = [];
4918
4960
  for (const mod of modifiers) {
4919
4961
  args.push(`kd:${mod}`);
4920
4962
  }
4921
- args.push(`kp:${mainKey}`);
4963
+ args.push(keyAction(mainKey));
4922
4964
  for (let i = modifiers.length - 1; i >= 0; i--) {
4923
4965
  args.push(`ku:${modifiers[i]}`);
4924
4966
  }
@@ -5101,12 +5143,10 @@ async function handleMouseRequest(req, res) {
5101
5143
  return;
5102
5144
  }
5103
5145
  const info = await getScreenInfo();
5104
- const maxX = Math.floor(info.width / info.scaleFactor);
5105
- const maxY = Math.floor(info.height / info.scaleFactor);
5106
- if (x < 0 || x >= maxX || y < 0 || y >= maxY) {
5146
+ if (x < 0 || x >= info.width || y < 0 || y >= info.height) {
5107
5147
  res.writeHead(400, { "Content-Type": "text/plain" });
5108
5148
  res.end(
5109
- `Coordinates out of bounds. Screen size: ${maxX}x${maxY} (points)`
5149
+ `Coordinates out of bounds. Screen size: ${info.width}x${info.height} (points)`
5110
5150
  );
5111
5151
  return;
5112
5152
  }
@@ -5680,6 +5720,23 @@ var clientCommand = new Command76().name("client").description("Interact with re
5680
5720
  var zeroComputerUseCommand = new Command76().name("computer-use").description("Remote desktop control for cloud agents").addCommand(hostCommand).addCommand(clientCommand).addHelpText(
5681
5721
  "after",
5682
5722
  `
5723
+ Coordinate System:
5724
+ All coordinate parameters use macOS logical coordinates (points), not physical
5725
+ pixels. On Retina displays (scaleFactor: 2), a 2880\xD71800 physical screen has
5726
+ logical dimensions of 1440\xD7900. Use the "info" command to check your screen's
5727
+ logical dimensions and scale factor.
5728
+
5729
+ The "screenshot" command returns an image at logical resolution. The "zoom"
5730
+ command accepts a region in logical coordinates but returns an image at physical
5731
+ resolution (logical size \xD7 scaleFactor), providing higher detail for precise
5732
+ element location.
5733
+
5734
+ Recommended AI agent workflow:
5735
+ 1. screenshot \u2014 get a screen overview at logical resolution
5736
+ 2. zoom --x --y ... \u2014 zoom into a region of interest for pixel-level detail
5737
+ 3. Calculate the logical coordinates of the target element
5738
+ 4. Execute click/type operations using those logical coordinates
5739
+
5683
5740
  Examples:
5684
5741
  Start the host daemon (on macOS): zero computer-use host start
5685
5742
  Stop the host daemon: zero computer-use host stop
@@ -5753,7 +5810,7 @@ function registerZeroCommands(prog, commands) {
5753
5810
  var program = new Command77();
5754
5811
  program.name("zero").description(
5755
5812
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
5756
- ).version("9.104.0").addHelpText(
5813
+ ).version("9.104.1").addHelpText(
5757
5814
  "after",
5758
5815
  `
5759
5816
  Examples: