@vm0/cli 9.134.1 → 9.135.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  source_default,
63
63
  volumeConfigSchema,
64
64
  withErrorHandler
65
- } from "./chunk-2MZO4LKL.js";
65
+ } from "./chunk-7C3QXZRH.js";
66
66
  import {
67
67
  __commonJS,
68
68
  __require,
@@ -7771,7 +7771,7 @@ function getConfigPath() {
7771
7771
  return join(homedir(), ".vm0", "config.json");
7772
7772
  }
7773
7773
  var infoCommand = new Command().name("info").description("Display environment and debug information").action(async () => {
7774
- console.log(source_default.bold(`VM0 CLI v${"9.134.1"}`));
7774
+ console.log(source_default.bold(`VM0 CLI v${"9.135.0"}`));
7775
7775
  console.log();
7776
7776
  const config = await loadConfig();
7777
7777
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -11716,7 +11716,7 @@ var composeCommand = new Command().name("compose").description("Create or update
11716
11716
  options.autoUpdate = false;
11717
11717
  }
11718
11718
  if (options.autoUpdate !== false) {
11719
- await startSilentUpgrade("9.134.1");
11719
+ await startSilentUpgrade("9.135.0");
11720
11720
  }
11721
11721
  try {
11722
11722
  let result;
@@ -11808,7 +11808,7 @@ var mainRunCommand = new Command().name("run").description("Run an agent").argum
11808
11808
  withErrorHandler(
11809
11809
  async (identifier, prompt, options) => {
11810
11810
  if (options.autoUpdate !== false) {
11811
- await startSilentUpgrade("9.134.1");
11811
+ await startSilentUpgrade("9.135.0");
11812
11812
  }
11813
11813
  const { name, version } = parseIdentifier(identifier);
11814
11814
  let composeId;
@@ -13581,13 +13581,13 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
13581
13581
  if (latestVersion === null) {
13582
13582
  throw new Error("Could not check for updates. Please try again later.");
13583
13583
  }
13584
- if (latestVersion === "9.134.1") {
13585
- console.log(source_default.green(`\u2713 Already up to date (${"9.134.1"})`));
13584
+ if (latestVersion === "9.135.0") {
13585
+ console.log(source_default.green(`\u2713 Already up to date (${"9.135.0"})`));
13586
13586
  return;
13587
13587
  }
13588
13588
  console.log(
13589
13589
  source_default.yellow(
13590
- `Current version: ${"9.134.1"} -> Latest version: ${latestVersion}`
13590
+ `Current version: ${"9.135.0"} -> Latest version: ${latestVersion}`
13591
13591
  )
13592
13592
  );
13593
13593
  console.log();
@@ -13614,7 +13614,7 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
13614
13614
  const success = await performUpgrade(packageManager);
13615
13615
  if (success) {
13616
13616
  console.log(
13617
- source_default.green(`\u2713 Upgraded from ${"9.134.1"} to ${latestVersion}`)
13617
+ source_default.green(`\u2713 Upgraded from ${"9.135.0"} to ${latestVersion}`)
13618
13618
  );
13619
13619
  return;
13620
13620
  }
@@ -13681,7 +13681,7 @@ var whoamiCommand = new Command().name("whoami").description("Show current ident
13681
13681
 
13682
13682
  // src/index.ts
13683
13683
  var program = new Command();
13684
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.134.1");
13684
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.135.0");
13685
13685
  program.addCommand(authCommand);
13686
13686
  program.addCommand(infoCommand);
13687
13687
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.134.1",
3
+ "version": "9.135.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  Option,
12
12
  allowsCustomModel,
13
13
  completeSlackFileUpload,
14
+ completeTelegramFileUpload,
14
15
  configureGlobalProxyFromEnv,
15
16
  connectorTypeSchema,
16
17
  createSkill,
@@ -59,6 +60,7 @@ import {
59
60
  hasAuthMethods,
60
61
  hasModelSelection,
61
62
  initSlackFileUpload,
63
+ initTelegramFileUpload,
62
64
  inviteZeroOrgMember,
63
65
  isInteractive,
64
66
  isUUID,
@@ -113,7 +115,7 @@ import {
113
115
  upsertZeroOrgModelProvider,
114
116
  withErrorHandler,
115
117
  zeroAgentCustomSkillNameSchema
116
- } from "./chunk-2MZO4LKL.js";
118
+ } from "./chunk-7C3QXZRH.js";
117
119
  import {
118
120
  __toESM,
119
121
  init_esm_shims
@@ -16787,11 +16789,111 @@ Notes:
16787
16789
  )
16788
16790
  );
16789
16791
 
16792
+ // src/commands/zero/telegram/upload-file.ts
16793
+ init_esm_shims();
16794
+ import { readFileSync as readFileSync7, statSync as statSync2 } from "fs";
16795
+ import { basename as basename2, extname } from "path";
16796
+ var MIME_BY_EXTENSION = {
16797
+ ".png": "image/png",
16798
+ ".jpg": "image/jpeg",
16799
+ ".jpeg": "image/jpeg",
16800
+ ".gif": "image/gif",
16801
+ ".webp": "image/webp",
16802
+ ".svg": "image/svg+xml",
16803
+ ".mp4": "video/mp4",
16804
+ ".webm": "video/webm",
16805
+ ".mov": "video/quicktime",
16806
+ ".pdf": "application/pdf",
16807
+ ".txt": "text/plain",
16808
+ ".csv": "text/csv",
16809
+ ".md": "text/markdown",
16810
+ ".json": "application/json"
16811
+ };
16812
+ function inferContentType(localPath) {
16813
+ const ext = extname(localPath).toLowerCase();
16814
+ return MIME_BY_EXTENSION[ext] ?? "application/octet-stream";
16815
+ }
16816
+ function parseMessageThreadId(value) {
16817
+ if (!value) return void 0;
16818
+ const parsed = Number(value);
16819
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) {
16820
+ throw new Error("message-thread-id must be a positive integer");
16821
+ }
16822
+ return parsed;
16823
+ }
16824
+ var uploadFileCommand2 = new Command().name("upload-file").description("Upload a local file to a Telegram chat as the bot").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("--bot-id <bot-id>", "Telegram bot id to send through").requiredOption("-c, --chat-id <chat-id>", "Telegram chat id or @channel").option("--caption <text>", "Caption to accompany the file").option("--message-thread-id <id>", "Forum topic message thread id").option("--content-type <mime>", "Override inferred content type").addHelpText(
16825
+ "after",
16826
+ `
16827
+ Examples:
16828
+ Upload a file: zero telegram upload-file -f /tmp/report.pdf --bot-id 123456789 -c -1001234567890
16829
+ Upload to a topic: zero telegram upload-file -f /tmp/log.txt --bot-id 123456789 -c -1001234567890 --message-thread-id 42
16830
+ With a caption: zero telegram upload-file -f /tmp/data.csv --bot-id 123456789 -c @channel --caption "Daily report"
16831
+
16832
+ Output:
16833
+ Prints a JSON object to stdout on success:
16834
+ {"messageId":123,"chatId":"-1001234567890","fileId":"...","filename":"report.pdf","mimetype":"application/pdf","size":12345,"url":"https://..."}
16835
+
16836
+ Notes:
16837
+ - Uses the Telegram bot token on the server side
16838
+ - Uploads through VM0 storage first, then asks Telegram to fetch the file URL
16839
+ - VM0 does not apply file type or size restrictions before calling Telegram`
16840
+ ).action(
16841
+ withErrorHandler(
16842
+ async (options) => {
16843
+ let fileSize;
16844
+ try {
16845
+ const stat = statSync2(options.file);
16846
+ if (!stat.isFile()) {
16847
+ throw new Error(`Not a regular file: ${options.file}`);
16848
+ }
16849
+ fileSize = stat.size;
16850
+ } catch (error) {
16851
+ if (error instanceof Error && error.message.startsWith("Not ")) {
16852
+ throw error;
16853
+ }
16854
+ throw new Error(`File not found: ${options.file}`);
16855
+ }
16856
+ if (fileSize === 0) {
16857
+ throw new Error("File is empty");
16858
+ }
16859
+ const filename = basename2(options.file);
16860
+ const contentType = options.contentType ?? inferContentType(options.file);
16861
+ const messageThreadId = parseMessageThreadId(options.messageThreadId);
16862
+ const prepared = await initTelegramFileUpload({
16863
+ filename,
16864
+ contentType,
16865
+ length: fileSize
16866
+ });
16867
+ const fileContent = readFileSync7(options.file);
16868
+ const uploadResponse = await fetch(prepared.uploadUrl, {
16869
+ method: "PUT",
16870
+ headers: { "Content-Type": prepared.contentType },
16871
+ body: new Uint8Array(fileContent)
16872
+ });
16873
+ if (!uploadResponse.ok) {
16874
+ throw new Error(
16875
+ `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`
16876
+ );
16877
+ }
16878
+ const result = await completeTelegramFileUpload({
16879
+ uploadId: prepared.uploadId,
16880
+ botId: options.botId,
16881
+ chatId: options.chatId,
16882
+ contentType: prepared.contentType,
16883
+ caption: options.caption,
16884
+ messageThreadId
16885
+ });
16886
+ console.log(JSON.stringify(result));
16887
+ }
16888
+ )
16889
+ );
16890
+
16790
16891
  // src/commands/zero/telegram/index.ts
16791
- var zeroTelegramCommand = new Command().name("telegram").description("Download files from Telegram as the bot").addCommand(downloadFileCommand2).addHelpText(
16892
+ var zeroTelegramCommand = new Command().name("telegram").description("Upload and download files from Telegram as the bot").addCommand(downloadFileCommand2).addCommand(uploadFileCommand2).addHelpText(
16792
16893
  "after",
16793
16894
  `
16794
16895
  Examples:
16896
+ Upload a file: zero telegram upload-file -f /tmp/report.pdf --bot-id <bot-id> -c <chat-id>
16795
16897
  Download a file: zero telegram download-file <file-id> --bot-id <bot-id> -o /tmp/out.jpg`
16796
16898
  );
16797
16899
 
@@ -17042,7 +17144,7 @@ init_esm_shims();
17042
17144
 
17043
17145
  // src/lib/skill-directory.ts
17044
17146
  init_esm_shims();
17045
- import { readFileSync as readFileSync7, readdirSync } from "fs";
17147
+ import { readFileSync as readFileSync8, readdirSync } from "fs";
17046
17148
  import { join as join3 } from "path";
17047
17149
  var IGNORED_NAMES = /* @__PURE__ */ new Set(["node_modules", ".git", ".DS_Store"]);
17048
17150
  function readSkillDirectory(dirPath) {
@@ -17057,7 +17159,7 @@ function readSkillDirectory(dirPath) {
17057
17159
  } else {
17058
17160
  files.push({
17059
17161
  path: relPath,
17060
- content: readFileSync7(join3(dir, entry.name), "utf-8")
17162
+ content: readFileSync8(join3(dir, entry.name), "utf-8")
17061
17163
  });
17062
17164
  }
17063
17165
  }
@@ -18877,7 +18979,7 @@ Notes:
18877
18979
 
18878
18980
  // src/commands/zero/web/upload-file.ts
18879
18981
  init_esm_shims();
18880
- var uploadFileCommand2 = new Command().name("upload-file").description("Upload a local file and print a permanent URL").requiredOption("-f, --file <path>", "Local file path to upload").option("--content-type <mime>", "Override inferred content type").addHelpText(
18982
+ var uploadFileCommand3 = new Command().name("upload-file").description("Upload a local file and print a permanent URL").requiredOption("-f, --file <path>", "Local file path to upload").option("--content-type <mime>", "Override inferred content type").addHelpText(
18881
18983
  "after",
18882
18984
  `
18883
18985
  Examples:
@@ -18906,7 +19008,7 @@ Notes:
18906
19008
  );
18907
19009
 
18908
19010
  // src/commands/zero/web/index.ts
18909
- var zeroWebCommand = new Command().name("web").description("Upload and download files via the web chat endpoint").addCommand(downloadFileCommand3).addCommand(uploadFileCommand2).addHelpText(
19011
+ var zeroWebCommand = new Command().name("web").description("Upload and download files via the web chat endpoint").addCommand(downloadFileCommand3).addCommand(uploadFileCommand3).addHelpText(
18910
19012
  "after",
18911
19013
  `
18912
19014
  Examples:
@@ -18926,7 +19028,7 @@ var COMMAND_CAPABILITY_MAP = {
18926
19028
  search: "chat-message:read",
18927
19029
  chat: "chat-message:write",
18928
19030
  slack: "slack:write",
18929
- telegram: "file:read",
19031
+ telegram: ["telegram:read", "telegram:write"],
18930
19032
  whoami: null,
18931
19033
  "developer-support": null,
18932
19034
  "computer-use": "computer-use:write",
@@ -18957,7 +19059,13 @@ function shouldHideCommand(name, payload) {
18957
19059
  if (!payload) return false;
18958
19060
  const requiredCap = COMMAND_CAPABILITY_MAP[name];
18959
19061
  if (requiredCap === void 0) return true;
18960
- return requiredCap !== null && !payload.capabilities.includes(requiredCap);
19062
+ if (requiredCap === null) return false;
19063
+ if (typeof requiredCap !== "string") {
19064
+ return !requiredCap.some((capability) => {
19065
+ return payload.capabilities.includes(capability);
19066
+ });
19067
+ }
19068
+ return !payload.capabilities.includes(requiredCap);
18961
19069
  }
18962
19070
  function registerZeroCommands(prog, commands) {
18963
19071
  const token = process.env.ZERO_TOKEN;
@@ -18970,12 +19078,13 @@ function registerZeroCommands(prog, commands) {
18970
19078
  var program = new Command();
18971
19079
  program.name("zero").description(
18972
19080
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
18973
- ).version("9.134.1").addHelpText(
19081
+ ).version("9.135.0").addHelpText(
18974
19082
  "after",
18975
19083
  `
18976
19084
  Examples:
18977
19085
  Check a connector? zero doctor check-connector --env-name <ENV_NAME>
18978
19086
  Send a Slack message? zero slack message send --help
19087
+ Upload Telegram? zero telegram upload-file --help
18979
19088
  Download Telegram? zero telegram download-file --help
18980
19089
  Set up a schedule? zero schedule setup --help
18981
19090
  Update yourself? zero agent --help