@vm0/cli 9.160.8 → 9.160.9

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/zero.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  MODEL_PROVIDER_TYPES,
13
13
  Option,
14
14
  callZeroMaps,
15
+ completeGithubFileUpload,
15
16
  completeHostedSite,
16
17
  completePhoneFileUpload,
17
18
  completeSlackFileUpload,
@@ -27,7 +28,6 @@ import {
27
28
  createZeroRun,
28
29
  decodeCliTokenPayload,
29
30
  decodeZeroTokenPayload,
30
- deleteComputerUseHost,
31
31
  deleteLocalBrowserHost,
32
32
  deleteSkill,
33
33
  deleteZeroAgent,
@@ -40,6 +40,7 @@ import {
40
40
  deleteZeroVariable,
41
41
  deployZeroSchedule,
42
42
  disableZeroSchedule,
43
+ downloadGithubFile,
43
44
  downloadPhoneFile,
44
45
  downloadSlackFile,
45
46
  downloadTelegramFile,
@@ -81,6 +82,7 @@ import {
81
82
  getZeroUserPreferences,
82
83
  hasAuthMethods,
83
84
  hasRequiredScopes,
85
+ initGithubFileUpload,
84
86
  initPhoneFileUpload,
85
87
  initSlackFileUpload,
86
88
  initTelegramFileUpload,
@@ -89,8 +91,6 @@ import {
89
91
  isInteractive,
90
92
  isUUID,
91
93
  leaveZeroOrg,
92
- listComputerUseAuditEvents,
93
- listComputerUseHosts,
94
94
  listLocalBrowserAuditEvents,
95
95
  listLocalBrowserHosts,
96
96
  listSkills,
@@ -148,7 +148,7 @@ import {
148
148
  zeroAgentCustomSkillNameSchema,
149
149
  zeroLocalAgentCommand,
150
150
  zeroTokenAllowsFeatureSwitch
151
- } from "./chunk-3P3WTJU2.js";
151
+ } from "./chunk-W7PH4TIL.js";
152
152
  import {
153
153
  __commonJS,
154
154
  __require,
@@ -30315,38 +30315,32 @@ var BUILT_IN_GENERATION_PROVIDERS = {
30315
30315
  video: [
30316
30316
  {
30317
30317
  label: "Built-in",
30318
- model: "fal-ai/veo3.1/fast",
30319
- command: "zero built-in generate video --model veo3.1-fast -h",
30320
- reason: "available without connector setup"
30321
- },
30322
- {
30323
- label: "Built-in",
30324
- model: "fal-ai/veo3.1",
30325
- command: "zero built-in generate video --model veo3.1 -h",
30318
+ model: "dreamina-seedance-2-0-260128",
30319
+ command: "zero built-in generate video --model dreamina-seedance-2.0 -h",
30326
30320
  reason: "available without connector setup"
30327
30321
  },
30328
30322
  {
30329
30323
  label: "Built-in",
30330
- model: "fal-ai/kling-video/o3/standard/text-to-video",
30331
- command: "zero built-in generate video --model kling-o3-standard -h",
30324
+ model: "dreamina-seedance-2-0-fast-260128",
30325
+ command: "zero built-in generate video --model dreamina-seedance-2.0-fast -h",
30332
30326
  reason: "available without connector setup"
30333
30327
  },
30334
30328
  {
30335
30329
  label: "Built-in",
30336
- model: "fal-ai/kling-video/v3/4k/text-to-video",
30337
- command: "zero built-in generate video --model kling-v3-4k -h",
30330
+ model: "seedance-1-5-pro-251215",
30331
+ command: "zero built-in generate video --model seedance-1.5-pro -h",
30338
30332
  reason: "available without connector setup"
30339
30333
  },
30340
30334
  {
30341
- label: "Built-in",
30342
- model: "bytedance/seedance-2.0/text-to-video",
30343
- command: "zero built-in generate video --model seedance2.0 -h",
30335
+ label: "Built-in fal.ai",
30336
+ model: "fal-ai/veo3.1/fast",
30337
+ command: "zero built-in generate video --model veo3.1-fast -h",
30344
30338
  reason: "available without connector setup"
30345
30339
  },
30346
30340
  {
30347
- label: "Built-in",
30348
- model: "bytedance/seedance-2.0/fast/text-to-video",
30349
- command: "zero built-in generate video --model seedance2.0-fast -h",
30341
+ label: "Built-in fal.ai",
30342
+ model: "fal-ai/kling-video/v3/4k/text-to-video",
30343
+ command: "zero built-in generate video --model kling-v3-4k -h",
30350
30344
  reason: "available without connector setup"
30351
30345
  }
30352
30346
  ],
@@ -30368,7 +30362,7 @@ var BUILT_IN_GENERATION_COMMANDS = {
30368
30362
  video: {
30369
30363
  label: "Built-in video generation",
30370
30364
  command: "zero built-in generate video -h",
30371
- models: "veo3.1-fast, veo3.1, kling-o3-standard, kling-v3-4k, seedance2.0, seedance2.0-fast"
30365
+ models: "dreamina-seedance-2.0-fast (default), dreamina-seedance-2.0, seedance-1.5-pro, veo3.1-fast, kling-v3-4k"
30372
30366
  },
30373
30367
  presentation: {
30374
30368
  label: "Built-in presentation generation",
@@ -32265,6 +32259,167 @@ Examples:
32265
32259
  Send to agent: zero chat message send -a <agent-id> --text "Hello!"`
32266
32260
  );
32267
32261
 
32262
+ // src/commands/zero/github/index.ts
32263
+ init_esm_shims();
32264
+
32265
+ // src/commands/zero/github/download-file.ts
32266
+ init_esm_shims();
32267
+ import { basename, join } from "path";
32268
+ import { tmpdir } from "os";
32269
+ function defaultOutPath(fileUrl) {
32270
+ try {
32271
+ const parsed = new URL(fileUrl);
32272
+ const pathName = basename(parsed.pathname);
32273
+ return join(tmpdir(), `github-${pathName || "file"}`);
32274
+ } catch {
32275
+ return join(tmpdir(), "github-file");
32276
+ }
32277
+ }
32278
+ var downloadFileCommand = new Command().name("download-file").description("Download a GitHub attachment or raw file URL").argument("<url>", "URL from a [GitHub file] block").option(
32279
+ "-o, --out <path>",
32280
+ "Output path for the downloaded file (default: /tmp/github-<url-basename>)"
32281
+ ).option("--filename <name>", "Filename hint from the [GitHub file] block").addHelpText(
32282
+ "after",
32283
+ `
32284
+ Examples:
32285
+ Download to default temp path: zero github download-file https://github.com/user-attachments/assets/abc123
32286
+ Download to explicit path: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/screenshot.png
32287
+
32288
+ Output:
32289
+ Prints a JSON object to stdout on success:
32290
+ {"path":"/tmp/github-abc123","mimetype":"image/png","size":12345}
32291
+
32292
+ How to read the downloaded file:
32293
+ - Images (png/jpg/gif/webp/svg): open the file path with your image viewing tool
32294
+ - Videos (mp4/mov/webm): extract frames first with
32295
+ ffmpeg -i <path> -vf "fps=1" -q:v 2 /tmp/github_frame_%03d.jpg
32296
+ then view the extracted frames
32297
+ - PDF/text/csv/json/markdown: read the file directly
32298
+
32299
+ Notes:
32300
+ - Uses the GitHub App installation on the server side
32301
+ - Streams the file bytes directly to disk`
32302
+ ).action(
32303
+ withErrorHandler(
32304
+ async (fileUrl, options) => {
32305
+ const outPath = options.out ?? defaultOutPath(fileUrl);
32306
+ const result = await downloadGithubFile(
32307
+ fileUrl,
32308
+ outPath,
32309
+ options.filename
32310
+ );
32311
+ console.log(JSON.stringify(result));
32312
+ }
32313
+ )
32314
+ );
32315
+
32316
+ // src/commands/zero/github/upload-file.ts
32317
+ init_esm_shims();
32318
+ import { readFileSync as readFileSync5, statSync } from "fs";
32319
+ import { basename as basename2, extname } from "path";
32320
+ var MIME_BY_EXTENSION = {
32321
+ ".png": "image/png",
32322
+ ".jpg": "image/jpeg",
32323
+ ".jpeg": "image/jpeg",
32324
+ ".gif": "image/gif",
32325
+ ".webp": "image/webp",
32326
+ ".svg": "image/svg+xml",
32327
+ ".mp4": "video/mp4",
32328
+ ".webm": "video/webm",
32329
+ ".mov": "video/quicktime",
32330
+ ".pdf": "application/pdf",
32331
+ ".txt": "text/plain",
32332
+ ".csv": "text/csv",
32333
+ ".md": "text/markdown",
32334
+ ".json": "application/json"
32335
+ };
32336
+ function inferContentType(localPath) {
32337
+ const ext = extname(localPath).toLowerCase();
32338
+ return MIME_BY_EXTENSION[ext] ?? "application/octet-stream";
32339
+ }
32340
+ function parseIssueNumber(value) {
32341
+ const parsed = Number(value);
32342
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) {
32343
+ throw new Error("issue-number must be a positive integer");
32344
+ }
32345
+ return parsed;
32346
+ }
32347
+ var uploadFileCommand = new Command().name("upload-file").description("Upload a local file to a GitHub issue or pull request comment").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("-r, --repo <owner/name>", "GitHub repository").requiredOption(
32348
+ "-i, --issue-number <number>",
32349
+ "GitHub issue or pull request number"
32350
+ ).option("--caption <text>", "Text to include before the file link").option("--content-type <mime>", "Override inferred content type").addHelpText(
32351
+ "after",
32352
+ `
32353
+ Examples:
32354
+ Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42
32355
+ With a caption: zero github upload-file -f /tmp/data.csv -r vm0-ai/vm0 -i 42 --caption "Daily report"
32356
+
32357
+ Output:
32358
+ Prints a JSON object to stdout on success:
32359
+ {"commentId":"123","repo":"vm0-ai/vm0","issueNumber":42,"filename":"report.pdf","mimetype":"application/pdf","size":12345,"url":"https://..."}
32360
+
32361
+ Notes:
32362
+ - Uses the GitHub App installation on the server side
32363
+ - Uploads through VM0 storage first, then posts a GitHub comment containing the file URL`
32364
+ ).action(
32365
+ withErrorHandler(
32366
+ async (options) => {
32367
+ let fileSize;
32368
+ try {
32369
+ const stat2 = statSync(options.file);
32370
+ if (!stat2.isFile()) {
32371
+ throw new Error(`Not a regular file: ${options.file}`);
32372
+ }
32373
+ fileSize = stat2.size;
32374
+ } catch (error) {
32375
+ if (error instanceof Error && error.message.startsWith("Not ")) {
32376
+ throw error;
32377
+ }
32378
+ throw new Error(`File not found: ${options.file}`);
32379
+ }
32380
+ if (fileSize === 0) {
32381
+ throw new Error("File is empty");
32382
+ }
32383
+ const filename = basename2(options.file);
32384
+ const contentType = options.contentType ?? inferContentType(options.file);
32385
+ const issueNumber = parseIssueNumber(options.issueNumber);
32386
+ const prepared = await initGithubFileUpload({
32387
+ filename,
32388
+ contentType,
32389
+ length: fileSize
32390
+ });
32391
+ const fileContent = readFileSync5(options.file);
32392
+ const uploadResponse = await fetch(prepared.uploadUrl, {
32393
+ method: "PUT",
32394
+ headers: { "Content-Type": prepared.contentType },
32395
+ body: new Uint8Array(fileContent)
32396
+ });
32397
+ if (!uploadResponse.ok) {
32398
+ throw new Error(
32399
+ `File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`
32400
+ );
32401
+ }
32402
+ const result = await completeGithubFileUpload({
32403
+ uploadId: prepared.uploadId,
32404
+ repo: options.repo,
32405
+ issueNumber,
32406
+ contentType: prepared.contentType,
32407
+ caption: options.caption
32408
+ });
32409
+ console.log(JSON.stringify(result));
32410
+ }
32411
+ )
32412
+ );
32413
+
32414
+ // src/commands/zero/github/index.ts
32415
+ var zeroGithubCommand = new Command().name("github").description("Upload files to GitHub issues and download GitHub files").addCommand(downloadFileCommand).addCommand(uploadFileCommand).addHelpText(
32416
+ "after",
32417
+ `
32418
+ Examples:
32419
+ Upload a file: zero github upload-file -f /tmp/report.pdf -r vm0-ai/vm0 -i 42
32420
+ Download a file: zero github download-file https://github.com/user-attachments/assets/abc123 -o /tmp/out.png`
32421
+ );
32422
+
32268
32423
  // src/commands/zero/slack/index.ts
32269
32424
  init_esm_shims();
32270
32425
 
@@ -32273,7 +32428,7 @@ init_esm_shims();
32273
32428
 
32274
32429
  // src/commands/zero/slack/message/send.ts
32275
32430
  init_esm_shims();
32276
- import { readFileSync as readFileSync5 } from "fs";
32431
+ import { readFileSync as readFileSync6 } from "fs";
32277
32432
  var sendCommand2 = new Command().name("send").description("Send a message to a Slack channel or DM a user").option("-c, --channel <id>", "Channel ID").option("-u, --user <id>", 'Slack user ID for DM (use "me" for yourself)').option("-t, --text <message>", "Message text").option("--thread <ts>", "Thread timestamp for replies").option("--blocks <json>", "Block Kit JSON string").addHelpText(
32278
32433
  "after",
32279
32434
  `
@@ -32307,7 +32462,7 @@ Notes:
32307
32462
  });
32308
32463
  }
32309
32464
  if (!text && process.stdin.isTTY === false) {
32310
- text = readFileSync5("/dev/stdin", "utf8").trim();
32465
+ text = readFileSync6("/dev/stdin", "utf8").trim();
32311
32466
  }
32312
32467
  let blocks;
32313
32468
  if (blocksStr) {
@@ -32351,9 +32506,9 @@ Examples:
32351
32506
 
32352
32507
  // src/commands/zero/slack/upload-file.ts
32353
32508
  init_esm_shims();
32354
- import { statSync, readFileSync as readFileSync6 } from "fs";
32355
- import { basename } from "path";
32356
- var uploadFileCommand = new Command().name("upload-file").description("Upload a file to a Slack channel as the bot").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("-c, --channel <id>", "Slack channel ID").option("--thread <ts>", "Thread timestamp to post as a reply").option("--title <title>", "Display title for the file").option("--comment <text>", "Initial comment to accompany the file").addHelpText(
32509
+ import { statSync as statSync2, readFileSync as readFileSync7 } from "fs";
32510
+ import { basename as basename3 } from "path";
32511
+ var uploadFileCommand2 = new Command().name("upload-file").description("Upload a file to a Slack channel as the bot").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("-c, --channel <id>", "Slack channel ID").option("--thread <ts>", "Thread timestamp to post as a reply").option("--title <title>", "Display title for the file").option("--comment <text>", "Initial comment to accompany the file").addHelpText(
32357
32512
  "after",
32358
32513
  `
32359
32514
  Examples:
@@ -32369,7 +32524,7 @@ Notes:
32369
32524
  async (options) => {
32370
32525
  let fileSize;
32371
32526
  try {
32372
- const stat2 = statSync(options.file);
32527
+ const stat2 = statSync2(options.file);
32373
32528
  fileSize = stat2.size;
32374
32529
  } catch {
32375
32530
  throw new Error(`File not found: ${options.file}`);
@@ -32377,12 +32532,12 @@ Notes:
32377
32532
  if (fileSize === 0) {
32378
32533
  throw new Error("File is empty");
32379
32534
  }
32380
- const filename = basename(options.file);
32535
+ const filename = basename3(options.file);
32381
32536
  const { uploadUrl, fileId } = await initSlackFileUpload({
32382
32537
  filename,
32383
32538
  length: fileSize
32384
32539
  });
32385
- const fileContent = readFileSync6(options.file);
32540
+ const fileContent = readFileSync7(options.file);
32386
32541
  const uploadResponse = await fetch(uploadUrl, {
32387
32542
  method: "POST",
32388
32543
  body: fileContent
@@ -32407,12 +32562,12 @@ Notes:
32407
32562
 
32408
32563
  // src/commands/zero/slack/download-file.ts
32409
32564
  init_esm_shims();
32410
- import { basename as basename2, join } from "path";
32411
- import { tmpdir } from "os";
32412
- function defaultOutPath(fileId) {
32413
- return join(tmpdir(), `slack-${basename2(fileId)}`);
32565
+ import { basename as basename4, join as join2 } from "path";
32566
+ import { tmpdir as tmpdir2 } from "os";
32567
+ function defaultOutPath2(fileId) {
32568
+ return join2(tmpdir2(), `slack-${basename4(fileId)}`);
32414
32569
  }
32415
- var downloadFileCommand = new Command().name("download-file").description("Download a Slack file by id using the bot token").argument("<file-id>", "Slack file id (e.g. F01234ABCD)").option(
32570
+ var downloadFileCommand2 = new Command().name("download-file").description("Download a Slack file by id using the bot token").argument("<file-id>", "Slack file id (e.g. F01234ABCD)").option(
32416
32571
  "-o, --out <path>",
32417
32572
  "Output path for the downloaded file (default: /tmp/slack-<file-id>)"
32418
32573
  ).addHelpText(
@@ -32438,7 +32593,7 @@ Notes:
32438
32593
  - Streams the file bytes directly to disk`
32439
32594
  ).action(
32440
32595
  withErrorHandler(async (fileId, options) => {
32441
- const outPath = options.out ?? defaultOutPath(fileId);
32596
+ const outPath = options.out ?? defaultOutPath2(fileId);
32442
32597
  const result = await downloadSlackFile(fileId, outPath);
32443
32598
  console.log(JSON.stringify(result));
32444
32599
  })
@@ -32447,7 +32602,7 @@ Notes:
32447
32602
  // src/commands/zero/slack/index.ts
32448
32603
  var zeroSlackCommand = new Command().name("slack").description(
32449
32604
  "Send messages, upload files, and download files from Slack as the bot"
32450
- ).addCommand(zeroSlackMessageCommand).addCommand(uploadFileCommand).addCommand(downloadFileCommand).addHelpText(
32605
+ ).addCommand(zeroSlackMessageCommand).addCommand(uploadFileCommand2).addCommand(downloadFileCommand2).addHelpText(
32451
32606
  "after",
32452
32607
  `
32453
32608
  Examples:
@@ -32542,12 +32697,12 @@ Examples:
32542
32697
 
32543
32698
  // src/commands/zero/telegram/download-file.ts
32544
32699
  init_esm_shims();
32545
- import { basename as basename3, join as join2 } from "path";
32546
- import { tmpdir as tmpdir2 } from "os";
32547
- function defaultOutPath2(fileId) {
32548
- return join2(tmpdir2(), `telegram-${basename3(fileId)}`);
32700
+ import { basename as basename5, join as join3 } from "path";
32701
+ import { tmpdir as tmpdir3 } from "os";
32702
+ function defaultOutPath3(fileId) {
32703
+ return join3(tmpdir3(), `telegram-${basename5(fileId)}`);
32549
32704
  }
32550
- var downloadFileCommand2 = new Command().name("download-file").description("Download a Telegram file by id using the bot token").argument("<file-id>", "Telegram file id from a [Telegram file] block").option(
32705
+ var downloadFileCommand3 = new Command().name("download-file").description("Download a Telegram file by id using the bot token").argument("<file-id>", "Telegram file id from a [Telegram file] block").option(
32551
32706
  "-o, --out <path>",
32552
32707
  "Output path for the downloaded file (default: /tmp/telegram-<file-id>)"
32553
32708
  ).requiredOption(
@@ -32577,7 +32732,7 @@ Notes:
32577
32732
  ).action(
32578
32733
  withErrorHandler(
32579
32734
  async (fileId, options) => {
32580
- const outPath = options.out ?? defaultOutPath2(fileId);
32735
+ const outPath = options.out ?? defaultOutPath3(fileId);
32581
32736
  const result = await downloadTelegramFile(
32582
32737
  fileId,
32583
32738
  options.botId,
@@ -32593,7 +32748,7 @@ init_esm_shims();
32593
32748
 
32594
32749
  // src/commands/zero/telegram/message/send.ts
32595
32750
  init_esm_shims();
32596
- import { readFileSync as readFileSync7 } from "fs";
32751
+ import { readFileSync as readFileSync8 } from "fs";
32597
32752
  function parsePositiveInteger(value, flag) {
32598
32753
  const parsed = Number(value);
32599
32754
  if (!Number.isInteger(parsed) || parsed <= 0) {
@@ -32617,7 +32772,7 @@ Notes:
32617
32772
  async (options) => {
32618
32773
  let text = options.text;
32619
32774
  if (!text && process.stdin.isTTY === false) {
32620
- text = readFileSync7("/dev/stdin", "utf8").trim();
32775
+ text = readFileSync8("/dev/stdin", "utf8").trim();
32621
32776
  }
32622
32777
  if (!text) {
32623
32778
  throw new Error("Either --text or piped stdin must be provided", {
@@ -32653,9 +32808,9 @@ Examples:
32653
32808
 
32654
32809
  // src/commands/zero/telegram/upload-file.ts
32655
32810
  init_esm_shims();
32656
- import { readFileSync as readFileSync8, statSync as statSync2 } from "fs";
32657
- import { basename as basename4, extname } from "path";
32658
- var MIME_BY_EXTENSION = {
32811
+ import { readFileSync as readFileSync9, statSync as statSync3 } from "fs";
32812
+ import { basename as basename6, extname as extname2 } from "path";
32813
+ var MIME_BY_EXTENSION2 = {
32659
32814
  ".png": "image/png",
32660
32815
  ".jpg": "image/jpeg",
32661
32816
  ".jpeg": "image/jpeg",
@@ -32671,9 +32826,9 @@ var MIME_BY_EXTENSION = {
32671
32826
  ".md": "text/markdown",
32672
32827
  ".json": "application/json"
32673
32828
  };
32674
- function inferContentType(localPath) {
32675
- const ext = extname(localPath).toLowerCase();
32676
- return MIME_BY_EXTENSION[ext] ?? "application/octet-stream";
32829
+ function inferContentType2(localPath) {
32830
+ const ext = extname2(localPath).toLowerCase();
32831
+ return MIME_BY_EXTENSION2[ext] ?? "application/octet-stream";
32677
32832
  }
32678
32833
  function parseMessageThreadId(value) {
32679
32834
  if (!value) return void 0;
@@ -32683,7 +32838,7 @@ function parseMessageThreadId(value) {
32683
32838
  }
32684
32839
  return parsed;
32685
32840
  }
32686
- 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(
32841
+ var uploadFileCommand3 = 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(
32687
32842
  "after",
32688
32843
  `
32689
32844
  Examples:
@@ -32704,7 +32859,7 @@ Notes:
32704
32859
  async (options) => {
32705
32860
  let fileSize;
32706
32861
  try {
32707
- const stat2 = statSync2(options.file);
32862
+ const stat2 = statSync3(options.file);
32708
32863
  if (!stat2.isFile()) {
32709
32864
  throw new Error(`Not a regular file: ${options.file}`);
32710
32865
  }
@@ -32718,15 +32873,15 @@ Notes:
32718
32873
  if (fileSize === 0) {
32719
32874
  throw new Error("File is empty");
32720
32875
  }
32721
- const filename = basename4(options.file);
32722
- const contentType = options.contentType ?? inferContentType(options.file);
32876
+ const filename = basename6(options.file);
32877
+ const contentType = options.contentType ?? inferContentType2(options.file);
32723
32878
  const messageThreadId = parseMessageThreadId(options.messageThreadId);
32724
32879
  const prepared = await initTelegramFileUpload({
32725
32880
  filename,
32726
32881
  contentType,
32727
32882
  length: fileSize
32728
32883
  });
32729
- const fileContent = readFileSync8(options.file);
32884
+ const fileContent = readFileSync9(options.file);
32730
32885
  const uploadResponse = await fetch(prepared.uploadUrl, {
32731
32886
  method: "PUT",
32732
32887
  headers: { "Content-Type": prepared.contentType },
@@ -32753,7 +32908,7 @@ Notes:
32753
32908
  // src/commands/zero/telegram/index.ts
32754
32909
  var zeroTelegramCommand = new Command().name("telegram").description(
32755
32910
  "Inspect bots, send messages, upload files, and download files from Telegram"
32756
- ).addCommand(zeroTelegramBotCommand).addCommand(zeroTelegramMessageCommand).addCommand(downloadFileCommand2).addCommand(uploadFileCommand2).addHelpText(
32911
+ ).addCommand(zeroTelegramBotCommand).addCommand(zeroTelegramMessageCommand).addCommand(downloadFileCommand3).addCommand(uploadFileCommand3).addHelpText(
32757
32912
  "after",
32758
32913
  `
32759
32914
  Examples:
@@ -32768,12 +32923,12 @@ init_esm_shims();
32768
32923
 
32769
32924
  // src/commands/zero/phone/download-file.ts
32770
32925
  init_esm_shims();
32771
- import { basename as basename5, join as join3 } from "path";
32772
- import { tmpdir as tmpdir3 } from "os";
32773
- function defaultOutPath3(fileId) {
32774
- return join3(tmpdir3(), `phone-${basename5(fileId)}`);
32926
+ import { basename as basename7, join as join4 } from "path";
32927
+ import { tmpdir as tmpdir4 } from "os";
32928
+ function defaultOutPath4(fileId) {
32929
+ return join4(tmpdir4(), `phone-${basename7(fileId)}`);
32775
32930
  }
32776
- var downloadFileCommand3 = new Command().name("download-file").description("Download an AgentPhone media file by id").argument(
32931
+ var downloadFileCommand4 = new Command().name("download-file").description("Download an AgentPhone media file by id").argument(
32777
32932
  "<file-id>",
32778
32933
  "AgentPhone message id from an [AgentPhone file] block"
32779
32934
  ).option(
@@ -32798,7 +32953,7 @@ How to read the downloaded file:
32798
32953
  - PDF/text/csv/json/markdown: read the file directly`
32799
32954
  ).action(
32800
32955
  withErrorHandler(async (fileId, options) => {
32801
- const outPath = options.out ?? defaultOutPath3(fileId);
32956
+ const outPath = options.out ?? defaultOutPath4(fileId);
32802
32957
  const result = await downloadPhoneFile(fileId, outPath);
32803
32958
  console.log(JSON.stringify(result));
32804
32959
  })
@@ -32806,7 +32961,7 @@ How to read the downloaded file:
32806
32961
 
32807
32962
  // src/commands/zero/phone/message.ts
32808
32963
  init_esm_shims();
32809
- import { readFileSync as readFileSync9 } from "fs";
32964
+ import { readFileSync as readFileSync10 } from "fs";
32810
32965
  var messageCommand = new Command().name("message").description("Send an AgentPhone text message").requiredOption("--to <phone>", "Connected phone handle to message").option("--agent-id <id>", "AgentPhone agent ID (inferred when omitted)").option("-t, --text <message>", "Message text").addHelpText(
32811
32966
  "after",
32812
32967
  `
@@ -32822,7 +32977,7 @@ Notes:
32822
32977
  async (options) => {
32823
32978
  let text = options.text;
32824
32979
  if (!text && process.stdin.isTTY === false) {
32825
- text = readFileSync9("/dev/stdin", "utf8").trim();
32980
+ text = readFileSync10("/dev/stdin", "utf8").trim();
32826
32981
  }
32827
32982
  if (!text) {
32828
32983
  throw new Error("Either --text or piped stdin must be provided", {
@@ -32845,9 +33000,9 @@ Notes:
32845
33000
 
32846
33001
  // src/commands/zero/phone/upload-file.ts
32847
33002
  init_esm_shims();
32848
- import { readFileSync as readFileSync10, statSync as statSync3 } from "fs";
32849
- import { basename as basename6, extname as extname2 } from "path";
32850
- var MIME_BY_EXTENSION2 = {
33003
+ import { readFileSync as readFileSync11, statSync as statSync4 } from "fs";
33004
+ import { basename as basename8, extname as extname3 } from "path";
33005
+ var MIME_BY_EXTENSION3 = {
32851
33006
  ".png": "image/png",
32852
33007
  ".jpg": "image/jpeg",
32853
33008
  ".jpeg": "image/jpeg",
@@ -32863,11 +33018,11 @@ var MIME_BY_EXTENSION2 = {
32863
33018
  ".md": "text/markdown",
32864
33019
  ".json": "application/json"
32865
33020
  };
32866
- function inferContentType2(localPath) {
32867
- const ext = extname2(localPath).toLowerCase();
32868
- return MIME_BY_EXTENSION2[ext] ?? "application/octet-stream";
33021
+ function inferContentType3(localPath) {
33022
+ const ext = extname3(localPath).toLowerCase();
33023
+ return MIME_BY_EXTENSION3[ext] ?? "application/octet-stream";
32869
33024
  }
32870
- var uploadFileCommand3 = new Command().name("upload-file").description("Upload a local file to an AgentPhone conversation").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("--to <phone>", "Connected phone handle to message").option("--agent-id <id>", "AgentPhone agent ID (inferred when omitted)").option("--caption <text>", "Caption to accompany the file").option("--content-type <mime>", "Override inferred content type").addHelpText(
33025
+ var uploadFileCommand4 = new Command().name("upload-file").description("Upload a local file to an AgentPhone conversation").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("--to <phone>", "Connected phone handle to message").option("--agent-id <id>", "AgentPhone agent ID (inferred when omitted)").option("--caption <text>", "Caption to accompany the file").option("--content-type <mime>", "Override inferred content type").addHelpText(
32871
33026
  "after",
32872
33027
  `
32873
33028
  Examples:
@@ -32882,7 +33037,7 @@ Output:
32882
33037
  async (options) => {
32883
33038
  let fileSize;
32884
33039
  try {
32885
- const stat2 = statSync3(options.file);
33040
+ const stat2 = statSync4(options.file);
32886
33041
  if (!stat2.isFile()) {
32887
33042
  throw new Error(`Not a regular file: ${options.file}`);
32888
33043
  }
@@ -32896,14 +33051,14 @@ Output:
32896
33051
  if (fileSize === 0) {
32897
33052
  throw new Error("File is empty");
32898
33053
  }
32899
- const filename = basename6(options.file);
32900
- const contentType = options.contentType ?? inferContentType2(options.file);
33054
+ const filename = basename8(options.file);
33055
+ const contentType = options.contentType ?? inferContentType3(options.file);
32901
33056
  const prepared = await initPhoneFileUpload({
32902
33057
  filename,
32903
33058
  contentType,
32904
33059
  length: fileSize
32905
33060
  });
32906
- const fileContent = readFileSync10(options.file);
33061
+ const fileContent = readFileSync11(options.file);
32907
33062
  const uploadResponse = await fetch(prepared.uploadUrl, {
32908
33063
  method: "PUT",
32909
33064
  headers: { "Content-Type": prepared.contentType },
@@ -32927,7 +33082,7 @@ Output:
32927
33082
  );
32928
33083
 
32929
33084
  // src/commands/zero/phone/index.ts
32930
- var zeroPhoneCommand = new Command().name("phone").description("Send AgentPhone messages, upload files, and download media").addCommand(messageCommand).addCommand(downloadFileCommand3).addCommand(uploadFileCommand3).addHelpText(
33085
+ var zeroPhoneCommand = new Command().name("phone").description("Send AgentPhone messages, upload files, and download media").addCommand(messageCommand).addCommand(downloadFileCommand4).addCommand(uploadFileCommand4).addHelpText(
32931
33086
  "after",
32932
33087
  `
32933
33088
  Examples:
@@ -33183,8 +33338,8 @@ init_esm_shims();
33183
33338
 
33184
33339
  // src/lib/skill-directory.ts
33185
33340
  init_esm_shims();
33186
- import { readFileSync as readFileSync11, readdirSync } from "fs";
33187
- import { join as join4 } from "path";
33341
+ import { readFileSync as readFileSync12, readdirSync } from "fs";
33342
+ import { join as join5 } from "path";
33188
33343
  var IGNORED_NAMES = /* @__PURE__ */ new Set(["node_modules", ".git", ".DS_Store"]);
33189
33344
  function readSkillDirectory(dirPath) {
33190
33345
  const files = [];
@@ -33194,11 +33349,11 @@ function readSkillDirectory(dirPath) {
33194
33349
  if (entry.name.startsWith(".") || IGNORED_NAMES.has(entry.name)) continue;
33195
33350
  const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
33196
33351
  if (entry.isDirectory()) {
33197
- walk2(join4(dir, entry.name), relPath);
33352
+ walk2(join5(dir, entry.name), relPath);
33198
33353
  } else {
33199
33354
  files.push({
33200
33355
  path: relPath,
33201
- content: readFileSync11(join4(dir, entry.name), "utf-8")
33356
+ content: readFileSync12(join5(dir, entry.name), "utf-8")
33202
33357
  });
33203
33358
  }
33204
33359
  }
@@ -33955,7 +34110,7 @@ Notes:
33955
34110
  // src/commands/zero/computer-use/index.ts
33956
34111
  init_esm_shims();
33957
34112
  import { mkdir, writeFile } from "fs/promises";
33958
- import { join as join5 } from "path";
34113
+ import { join as join6 } from "path";
33959
34114
  var COMPUTER_USE_SCREENSHOT_DIR = "/tmp/vm0/computer-use";
33960
34115
  var DATA_URL_PATTERN = /^data:([^;,]+);base64,(.*)$/s;
33961
34116
  function sleep2(ms) {
@@ -34003,15 +34158,18 @@ function parseMouseButton(value) {
34003
34158
  }
34004
34159
  throw new Error("button must be left, right, or middle");
34005
34160
  }
34006
- function parseLimit4(value) {
34007
- if (value === void 0) {
34008
- return 50;
34009
- }
34010
- const parsed = parsePositiveInteger2(value, "limit");
34011
- if (parsed > 200) {
34012
- throw new Error("limit must be 200 or less");
34161
+ function elementTargetPayload(options) {
34162
+ const elementIndex = parseOptionalNonNegativeInteger(
34163
+ options.elementIndex,
34164
+ "element-index"
34165
+ );
34166
+ if (!options.element && elementIndex === void 0) {
34167
+ throw new Error("element or element-index is required");
34013
34168
  }
34014
- return parsed;
34169
+ return {
34170
+ ...options.element ? { elementId: options.element } : {},
34171
+ ...elementIndex !== void 0 ? { elementIndex } : {}
34172
+ };
34015
34173
  }
34016
34174
  function sanitizeFilenamePart(value, fallback) {
34017
34175
  if (typeof value !== "string") {
@@ -34045,7 +34203,7 @@ async function writeScreenshotDataUrl(result, dataUrl) {
34045
34203
  const base64Data = match[2] ?? "";
34046
34204
  const appName = sanitizeFilenamePart(result.app, "app");
34047
34205
  const snapshotId = sanitizeFilenamePart(result.snapshotId, "snapshot");
34048
- const outputPath = join5(
34206
+ const outputPath = join6(
34049
34207
  COMPUTER_USE_SCREENSHOT_DIR,
34050
34208
  `${appName}-${snapshotId}.${extensionForMimeType(mimeType)}`
34051
34209
  );
@@ -34127,25 +34285,6 @@ function addTargetOptions(command) {
34127
34285
  function appOption(command) {
34128
34286
  return command.requiredOption("--app <name>", "Target app name or bundle id");
34129
34287
  }
34130
- function auditMetadataValue(metadata, key) {
34131
- const value = metadata?.[key];
34132
- return typeof value === "string" && value.length > 0 ? value : null;
34133
- }
34134
- function formatAuditEvent(event) {
34135
- const dispatchMode = auditMetadataValue(event.redactedResult, "dispatchMode");
34136
- const inputRisk = auditMetadataValue(event.redactedResult, "inputRisk");
34137
- return [
34138
- `${event.createdAt} ${event.event} ${event.kind}`,
34139
- `command=${event.commandId}`,
34140
- event.hostId ? `host=${event.hostId}` : null,
34141
- event.app ? `app=${event.app}` : null,
34142
- event.approvalOutcome ? `approval=${event.approvalOutcome}` : null,
34143
- dispatchMode ? `dispatch=${dispatchMode}` : null,
34144
- inputRisk ? `risk=${inputRisk}` : null
34145
- ].filter((part) => {
34146
- return part !== null;
34147
- }).join(" ");
34148
- }
34149
34288
  var listAppsCommand = addTargetOptions(
34150
34289
  new Command().name("list-apps").description("List apps available to the Desktop Computer Use host").action(
34151
34290
  withErrorHandler(async (options) => {
@@ -34164,14 +34303,19 @@ var getAppStateCommand = appOption(
34164
34303
  );
34165
34304
  var clickCommand = appOption(
34166
34305
  addTargetOptions(
34167
- new Command().name("click").description("Click an accessibility element or screenshot coordinate").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").option("--element <id>", "Element id from get-app-state").option("--x <points>", "Screenshot x coordinate fallback").option("--y <points>", "Screenshot y coordinate fallback").option("--button <button>", "Mouse button", "left").option("--click-count <count>", "Number of clicks", "1").action(
34306
+ new Command().name("click").description("Click an accessibility element or screenshot coordinate").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").option("--element <id>", "Element id from get-app-state").option("--element-index <index>", "Element index from get-app-state").option("--x <points>", "Screenshot x coordinate fallback").option("--y <points>", "Screenshot y coordinate fallback").option("--button <button>", "Mouse button", "left").option("--click-count <count>", "Number of clicks", "1").action(
34168
34307
  withErrorHandler(async (options) => {
34169
34308
  const x = parseOptionalNonNegativeInteger(options.x, "x");
34170
34309
  const y = parseOptionalNonNegativeInteger(options.y, "y");
34310
+ const elementIndex = parseOptionalNonNegativeInteger(
34311
+ options.elementIndex,
34312
+ "element-index"
34313
+ );
34171
34314
  await runWriteCommand("element.click", options, {
34172
34315
  app: options.app,
34173
34316
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34174
34317
  ...options.element ? { elementId: options.element } : {},
34318
+ ...elementIndex !== void 0 ? { elementIndex } : {},
34175
34319
  ...x !== void 0 ? { x } : {},
34176
34320
  ...y !== void 0 ? { y } : {},
34177
34321
  button: parseMouseButton(options.button),
@@ -34183,7 +34327,7 @@ var clickCommand = appOption(
34183
34327
  );
34184
34328
  var scrollCommand = appOption(
34185
34329
  addTargetOptions(
34186
- new Command().name("scroll").description("Scroll an accessibility element").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").requiredOption("--element <id>", "Element id from get-app-state").requiredOption(
34330
+ new Command().name("scroll").description("Scroll an accessibility element").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").option("--element <id>", "Element id from get-app-state").option("--element-index <index>", "Element index from get-app-state").requiredOption(
34187
34331
  "--direction <direction>",
34188
34332
  "Scroll direction: up, down, left, or right"
34189
34333
  ).option("--pages <count>", "Number of pages to scroll", "1").action(
@@ -34191,7 +34335,7 @@ var scrollCommand = appOption(
34191
34335
  await runWriteCommand("element.scroll", options, {
34192
34336
  app: options.app,
34193
34337
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34194
- elementId: options.element,
34338
+ ...elementTargetPayload(options),
34195
34339
  direction: options.direction,
34196
34340
  pages: parsePositiveNumber(options.pages, "pages")
34197
34341
  });
@@ -34201,12 +34345,12 @@ var scrollCommand = appOption(
34201
34345
  );
34202
34346
  var setValueCommand = appOption(
34203
34347
  addTargetOptions(
34204
- new Command().name("set-value").description("Set the value of a settable accessibility element").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").requiredOption("--element <id>", "Element id from get-app-state").requiredOption("--value <text>", "Value to assign").action(
34348
+ new Command().name("set-value").description("Set the value of a settable accessibility element").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").option("--element <id>", "Element id from get-app-state").option("--element-index <index>", "Element index from get-app-state").requiredOption("--value <text>", "Value to assign").action(
34205
34349
  withErrorHandler(async (options) => {
34206
34350
  await runWriteCommand("element.set_value", options, {
34207
34351
  app: options.app,
34208
34352
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34209
- elementId: options.element,
34353
+ ...elementTargetPayload(options),
34210
34354
  value: options.value
34211
34355
  });
34212
34356
  })
@@ -34242,12 +34386,12 @@ var pressKeyCommand = appOption(
34242
34386
  );
34243
34387
  var performActionCommand = appOption(
34244
34388
  addTargetOptions(
34245
- new Command().name("perform-action").description("Invoke a secondary accessibility action").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").requiredOption("--element <id>", "Element id from get-app-state").requiredOption("--action <name>", "Accessibility action name").action(
34389
+ new Command().name("perform-action").description("Invoke a secondary accessibility action").option("--snapshot-id <id>", "Snapshot id returned by get-app-state").option("--element <id>", "Element id from get-app-state").option("--element-index <index>", "Element index from get-app-state").requiredOption("--action <name>", "Accessibility action name").action(
34246
34390
  withErrorHandler(async (options) => {
34247
34391
  await runWriteCommand("element.perform_action", options, {
34248
34392
  app: options.app,
34249
34393
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34250
- elementId: options.element,
34394
+ ...elementTargetPayload(options),
34251
34395
  action: options.action
34252
34396
  });
34253
34397
  })
@@ -34263,32 +34407,7 @@ var openAppCommand = appOption(
34263
34407
  )
34264
34408
  )
34265
34409
  );
34266
- var hostsCommand = new Command().name("hosts").description("List linked Desktop Computer Use hosts").action(
34267
- withErrorHandler(async () => {
34268
- const { hosts } = await listComputerUseHosts();
34269
- console.log(JSON.stringify({ hosts }, null, 2));
34270
- })
34271
- );
34272
- var revokeHostCommand = new Command().name("revoke-host").description("Revoke a linked Desktop Computer Use host").argument("<host-id>").action(
34273
- withErrorHandler(async (hostId) => {
34274
- await deleteComputerUseHost(hostId);
34275
- console.log(`Revoked computer-use host ${hostId}`);
34276
- })
34277
- );
34278
- var auditCommand = new Command().name("audit").description("List Desktop Computer Use write-command audit events").option("--limit <count>", "Maximum events to return", "50").option("--command-id <id>", "Filter by command id").option("--host-id <id>", "Filter by host id").option("--run-id <id>", "Filter by run id").action(
34279
- withErrorHandler(async (options) => {
34280
- const { auditEvents } = await listComputerUseAuditEvents({
34281
- limit: parseLimit4(options.limit),
34282
- ...options.commandId ? { commandId: options.commandId } : {},
34283
- ...options.hostId ? { hostId: options.hostId } : {},
34284
- ...options.runId ? { runId: options.runId } : {}
34285
- });
34286
- for (const event of auditEvents) {
34287
- console.log(formatAuditEvent(event));
34288
- }
34289
- })
34290
- );
34291
- var zeroComputerUseCommand = new Command().name("computer-use").description("Desktop app computer use through Zero CLI").addCommand(listAppsCommand).addCommand(getAppStateCommand).addCommand(clickCommand).addCommand(scrollCommand).addCommand(setValueCommand).addCommand(typeTextCommand).addCommand(pressKeyCommand).addCommand(performActionCommand).addCommand(openAppCommand).addCommand(hostsCommand).addCommand(revokeHostCommand).addCommand(auditCommand);
34410
+ var zeroComputerUseCommand = new Command().name("computer-use").description("Desktop app computer use through Zero CLI").addCommand(listAppsCommand).addCommand(getAppStateCommand).addCommand(clickCommand).addCommand(scrollCommand).addCommand(setValueCommand).addCommand(typeTextCommand).addCommand(pressKeyCommand).addCommand(performActionCommand).addCommand(openAppCommand);
34292
34411
 
34293
34412
  // src/commands/zero/built-in/index.ts
34294
34413
  init_esm_shims();
@@ -34301,13 +34420,13 @@ init_esm_shims();
34301
34420
 
34302
34421
  // src/commands/zero/shared/image-generate.ts
34303
34422
  init_esm_shims();
34304
- import { readFileSync as readFileSync12 } from "fs";
34423
+ import { readFileSync as readFileSync13 } from "fs";
34305
34424
  function readPrompt(options, usageCommand) {
34306
34425
  if (options.prompt?.trim()) {
34307
34426
  return options.prompt.trim();
34308
34427
  }
34309
34428
  if (process.stdin.isTTY === false) {
34310
- const prompt = readFileSync12("/dev/stdin", "utf8").trim();
34429
+ const prompt = readFileSync13("/dev/stdin", "utf8").trim();
34311
34430
  if (prompt.length > 0) {
34312
34431
  return prompt;
34313
34432
  }
@@ -34506,7 +34625,7 @@ init_esm_shims();
34506
34625
 
34507
34626
  // src/commands/zero/shared/presentation-generate.ts
34508
34627
  init_esm_shims();
34509
- import { readFileSync as readFileSync13 } from "fs";
34628
+ import { readFileSync as readFileSync14 } from "fs";
34510
34629
  var PRESENTATION_MAX_IMAGES = 8;
34511
34630
  function parseSlideCount(value) {
34512
34631
  const slideCount = Number(value);
@@ -34532,7 +34651,7 @@ function readPrompt2(options, usageCommand) {
34532
34651
  return options.prompt.trim();
34533
34652
  }
34534
34653
  if (process.stdin.isTTY === false) {
34535
- const prompt = readFileSync13("/dev/stdin", "utf8").trim();
34654
+ const prompt = readFileSync14("/dev/stdin", "utf8").trim();
34536
34655
  if (prompt.length > 0) {
34537
34656
  return prompt;
34538
34657
  }
@@ -34621,7 +34740,7 @@ init_esm_shims();
34621
34740
 
34622
34741
  // src/commands/zero/shared/video-generate.ts
34623
34742
  init_esm_shims();
34624
- import { readFileSync as readFileSync14 } from "fs";
34743
+ import { readFileSync as readFileSync15 } from "fs";
34625
34744
  function parseSeed2(value) {
34626
34745
  const seed = Number(value);
34627
34746
  if (!Number.isInteger(seed) || seed < 0 || !Number.isSafeInteger(seed)) {
@@ -34629,12 +34748,15 @@ function parseSeed2(value) {
34629
34748
  }
34630
34749
  return seed;
34631
34750
  }
34751
+ function collectUrl(value, previous = []) {
34752
+ return [...previous, value];
34753
+ }
34632
34754
  function readPrompt3(options, usageCommand) {
34633
34755
  if (options.prompt?.trim()) {
34634
34756
  return options.prompt.trim();
34635
34757
  }
34636
34758
  if (process.stdin.isTTY === false) {
34637
- const prompt = readFileSync14("/dev/stdin", "utf8").trim();
34759
+ const prompt = readFileSync15("/dev/stdin", "utf8").trim();
34638
34760
  if (prompt.length > 0) {
34639
34761
  return prompt;
34640
34762
  }
@@ -34646,17 +34768,32 @@ function readPrompt3(options, usageCommand) {
34646
34768
  function createVideoGenerateCommand(config) {
34647
34769
  return new Command().name(config.name).description("Generate a billed video file from a prompt").option("--prompt <text>", "Video prompt; can also be piped via stdin").option(
34648
34770
  "--model <model>",
34649
- "Model: veo3.1-fast, veo3.1, kling-o3-standard, kling-v3-4k, seedance2.0, or seedance2.0-fast",
34650
- "veo3.1-fast"
34771
+ "Model: dreamina-seedance-2.0-fast, dreamina-seedance-2.0, seedance-1.5-pro, veo3.1-fast, or kling-v3-4k",
34772
+ "dreamina-seedance-2.0-fast"
34651
34773
  ).option(
34652
34774
  "--aspect-ratio <ratio>",
34653
- "Aspect ratio: 16:9 or 9:16; Seedance also supports 21:9, 4:3, 1:1, 3:4",
34775
+ "Aspect ratio: 21:9, 16:9, 4:3, 1:1, 3:4, or 9:16",
34654
34776
  "16:9"
34655
34777
  ).option(
34656
34778
  "--duration <duration>",
34657
- "Duration: 3s-15s; Veo supports 4s/6s/8s",
34779
+ "Duration: 2s-15s depending on model",
34658
34780
  "8s"
34659
- ).option("--resolution <resolution>", "Resolution: 720p, 1080p, or 4k").option("--no-audio", "Generate a silent video").option("--negative-prompt <text>", "Negative prompt").option("--seed <integer>", "Deterministic seed", parseSeed2).option("--no-auto-fix", "Disable fal prompt auto-fix").option("--safety-tolerance <level>", "Safety tolerance: 1-6", "4").option("--json", "Print metadata as JSON").addHelpText(
34781
+ ).option("--resolution <resolution>", "Resolution: 480p, 720p, or 1080p").option("--no-audio", "Generate a silent video").option("--negative-prompt <text>", "Negative prompt").option("--seed <integer>", "Deterministic seed", parseSeed2).option("--no-auto-fix", "Disable prompt auto-fix").option("--safety-tolerance <level>", "Safety tolerance", "4").option(
34782
+ "--image-url <url>",
34783
+ "Reference image URL; repeat for multiple Dreamina Seedance 2.0 references",
34784
+ collectUrl,
34785
+ []
34786
+ ).option(
34787
+ "--video-url <url>",
34788
+ "Reference video URL; repeat up to 3 times for Dreamina Seedance 2.0",
34789
+ collectUrl,
34790
+ []
34791
+ ).option(
34792
+ "--audio-url <url>",
34793
+ "Reference audio URL for Dreamina Seedance 2.0",
34794
+ collectUrl,
34795
+ []
34796
+ ).option("--first-frame-image-url <url>", "First frame image URL").option("--last-frame-image-url <url>", "Last frame image URL").option("--json", "Print metadata as JSON").addHelpText(
34660
34797
  "after",
34661
34798
  `
34662
34799
  Examples:
@@ -34668,18 +34805,20 @@ Output:
34668
34805
  Notes:
34669
34806
  - Authenticates via ZERO_TOKEN (requires file:write capability)
34670
34807
  - Charges org credits after successful video generation
34671
- - Uses fal video models with configured usage pricing
34808
+ - Uses BytePlus ModelArk and fal.ai video models with configured usage pricing
34672
34809
 
34673
34810
  Models:
34674
- - Veo: veo3.1-fast (default), veo3.1. Supports 4s/6s/8s,
34675
- 16:9 or 9:16, 720p/1080p/4k, negative prompts, seed,
34676
- auto-fix, safety tolerance, and optional audio.
34677
- - Kling: kling-o3-standard, kling-v3-4k. Supports 3s-15s and
34678
- 16:9 or 9:16. kling-v3-4k uses 4k output; kling-o3-standard
34679
- uses 1080p output.
34680
- - Seedance: seedance2.0, seedance2.0-fast. Supports 4s-15s,
34681
- 480p/720p, seed, and aspect ratios 21:9, 16:9, 4:3, 1:1,
34682
- 3:4, or 9:16.`
34811
+ - Dreamina Seedance 2.0: dreamina-seedance-2.0,
34812
+ dreamina-seedance-2.0-fast (default). Supports 4s-15s,
34813
+ 480p/720p, seed, optional audio, image references, and first/last
34814
+ frames. The non-fast model also supports 1080p and video/audio references.
34815
+ - Seedance 1.5 Pro: seedance-1.5-pro. Supports 4s-12s,
34816
+ 480p/720p/1080p, seed, optional audio, image references, and
34817
+ first/last frames.
34818
+ - fal.ai: veo3.1-fast and kling-v3-4k. veo3.1-fast supports
34819
+ 4s/6s/8s, 720p/1080p/4k, negative prompts, seed, auto-fix,
34820
+ safety tolerance, and optional audio. kling-v3-4k supports 3s-15s,
34821
+ 4k output, negative prompts, and optional audio.`
34683
34822
  ).action(
34684
34823
  withErrorHandler(async (options) => {
34685
34824
  const prompt = readPrompt3(options, config.usageCommand);
@@ -34693,7 +34832,12 @@ Models:
34693
34832
  negativePrompt: options.negativePrompt,
34694
34833
  seed: options.seed,
34695
34834
  autoFix: options.autoFix !== false,
34696
- safetyTolerance: options.safetyTolerance
34835
+ safetyTolerance: options.safetyTolerance,
34836
+ imageUrls: options.imageUrl,
34837
+ videoUrls: options.videoUrl,
34838
+ audioUrls: options.audioUrl,
34839
+ firstFrameImageUrl: options.firstFrameImageUrl,
34840
+ lastFrameImageUrl: options.lastFrameImageUrl
34697
34841
  });
34698
34842
  if (options.json) {
34699
34843
  console.log(JSON.stringify(result));
@@ -34719,17 +34863,17 @@ var videoCommand = createVideoGenerateCommand({
34719
34863
  usageCommand: "zero built-in generate video",
34720
34864
  examples: ` Generate video: zero built-in generate video --prompt "A tracking shot through a neon market"
34721
34865
  Pipe prompt: cat prompt.txt | zero built-in generate video
34722
- Use Kling: zero built-in generate video --model kling-o3-standard --prompt "A product reveal" --duration 10s
34723
- Use Seedance: zero built-in generate video --model seedance2.0-fast --prompt "A multi-shot chase scene" --duration 8s --resolution 480p
34724
- Use Veo 3.1: zero built-in generate video --model veo3.1 --prompt "A cinematic product reveal" --duration 6s --resolution 1080p`
34866
+ Use Dreamina 2.0: zero built-in generate video --model dreamina-seedance-2.0 --prompt "A cinematic product reveal" --duration 6s --resolution 1080p
34867
+ Use Seedance 1.5 Pro: zero built-in generate video --model seedance-1.5-pro --prompt "A multi-shot chase scene" --duration 8s --resolution 720p
34868
+ Add a first frame: zero built-in generate video --first-frame-image-url https://example.com/frame.png --prompt "Animate this frame"`
34725
34869
  });
34726
34870
 
34727
34871
  // src/commands/zero/built-in/generate/website.ts
34728
34872
  init_esm_shims();
34729
34873
  import { mkdtemp, rm } from "fs/promises";
34730
- import { readFileSync as readFileSync15 } from "fs";
34731
- import { join as join7 } from "path";
34732
- import { tmpdir as tmpdir4 } from "os";
34874
+ import { readFileSync as readFileSync16 } from "fs";
34875
+ import { join as join8 } from "path";
34876
+ import { tmpdir as tmpdir5 } from "os";
34733
34877
 
34734
34878
  // src/lib/host/publish-static-site.ts
34735
34879
  init_esm_shims();
@@ -34739,8 +34883,8 @@ import { readFile as readFile2 } from "fs/promises";
34739
34883
  init_esm_shims();
34740
34884
  import { createHash } from "crypto";
34741
34885
  import { readdir, readFile, stat } from "fs/promises";
34742
- import { extname as extname3, relative, resolve, sep, dirname, posix } from "path";
34743
- var MIME_BY_EXTENSION3 = {
34886
+ import { extname as extname4, relative, resolve, sep, dirname, posix } from "path";
34887
+ var MIME_BY_EXTENSION4 = {
34744
34888
  ".html": "text/html; charset=utf-8",
34745
34889
  ".htm": "text/html; charset=utf-8",
34746
34890
  ".css": "text/css; charset=utf-8",
@@ -34773,8 +34917,8 @@ var HTML_REFERENCE_RE = /<(?:script|link|img|source|video|audio|embed|object)\b[
34773
34917
  var SRCSET_RE = /\s(?:srcset)=["']([^"']+)["']/giu;
34774
34918
  var CSS_URL_RE = /url\(\s*["']?([^"')]+)["']?\s*\)/giu;
34775
34919
  var CSS_IMPORT_RE = /@import\s+(?:url\()?["']([^"']+)["']\)?/giu;
34776
- function inferContentType3(path) {
34777
- return MIME_BY_EXTENSION3[extname3(path).toLowerCase()] ?? "application/octet-stream";
34920
+ function inferContentType4(path) {
34921
+ return MIME_BY_EXTENSION4[extname4(path).toLowerCase()] ?? "application/octet-stream";
34778
34922
  }
34779
34923
  function looksImmutable(path) {
34780
34924
  if (path.startsWith("/assets/")) {
@@ -34824,7 +34968,7 @@ function normalizeReference(fromPath, raw) {
34824
34968
  return path;
34825
34969
  }
34826
34970
  function shouldRequireHtmlReference(path) {
34827
- return extname3(path).length > 0 || path.startsWith("/assets/");
34971
+ return extname4(path).length > 0 || path.startsWith("/assets/");
34828
34972
  }
34829
34973
  function isHtmlExtension(ext) {
34830
34974
  return ext === ".html" || ext === ".htm";
@@ -34886,7 +35030,7 @@ async function walk(root, dir, files) {
34886
35030
  path,
34887
35031
  size: fileStat.size,
34888
35032
  sha256: await hashFile(fullPath),
34889
- contentType: inferContentType3(path),
35033
+ contentType: inferContentType4(path),
34890
35034
  immutable: looksImmutable(path) || void 0
34891
35035
  });
34892
35036
  }
@@ -34898,7 +35042,7 @@ async function assertReferencesExist(files) {
34898
35042
  })
34899
35043
  );
34900
35044
  for (const file of files) {
34901
- const ext = extname3(file.path).toLowerCase();
35045
+ const ext = extname4(file.path).toLowerCase();
34902
35046
  if (!shouldValidateReferences(ext)) {
34903
35047
  continue;
34904
35048
  }
@@ -35004,7 +35148,7 @@ init_esm_shims();
35004
35148
  var import_react = __toESM(require_react(), 1);
35005
35149
  var import_server = __toESM(require_server_node(), 1);
35006
35150
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
35007
- import { join as join6 } from "path";
35151
+ import { join as join7 } from "path";
35008
35152
  function h(type, props, ...children) {
35009
35153
  return import_react.default.createElement(type, props, ...children);
35010
35154
  }
@@ -35743,7 +35887,7 @@ h1 {
35743
35887
  }
35744
35888
  `;
35745
35889
  async function buildGeneratedWebsite(options) {
35746
- const assetsDir = join6(options.outDir, "assets");
35890
+ const assetsDir = join7(options.outDir, "assets");
35747
35891
  await mkdir2(assetsDir, { recursive: true });
35748
35892
  const markup = (0, import_server.renderToStaticMarkup)(
35749
35893
  import_react.default.createElement(WebsiteDocument, {
@@ -35753,10 +35897,10 @@ async function buildGeneratedWebsite(options) {
35753
35897
  })
35754
35898
  );
35755
35899
  await writeFile2(
35756
- join6(options.outDir, "index.html"),
35900
+ join7(options.outDir, "index.html"),
35757
35901
  `<!doctype html>${markup}`
35758
35902
  );
35759
- await writeFile2(join6(assetsDir, "styles.css"), WEBSITE_CSS.trimStart());
35903
+ await writeFile2(join7(assetsDir, "styles.css"), WEBSITE_CSS.trimStart());
35760
35904
  }
35761
35905
 
35762
35906
  // src/commands/zero/built-in/generate/website.ts
@@ -35787,7 +35931,7 @@ function readPrompt4(options) {
35787
35931
  return options.prompt.trim();
35788
35932
  }
35789
35933
  if (process.stdin.isTTY === false) {
35790
- const prompt = readFileSync15("/dev/stdin", "utf8").trim();
35934
+ const prompt = readFileSync16("/dev/stdin", "utf8").trim();
35791
35935
  if (prompt.length > 0) {
35792
35936
  return prompt;
35793
35937
  }
@@ -35846,8 +35990,8 @@ Notes:
35846
35990
  title: options.title,
35847
35991
  audience: options.audience
35848
35992
  });
35849
- const buildRoot = await mkdtemp(join7(tmpdir4(), "zero-website-"));
35850
- const outDir = join7(buildRoot, "dist");
35993
+ const buildRoot = await mkdtemp(join8(tmpdir5(), "zero-website-"));
35994
+ const outDir = join8(buildRoot, "dist");
35851
35995
  try {
35852
35996
  if (!options.json) {
35853
35997
  console.log(source_default.dim("Building React template..."));
@@ -35932,13 +36076,13 @@ init_esm_shims();
35932
36076
 
35933
36077
  // src/commands/zero/shared/voice-generate.ts
35934
36078
  init_esm_shims();
35935
- import { readFileSync as readFileSync16 } from "fs";
36079
+ import { readFileSync as readFileSync17 } from "fs";
35936
36080
  function readText(options, usageCommand) {
35937
36081
  if (options.text?.trim()) {
35938
36082
  return options.text.trim();
35939
36083
  }
35940
36084
  if (process.stdin.isTTY === false) {
35941
- const text = readFileSync16("/dev/stdin", "utf8").trim();
36085
+ const text = readFileSync17("/dev/stdin", "utf8").trim();
35942
36086
  if (text.length > 0) {
35943
36087
  return text;
35944
36088
  }
@@ -36034,12 +36178,12 @@ init_esm_shims();
36034
36178
 
36035
36179
  // src/commands/zero/web/download-file.ts
36036
36180
  init_esm_shims();
36037
- import { basename as basename7, join as join8 } from "path";
36038
- import { tmpdir as tmpdir5 } from "os";
36039
- function defaultOutPath4(fileId) {
36040
- return join8(tmpdir5(), `web-${basename7(fileId)}`);
36181
+ import { basename as basename9, join as join9 } from "path";
36182
+ import { tmpdir as tmpdir6 } from "os";
36183
+ function defaultOutPath5(fileId) {
36184
+ return join9(tmpdir6(), `web-${basename9(fileId)}`);
36041
36185
  }
36042
- var downloadFileCommand4 = new Command().name("download-file").description("Download a web-uploaded file by id").argument("<file-id>", "File id (UUID returned by the upload API)").option(
36186
+ var downloadFileCommand5 = new Command().name("download-file").description("Download a web-uploaded file by id").argument("<file-id>", "File id (UUID returned by the upload API)").option(
36043
36187
  "-o, --out <path>",
36044
36188
  "Output path for the downloaded file (default: /tmp/web-<file-id>)"
36045
36189
  ).addHelpText(
@@ -36065,7 +36209,7 @@ Notes:
36065
36209
  - Streams the file bytes directly to disk`
36066
36210
  ).action(
36067
36211
  withErrorHandler(async (fileId, options) => {
36068
- const outPath = options.out ?? defaultOutPath4(fileId);
36212
+ const outPath = options.out ?? defaultOutPath5(fileId);
36069
36213
  const result = await downloadWebFile(fileId, outPath);
36070
36214
  console.log(JSON.stringify(result));
36071
36215
  })
@@ -36073,7 +36217,7 @@ Notes:
36073
36217
 
36074
36218
  // src/commands/zero/web/upload-file.ts
36075
36219
  init_esm_shims();
36076
- var uploadFileCommand4 = 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(
36220
+ var uploadFileCommand5 = 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(
36077
36221
  "after",
36078
36222
  `
36079
36223
  Examples:
@@ -36107,7 +36251,7 @@ Notes:
36107
36251
  );
36108
36252
 
36109
36253
  // src/commands/zero/web/index.ts
36110
- var zeroWebCommand = new Command().name("web").description("Upload and download files via the web chat endpoint").addCommand(downloadFileCommand4).addCommand(uploadFileCommand4).addHelpText(
36254
+ var zeroWebCommand = new Command().name("web").description("Upload and download files via the web chat endpoint").addCommand(downloadFileCommand5).addCommand(uploadFileCommand5).addHelpText(
36111
36255
  "after",
36112
36256
  `
36113
36257
  Examples:
@@ -36148,7 +36292,7 @@ function parsePositiveInteger3(value, label) {
36148
36292
  }
36149
36293
  return parsed;
36150
36294
  }
36151
- function parseLimit5(value) {
36295
+ function parseLimit4(value) {
36152
36296
  if (value === void 0) {
36153
36297
  return 50;
36154
36298
  }
@@ -36268,7 +36412,7 @@ function formatHost(host) {
36268
36412
  ` capabilities: ${formatCapabilities(host.supportedCapabilities)}`
36269
36413
  ].join("\n");
36270
36414
  }
36271
- function formatAuditEvent2(event) {
36415
+ function formatAuditEvent(event) {
36272
36416
  const parts = [
36273
36417
  event.createdAt,
36274
36418
  event.event,
@@ -36295,7 +36439,7 @@ function formatAuditEvent2(event) {
36295
36439
  }
36296
36440
  return parts.join(" ");
36297
36441
  }
36298
- var hostsCommand2 = new Command().name("hosts").description("List and revoke linked local-browser hosts").addCommand(
36442
+ var hostsCommand = new Command().name("hosts").description("List and revoke linked local-browser hosts").addCommand(
36299
36443
  new Command().name("list").description("List linked local-browser hosts").option("--json", "Output hosts as JSON").action(
36300
36444
  withErrorHandler(async (options) => {
36301
36445
  const result = await listLocalBrowserHosts();
@@ -36323,11 +36467,11 @@ var hostsCommand2 = new Command().name("hosts").description("List and revoke lin
36323
36467
  })
36324
36468
  )
36325
36469
  );
36326
- var auditCommand2 = new Command().name("audit").description("Inspect local-browser write command audit events").addCommand(
36470
+ var auditCommand = new Command().name("audit").description("Inspect local-browser write command audit events").addCommand(
36327
36471
  new Command().name("list").description("List local-browser write command audit events").option("--limit <count>", "Maximum events to show", "50").option("--command-id <id>", "Filter by command id").option("--host-id <id>", "Filter by host id").option("--run-id <id>", "Filter by run id").option("--json", "Output audit events as JSON").action(
36328
36472
  withErrorHandler(async (options) => {
36329
36473
  const result = await listLocalBrowserAuditEvents({
36330
- limit: parseLimit5(options.limit),
36474
+ limit: parseLimit4(options.limit),
36331
36475
  ...options.commandId ? { commandId: options.commandId } : {},
36332
36476
  ...options.hostId ? { hostId: options.hostId } : {},
36333
36477
  ...options.runId ? { runId: options.runId } : {}
@@ -36340,7 +36484,7 @@ var auditCommand2 = new Command().name("audit").description("Inspect local-brows
36340
36484
  console.log(source_default.dim("No local-browser audit events found."));
36341
36485
  return;
36342
36486
  }
36343
- console.log(result.auditEvents.map(formatAuditEvent2).join("\n"));
36487
+ console.log(result.auditEvents.map(formatAuditEvent).join("\n"));
36344
36488
  })
36345
36489
  )
36346
36490
  );
@@ -36434,7 +36578,7 @@ Examples:
36434
36578
  Click page? zero local-browser page click --selector button
36435
36579
  Open tab? zero local-browser tabs open --url https://example.com
36436
36580
  Audit actions? zero local-browser audit list`
36437
- ).addCommand(hostsCommand2).addCommand(auditCommand2).addCommand(tabsCommand).addCommand(pageCommand);
36581
+ ).addCommand(hostsCommand).addCommand(auditCommand).addCommand(tabsCommand).addCommand(pageCommand);
36438
36582
 
36439
36583
  // src/commands/zero/host/index.ts
36440
36584
  init_esm_shims();
@@ -36510,7 +36654,7 @@ function parsePositiveInteger4(value) {
36510
36654
  }
36511
36655
  return parsed;
36512
36656
  }
36513
- function parseLimit6(value) {
36657
+ function parseLimit5(value) {
36514
36658
  const limit = parsePositiveInteger4(value);
36515
36659
  if (limit > 20) {
36516
36660
  throw new InvalidArgumentError("limit must be between 1 and 20");
@@ -36611,7 +36755,7 @@ var placesSearchCommand = new Command().name("search").description("Search for p
36611
36755
  ).option(
36612
36756
  "--limit <n>",
36613
36757
  "Maximum places to return, from 1 to 20",
36614
- parseLimit6,
36758
+ parseLimit5,
36615
36759
  5
36616
36760
  ).option("--region <code>", "Optional region bias, such as US or CN").option("--json", "Print the raw maps response as JSON").action(
36617
36761
  withErrorHandler(async (options) => {
@@ -36808,6 +36952,7 @@ var COMMAND_CAPABILITY_MAP = {
36808
36952
  logs: "agent-run:read",
36809
36953
  search: "chat-message:read",
36810
36954
  chat: "chat-message:write",
36955
+ github: ["github:read", "github:write"],
36811
36956
  slack: "slack:write",
36812
36957
  telegram: ["telegram:read", "telegram:write"],
36813
36958
  phone: ["phone:read", "phone:write"],
@@ -36833,6 +36978,7 @@ var DEFAULT_COMMANDS = [
36833
36978
  zeroScheduleCommand,
36834
36979
  zeroSecretCommand,
36835
36980
  zeroChatCommand,
36981
+ zeroGithubCommand,
36836
36982
  zeroSlackCommand,
36837
36983
  zeroTelegramCommand,
36838
36984
  zeroPhoneCommand,
@@ -36869,6 +37015,8 @@ function buildZeroHelpText(payload = decodeZeroTokenPayload()) {
36869
37015
  const examples = [
36870
37016
  " Check a connector? zero doctor check-connector --env-name <ENV_NAME>",
36871
37017
  " Send a Slack message? zero slack message send --help",
37018
+ " Upload GitHub? zero github upload-file --help",
37019
+ " Download GitHub? zero github download-file --help",
36872
37020
  " List Telegram bots? zero telegram bot list",
36873
37021
  " Send Telegram? zero telegram message send --help",
36874
37022
  " Upload Telegram? zero telegram upload-file --help",
@@ -36906,7 +37054,7 @@ function registerZeroCommands(prog, commands) {
36906
37054
  var program = new Command();
36907
37055
  program.name("zero").description(
36908
37056
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
36909
- ).version("9.160.8").addHelpText("after", () => {
37057
+ ).version("9.160.9").addHelpText("after", () => {
36910
37058
  return buildZeroHelpText();
36911
37059
  });
36912
37060
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {