@vm0/cli 9.142.1 → 9.144.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.142.1",
3
+ "version": "9.144.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -35,6 +35,7 @@ import {
35
35
  enableZeroSchedule,
36
36
  extractSecretNamesFromApis,
37
37
  findMatchingPermissions,
38
+ generateWebImage,
38
39
  generateWebVoice,
39
40
  getActiveOrg,
40
41
  getApiUrl,
@@ -127,7 +128,7 @@ import {
127
128
  upsertZeroOrgModelProvider,
128
129
  withErrorHandler,
129
130
  zeroAgentCustomSkillNameSchema
130
- } from "./chunk-MB6EHK2G.js";
131
+ } from "./chunk-75VR4R5J.js";
131
132
  import {
132
133
  __toESM,
133
134
  init_esm_shims
@@ -2725,10 +2726,19 @@ How connectors work:
2725
2726
 
2726
2727
  // src/commands/zero/doctor/generate.ts
2727
2728
  init_esm_shims();
2729
+ var BUILT_IN_GENERATION_OPTIONS = {
2730
+ image: {
2731
+ description: "If the user did not explicitly request a specific connector or provider, you can use the official generation capability. Run `zero official generate image -h` for options."
2732
+ },
2733
+ voice: {
2734
+ description: "If the user did not explicitly request a specific connector or provider, you can use the official generation capability. Run `zero official generate voice -h` for options."
2735
+ }
2736
+ };
2728
2737
  var GENERATION_TYPE_ORDER = [
2729
2738
  "image",
2730
2739
  "video",
2731
2740
  "audio",
2741
+ "voice",
2732
2742
  "text",
2733
2743
  "code",
2734
2744
  "document",
@@ -2743,8 +2753,15 @@ var GENERATION_TYPE_LABELS = {
2743
2753
  presentation: "Presentation",
2744
2754
  text: "Text",
2745
2755
  video: "Video",
2756
+ voice: "Voice",
2746
2757
  website: "Website"
2747
2758
  };
2759
+ function getConnectorGenerationType(generationType) {
2760
+ if (generationType === "voice") {
2761
+ return "audio";
2762
+ }
2763
+ return generationType;
2764
+ }
2748
2765
  function getAvailableGenerationTypes() {
2749
2766
  const available = /* @__PURE__ */ new Set();
2750
2767
  for (const config of Object.values(CONNECTOR_TYPES)) {
@@ -2753,7 +2770,7 @@ function getAvailableGenerationTypes() {
2753
2770
  }
2754
2771
  }
2755
2772
  return GENERATION_TYPE_ORDER.filter((type) => {
2756
- return available.has(type);
2773
+ return type in BUILT_IN_GENERATION_OPTIONS || available.has(getConnectorGenerationType(type));
2757
2774
  });
2758
2775
  }
2759
2776
  function parseGenerationType(value) {
@@ -2874,6 +2891,13 @@ function renderActions(candidates) {
2874
2891
  console.log(` [${candidate.actionLabel}](${candidate.actionUrl})`);
2875
2892
  }
2876
2893
  }
2894
+ function renderBuiltInOption(generationType) {
2895
+ const option = BUILT_IN_GENERATION_OPTIONS[generationType];
2896
+ if (!option) return;
2897
+ console.log("");
2898
+ console.log("Fallback option:");
2899
+ console.log(` ${option.description}`);
2900
+ }
2877
2901
  function renderText(params) {
2878
2902
  const { generationType, agentId, ready, other, showAll } = params;
2879
2903
  const label = GENERATION_TYPE_LABELS[generationType];
@@ -2894,6 +2918,7 @@ function renderText(params) {
2894
2918
  } else {
2895
2919
  console.log(`No ready ${generationType} generation connectors found.`);
2896
2920
  }
2921
+ renderBuiltInOption(generationType);
2897
2922
  if (showAll && other.length > 0) {
2898
2923
  console.log("");
2899
2924
  console.log(`Other ${generationType} generation connectors`);
@@ -2910,6 +2935,7 @@ var generateCommand = new Command().name("generate").description("Show generatio
2910
2935
  ).option("--all", "Also show unavailable or not-yet-authorized connectors").option("--json", "Output machine-readable JSON").action(
2911
2936
  withErrorHandler(async (type, options) => {
2912
2937
  const generationType = parseGenerationType(type);
2938
+ const connectorGenerationType = getConnectorGenerationType(generationType);
2913
2939
  const agentId = process.env.ZERO_AGENT_ID;
2914
2940
  const [connectorList, enabledTypes, platformOrigin] = await Promise.all([
2915
2941
  listZeroConnectors(),
@@ -2923,7 +2949,7 @@ var generateCommand = new Command().name("generate").description("Show generatio
2923
2949
  );
2924
2950
  const configuredTypes = new Set(connectorList.configuredTypes);
2925
2951
  const authorizedTypes = enabledTypes ? new Set(enabledTypes) : null;
2926
- const candidates = getGenerationConnectors(generationType).map(
2952
+ const candidates = getGenerationConnectors(connectorGenerationType).map(
2927
2953
  ([connectorType, config]) => {
2928
2954
  return toCandidate({
2929
2955
  type: connectorType,
@@ -2947,10 +2973,12 @@ var generateCommand = new Command().name("generate").description("Show generatio
2947
2973
  JSON.stringify(
2948
2974
  {
2949
2975
  generationType,
2976
+ connectorGenerationType,
2950
2977
  availableTypes: getAvailableGenerationTypes(),
2951
2978
  agentId: agentId ?? null,
2952
2979
  choices: ready,
2953
- otherCandidates: other
2980
+ otherCandidates: other,
2981
+ builtInOption: BUILT_IN_GENERATION_OPTIONS[generationType] ?? null
2954
2982
  },
2955
2983
  null,
2956
2984
  2
@@ -5568,7 +5596,7 @@ Examples:
5568
5596
  const limit = options.limit ? parseInt(options.limit, 10) : void 0;
5569
5597
  const since = options.since ? parseTime(options.since) : void 0;
5570
5598
  const result = await listZeroLogs({
5571
- agent: options.agent,
5599
+ agentId: options.agent,
5572
5600
  status: options.status,
5573
5601
  since,
5574
5602
  limit
@@ -5714,7 +5742,7 @@ async function runLogsSearch(keyword, options) {
5714
5742
  const limit = parseLimit2(options.limit);
5715
5743
  const response = await searchZeroLogs({
5716
5744
  keyword,
5717
- agent: options.agent,
5745
+ agentId: options.agentId,
5718
5746
  runId: options.run,
5719
5747
  since,
5720
5748
  limit,
@@ -5740,9 +5768,12 @@ Examples:
5740
5768
  zero logs search "timeout" --agent 123e4567-e89b-12d3-a456-426614174000 -C 2
5741
5769
  zero logs search "failed" --since 30d --limit 50`
5742
5770
  ).action(
5743
- withErrorHandler(async (keyword, options) => {
5744
- await runLogsSearch(keyword, options);
5745
- })
5771
+ withErrorHandler(
5772
+ async (keyword, options) => {
5773
+ const { agent, ...searchOptions } = options;
5774
+ await runLogsSearch(keyword, { ...searchOptions, agentId: agent });
5775
+ }
5776
+ )
5746
5777
  );
5747
5778
 
5748
5779
  // src/commands/zero/logs/index.ts
@@ -5920,7 +5951,7 @@ async function runLogsSource(query, options) {
5920
5951
  afterContext: options.afterContext,
5921
5952
  beforeContext: options.beforeContext,
5922
5953
  context: options.context,
5923
- agent: options.agent,
5954
+ agentId: options.agent,
5924
5955
  run: options.run,
5925
5956
  since: options.since,
5926
5957
  limit: options.limit
@@ -5972,7 +6003,7 @@ async function runChatSource(query, options) {
5972
6003
  const since = options.since ? parseTime(options.since) : Date.now() - SEVEN_DAYS_MS2;
5973
6004
  const response = await searchZeroChat({
5974
6005
  keyword: query,
5975
- agent: options.agent,
6006
+ agentId: options.agent,
5976
6007
  since,
5977
6008
  limit,
5978
6009
  before,
@@ -5997,7 +6028,7 @@ var zeroSearchCommand = new Command().name("search").description("Search logs, c
5997
6028
  "Source to search: logs | chat | slack (pass once)",
5998
6029
  collectSource,
5999
6030
  []
6000
- ).option("--agent <agent>", "Filter by agent (logs use ID; chat uses name)").option("--run <id>", "Filter by run ID").option("--since <time>", "Time window (e.g., 7d, 2h)").option("--limit <n>", "Maximum number of matches").option("-A, --after-context <n>", "Show n items after each match").option("-B, --before-context <n>", "Show n items before each match").option("-C, --context <n>", "Show n items before and after each match").addHelpText("after", SEARCH_EXPLAINER).action(
6031
+ ).option("--agent <id>", "Filter by Zero agent ID").option("--run <id>", "Filter by run ID").option("--since <time>", "Time window (e.g., 7d, 2h)").option("--limit <n>", "Maximum number of matches").option("-A, --after-context <n>", "Show n items after each match").option("-B, --before-context <n>", "Show n items before each match").option("-C, --context <n>", "Show n items before and after each match").addHelpText("after", SEARCH_EXPLAINER).action(
6001
6032
  withErrorHandler(async (query, options) => {
6002
6033
  const sources = options.source;
6003
6034
  if (sources.length === 0) {
@@ -7100,6 +7131,175 @@ Examples:
7100
7131
  );
7101
7132
  var zeroComputerUseCommand = new Command().name("computer-use").description("Remote desktop control for cloud agents").addCommand(hostCommand).addCommand(clientCommand);
7102
7133
 
7134
+ // src/commands/zero/official/index.ts
7135
+ init_esm_shims();
7136
+
7137
+ // src/commands/zero/official/generate/index.ts
7138
+ init_esm_shims();
7139
+
7140
+ // src/commands/zero/official/generate/image.ts
7141
+ init_esm_shims();
7142
+
7143
+ // src/commands/zero/shared/image-generate.ts
7144
+ init_esm_shims();
7145
+ import { readFileSync as readFileSync10 } from "fs";
7146
+ function readPrompt(options, usageCommand) {
7147
+ if (options.prompt?.trim()) {
7148
+ return options.prompt.trim();
7149
+ }
7150
+ if (process.stdin.isTTY === false) {
7151
+ const prompt = readFileSync10("/dev/stdin", "utf8").trim();
7152
+ if (prompt.length > 0) {
7153
+ return prompt;
7154
+ }
7155
+ }
7156
+ throw new Error("--prompt is required", {
7157
+ cause: new Error(`Usage: ${usageCommand} --prompt "A watercolor fox"`)
7158
+ });
7159
+ }
7160
+ function createImageGenerateCommand(config) {
7161
+ return new Command().name(config.name).description("Generate a billed image file from a prompt").option("--prompt <text>", "Image prompt; can also be piped via stdin").option(
7162
+ "--size <size>",
7163
+ "Image size: 1024x1024, 1024x1536, or 1536x1024",
7164
+ "1024x1024"
7165
+ ).option(
7166
+ "--quality <quality>",
7167
+ "Image quality: low, medium, high, or auto",
7168
+ "medium"
7169
+ ).option(
7170
+ "--background <background>",
7171
+ "Background: auto, opaque, or transparent",
7172
+ "auto"
7173
+ ).option("--format <format>", "Output format: png, webp, or jpeg", "png").option("--json", "Print metadata as JSON").addHelpText(
7174
+ "after",
7175
+ `
7176
+ Examples:
7177
+ ${config.examples}
7178
+
7179
+ Output:
7180
+ Prints the generated /f/ image file URL and metadata
7181
+
7182
+ Notes:
7183
+ - Authenticates via ZERO_TOKEN (requires file:write capability)
7184
+ - Charges org credits after successful image generation
7185
+ - Uses OpenAI gpt-image-2 and bills returned usage tokens`
7186
+ ).action(
7187
+ withErrorHandler(async (options) => {
7188
+ const prompt = readPrompt(options, config.usageCommand);
7189
+ const result = await generateWebImage({
7190
+ prompt,
7191
+ size: options.size,
7192
+ quality: options.quality,
7193
+ background: options.background,
7194
+ outputFormat: options.format
7195
+ });
7196
+ if (options.json) {
7197
+ console.log(JSON.stringify(result));
7198
+ return;
7199
+ }
7200
+ console.log(source_default.green(`\u2713 Image generated: ${result.url}`));
7201
+ console.log(source_default.dim(` File: ${result.filename}`));
7202
+ console.log(source_default.dim(` Size: ${result.imageSize}`));
7203
+ console.log(source_default.dim(` Quality: ${result.quality}`));
7204
+ console.log(source_default.dim(` Format: ${result.outputFormat}`));
7205
+ console.log(source_default.dim(` Credits charged: ${result.creditsCharged}`));
7206
+ console.log(source_default.dim(` Model: ${result.model}`));
7207
+ })
7208
+ );
7209
+ }
7210
+
7211
+ // src/commands/zero/official/generate/image.ts
7212
+ var imageCommand = createImageGenerateCommand({
7213
+ name: "image",
7214
+ usageCommand: "zero official generate image",
7215
+ examples: ` Generate image: zero official generate image --prompt "A watercolor fox"
7216
+ Pipe prompt: cat prompt.txt | zero official generate image
7217
+ Pick size/quality: zero official generate image --prompt "A poster" --size 1024x1536 --quality high`
7218
+ });
7219
+
7220
+ // src/commands/zero/official/generate/voice.ts
7221
+ init_esm_shims();
7222
+
7223
+ // src/commands/zero/shared/voice-generate.ts
7224
+ init_esm_shims();
7225
+ import { readFileSync as readFileSync11 } from "fs";
7226
+ function readText(options, usageCommand) {
7227
+ if (options.text?.trim()) {
7228
+ return options.text.trim();
7229
+ }
7230
+ if (process.stdin.isTTY === false) {
7231
+ const text = readFileSync11("/dev/stdin", "utf8").trim();
7232
+ if (text.length > 0) {
7233
+ return text;
7234
+ }
7235
+ }
7236
+ throw new Error("--text is required", {
7237
+ cause: new Error(`Usage: ${usageCommand} --text "Hello"`)
7238
+ });
7239
+ }
7240
+ function createVoiceGenerateCommand(config) {
7241
+ return new Command().name(config.name).description("Generate a billed speech audio file from text").option("--text <text>", "Text to speak; can also be piped via stdin").option("--voice <voice>", "OpenAI voice to use", "marin").option("--instructions <text>", "Voice style instructions").option("--json", "Print metadata as JSON").addHelpText(
7242
+ "after",
7243
+ `
7244
+ Examples:
7245
+ ${config.examples}
7246
+
7247
+ Output:
7248
+ Prints the generated /f/ audio file URL and metadata
7249
+
7250
+ Notes:
7251
+ - Authenticates via ZERO_TOKEN (requires file:write capability)
7252
+ - Charges org credits after successful audio generation
7253
+ - Uses gpt-4o-mini-tts with WAV output`
7254
+ ).action(
7255
+ withErrorHandler(async (options) => {
7256
+ const text = readText(options, config.usageCommand);
7257
+ const result = await generateWebVoice({
7258
+ text,
7259
+ voice: options.voice,
7260
+ instructions: options.instructions
7261
+ });
7262
+ if (options.json) {
7263
+ console.log(JSON.stringify(result));
7264
+ return;
7265
+ }
7266
+ console.log(source_default.green(`\u2713 Voice generated: ${result.url}`));
7267
+ console.log(source_default.dim(` File: ${result.filename}`));
7268
+ console.log(source_default.dim(` Duration: ${result.durationSeconds}s`));
7269
+ console.log(source_default.dim(` Credits charged: ${result.creditsCharged}`));
7270
+ console.log(source_default.dim(` Model: ${result.model}`));
7271
+ console.log(source_default.dim(` Voice: ${result.voice}`));
7272
+ })
7273
+ );
7274
+ }
7275
+
7276
+ // src/commands/zero/official/generate/voice.ts
7277
+ var voiceCommand = createVoiceGenerateCommand({
7278
+ name: "voice",
7279
+ usageCommand: "zero official generate voice",
7280
+ examples: ` Generate speech: zero official generate voice --text "Hello from vm0"
7281
+ Pipe text: cat script.txt | zero official generate voice
7282
+ Pick a voice: zero official generate voice --text "Ship it" --voice cedar`
7283
+ });
7284
+
7285
+ // src/commands/zero/official/generate/index.ts
7286
+ var generateCommand2 = new Command().name("generate").description("Generate assets with official Zero services").addCommand(imageCommand).addCommand(voiceCommand).addHelpText(
7287
+ "after",
7288
+ `
7289
+ Examples:
7290
+ Generate image: zero official generate image --prompt "A watercolor fox"
7291
+ Generate speech: zero official generate voice --text "Hello"`
7292
+ );
7293
+
7294
+ // src/commands/zero/official/index.ts
7295
+ var zeroOfficialCommand = new Command().name("official").description("Use official Zero services").addCommand(generateCommand2).addHelpText(
7296
+ "after",
7297
+ `
7298
+ Examples:
7299
+ Generate image: zero official generate image --prompt "A watercolor fox"
7300
+ Generate speech: zero official generate voice --text "Hello"`
7301
+ );
7302
+
7103
7303
  // src/commands/zero/web/index.ts
7104
7304
  init_esm_shims();
7105
7305
 
@@ -7177,67 +7377,13 @@ Notes:
7177
7377
  )
7178
7378
  );
7179
7379
 
7180
- // src/commands/zero/web/voice.ts
7181
- init_esm_shims();
7182
- import { readFileSync as readFileSync10 } from "fs";
7183
- function readText(options) {
7184
- if (options.text?.trim()) {
7185
- return options.text.trim();
7186
- }
7187
- if (process.stdin.isTTY === false) {
7188
- const text = readFileSync10("/dev/stdin", "utf8").trim();
7189
- if (text.length > 0) {
7190
- return text;
7191
- }
7192
- }
7193
- throw new Error("--text is required", {
7194
- cause: new Error('Usage: zero web voice --text "Hello"')
7195
- });
7196
- }
7197
- var voiceCommand = new Command().name("voice").description("Generate a billed speech audio file from text").option("--text <text>", "Text to speak; can also be piped via stdin").option("--voice <voice>", "OpenAI voice to use", "marin").option("--instructions <text>", "Voice style instructions").option("--json", "Print metadata as JSON").addHelpText(
7198
- "after",
7199
- `
7200
- Examples:
7201
- Generate speech: zero web voice --text "Hello from vm0"
7202
- Pipe text: cat script.txt | zero web voice
7203
- Pick a voice: zero web voice --text "Ship it" --voice cedar
7204
-
7205
- Output:
7206
- Prints the generated /f/ audio file URL and metadata
7207
-
7208
- Notes:
7209
- - Authenticates via ZERO_TOKEN (requires file:write capability)
7210
- - Charges org credits after successful audio generation
7211
- - Uses gpt-4o-mini-tts with WAV output`
7212
- ).action(
7213
- withErrorHandler(async (options) => {
7214
- const text = readText(options);
7215
- const result = await generateWebVoice({
7216
- text,
7217
- voice: options.voice,
7218
- instructions: options.instructions
7219
- });
7220
- if (options.json) {
7221
- console.log(JSON.stringify(result));
7222
- return;
7223
- }
7224
- console.log(source_default.green(`\u2713 Voice generated: ${result.url}`));
7225
- console.log(source_default.dim(` File: ${result.filename}`));
7226
- console.log(source_default.dim(` Duration: ${result.durationSeconds}s`));
7227
- console.log(source_default.dim(` Credits charged: ${result.creditsCharged}`));
7228
- console.log(source_default.dim(` Model: ${result.model}`));
7229
- console.log(source_default.dim(` Voice: ${result.voice}`));
7230
- })
7231
- );
7232
-
7233
7380
  // src/commands/zero/web/index.ts
7234
- var zeroWebCommand = new Command().name("web").description("Upload, download, and generate files via the web chat endpoint").addCommand(downloadFileCommand3).addCommand(voiceCommand).addCommand(uploadFileCommand3).addHelpText(
7381
+ var zeroWebCommand = new Command().name("web").description("Upload and download files via the web chat endpoint").addCommand(downloadFileCommand3).addCommand(uploadFileCommand3).addHelpText(
7235
7382
  "after",
7236
7383
  `
7237
7384
  Examples:
7238
7385
  Upload a file: zero web upload-file -f /tmp/report.pdf
7239
- Download a file: zero web download-file <file-id> -o /tmp/out.pdf
7240
- Generate speech: zero web voice --text "Hello"`
7386
+ Download a file: zero web download-file <file-id> -o /tmp/out.pdf`
7241
7387
  );
7242
7388
 
7243
7389
  // src/zero.ts
@@ -7256,6 +7402,7 @@ var COMMAND_CAPABILITY_MAP = {
7256
7402
  whoami: null,
7257
7403
  "developer-support": null,
7258
7404
  "computer-use": "computer-use:write",
7405
+ official: "file:write",
7259
7406
  web: null
7260
7407
  };
7261
7408
  var DEFAULT_COMMANDS = [
@@ -7277,6 +7424,7 @@ var DEFAULT_COMMANDS = [
7277
7424
  zeroSkillCommand,
7278
7425
  zeroDeveloperSupportCommand,
7279
7426
  zeroComputerUseCommand,
7427
+ zeroOfficialCommand,
7280
7428
  zeroWebCommand
7281
7429
  ];
7282
7430
  function shouldHideCommand(name, payload) {
@@ -7302,7 +7450,7 @@ function registerZeroCommands(prog, commands) {
7302
7450
  var program = new Command();
7303
7451
  program.name("zero").description(
7304
7452
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
7305
- ).version("9.142.1").addHelpText(
7453
+ ).version("9.144.0").addHelpText(
7306
7454
  "after",
7307
7455
  `
7308
7456
  Examples:
@@ -7315,6 +7463,8 @@ Examples:
7315
7463
  Set up a schedule? zero schedule setup --help
7316
7464
  Update yourself? zero agent --help
7317
7465
  Manage custom skills? zero skill --help
7466
+ Generate image? zero official generate image --help
7467
+ Generate voice? zero official generate voice --help
7318
7468
  Check your identity? zero whoami`
7319
7469
  );
7320
7470
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {