@vm0/cli 9.160.7 → 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-JLWCGWMZ.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,17 +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 formatAuditEvent(event) {
34131
- return [
34132
- `${event.createdAt} ${event.event} ${event.kind}`,
34133
- `command=${event.commandId}`,
34134
- event.hostId ? `host=${event.hostId}` : null,
34135
- event.app ? `app=${event.app}` : null,
34136
- event.approvalOutcome ? `approval=${event.approvalOutcome}` : null
34137
- ].filter((part) => {
34138
- return part !== null;
34139
- }).join(" ");
34140
- }
34141
34288
  var listAppsCommand = addTargetOptions(
34142
34289
  new Command().name("list-apps").description("List apps available to the Desktop Computer Use host").action(
34143
34290
  withErrorHandler(async (options) => {
@@ -34156,14 +34303,19 @@ var getAppStateCommand = appOption(
34156
34303
  );
34157
34304
  var clickCommand = appOption(
34158
34305
  addTargetOptions(
34159
- 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(
34160
34307
  withErrorHandler(async (options) => {
34161
34308
  const x = parseOptionalNonNegativeInteger(options.x, "x");
34162
34309
  const y = parseOptionalNonNegativeInteger(options.y, "y");
34310
+ const elementIndex = parseOptionalNonNegativeInteger(
34311
+ options.elementIndex,
34312
+ "element-index"
34313
+ );
34163
34314
  await runWriteCommand("element.click", options, {
34164
34315
  app: options.app,
34165
34316
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34166
34317
  ...options.element ? { elementId: options.element } : {},
34318
+ ...elementIndex !== void 0 ? { elementIndex } : {},
34167
34319
  ...x !== void 0 ? { x } : {},
34168
34320
  ...y !== void 0 ? { y } : {},
34169
34321
  button: parseMouseButton(options.button),
@@ -34175,7 +34327,7 @@ var clickCommand = appOption(
34175
34327
  );
34176
34328
  var scrollCommand = appOption(
34177
34329
  addTargetOptions(
34178
- 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(
34179
34331
  "--direction <direction>",
34180
34332
  "Scroll direction: up, down, left, or right"
34181
34333
  ).option("--pages <count>", "Number of pages to scroll", "1").action(
@@ -34183,7 +34335,7 @@ var scrollCommand = appOption(
34183
34335
  await runWriteCommand("element.scroll", options, {
34184
34336
  app: options.app,
34185
34337
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34186
- elementId: options.element,
34338
+ ...elementTargetPayload(options),
34187
34339
  direction: options.direction,
34188
34340
  pages: parsePositiveNumber(options.pages, "pages")
34189
34341
  });
@@ -34193,12 +34345,12 @@ var scrollCommand = appOption(
34193
34345
  );
34194
34346
  var setValueCommand = appOption(
34195
34347
  addTargetOptions(
34196
- 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(
34197
34349
  withErrorHandler(async (options) => {
34198
34350
  await runWriteCommand("element.set_value", options, {
34199
34351
  app: options.app,
34200
34352
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34201
- elementId: options.element,
34353
+ ...elementTargetPayload(options),
34202
34354
  value: options.value
34203
34355
  });
34204
34356
  })
@@ -34219,7 +34371,10 @@ var typeTextCommand = appOption(
34219
34371
  );
34220
34372
  var pressKeyCommand = appOption(
34221
34373
  addTargetOptions(
34222
- new Command().name("press-key").description("Press a key or key combination in the target app").requiredOption("--key <key>", "Key or key combination to press").action(
34374
+ new Command().name("press-key").description("Press a key or key combination in the target app").requiredOption(
34375
+ "--key <key>",
34376
+ "Key or key combination to press, for example Command+K or Control+K"
34377
+ ).action(
34223
34378
  withErrorHandler(async (options) => {
34224
34379
  await runWriteCommand("keyboard.press_key", options, {
34225
34380
  app: options.app,
@@ -34231,12 +34386,12 @@ var pressKeyCommand = appOption(
34231
34386
  );
34232
34387
  var performActionCommand = appOption(
34233
34388
  addTargetOptions(
34234
- 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(
34235
34390
  withErrorHandler(async (options) => {
34236
34391
  await runWriteCommand("element.perform_action", options, {
34237
34392
  app: options.app,
34238
34393
  ...options.snapshotId ? { snapshotId: options.snapshotId } : {},
34239
- elementId: options.element,
34394
+ ...elementTargetPayload(options),
34240
34395
  action: options.action
34241
34396
  });
34242
34397
  })
@@ -34252,32 +34407,7 @@ var openAppCommand = appOption(
34252
34407
  )
34253
34408
  )
34254
34409
  );
34255
- var hostsCommand = new Command().name("hosts").description("List linked Desktop Computer Use hosts").action(
34256
- withErrorHandler(async () => {
34257
- const { hosts } = await listComputerUseHosts();
34258
- console.log(JSON.stringify({ hosts }, null, 2));
34259
- })
34260
- );
34261
- var revokeHostCommand = new Command().name("revoke-host").description("Revoke a linked Desktop Computer Use host").argument("<host-id>").action(
34262
- withErrorHandler(async (hostId) => {
34263
- await deleteComputerUseHost(hostId);
34264
- console.log(`Revoked computer-use host ${hostId}`);
34265
- })
34266
- );
34267
- 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(
34268
- withErrorHandler(async (options) => {
34269
- const { auditEvents } = await listComputerUseAuditEvents({
34270
- limit: parseLimit4(options.limit),
34271
- ...options.commandId ? { commandId: options.commandId } : {},
34272
- ...options.hostId ? { hostId: options.hostId } : {},
34273
- ...options.runId ? { runId: options.runId } : {}
34274
- });
34275
- for (const event of auditEvents) {
34276
- console.log(formatAuditEvent(event));
34277
- }
34278
- })
34279
- );
34280
- 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);
34281
34411
 
34282
34412
  // src/commands/zero/built-in/index.ts
34283
34413
  init_esm_shims();
@@ -34290,13 +34420,13 @@ init_esm_shims();
34290
34420
 
34291
34421
  // src/commands/zero/shared/image-generate.ts
34292
34422
  init_esm_shims();
34293
- import { readFileSync as readFileSync12 } from "fs";
34423
+ import { readFileSync as readFileSync13 } from "fs";
34294
34424
  function readPrompt(options, usageCommand) {
34295
34425
  if (options.prompt?.trim()) {
34296
34426
  return options.prompt.trim();
34297
34427
  }
34298
34428
  if (process.stdin.isTTY === false) {
34299
- const prompt = readFileSync12("/dev/stdin", "utf8").trim();
34429
+ const prompt = readFileSync13("/dev/stdin", "utf8").trim();
34300
34430
  if (prompt.length > 0) {
34301
34431
  return prompt;
34302
34432
  }
@@ -34495,7 +34625,7 @@ init_esm_shims();
34495
34625
 
34496
34626
  // src/commands/zero/shared/presentation-generate.ts
34497
34627
  init_esm_shims();
34498
- import { readFileSync as readFileSync13 } from "fs";
34628
+ import { readFileSync as readFileSync14 } from "fs";
34499
34629
  var PRESENTATION_MAX_IMAGES = 8;
34500
34630
  function parseSlideCount(value) {
34501
34631
  const slideCount = Number(value);
@@ -34521,7 +34651,7 @@ function readPrompt2(options, usageCommand) {
34521
34651
  return options.prompt.trim();
34522
34652
  }
34523
34653
  if (process.stdin.isTTY === false) {
34524
- const prompt = readFileSync13("/dev/stdin", "utf8").trim();
34654
+ const prompt = readFileSync14("/dev/stdin", "utf8").trim();
34525
34655
  if (prompt.length > 0) {
34526
34656
  return prompt;
34527
34657
  }
@@ -34610,7 +34740,7 @@ init_esm_shims();
34610
34740
 
34611
34741
  // src/commands/zero/shared/video-generate.ts
34612
34742
  init_esm_shims();
34613
- import { readFileSync as readFileSync14 } from "fs";
34743
+ import { readFileSync as readFileSync15 } from "fs";
34614
34744
  function parseSeed2(value) {
34615
34745
  const seed = Number(value);
34616
34746
  if (!Number.isInteger(seed) || seed < 0 || !Number.isSafeInteger(seed)) {
@@ -34618,12 +34748,15 @@ function parseSeed2(value) {
34618
34748
  }
34619
34749
  return seed;
34620
34750
  }
34751
+ function collectUrl(value, previous = []) {
34752
+ return [...previous, value];
34753
+ }
34621
34754
  function readPrompt3(options, usageCommand) {
34622
34755
  if (options.prompt?.trim()) {
34623
34756
  return options.prompt.trim();
34624
34757
  }
34625
34758
  if (process.stdin.isTTY === false) {
34626
- const prompt = readFileSync14("/dev/stdin", "utf8").trim();
34759
+ const prompt = readFileSync15("/dev/stdin", "utf8").trim();
34627
34760
  if (prompt.length > 0) {
34628
34761
  return prompt;
34629
34762
  }
@@ -34635,17 +34768,32 @@ function readPrompt3(options, usageCommand) {
34635
34768
  function createVideoGenerateCommand(config) {
34636
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(
34637
34770
  "--model <model>",
34638
- "Model: veo3.1-fast, veo3.1, kling-o3-standard, kling-v3-4k, seedance2.0, or seedance2.0-fast",
34639
- "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"
34640
34773
  ).option(
34641
34774
  "--aspect-ratio <ratio>",
34642
- "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",
34643
34776
  "16:9"
34644
34777
  ).option(
34645
34778
  "--duration <duration>",
34646
- "Duration: 3s-15s; Veo supports 4s/6s/8s",
34779
+ "Duration: 2s-15s depending on model",
34647
34780
  "8s"
34648
- ).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(
34649
34797
  "after",
34650
34798
  `
34651
34799
  Examples:
@@ -34657,18 +34805,20 @@ Output:
34657
34805
  Notes:
34658
34806
  - Authenticates via ZERO_TOKEN (requires file:write capability)
34659
34807
  - Charges org credits after successful video generation
34660
- - Uses fal video models with configured usage pricing
34808
+ - Uses BytePlus ModelArk and fal.ai video models with configured usage pricing
34661
34809
 
34662
34810
  Models:
34663
- - Veo: veo3.1-fast (default), veo3.1. Supports 4s/6s/8s,
34664
- 16:9 or 9:16, 720p/1080p/4k, negative prompts, seed,
34665
- auto-fix, safety tolerance, and optional audio.
34666
- - Kling: kling-o3-standard, kling-v3-4k. Supports 3s-15s and
34667
- 16:9 or 9:16. kling-v3-4k uses 4k output; kling-o3-standard
34668
- uses 1080p output.
34669
- - Seedance: seedance2.0, seedance2.0-fast. Supports 4s-15s,
34670
- 480p/720p, seed, and aspect ratios 21:9, 16:9, 4:3, 1:1,
34671
- 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.`
34672
34822
  ).action(
34673
34823
  withErrorHandler(async (options) => {
34674
34824
  const prompt = readPrompt3(options, config.usageCommand);
@@ -34682,7 +34832,12 @@ Models:
34682
34832
  negativePrompt: options.negativePrompt,
34683
34833
  seed: options.seed,
34684
34834
  autoFix: options.autoFix !== false,
34685
- 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
34686
34841
  });
34687
34842
  if (options.json) {
34688
34843
  console.log(JSON.stringify(result));
@@ -34708,17 +34863,17 @@ var videoCommand = createVideoGenerateCommand({
34708
34863
  usageCommand: "zero built-in generate video",
34709
34864
  examples: ` Generate video: zero built-in generate video --prompt "A tracking shot through a neon market"
34710
34865
  Pipe prompt: cat prompt.txt | zero built-in generate video
34711
- Use Kling: zero built-in generate video --model kling-o3-standard --prompt "A product reveal" --duration 10s
34712
- Use Seedance: zero built-in generate video --model seedance2.0-fast --prompt "A multi-shot chase scene" --duration 8s --resolution 480p
34713
- 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"`
34714
34869
  });
34715
34870
 
34716
34871
  // src/commands/zero/built-in/generate/website.ts
34717
34872
  init_esm_shims();
34718
34873
  import { mkdtemp, rm } from "fs/promises";
34719
- import { readFileSync as readFileSync15 } from "fs";
34720
- import { join as join7 } from "path";
34721
- 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";
34722
34877
 
34723
34878
  // src/lib/host/publish-static-site.ts
34724
34879
  init_esm_shims();
@@ -34728,8 +34883,8 @@ import { readFile as readFile2 } from "fs/promises";
34728
34883
  init_esm_shims();
34729
34884
  import { createHash } from "crypto";
34730
34885
  import { readdir, readFile, stat } from "fs/promises";
34731
- import { extname as extname3, relative, resolve, sep, dirname, posix } from "path";
34732
- var MIME_BY_EXTENSION3 = {
34886
+ import { extname as extname4, relative, resolve, sep, dirname, posix } from "path";
34887
+ var MIME_BY_EXTENSION4 = {
34733
34888
  ".html": "text/html; charset=utf-8",
34734
34889
  ".htm": "text/html; charset=utf-8",
34735
34890
  ".css": "text/css; charset=utf-8",
@@ -34762,8 +34917,8 @@ var HTML_REFERENCE_RE = /<(?:script|link|img|source|video|audio|embed|object)\b[
34762
34917
  var SRCSET_RE = /\s(?:srcset)=["']([^"']+)["']/giu;
34763
34918
  var CSS_URL_RE = /url\(\s*["']?([^"')]+)["']?\s*\)/giu;
34764
34919
  var CSS_IMPORT_RE = /@import\s+(?:url\()?["']([^"']+)["']\)?/giu;
34765
- function inferContentType3(path) {
34766
- 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";
34767
34922
  }
34768
34923
  function looksImmutable(path) {
34769
34924
  if (path.startsWith("/assets/")) {
@@ -34813,7 +34968,7 @@ function normalizeReference(fromPath, raw) {
34813
34968
  return path;
34814
34969
  }
34815
34970
  function shouldRequireHtmlReference(path) {
34816
- return extname3(path).length > 0 || path.startsWith("/assets/");
34971
+ return extname4(path).length > 0 || path.startsWith("/assets/");
34817
34972
  }
34818
34973
  function isHtmlExtension(ext) {
34819
34974
  return ext === ".html" || ext === ".htm";
@@ -34875,7 +35030,7 @@ async function walk(root, dir, files) {
34875
35030
  path,
34876
35031
  size: fileStat.size,
34877
35032
  sha256: await hashFile(fullPath),
34878
- contentType: inferContentType3(path),
35033
+ contentType: inferContentType4(path),
34879
35034
  immutable: looksImmutable(path) || void 0
34880
35035
  });
34881
35036
  }
@@ -34887,7 +35042,7 @@ async function assertReferencesExist(files) {
34887
35042
  })
34888
35043
  );
34889
35044
  for (const file of files) {
34890
- const ext = extname3(file.path).toLowerCase();
35045
+ const ext = extname4(file.path).toLowerCase();
34891
35046
  if (!shouldValidateReferences(ext)) {
34892
35047
  continue;
34893
35048
  }
@@ -34993,7 +35148,7 @@ init_esm_shims();
34993
35148
  var import_react = __toESM(require_react(), 1);
34994
35149
  var import_server = __toESM(require_server_node(), 1);
34995
35150
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
34996
- import { join as join6 } from "path";
35151
+ import { join as join7 } from "path";
34997
35152
  function h(type, props, ...children) {
34998
35153
  return import_react.default.createElement(type, props, ...children);
34999
35154
  }
@@ -35732,7 +35887,7 @@ h1 {
35732
35887
  }
35733
35888
  `;
35734
35889
  async function buildGeneratedWebsite(options) {
35735
- const assetsDir = join6(options.outDir, "assets");
35890
+ const assetsDir = join7(options.outDir, "assets");
35736
35891
  await mkdir2(assetsDir, { recursive: true });
35737
35892
  const markup = (0, import_server.renderToStaticMarkup)(
35738
35893
  import_react.default.createElement(WebsiteDocument, {
@@ -35742,10 +35897,10 @@ async function buildGeneratedWebsite(options) {
35742
35897
  })
35743
35898
  );
35744
35899
  await writeFile2(
35745
- join6(options.outDir, "index.html"),
35900
+ join7(options.outDir, "index.html"),
35746
35901
  `<!doctype html>${markup}`
35747
35902
  );
35748
- await writeFile2(join6(assetsDir, "styles.css"), WEBSITE_CSS.trimStart());
35903
+ await writeFile2(join7(assetsDir, "styles.css"), WEBSITE_CSS.trimStart());
35749
35904
  }
35750
35905
 
35751
35906
  // src/commands/zero/built-in/generate/website.ts
@@ -35776,7 +35931,7 @@ function readPrompt4(options) {
35776
35931
  return options.prompt.trim();
35777
35932
  }
35778
35933
  if (process.stdin.isTTY === false) {
35779
- const prompt = readFileSync15("/dev/stdin", "utf8").trim();
35934
+ const prompt = readFileSync16("/dev/stdin", "utf8").trim();
35780
35935
  if (prompt.length > 0) {
35781
35936
  return prompt;
35782
35937
  }
@@ -35835,8 +35990,8 @@ Notes:
35835
35990
  title: options.title,
35836
35991
  audience: options.audience
35837
35992
  });
35838
- const buildRoot = await mkdtemp(join7(tmpdir4(), "zero-website-"));
35839
- const outDir = join7(buildRoot, "dist");
35993
+ const buildRoot = await mkdtemp(join8(tmpdir5(), "zero-website-"));
35994
+ const outDir = join8(buildRoot, "dist");
35840
35995
  try {
35841
35996
  if (!options.json) {
35842
35997
  console.log(source_default.dim("Building React template..."));
@@ -35921,13 +36076,13 @@ init_esm_shims();
35921
36076
 
35922
36077
  // src/commands/zero/shared/voice-generate.ts
35923
36078
  init_esm_shims();
35924
- import { readFileSync as readFileSync16 } from "fs";
36079
+ import { readFileSync as readFileSync17 } from "fs";
35925
36080
  function readText(options, usageCommand) {
35926
36081
  if (options.text?.trim()) {
35927
36082
  return options.text.trim();
35928
36083
  }
35929
36084
  if (process.stdin.isTTY === false) {
35930
- const text = readFileSync16("/dev/stdin", "utf8").trim();
36085
+ const text = readFileSync17("/dev/stdin", "utf8").trim();
35931
36086
  if (text.length > 0) {
35932
36087
  return text;
35933
36088
  }
@@ -36023,12 +36178,12 @@ init_esm_shims();
36023
36178
 
36024
36179
  // src/commands/zero/web/download-file.ts
36025
36180
  init_esm_shims();
36026
- import { basename as basename7, join as join8 } from "path";
36027
- import { tmpdir as tmpdir5 } from "os";
36028
- function defaultOutPath4(fileId) {
36029
- 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)}`);
36030
36185
  }
36031
- 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(
36032
36187
  "-o, --out <path>",
36033
36188
  "Output path for the downloaded file (default: /tmp/web-<file-id>)"
36034
36189
  ).addHelpText(
@@ -36054,7 +36209,7 @@ Notes:
36054
36209
  - Streams the file bytes directly to disk`
36055
36210
  ).action(
36056
36211
  withErrorHandler(async (fileId, options) => {
36057
- const outPath = options.out ?? defaultOutPath4(fileId);
36212
+ const outPath = options.out ?? defaultOutPath5(fileId);
36058
36213
  const result = await downloadWebFile(fileId, outPath);
36059
36214
  console.log(JSON.stringify(result));
36060
36215
  })
@@ -36062,7 +36217,7 @@ Notes:
36062
36217
 
36063
36218
  // src/commands/zero/web/upload-file.ts
36064
36219
  init_esm_shims();
36065
- 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(
36066
36221
  "after",
36067
36222
  `
36068
36223
  Examples:
@@ -36096,7 +36251,7 @@ Notes:
36096
36251
  );
36097
36252
 
36098
36253
  // src/commands/zero/web/index.ts
36099
- 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(
36100
36255
  "after",
36101
36256
  `
36102
36257
  Examples:
@@ -36137,7 +36292,7 @@ function parsePositiveInteger3(value, label) {
36137
36292
  }
36138
36293
  return parsed;
36139
36294
  }
36140
- function parseLimit5(value) {
36295
+ function parseLimit4(value) {
36141
36296
  if (value === void 0) {
36142
36297
  return 50;
36143
36298
  }
@@ -36257,7 +36412,7 @@ function formatHost(host) {
36257
36412
  ` capabilities: ${formatCapabilities(host.supportedCapabilities)}`
36258
36413
  ].join("\n");
36259
36414
  }
36260
- function formatAuditEvent2(event) {
36415
+ function formatAuditEvent(event) {
36261
36416
  const parts = [
36262
36417
  event.createdAt,
36263
36418
  event.event,
@@ -36284,7 +36439,7 @@ function formatAuditEvent2(event) {
36284
36439
  }
36285
36440
  return parts.join(" ");
36286
36441
  }
36287
- 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(
36288
36443
  new Command().name("list").description("List linked local-browser hosts").option("--json", "Output hosts as JSON").action(
36289
36444
  withErrorHandler(async (options) => {
36290
36445
  const result = await listLocalBrowserHosts();
@@ -36312,11 +36467,11 @@ var hostsCommand2 = new Command().name("hosts").description("List and revoke lin
36312
36467
  })
36313
36468
  )
36314
36469
  );
36315
- 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(
36316
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(
36317
36472
  withErrorHandler(async (options) => {
36318
36473
  const result = await listLocalBrowserAuditEvents({
36319
- limit: parseLimit5(options.limit),
36474
+ limit: parseLimit4(options.limit),
36320
36475
  ...options.commandId ? { commandId: options.commandId } : {},
36321
36476
  ...options.hostId ? { hostId: options.hostId } : {},
36322
36477
  ...options.runId ? { runId: options.runId } : {}
@@ -36329,7 +36484,7 @@ var auditCommand2 = new Command().name("audit").description("Inspect local-brows
36329
36484
  console.log(source_default.dim("No local-browser audit events found."));
36330
36485
  return;
36331
36486
  }
36332
- console.log(result.auditEvents.map(formatAuditEvent2).join("\n"));
36487
+ console.log(result.auditEvents.map(formatAuditEvent).join("\n"));
36333
36488
  })
36334
36489
  )
36335
36490
  );
@@ -36423,7 +36578,7 @@ Examples:
36423
36578
  Click page? zero local-browser page click --selector button
36424
36579
  Open tab? zero local-browser tabs open --url https://example.com
36425
36580
  Audit actions? zero local-browser audit list`
36426
- ).addCommand(hostsCommand2).addCommand(auditCommand2).addCommand(tabsCommand).addCommand(pageCommand);
36581
+ ).addCommand(hostsCommand).addCommand(auditCommand).addCommand(tabsCommand).addCommand(pageCommand);
36427
36582
 
36428
36583
  // src/commands/zero/host/index.ts
36429
36584
  init_esm_shims();
@@ -36499,7 +36654,7 @@ function parsePositiveInteger4(value) {
36499
36654
  }
36500
36655
  return parsed;
36501
36656
  }
36502
- function parseLimit6(value) {
36657
+ function parseLimit5(value) {
36503
36658
  const limit = parsePositiveInteger4(value);
36504
36659
  if (limit > 20) {
36505
36660
  throw new InvalidArgumentError("limit must be between 1 and 20");
@@ -36600,7 +36755,7 @@ var placesSearchCommand = new Command().name("search").description("Search for p
36600
36755
  ).option(
36601
36756
  "--limit <n>",
36602
36757
  "Maximum places to return, from 1 to 20",
36603
- parseLimit6,
36758
+ parseLimit5,
36604
36759
  5
36605
36760
  ).option("--region <code>", "Optional region bias, such as US or CN").option("--json", "Print the raw maps response as JSON").action(
36606
36761
  withErrorHandler(async (options) => {
@@ -36797,6 +36952,7 @@ var COMMAND_CAPABILITY_MAP = {
36797
36952
  logs: "agent-run:read",
36798
36953
  search: "chat-message:read",
36799
36954
  chat: "chat-message:write",
36955
+ github: ["github:read", "github:write"],
36800
36956
  slack: "slack:write",
36801
36957
  telegram: ["telegram:read", "telegram:write"],
36802
36958
  phone: ["phone:read", "phone:write"],
@@ -36822,6 +36978,7 @@ var DEFAULT_COMMANDS = [
36822
36978
  zeroScheduleCommand,
36823
36979
  zeroSecretCommand,
36824
36980
  zeroChatCommand,
36981
+ zeroGithubCommand,
36825
36982
  zeroSlackCommand,
36826
36983
  zeroTelegramCommand,
36827
36984
  zeroPhoneCommand,
@@ -36858,6 +37015,8 @@ function buildZeroHelpText(payload = decodeZeroTokenPayload()) {
36858
37015
  const examples = [
36859
37016
  " Check a connector? zero doctor check-connector --env-name <ENV_NAME>",
36860
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",
36861
37020
  " List Telegram bots? zero telegram bot list",
36862
37021
  " Send Telegram? zero telegram message send --help",
36863
37022
  " Upload Telegram? zero telegram upload-file --help",
@@ -36895,7 +37054,7 @@ function registerZeroCommands(prog, commands) {
36895
37054
  var program = new Command();
36896
37055
  program.name("zero").description(
36897
37056
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
36898
- ).version("9.160.7").addHelpText("after", () => {
37057
+ ).version("9.160.9").addHelpText("after", () => {
36899
37058
  return buildZeroHelpText();
36900
37059
  });
36901
37060
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {