@vm0/cli 9.110.2 → 9.111.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -70,7 +70,7 @@ import {
70
70
  source_default,
71
71
  volumeConfigSchema,
72
72
  withErrorHandler
73
- } from "./chunk-W353Y7DH.js";
73
+ } from "./chunk-H56HRDOU.js";
74
74
 
75
75
  // src/index.ts
76
76
  init_esm_shims();
@@ -463,7 +463,7 @@ function getConfigPath() {
463
463
  return join(homedir(), ".vm0", "config.json");
464
464
  }
465
465
  var infoCommand = new Command().name("info").description("Display environment and debug information").action(async () => {
466
- console.log(source_default.bold(`VM0 CLI v${"9.110.2"}`));
466
+ console.log(source_default.bold(`VM0 CLI v${"9.111.1"}`));
467
467
  console.log();
468
468
  const config = await loadConfig();
469
469
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -4492,7 +4492,7 @@ var composeCommand = new Command().name("compose").description("Create or update
4492
4492
  options.autoUpdate = false;
4493
4493
  }
4494
4494
  if (options.autoUpdate !== false) {
4495
- await startSilentUpgrade("9.110.2");
4495
+ await startSilentUpgrade("9.111.1");
4496
4496
  }
4497
4497
  try {
4498
4498
  let result;
@@ -4572,7 +4572,7 @@ var mainRunCommand = new Command().name("run").description("Run an agent").argum
4572
4572
  withErrorHandler(
4573
4573
  async (identifier, prompt, options) => {
4574
4574
  if (options.autoUpdate !== false) {
4575
- await startSilentUpgrade("9.110.2");
4575
+ await startSilentUpgrade("9.111.1");
4576
4576
  }
4577
4577
  const { name, version } = parseIdentifier(identifier);
4578
4578
  let composeId;
@@ -6313,7 +6313,7 @@ var cookAction = new Command().name("cook").description("Quick start: prepare, c
6313
6313
  withErrorHandler(
6314
6314
  async (prompt, options) => {
6315
6315
  if (options.autoUpdate !== false) {
6316
- const shouldExit = await checkAndUpgrade("9.110.2", prompt);
6316
+ const shouldExit = await checkAndUpgrade("9.111.1", prompt);
6317
6317
  if (shouldExit) {
6318
6318
  process.exit(0);
6319
6319
  }
@@ -7080,13 +7080,13 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
7080
7080
  if (latestVersion === null) {
7081
7081
  throw new Error("Could not check for updates. Please try again later.");
7082
7082
  }
7083
- if (latestVersion === "9.110.2") {
7084
- console.log(source_default.green(`\u2713 Already up to date (${"9.110.2"})`));
7083
+ if (latestVersion === "9.111.1") {
7084
+ console.log(source_default.green(`\u2713 Already up to date (${"9.111.1"})`));
7085
7085
  return;
7086
7086
  }
7087
7087
  console.log(
7088
7088
  source_default.yellow(
7089
- `Current version: ${"9.110.2"} -> Latest version: ${latestVersion}`
7089
+ `Current version: ${"9.111.1"} -> Latest version: ${latestVersion}`
7090
7090
  )
7091
7091
  );
7092
7092
  console.log();
@@ -7113,7 +7113,7 @@ var upgradeCommand = new Command().name("upgrade").description("Upgrade vm0 CLI
7113
7113
  const success = await performUpgrade(packageManager);
7114
7114
  if (success) {
7115
7115
  console.log(
7116
- source_default.green(`\u2713 Upgraded from ${"9.110.2"} to ${latestVersion}`)
7116
+ source_default.green(`\u2713 Upgraded from ${"9.111.1"} to ${latestVersion}`)
7117
7117
  );
7118
7118
  return;
7119
7119
  }
@@ -7180,7 +7180,7 @@ var whoamiCommand = new Command().name("whoami").description("Show current ident
7180
7180
 
7181
7181
  // src/index.ts
7182
7182
  var program = new Command();
7183
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.110.2");
7183
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.111.1");
7184
7184
  program.addCommand(authCommand);
7185
7185
  program.addCommand(infoCommand);
7186
7186
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.110.2",
3
+ "version": "9.111.1",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -40,7 +40,6 @@ import {
40
40
  findMatchingPermissions,
41
41
  getActiveOrg,
42
42
  getApiUrl,
43
- getAskUserAnswer,
44
43
  getAuthMethodsForType,
45
44
  getBaseUrl,
46
45
  getComputerUseHost,
@@ -94,7 +93,6 @@ import {
94
93
  paginate,
95
94
  parseEvent,
96
95
  parseTime,
97
- postAskUserQuestion,
98
96
  promptConfirm,
99
97
  promptPassword,
100
98
  promptSelect,
@@ -128,7 +126,7 @@ import {
128
126
  upsertZeroOrgModelProvider,
129
127
  withErrorHandler,
130
128
  zeroAgentCustomSkillNameSchema
131
- } from "./chunk-W353Y7DH.js";
129
+ } from "./chunk-H56HRDOU.js";
132
130
 
133
131
  // src/zero.ts
134
132
  init_esm_shims();
@@ -1300,7 +1298,8 @@ function getConnectorPermissionInfo(type, resolvedPolicies) {
1300
1298
  total: 0
1301
1299
  };
1302
1300
  }
1303
- const policies = resolvedPolicies?.[type] ?? null;
1301
+ const rawPolicies = resolvedPolicies?.[type];
1302
+ const policies = rawPolicies && Object.keys(rawPolicies).length > 0 ? rawPolicies : null;
1304
1303
  const config = getConnectorFirewall(type);
1305
1304
  const permissions = config.apis.flatMap((a) => {
1306
1305
  return a.permissions ?? [];
@@ -3899,8 +3898,8 @@ function formatConnectorIdentity2(connector) {
3899
3898
  }
3900
3899
  function printConnectorPermissions(type, resolvedPolicies) {
3901
3900
  if (!isFirewallConnectorType(type)) return;
3902
- const policies = resolvedPolicies?.[type] ?? null;
3903
- if (!policies) {
3901
+ const policies = resolvedPolicies?.[type];
3902
+ if (!policies || Object.keys(policies).length === 0) {
3904
3903
  console.log(source_default.dim(" full access \u2014 no permission rules configured"));
3905
3904
  return;
3906
3905
  }
@@ -4018,115 +4017,6 @@ Notes:
4018
4017
  })
4019
4018
  );
4020
4019
 
4021
- // src/commands/zero/ask-user/index.ts
4022
- init_esm_shims();
4023
-
4024
- // src/commands/zero/ask-user/question.ts
4025
- init_esm_shims();
4026
- function collectOption(value, previous) {
4027
- const list = previous ?? [];
4028
- list.push({ label: value });
4029
- return list;
4030
- }
4031
- function collectDesc(value, previous) {
4032
- const list = previous ?? [];
4033
- list.push(value);
4034
- return list;
4035
- }
4036
- var questionCommand = new Command().name("question").description("Ask the user a question and wait for the answer").argument("<question>", "The question to ask").option("--header <text>", "Short label displayed as chip/tag (max 12 chars)").option("--option <label>", "Add a choice option (repeatable)", collectOption).option(
4037
- "--desc <text>",
4038
- "Description for the preceding --option",
4039
- collectDesc
4040
- ).option("--multi-select", "Allow multiple selections").option("--timeout <seconds>", "How long to wait for answer", "300").addHelpText(
4041
- "after",
4042
- `
4043
- Examples:
4044
- Yes/No confirmation:
4045
- zero ask-user question "Deploy to production?" --option "Yes" --option "No"
4046
-
4047
- Options with descriptions:
4048
- zero ask-user question "Pick a strategy" \\
4049
- --header "Strategy" \\
4050
- --option "Fast" --desc "Quick but risky" \\
4051
- --option "Safe" --desc "Slow but reliable"
4052
-
4053
- Multi-select:
4054
- zero ask-user question "Which services to restart?" \\
4055
- --multi-select \\
4056
- --option "API" --option "Worker" --option "Scheduler"
4057
-
4058
- Notes:
4059
- - At least one --option is required
4060
- - --desc must immediately follow its --option`
4061
- ).action(
4062
- withErrorHandler(
4063
- async (question, options) => {
4064
- const optionItems = options.option ?? [];
4065
- const descItems = options.desc ?? [];
4066
- for (let i = 0; i < descItems.length; i++) {
4067
- const opt = optionItems[i];
4068
- if (!opt) {
4069
- throw new Error("--desc must follow an --option flag");
4070
- }
4071
- opt.description = descItems[i];
4072
- }
4073
- if (optionItems.length === 0) {
4074
- throw new Error(
4075
- 'At least one --option is required. Example: zero ask-user question "Pick one" --option "Yes" --option "No"'
4076
- );
4077
- }
4078
- const timeoutMs = parseInt(options.timeout, 10) * 1e3;
4079
- if (isNaN(timeoutMs) || timeoutMs <= 0) {
4080
- throw new Error("--timeout must be a positive number of seconds");
4081
- }
4082
- const questionItem = {
4083
- question,
4084
- header: options.header,
4085
- options: optionItems,
4086
- multiSelect: options.multiSelect
4087
- };
4088
- const { pendingId } = await postAskUserQuestion({
4089
- questions: [questionItem]
4090
- });
4091
- console.error(
4092
- source_default.dim(
4093
- `\u23F3 Waiting for user response... (pendingId: ${pendingId})`
4094
- )
4095
- );
4096
- const deadline = Date.now() + timeoutMs;
4097
- const pollIntervalMs = 1e3;
4098
- while (Date.now() < deadline) {
4099
- const response = await getAskUserAnswer(pendingId);
4100
- if (response.status === "answered") {
4101
- console.log(response.answer ?? "");
4102
- return;
4103
- }
4104
- if (response.status === "expired") {
4105
- throw new Error("Question expired before user responded");
4106
- }
4107
- await new Promise((resolve) => {
4108
- return setTimeout(resolve, pollIntervalMs);
4109
- });
4110
- }
4111
- throw new Error(
4112
- `Timed out waiting for user response after ${options.timeout}s`
4113
- );
4114
- }
4115
- )
4116
- );
4117
-
4118
- // src/commands/zero/ask-user/index.ts
4119
- var zeroAskUserCommand = new Command().name("ask-user").description("Ask the user a question and wait for the answer").addCommand(questionCommand).addHelpText(
4120
- "after",
4121
- `
4122
- Examples:
4123
- zero ask-user question "Deploy to production?" --option "Yes" --option "No"
4124
-
4125
- Notes:
4126
- - The command blocks until the user responds or the timeout expires (default 300s)
4127
- - The user's answer is printed to stdout for your consumption`
4128
- );
4129
-
4130
4020
  // src/commands/zero/skill/index.ts
4131
4021
  init_esm_shims();
4132
4022
 
@@ -5762,12 +5652,58 @@ init_esm_shims();
5762
5652
  // src/commands/zero/phone/call.ts
5763
5653
  init_esm_shims();
5764
5654
  import * as fs from "fs";
5655
+
5656
+ // src/commands/zero/phone/format.ts
5657
+ init_esm_shims();
5658
+ function printTranscript(transcript) {
5659
+ if (!transcript || transcript.length === 0) {
5660
+ console.log(" (no transcript)");
5661
+ return;
5662
+ }
5663
+ for (const entry of transcript) {
5664
+ console.log(` ${source_default.dim(`[${entry.role}]`)} ${entry.text}`);
5665
+ }
5666
+ }
5667
+ function printCallInfo(call, callId) {
5668
+ console.log(` ${"Call ID:".padEnd(16)}${source_default.cyan(call.id ?? callId)}`);
5669
+ console.log(` ${"From:".padEnd(16)}${call.fromNumber}`);
5670
+ console.log(` ${"To:".padEnd(16)}${call.toNumber}`);
5671
+ console.log(` ${"Status:".padEnd(16)}${call.status}`);
5672
+ console.log(
5673
+ ` ${"Duration:".padEnd(16)}${call.durationSeconds != null ? `${call.durationSeconds}s` : "N/A"}`
5674
+ );
5675
+ console.log(` ${"Started:".padEnd(16)}${call.startedAt ?? ""}`);
5676
+ }
5677
+
5678
+ // src/commands/zero/phone/call.ts
5679
+ var POLL_INTERVAL_MS = 1e4;
5680
+ var POLL_TIMEOUT_MS = 15 * 60 * 1e3;
5681
+ var delay2 = {
5682
+ ms: (ms) => {
5683
+ return new Promise((resolve) => {
5684
+ setTimeout(resolve, ms);
5685
+ });
5686
+ }
5687
+ };
5688
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
5689
+ "completed",
5690
+ "ended",
5691
+ "failed",
5692
+ "no-answer",
5693
+ "busy",
5694
+ "cancelled"
5695
+ ]);
5765
5696
  function isErrnoException(err) {
5766
5697
  return err instanceof Error && "code" in err;
5767
5698
  }
5768
5699
  var callCommand = new Command().name("call").description("Initiate an outbound phone call").argument(
5769
5700
  "<to-number>",
5770
5701
  "Phone number to call (E.164 format, e.g. +14155551234)"
5702
+ ).addOption(
5703
+ new Option(
5704
+ "--mode <mode>",
5705
+ "onhold: wait for call to complete and return transcript. fire-and-forget: initiate and return immediately."
5706
+ ).choices(["onhold", "fire-and-forget"]).makeOptionMandatory()
5771
5707
  ).option(
5772
5708
  "--system-prompt-file <path>",
5773
5709
  "File that defines the agent's persona and task context for this call"
@@ -5803,48 +5739,43 @@ var callCommand = new Command().name("call").description("Initiate an outbound p
5803
5739
  console.log(source_default.green("Call initiated"));
5804
5740
  console.log(` ${"Call ID:".padEnd(12)}${source_default.cyan(result.callId)}`);
5805
5741
  console.log(` ${"Status:".padEnd(12)}${result.status}`);
5742
+ if (options.mode === "fire-and-forget") {
5743
+ return;
5744
+ }
5745
+ console.log();
5746
+ console.log(
5747
+ source_default.dim("Waiting for call to complete (polling every 10s)...")
5748
+ );
5749
+ const startTime = Date.now();
5750
+ while (Date.now() - startTime < POLL_TIMEOUT_MS) {
5751
+ await delay2.ms(POLL_INTERVAL_MS);
5752
+ const detail = await getPhoneCallDetail(result.callId);
5753
+ const status = detail.call.status;
5754
+ const elapsed = Math.round((Date.now() - startTime) / 1e3);
5755
+ if (TERMINAL_STATUSES.has(status)) {
5756
+ console.log();
5757
+ console.log(source_default.bold("Call Detail"));
5758
+ console.log();
5759
+ printCallInfo(detail.call, result.callId);
5760
+ console.log();
5761
+ console.log(source_default.bold("Transcript"));
5762
+ console.log();
5763
+ printTranscript(detail.transcript);
5764
+ if (status === "failed") {
5765
+ process.exit(1);
5766
+ }
5767
+ return;
5768
+ }
5769
+ console.log(source_default.dim(` [${elapsed}s] status: ${status}`));
5770
+ }
5771
+ console.error(source_default.red("\nCall timed out after 15 minutes"));
5772
+ process.exit(1);
5806
5773
  }
5807
5774
  )
5808
5775
  );
5809
5776
 
5810
5777
  // src/commands/zero/phone/record.ts
5811
5778
  init_esm_shims();
5812
- function printTranscript(transcript) {
5813
- if (Array.isArray(transcript)) {
5814
- for (const entry of transcript) {
5815
- if (typeof entry === "string") {
5816
- console.log(` ${entry}`);
5817
- } else if (typeof entry === "object" && entry !== null) {
5818
- const e = entry;
5819
- const role = e.role ?? e.speaker ?? "Unknown";
5820
- const text = e.text ?? e.content ?? e.body ?? "";
5821
- console.log(` ${source_default.dim(`[${role}]`)} ${text}`);
5822
- }
5823
- }
5824
- } else if (typeof transcript === "string") {
5825
- console.log(` ${transcript}`);
5826
- } else {
5827
- console.log(` ${JSON.stringify(transcript, null, 2)}`);
5828
- }
5829
- }
5830
- function printCallInfo(call, callId) {
5831
- console.log(
5832
- ` ${"Call ID:".padEnd(16)}${source_default.cyan(String(call.id ?? callId))}`
5833
- );
5834
- console.log(
5835
- ` ${"From:".padEnd(16)}${String(call.fromNumber ?? call.from_number ?? "")}`
5836
- );
5837
- console.log(
5838
- ` ${"To:".padEnd(16)}${String(call.toNumber ?? call.to_number ?? "")}`
5839
- );
5840
- console.log(` ${"Status:".padEnd(16)}${String(call.status ?? "")}`);
5841
- console.log(
5842
- ` ${"Duration:".padEnd(16)}${String(call.durationSeconds ?? call.duration_seconds ?? "N/A")}s`
5843
- );
5844
- console.log(
5845
- ` ${"Started:".padEnd(16)}${String(call.startedAt ?? call.started_at ?? "")}`
5846
- );
5847
- }
5848
5779
  async function showCallDetail(callId) {
5849
5780
  const result = await getPhoneCallDetail(callId);
5850
5781
  console.log(source_default.bold("Call Detail"));
@@ -5864,14 +5795,12 @@ async function showCallList(limit) {
5864
5795
  console.log(source_default.bold("Recent Calls"));
5865
5796
  console.log();
5866
5797
  for (const call of result.data) {
5867
- const id = String(call.id ?? "");
5868
- const from = String(call.fromNumber ?? call.from_number ?? "");
5869
- const to = String(call.toNumber ?? call.to_number ?? "");
5870
- const status = String(call.status ?? "");
5871
- const duration = call.durationSeconds ?? call.duration_seconds;
5872
- const snippet = String(
5873
- call.lastTranscriptSnippet ?? call.last_transcript_snippet ?? ""
5874
- );
5798
+ const id = call.id;
5799
+ const from = call.fromNumber;
5800
+ const to = call.toNumber;
5801
+ const status = call.status;
5802
+ const duration = call.durationSeconds;
5803
+ const snippet = call.lastTranscriptSnippet ?? "";
5875
5804
  console.log(` ${source_default.cyan(id)}`);
5876
5805
  console.log(
5877
5806
  ` ${from} \u2192 ${to} ${source_default.dim(status)}${duration != null ? ` ${duration}s` : ""}`
@@ -5976,7 +5905,6 @@ var COMMAND_CAPABILITY_MAP = {
5976
5905
  logs: "agent-run:read",
5977
5906
  slack: "slack:write",
5978
5907
  whoami: null,
5979
- "ask-user": null,
5980
5908
  "developer-support": null,
5981
5909
  "computer-use": "computer-use:write",
5982
5910
  phone: "phone:write",
@@ -5995,7 +5923,6 @@ var DEFAULT_COMMANDS = [
5995
5923
  zeroVariableCommand,
5996
5924
  zeroLogsCommand,
5997
5925
  zeroWhoamiCommand,
5998
- zeroAskUserCommand,
5999
5926
  zeroSkillCommand,
6000
5927
  zeroDeveloperSupportCommand,
6001
5928
  zeroComputerUseCommand,
@@ -6019,7 +5946,7 @@ function registerZeroCommands(prog, commands) {
6019
5946
  var program = new Command();
6020
5947
  program.name("zero").description(
6021
5948
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
6022
- ).version("9.110.2").addHelpText(
5949
+ ).version("9.111.1").addHelpText(
6023
5950
  "after",
6024
5951
  `
6025
5952
  Examples: