@vm0/cli 9.136.0 → 9.137.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/{chunk-5F6QHYHS.js → chunk-HH2HTGSA.js} +77 -3
- package/{chunk-5F6QHYHS.js.map → chunk-HH2HTGSA.js.map} +1 -1
- package/index.js +9 -9
- package/package.json +1 -1
- package/zero.js +165 -15
- package/zero.js.map +1 -1
package/index.js
CHANGED
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
source_default,
|
|
63
63
|
volumeConfigSchema,
|
|
64
64
|
withErrorHandler
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-HH2HTGSA.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.
|
|
7774
|
+
console.log(source_default.bold(`VM0 CLI v${"9.137.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.
|
|
11719
|
+
await startSilentUpgrade("9.137.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.
|
|
11811
|
+
await startSilentUpgrade("9.137.0");
|
|
11812
11812
|
}
|
|
11813
11813
|
const { name, version } = parseIdentifier(identifier);
|
|
11814
11814
|
let composeId;
|
|
@@ -13582,13 +13582,13 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
|
|
|
13582
13582
|
if (latestVersion === null) {
|
|
13583
13583
|
throw new Error("Could not check for updates. Please try again later.");
|
|
13584
13584
|
}
|
|
13585
|
-
if (latestVersion === "9.
|
|
13586
|
-
console.log(source_default.green(`\u2713 Already up to date (${"9.
|
|
13585
|
+
if (latestVersion === "9.137.0") {
|
|
13586
|
+
console.log(source_default.green(`\u2713 Already up to date (${"9.137.0"})`));
|
|
13587
13587
|
return;
|
|
13588
13588
|
}
|
|
13589
13589
|
console.log(
|
|
13590
13590
|
source_default.yellow(
|
|
13591
|
-
`Current version: ${"9.
|
|
13591
|
+
`Current version: ${"9.137.0"} -> Latest version: ${latestVersion}`
|
|
13592
13592
|
)
|
|
13593
13593
|
);
|
|
13594
13594
|
console.log();
|
|
@@ -13615,7 +13615,7 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
|
|
|
13615
13615
|
const success = await performUpgrade(packageManager);
|
|
13616
13616
|
if (success) {
|
|
13617
13617
|
console.log(
|
|
13618
|
-
source_default.green(`\u2713 Upgraded from ${"9.
|
|
13618
|
+
source_default.green(`\u2713 Upgraded from ${"9.137.0"} to ${latestVersion}`)
|
|
13619
13619
|
);
|
|
13620
13620
|
return;
|
|
13621
13621
|
}
|
|
@@ -13682,7 +13682,7 @@ var whoamiCommand = new Command().name("whoami").description("Show current ident
|
|
|
13682
13682
|
|
|
13683
13683
|
// src/index.ts
|
|
13684
13684
|
var program = new Command();
|
|
13685
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
13685
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.137.0");
|
|
13686
13686
|
program.addCommand(authCommand);
|
|
13687
13687
|
program.addCommand(infoCommand);
|
|
13688
13688
|
program.addCommand(composeCommand);
|
package/package.json
CHANGED
package/zero.js
CHANGED
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
isUUID,
|
|
67
67
|
leaveZeroOrg,
|
|
68
68
|
listSkills,
|
|
69
|
+
listTelegramBots,
|
|
69
70
|
listZeroAgents,
|
|
70
71
|
listZeroConnectors,
|
|
71
72
|
listZeroLogs,
|
|
@@ -96,6 +97,7 @@ import {
|
|
|
96
97
|
searchZeroLogs,
|
|
97
98
|
sendChatMessage,
|
|
98
99
|
sendSlackMessage,
|
|
100
|
+
sendTelegramMessage,
|
|
99
101
|
setZeroOrgModelProviderDefault,
|
|
100
102
|
setZeroOrgSecret,
|
|
101
103
|
setZeroOrgVariable,
|
|
@@ -115,7 +117,7 @@ import {
|
|
|
115
117
|
upsertZeroOrgModelProvider,
|
|
116
118
|
withErrorHandler,
|
|
117
119
|
zeroAgentCustomSkillNameSchema
|
|
118
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-HH2HTGSA.js";
|
|
119
121
|
import {
|
|
120
122
|
__toESM,
|
|
121
123
|
init_esm_shims
|
|
@@ -13956,8 +13958,7 @@ var FEATURE_SWITCHES = {
|
|
|
13956
13958
|
["chatArtifactsDrawer" /* ChatArtifactsDrawer */]: {
|
|
13957
13959
|
maintainer: "ethan@vm0.ai",
|
|
13958
13960
|
description: "Show an artifacts button in the chat header that opens a drawer listing uploaded files grouped by run",
|
|
13959
|
-
enabled:
|
|
13960
|
-
enabledOrgIdHashes: STAFF_ORG_ID_HASHES
|
|
13961
|
+
enabled: true
|
|
13961
13962
|
},
|
|
13962
13963
|
["chatThreadReadIndicator" /* ChatThreadReadIndicator */]: {
|
|
13963
13964
|
maintainer: "ethan@vm0.ai",
|
|
@@ -16741,6 +16742,86 @@ Examples:
|
|
|
16741
16742
|
// src/commands/zero/telegram/index.ts
|
|
16742
16743
|
init_esm_shims();
|
|
16743
16744
|
|
|
16745
|
+
// src/commands/zero/telegram/bot/index.ts
|
|
16746
|
+
init_esm_shims();
|
|
16747
|
+
|
|
16748
|
+
// src/commands/zero/telegram/bot/list.ts
|
|
16749
|
+
init_esm_shims();
|
|
16750
|
+
function usernameLabel(bot) {
|
|
16751
|
+
if (!bot.username) return "-";
|
|
16752
|
+
return bot.username.startsWith("@") ? bot.username : `@${bot.username}`;
|
|
16753
|
+
}
|
|
16754
|
+
function statusLabel(bot) {
|
|
16755
|
+
if (bot.tokenStatus === "valid") return source_default.green("valid");
|
|
16756
|
+
if (bot.tokenStatus === "invalid") return source_default.red("invalid");
|
|
16757
|
+
return source_default.yellow("unknown");
|
|
16758
|
+
}
|
|
16759
|
+
var listCommand9 = new Command().name("list").alias("ls").description("List Telegram bots available in the active organization").addHelpText(
|
|
16760
|
+
"after",
|
|
16761
|
+
`
|
|
16762
|
+
Examples:
|
|
16763
|
+
zero telegram bot list
|
|
16764
|
+
|
|
16765
|
+
Notes:
|
|
16766
|
+
- Use this to find the --bot-id value before sending Telegram messages.`
|
|
16767
|
+
).action(
|
|
16768
|
+
withErrorHandler(async () => {
|
|
16769
|
+
const result = await listTelegramBots();
|
|
16770
|
+
const { bots } = result;
|
|
16771
|
+
if (bots.length === 0) {
|
|
16772
|
+
console.log(source_default.dim("No Telegram bots found"));
|
|
16773
|
+
console.log(
|
|
16774
|
+
source_default.dim(" Add one from Settings > Integrations > Telegram")
|
|
16775
|
+
);
|
|
16776
|
+
return;
|
|
16777
|
+
}
|
|
16778
|
+
const botIdWidth = Math.max(
|
|
16779
|
+
6,
|
|
16780
|
+
...bots.map((bot) => {
|
|
16781
|
+
return bot.id.length;
|
|
16782
|
+
})
|
|
16783
|
+
);
|
|
16784
|
+
const usernameWidth = Math.max(
|
|
16785
|
+
8,
|
|
16786
|
+
...bots.map((bot) => {
|
|
16787
|
+
return usernameLabel(bot).length;
|
|
16788
|
+
})
|
|
16789
|
+
);
|
|
16790
|
+
const agentWidth = Math.max(
|
|
16791
|
+
5,
|
|
16792
|
+
...bots.map((bot) => {
|
|
16793
|
+
return (bot.agent?.name ?? "-").length;
|
|
16794
|
+
})
|
|
16795
|
+
);
|
|
16796
|
+
const header = [
|
|
16797
|
+
"BOT ID".padEnd(botIdWidth),
|
|
16798
|
+
"USERNAME".padEnd(usernameWidth),
|
|
16799
|
+
"AGENT".padEnd(agentWidth),
|
|
16800
|
+
"CONNECTED",
|
|
16801
|
+
"TOKEN"
|
|
16802
|
+
].join(" ");
|
|
16803
|
+
console.log(source_default.dim(header));
|
|
16804
|
+
for (const bot of bots) {
|
|
16805
|
+
const row = [
|
|
16806
|
+
bot.id.padEnd(botIdWidth),
|
|
16807
|
+
usernameLabel(bot).padEnd(usernameWidth),
|
|
16808
|
+
(bot.agent?.name ?? "-").padEnd(agentWidth),
|
|
16809
|
+
(bot.isConnected ? "yes" : "no").padEnd(9),
|
|
16810
|
+
statusLabel(bot)
|
|
16811
|
+
].join(" ");
|
|
16812
|
+
console.log(row);
|
|
16813
|
+
}
|
|
16814
|
+
})
|
|
16815
|
+
);
|
|
16816
|
+
|
|
16817
|
+
// src/commands/zero/telegram/bot/index.ts
|
|
16818
|
+
var zeroTelegramBotCommand = new Command().name("bot").description("Inspect Telegram bots").addCommand(listCommand9).addHelpText(
|
|
16819
|
+
"after",
|
|
16820
|
+
`
|
|
16821
|
+
Examples:
|
|
16822
|
+
zero telegram bot list`
|
|
16823
|
+
);
|
|
16824
|
+
|
|
16744
16825
|
// src/commands/zero/telegram/download-file.ts
|
|
16745
16826
|
init_esm_shims();
|
|
16746
16827
|
import { join as join2 } from "path";
|
|
@@ -16789,9 +16870,72 @@ Notes:
|
|
|
16789
16870
|
)
|
|
16790
16871
|
);
|
|
16791
16872
|
|
|
16873
|
+
// src/commands/zero/telegram/message/index.ts
|
|
16874
|
+
init_esm_shims();
|
|
16875
|
+
|
|
16876
|
+
// src/commands/zero/telegram/message/send.ts
|
|
16877
|
+
init_esm_shims();
|
|
16878
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
16879
|
+
function parsePositiveInteger(value, flag) {
|
|
16880
|
+
const parsed = Number(value);
|
|
16881
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
16882
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
16883
|
+
}
|
|
16884
|
+
return parsed;
|
|
16885
|
+
}
|
|
16886
|
+
var sendCommand3 = new Command().name("send").description("Send a message to a Telegram chat as the bot").requiredOption("--bot-id <id>", "Telegram bot ID").requiredOption("-c, --chat-id <id>", "Telegram chat ID").option("-t, --text <message>", "Message text").option("--reply-to-message-id <id>", "Message ID to reply to").option("--message-thread-id <id>", "Telegram forum topic thread ID").addHelpText(
|
|
16887
|
+
"after",
|
|
16888
|
+
`
|
|
16889
|
+
Examples:
|
|
16890
|
+
Simple message: zero telegram message send --bot-id 123456789 -c -1001234567890 -t "Hello!"
|
|
16891
|
+
Reply to message: zero telegram message send --bot-id 123456789 -c -1001234567890 --reply-to-message-id 42 -t "reply"
|
|
16892
|
+
Forum topic message: zero telegram message send --bot-id 123456789 -c -1001234567890 --message-thread-id 7 -t "topic update"
|
|
16893
|
+
|
|
16894
|
+
Notes:
|
|
16895
|
+
- Message text can be provided with --text or piped on stdin
|
|
16896
|
+
- Choose an explicit --bot-id. Run "zero telegram bot list" to inspect available bots.`
|
|
16897
|
+
).action(
|
|
16898
|
+
withErrorHandler(
|
|
16899
|
+
async (options) => {
|
|
16900
|
+
let text = options.text;
|
|
16901
|
+
if (!text && process.stdin.isTTY === false) {
|
|
16902
|
+
text = readFileSync7("/dev/stdin", "utf8").trim();
|
|
16903
|
+
}
|
|
16904
|
+
if (!text) {
|
|
16905
|
+
throw new Error("Either --text or piped stdin must be provided", {
|
|
16906
|
+
cause: new Error(
|
|
16907
|
+
'Usage: zero telegram message send --bot-id BOT_ID -c CHAT_ID -t "your message"'
|
|
16908
|
+
)
|
|
16909
|
+
});
|
|
16910
|
+
}
|
|
16911
|
+
const result = await sendTelegramMessage({
|
|
16912
|
+
botId: options.botId,
|
|
16913
|
+
chatId: options.chatId,
|
|
16914
|
+
text,
|
|
16915
|
+
replyToMessageId: options.replyToMessageId ? parsePositiveInteger(
|
|
16916
|
+
options.replyToMessageId,
|
|
16917
|
+
"reply-to-message-id"
|
|
16918
|
+
) : void 0,
|
|
16919
|
+
messageThreadId: options.messageThreadId ? parsePositiveInteger(options.messageThreadId, "message-thread-id") : void 0
|
|
16920
|
+
});
|
|
16921
|
+
console.log(
|
|
16922
|
+
source_default.green(`\u2713 Message sent (message_id: ${result.messageId})`)
|
|
16923
|
+
);
|
|
16924
|
+
}
|
|
16925
|
+
)
|
|
16926
|
+
);
|
|
16927
|
+
|
|
16928
|
+
// src/commands/zero/telegram/message/index.ts
|
|
16929
|
+
var zeroTelegramMessageCommand = new Command().name("message").description("Manage Telegram messages").addCommand(sendCommand3).addHelpText(
|
|
16930
|
+
"after",
|
|
16931
|
+
`
|
|
16932
|
+
Examples:
|
|
16933
|
+
zero telegram message send --bot-id <bot-id> -c <chat-id> -t "Hello!"`
|
|
16934
|
+
);
|
|
16935
|
+
|
|
16792
16936
|
// src/commands/zero/telegram/upload-file.ts
|
|
16793
16937
|
init_esm_shims();
|
|
16794
|
-
import { readFileSync as
|
|
16938
|
+
import { readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
16795
16939
|
import { basename as basename2, extname } from "path";
|
|
16796
16940
|
var MIME_BY_EXTENSION = {
|
|
16797
16941
|
".png": "image/png",
|
|
@@ -16864,7 +17008,7 @@ Notes:
|
|
|
16864
17008
|
contentType,
|
|
16865
17009
|
length: fileSize
|
|
16866
17010
|
});
|
|
16867
|
-
const fileContent =
|
|
17011
|
+
const fileContent = readFileSync8(options.file);
|
|
16868
17012
|
const uploadResponse = await fetch(prepared.uploadUrl, {
|
|
16869
17013
|
method: "PUT",
|
|
16870
17014
|
headers: { "Content-Type": prepared.contentType },
|
|
@@ -16889,10 +17033,14 @@ Notes:
|
|
|
16889
17033
|
);
|
|
16890
17034
|
|
|
16891
17035
|
// src/commands/zero/telegram/index.ts
|
|
16892
|
-
var zeroTelegramCommand = new Command().name("telegram").description(
|
|
17036
|
+
var zeroTelegramCommand = new Command().name("telegram").description(
|
|
17037
|
+
"Inspect bots, send messages, upload files, and download files from Telegram"
|
|
17038
|
+
).addCommand(zeroTelegramBotCommand).addCommand(zeroTelegramMessageCommand).addCommand(downloadFileCommand2).addCommand(uploadFileCommand2).addHelpText(
|
|
16893
17039
|
"after",
|
|
16894
17040
|
`
|
|
16895
17041
|
Examples:
|
|
17042
|
+
List bots: zero telegram bot list
|
|
17043
|
+
Send a message: zero telegram message send --bot-id <bot-id> -c <chat-id> -t "Hello!"
|
|
16896
17044
|
Upload a file: zero telegram upload-file -f /tmp/report.pdf --bot-id <bot-id> -c <chat-id>
|
|
16897
17045
|
Download a file: zero telegram download-file <file-id> --bot-id <bot-id> -o /tmp/out.jpg`
|
|
16898
17046
|
);
|
|
@@ -16908,7 +17056,7 @@ function truncateValue2(value, maxLength = 60) {
|
|
|
16908
17056
|
}
|
|
16909
17057
|
return value.slice(0, maxLength - 15) + "... [truncated]";
|
|
16910
17058
|
}
|
|
16911
|
-
var
|
|
17059
|
+
var listCommand10 = new Command().name("list").alias("ls").description("List all variables").action(
|
|
16912
17060
|
withErrorHandler(async () => {
|
|
16913
17061
|
const result = await listZeroVariables();
|
|
16914
17062
|
if (result.variables.length === 0) {
|
|
@@ -16985,7 +17133,7 @@ var deleteCommand5 = new Command().name("delete").description("Delete a variable
|
|
|
16985
17133
|
);
|
|
16986
17134
|
|
|
16987
17135
|
// src/commands/zero/variable/index.ts
|
|
16988
|
-
var zeroVariableCommand = new Command().name("variable").description("Read or write non-sensitive configuration values").addCommand(
|
|
17136
|
+
var zeroVariableCommand = new Command().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand10).addCommand(setCommand5).addCommand(deleteCommand5);
|
|
16989
17137
|
|
|
16990
17138
|
// src/commands/zero/whoami.ts
|
|
16991
17139
|
init_esm_shims();
|
|
@@ -17144,7 +17292,7 @@ init_esm_shims();
|
|
|
17144
17292
|
|
|
17145
17293
|
// src/lib/skill-directory.ts
|
|
17146
17294
|
init_esm_shims();
|
|
17147
|
-
import { readFileSync as
|
|
17295
|
+
import { readFileSync as readFileSync9, readdirSync } from "fs";
|
|
17148
17296
|
import { join as join3 } from "path";
|
|
17149
17297
|
var IGNORED_NAMES = /* @__PURE__ */ new Set(["node_modules", ".git", ".DS_Store"]);
|
|
17150
17298
|
function readSkillDirectory(dirPath) {
|
|
@@ -17159,7 +17307,7 @@ function readSkillDirectory(dirPath) {
|
|
|
17159
17307
|
} else {
|
|
17160
17308
|
files.push({
|
|
17161
17309
|
path: relPath,
|
|
17162
|
-
content:
|
|
17310
|
+
content: readFileSync9(join3(dir, entry.name), "utf-8")
|
|
17163
17311
|
});
|
|
17164
17312
|
}
|
|
17165
17313
|
}
|
|
@@ -17264,7 +17412,7 @@ Examples:
|
|
|
17264
17412
|
|
|
17265
17413
|
// src/commands/zero/skill/list.ts
|
|
17266
17414
|
init_esm_shims();
|
|
17267
|
-
var
|
|
17415
|
+
var listCommand11 = new Command().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
|
|
17268
17416
|
"after",
|
|
17269
17417
|
`
|
|
17270
17418
|
Examples:
|
|
@@ -17342,7 +17490,7 @@ Notes:
|
|
|
17342
17490
|
);
|
|
17343
17491
|
|
|
17344
17492
|
// src/commands/zero/skill/index.ts
|
|
17345
|
-
var zeroSkillCommand = new Command("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(
|
|
17493
|
+
var zeroSkillCommand = new Command("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand11).addCommand(deleteCommand6).addHelpText(
|
|
17346
17494
|
"after",
|
|
17347
17495
|
`
|
|
17348
17496
|
Examples:
|
|
@@ -17383,7 +17531,7 @@ function formatStatus(status) {
|
|
|
17383
17531
|
function formatTime(iso) {
|
|
17384
17532
|
return new Date(iso).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
17385
17533
|
}
|
|
17386
|
-
var
|
|
17534
|
+
var listCommand12 = new Command().name("list").alias("ls").description("List agent run logs").option("--agent <name>", "Filter by agent name").option(
|
|
17387
17535
|
"--status <status>",
|
|
17388
17536
|
"Filter by status (queued|pending|running|completed|failed|timeout|cancelled)"
|
|
17389
17537
|
).option(
|
|
@@ -17636,7 +17784,7 @@ async function showAgentEvents(runId, options) {
|
|
|
17636
17784
|
renderAgentEvent(event, renderer);
|
|
17637
17785
|
}
|
|
17638
17786
|
}
|
|
17639
|
-
var zeroLogsCommand = new Command().name("logs").description("View and search agent run logs").argument("[runId]", "Run ID to view agent events for").addCommand(
|
|
17787
|
+
var zeroLogsCommand = new Command().name("logs").description("View and search agent run logs").argument("[runId]", "Run ID to view agent events for").addCommand(listCommand12).addCommand(searchCommand2).option(
|
|
17640
17788
|
"--since <time>",
|
|
17641
17789
|
"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)"
|
|
17642
17790
|
).option("--tail <n>", "Show last N entries (default: 5)").option("--head <n>", "Show first N entries").option("--all", "Fetch all log entries").addHelpText(
|
|
@@ -19078,12 +19226,14 @@ function registerZeroCommands(prog, commands) {
|
|
|
19078
19226
|
var program = new Command();
|
|
19079
19227
|
program.name("zero").description(
|
|
19080
19228
|
"Zero CLI \u2014 interact with the zero platform from inside the sandbox"
|
|
19081
|
-
).version("9.
|
|
19229
|
+
).version("9.137.0").addHelpText(
|
|
19082
19230
|
"after",
|
|
19083
19231
|
`
|
|
19084
19232
|
Examples:
|
|
19085
19233
|
Check a connector? zero doctor check-connector --env-name <ENV_NAME>
|
|
19086
19234
|
Send a Slack message? zero slack message send --help
|
|
19235
|
+
List Telegram bots? zero telegram bot list
|
|
19236
|
+
Send Telegram? zero telegram message send --help
|
|
19087
19237
|
Upload Telegram? zero telegram upload-file --help
|
|
19088
19238
|
Download Telegram? zero telegram download-file --help
|
|
19089
19239
|
Set up a schedule? zero schedule setup --help
|