@vm0/cli 9.80.0 → 9.82.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/index.js CHANGED
@@ -65,7 +65,7 @@ import {
65
65
  storagesPrepareContract,
66
66
  volumeConfigSchema,
67
67
  withErrorHandler
68
- } from "./chunk-QKXNL42S.js";
68
+ } from "./chunk-RGS2GO4Q.js";
69
69
 
70
70
  // src/index.ts
71
71
  import { Command as Command44 } from "commander";
@@ -451,7 +451,7 @@ function getConfigPath() {
451
451
  return join(homedir(), ".vm0", "config.json");
452
452
  }
453
453
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
454
- console.log(chalk3.bold(`VM0 CLI v${"9.80.0"}`));
454
+ console.log(chalk3.bold(`VM0 CLI v${"9.82.0"}`));
455
455
  console.log();
456
456
  const config = await loadConfig();
457
457
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -1677,7 +1677,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
1677
1677
  options.autoUpdate = false;
1678
1678
  }
1679
1679
  if (options.autoUpdate !== false) {
1680
- await startSilentUpgrade("9.80.0");
1680
+ await startSilentUpgrade("9.82.0");
1681
1681
  }
1682
1682
  try {
1683
1683
  let result;
@@ -2512,7 +2512,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
2512
2512
  withErrorHandler(
2513
2513
  async (identifier, prompt, options) => {
2514
2514
  if (options.autoUpdate !== false) {
2515
- await startSilentUpgrade("9.80.0");
2515
+ await startSilentUpgrade("9.82.0");
2516
2516
  }
2517
2517
  const { org, name, version } = parseIdentifier(identifier);
2518
2518
  let composeId;
@@ -4268,7 +4268,7 @@ var cookAction = new Command35().name("cook").description("Quick start: prepare,
4268
4268
  withErrorHandler(
4269
4269
  async (prompt, options) => {
4270
4270
  if (options.autoUpdate !== false) {
4271
- const shouldExit = await checkAndUpgrade("9.80.0", prompt);
4271
+ const shouldExit = await checkAndUpgrade("9.82.0", prompt);
4272
4272
  if (shouldExit) {
4273
4273
  process.exit(0);
4274
4274
  }
@@ -5434,13 +5434,13 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
5434
5434
  if (latestVersion === null) {
5435
5435
  throw new Error("Could not check for updates. Please try again later.");
5436
5436
  }
5437
- if (latestVersion === "9.80.0") {
5438
- console.log(chalk36.green(`\u2713 Already up to date (${"9.80.0"})`));
5437
+ if (latestVersion === "9.82.0") {
5438
+ console.log(chalk36.green(`\u2713 Already up to date (${"9.82.0"})`));
5439
5439
  return;
5440
5440
  }
5441
5441
  console.log(
5442
5442
  chalk36.yellow(
5443
- `Current version: ${"9.80.0"} -> Latest version: ${latestVersion}`
5443
+ `Current version: ${"9.82.0"} -> Latest version: ${latestVersion}`
5444
5444
  )
5445
5445
  );
5446
5446
  console.log();
@@ -5467,7 +5467,7 @@ var upgradeCommand = new Command42().name("upgrade").description("Upgrade vm0 CL
5467
5467
  const success = await performUpgrade(packageManager);
5468
5468
  if (success) {
5469
5469
  console.log(
5470
- chalk36.green(`\u2713 Upgraded from ${"9.80.0"} to ${latestVersion}`)
5470
+ chalk36.green(`\u2713 Upgraded from ${"9.82.0"} to ${latestVersion}`)
5471
5471
  );
5472
5472
  return;
5473
5473
  }
@@ -5535,7 +5535,7 @@ var whoamiCommand = new Command43().name("whoami").description("Show current ide
5535
5535
 
5536
5536
  // src/index.ts
5537
5537
  var program = new Command44();
5538
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.80.0");
5538
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.82.0");
5539
5539
  program.addCommand(authCommand);
5540
5540
  program.addCommand(infoCommand);
5541
5541
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.80.0",
3
+ "version": "9.82.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  createZeroAgent,
10
10
  createZeroComputerConnector,
11
11
  createZeroConnectorSession,
12
+ decodeZeroTokenPayload,
12
13
  deleteZeroAgent,
13
14
  deleteZeroComputerConnector,
14
15
  deleteZeroConnector,
@@ -23,6 +24,7 @@ import {
23
24
  disableZeroSchedule,
24
25
  enableZeroSchedule,
25
26
  getActiveOrg,
27
+ getApiUrl,
26
28
  getAuthMethodsForType,
27
29
  getBaseUrl,
28
30
  getComposeByName,
@@ -34,6 +36,7 @@ import {
34
36
  getScopeDiff,
35
37
  getSecretsForAuthMethod,
36
38
  getSelectableProviderTypes,
39
+ getToken,
37
40
  getZeroAgent,
38
41
  getZeroAgentInstructions,
39
42
  getZeroConnector,
@@ -64,6 +67,7 @@ import {
64
67
  removeZeroOrgMember,
65
68
  resolveZeroScheduleByAgent,
66
69
  saveConfig,
70
+ sendSlackMessage,
67
71
  setZeroOrgModelProviderDefault,
68
72
  setZeroOrgSecret,
69
73
  setZeroOrgVariable,
@@ -76,10 +80,10 @@ import {
76
80
  updateZeroUserPreferences,
77
81
  upsertZeroOrgModelProvider,
78
82
  withErrorHandler
79
- } from "./chunk-QKXNL42S.js";
83
+ } from "./chunk-RGS2GO4Q.js";
80
84
 
81
85
  // src/zero.ts
82
- import { Command as Command51 } from "commander";
86
+ import { Command as Command55 } from "commander";
83
87
 
84
88
  // src/commands/zero/org/index.ts
85
89
  import { Command as Command23 } from "commander";
@@ -320,10 +324,6 @@ var setCommand2 = new Command11().name("set").description("Create or update an o
320
324
  throw error;
321
325
  }
322
326
  console.log(chalk11.green(`\u2713 Org secret "${secret.name}" saved`));
323
- console.log();
324
- console.log("Use in vm0.yaml:");
325
- console.log(chalk11.cyan(` environment:`));
326
- console.log(chalk11.cyan(` ${name}: \${{ secrets.${name} }}`));
327
327
  }
328
328
  )
329
329
  );
@@ -417,10 +417,6 @@ var setCommand3 = new Command15().name("set").description("Create or update an o
417
417
  throw error;
418
418
  }
419
419
  console.log(chalk14.green(`\u2713 Org variable "${variable.name}" saved`));
420
- console.log();
421
- console.log("Use in vm0.yaml:");
422
- console.log(chalk14.cyan(` environment:`));
423
- console.log(chalk14.cyan(` ${name}: \${{ vars.${name} }}`));
424
420
  }
425
421
  )
426
422
  );
@@ -1058,7 +1054,7 @@ var createCommand = new Command24().name("create").description("Create a new zer
1058
1054
  import { Command as Command25 } from "commander";
1059
1055
  import { readFileSync as readFileSync2 } from "fs";
1060
1056
  import chalk22 from "chalk";
1061
- var editCommand = new Command25().name("edit").description("Edit a zero agent").argument("<name>", "Agent name").option(
1057
+ var editCommand = new Command25().name("edit").description("Edit a zero agent").argument("<agent-id>", "Agent ID").option(
1062
1058
  "--connectors <items>",
1063
1059
  "Comma-separated connector short names (e.g. github,linear)"
1064
1060
  ).option("--display-name <name>", "New display name").option("--description <text>", "New description").option(
@@ -1066,7 +1062,7 @@ var editCommand = new Command25().name("edit").description("Edit a zero agent").
1066
1062
  "New tone: professional, friendly, direct, supportive"
1067
1063
  ).option("--instructions-file <path>", "Path to new instructions file").action(
1068
1064
  withErrorHandler(
1069
- async (name, options) => {
1065
+ async (agentId, options) => {
1070
1066
  const hasAgentUpdate = options.connectors !== void 0 || options.displayName !== void 0 || options.description !== void 0 || options.sound !== void 0;
1071
1067
  if (!hasAgentUpdate && !options.instructionsFile) {
1072
1068
  throw new Error(
@@ -1074,9 +1070,9 @@ var editCommand = new Command25().name("edit").description("Edit a zero agent").
1074
1070
  );
1075
1071
  }
1076
1072
  if (hasAgentUpdate) {
1077
- const current = await getZeroAgent(name);
1073
+ const current = await getZeroAgent(agentId);
1078
1074
  const connectors = options.connectors ? options.connectors.split(",").map((s) => s.trim()) : current.connectors;
1079
- await updateZeroAgent(name, {
1075
+ await updateZeroAgent(agentId, {
1080
1076
  connectors,
1081
1077
  displayName: options.displayName !== void 0 ? options.displayName : current.displayName ?? void 0,
1082
1078
  description: options.description !== void 0 ? options.description : current.description ?? void 0,
@@ -1085,9 +1081,9 @@ var editCommand = new Command25().name("edit").description("Edit a zero agent").
1085
1081
  }
1086
1082
  if (options.instructionsFile) {
1087
1083
  const content = readFileSync2(options.instructionsFile, "utf-8");
1088
- await updateZeroAgentInstructions(name, content);
1084
+ await updateZeroAgentInstructions(agentId, content);
1089
1085
  }
1090
- console.log(chalk22.green(`\u2713 Zero agent '${name}' updated`));
1086
+ console.log(chalk22.green(`\u2713 Zero agent '${agentId}' updated`));
1091
1087
  }
1092
1088
  )
1093
1089
  );
@@ -1095,10 +1091,10 @@ var editCommand = new Command25().name("edit").description("Edit a zero agent").
1095
1091
  // src/commands/zero/agent/view.ts
1096
1092
  import { Command as Command26 } from "commander";
1097
1093
  import chalk23 from "chalk";
1098
- var viewCommand = new Command26().name("view").description("View a zero agent").argument("<name>", "Agent name").option("--instructions", "Also show instructions content").action(
1094
+ var viewCommand = new Command26().name("view").description("View a zero agent").argument("<agent-id>", "Agent ID").option("--instructions", "Also show instructions content").action(
1099
1095
  withErrorHandler(
1100
- async (name, options) => {
1101
- const agent = await getZeroAgent(name);
1096
+ async (agentId, options) => {
1097
+ const agent = await getZeroAgent(agentId);
1102
1098
  console.log(chalk23.bold(agent.agentId));
1103
1099
  if (agent.displayName) console.log(chalk23.dim(agent.displayName));
1104
1100
  console.log();
@@ -1109,7 +1105,7 @@ var viewCommand = new Command26().name("view").description("View a zero agent").
1109
1105
  if (agent.sound) console.log(`Sound: ${agent.sound}`);
1110
1106
  if (options.instructions) {
1111
1107
  console.log();
1112
- const result = await getZeroAgentInstructions(name);
1108
+ const result = await getZeroAgentInstructions(agentId);
1113
1109
  if (result.content) {
1114
1110
  console.log(chalk23.dim("\u2500\u2500 Instructions \u2500\u2500"));
1115
1111
  console.log(result.content);
@@ -1161,15 +1157,15 @@ var listCommand5 = new Command27().name("list").alias("ls").description("List al
1161
1157
  // src/commands/zero/agent/delete.ts
1162
1158
  import { Command as Command28 } from "commander";
1163
1159
  import chalk25 from "chalk";
1164
- var deleteCommand2 = new Command28().name("delete").alias("rm").description("Delete a zero agent").argument("<name>", "Agent name").option("-y, --yes", "Skip confirmation prompt").action(
1165
- withErrorHandler(async (name, options) => {
1166
- await getZeroAgent(name);
1160
+ var deleteCommand2 = new Command28().name("delete").alias("rm").description("Delete a zero agent").argument("<agent-id>", "Agent ID").option("-y, --yes", "Skip confirmation prompt").action(
1161
+ withErrorHandler(async (agentId, options) => {
1162
+ await getZeroAgent(agentId);
1167
1163
  if (!options.yes) {
1168
1164
  if (!isInteractive()) {
1169
1165
  throw new Error("--yes flag is required in non-interactive mode");
1170
1166
  }
1171
1167
  const confirmed = await promptConfirm(
1172
- `Delete zero agent '${name}'?`,
1168
+ `Delete zero agent '${agentId}'?`,
1173
1169
  false
1174
1170
  );
1175
1171
  if (!confirmed) {
@@ -1177,8 +1173,8 @@ var deleteCommand2 = new Command28().name("delete").alias("rm").description("Del
1177
1173
  return;
1178
1174
  }
1179
1175
  }
1180
- await deleteZeroAgent(name);
1181
- console.log(chalk25.green(`\u2713 Zero agent '${name}' deleted`));
1176
+ await deleteZeroAgent(agentId);
1177
+ console.log(chalk25.green(`\u2713 Zero agent '${agentId}' deleted`));
1182
1178
  })
1183
1179
  );
1184
1180
 
@@ -1432,7 +1428,8 @@ async function connectComputer() {
1432
1428
  async function resolveAuthMethod(connectorType, tokenFlag) {
1433
1429
  const config = CONNECTOR_TYPES[connectorType];
1434
1430
  const oauthFlag = CONNECTOR_TYPES[connectorType].featureFlag;
1435
- const oauthAvailable = "oauth" in config.authMethods && (!oauthFlag || await isFeatureEnabled(oauthFlag));
1431
+ const orgId = await getActiveOrg();
1432
+ const oauthAvailable = "oauth" in config.authMethods && (!oauthFlag || await isFeatureEnabled(oauthFlag, { orgId }));
1436
1433
  const apiTokenAvailable = "api-token" in config.authMethods;
1437
1434
  if (tokenFlag) {
1438
1435
  if (!apiTokenAvailable) {
@@ -1538,12 +1535,13 @@ var listCommand6 = new Command31().name("list").alias("ls").description("List al
1538
1535
  withErrorHandler(async () => {
1539
1536
  const result = await listZeroConnectors();
1540
1537
  const connectedMap = new Map(result.connectors.map((c) => [c.type, c]));
1538
+ const orgId = await getActiveOrg();
1541
1539
  const allTypesRaw = Object.keys(CONNECTOR_TYPES);
1542
1540
  const allTypes = [];
1543
1541
  for (const type of allTypesRaw) {
1544
1542
  const flag = CONNECTOR_TYPES[type].featureFlag;
1545
1543
  const hasApiToken = "api-token" in CONNECTOR_TYPES[type].authMethods;
1546
- if (flag && !await isFeatureEnabled(flag) && !hasApiToken) {
1544
+ if (flag && !await isFeatureEnabled(flag, { orgId }) && !hasApiToken) {
1547
1545
  continue;
1548
1546
  }
1549
1547
  allTypes.push(type);
@@ -1790,49 +1788,22 @@ function isValidTimezone(timezone) {
1790
1788
  return false;
1791
1789
  }
1792
1790
  }
1793
- function parseOnOff(flag, value) {
1794
- const lower = value.toLowerCase();
1795
- if (lower === "on" || lower === "true" || lower === "1") return true;
1796
- if (lower === "off" || lower === "false" || lower === "0") return false;
1797
- throw new Error(
1798
- `Invalid value for --${flag}: "${value}". Use "on" or "off".`
1799
- );
1800
- }
1801
1791
  function displayPreferences(prefs) {
1802
1792
  console.log(chalk31.bold("Current preferences:"));
1803
1793
  console.log(
1804
1794
  ` Timezone: ${prefs.timezone ? chalk31.cyan(prefs.timezone) : chalk31.dim("not set")}`
1805
1795
  );
1806
- console.log(
1807
- ` Email notify: ${prefs.notifyEmail ? chalk31.green("on") : chalk31.dim("off")}`
1808
- );
1809
- console.log(
1810
- ` Slack notify: ${prefs.notifySlack ? chalk31.green("on") : chalk31.dim("off")}`
1811
- );
1812
1796
  }
1813
1797
  function buildUpdates(opts) {
1814
- const hasTimezone = opts.timezone !== void 0;
1815
- const hasNotifyEmail = opts.notifyEmail !== void 0;
1816
- const hasNotifySlack = opts.notifySlack !== void 0;
1817
- if (!hasTimezone && !hasNotifyEmail && !hasNotifySlack) return null;
1818
- const updates = {};
1819
- if (hasTimezone) {
1820
- if (!isValidTimezone(opts.timezone)) {
1821
- throw new Error(`Invalid timezone: ${opts.timezone}`, {
1822
- cause: new Error(
1823
- "Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
1824
- )
1825
- });
1826
- }
1827
- updates.timezone = opts.timezone;
1828
- }
1829
- if (hasNotifyEmail) {
1830
- updates.notifyEmail = parseOnOff("notify-email", opts.notifyEmail);
1831
- }
1832
- if (hasNotifySlack) {
1833
- updates.notifySlack = parseOnOff("notify-slack", opts.notifySlack);
1798
+ if (opts.timezone === void 0) return null;
1799
+ if (!isValidTimezone(opts.timezone)) {
1800
+ throw new Error(`Invalid timezone: ${opts.timezone}`, {
1801
+ cause: new Error(
1802
+ "Use an IANA timezone identifier (e.g., America/New_York, Asia/Shanghai)"
1803
+ )
1804
+ });
1834
1805
  }
1835
- return updates;
1806
+ return { timezone: opts.timezone };
1836
1807
  }
1837
1808
  function printUpdateResult(updates, result) {
1838
1809
  if (updates.timezone !== void 0) {
@@ -1842,20 +1813,6 @@ function printUpdateResult(updates, result) {
1842
1813
  )
1843
1814
  );
1844
1815
  }
1845
- if (updates.notifyEmail !== void 0) {
1846
- console.log(
1847
- chalk31.green(
1848
- `Email notifications ${result.notifyEmail ? "enabled" : "disabled"}`
1849
- )
1850
- );
1851
- }
1852
- if (updates.notifySlack !== void 0) {
1853
- console.log(
1854
- chalk31.green(
1855
- `Slack notifications ${result.notifySlack ? "enabled" : "disabled"}`
1856
- )
1857
- );
1858
- }
1859
1816
  }
1860
1817
  async function interactiveSetup(prefs) {
1861
1818
  if (!prefs.timezone) {
@@ -1874,18 +1831,8 @@ System timezone detected: ${detectedTz}`));
1874
1831
  console.log(chalk31.green(`Timezone set to ${chalk31.cyan(tz.trim())}`));
1875
1832
  }
1876
1833
  }
1877
- if (!prefs.notifyEmail) {
1878
- const enable = await promptConfirm(
1879
- "\nEnable email notifications for scheduled runs?",
1880
- false
1881
- );
1882
- if (enable) {
1883
- await updateZeroUserPreferences({ notifyEmail: true });
1884
- console.log(chalk31.green("Email notifications enabled"));
1885
- }
1886
- }
1887
1834
  }
1888
- var zeroPreferenceCommand = new Command35().name("preference").description("View or update your preferences").option("--timezone <timezone>", "IANA timezone (e.g., America/New_York)").option("--notify-email <on|off>", "Enable or disable email notifications").option("--notify-slack <on|off>", "Enable or disable Slack notifications").action(
1835
+ var zeroPreferenceCommand = new Command35().name("preference").description("View or update your preferences").option("--timezone <timezone>", "IANA timezone (e.g., America/New_York)").action(
1889
1836
  withErrorHandler(async (opts) => {
1890
1837
  const updates = buildUpdates(opts);
1891
1838
  if (updates) {
@@ -2744,10 +2691,6 @@ var setCommand4 = new Command44().name("set").description("Create or update a se
2744
2691
  throw error;
2745
2692
  }
2746
2693
  console.log(chalk39.green(`\u2713 Secret "${secret.name}" saved`));
2747
- console.log();
2748
- console.log("Use in vm0.yaml:");
2749
- console.log(chalk39.cyan(` environment:`));
2750
- console.log(chalk39.cyan(` ${name}: \${{ secrets.${name} }}`));
2751
2694
  }
2752
2695
  )
2753
2696
  );
@@ -2778,49 +2721,104 @@ var deleteCommand4 = new Command45().name("delete").description("Delete a secret
2778
2721
  // src/commands/zero/secret/index.ts
2779
2722
  var zeroSecretCommand = new Command46().name("secret").description("Manage secrets").addCommand(listCommand8).addCommand(setCommand4).addCommand(deleteCommand4);
2780
2723
 
2781
- // src/commands/zero/variable/index.ts
2782
- import { Command as Command50 } from "commander";
2724
+ // src/commands/zero/slack/index.ts
2725
+ import { Command as Command49 } from "commander";
2783
2726
 
2784
- // src/commands/zero/variable/list.ts
2727
+ // src/commands/zero/slack/message/index.ts
2728
+ import { Command as Command48 } from "commander";
2729
+
2730
+ // src/commands/zero/slack/message/send.ts
2731
+ import { readFileSync as readFileSync3 } from "fs";
2785
2732
  import { Command as Command47 } from "commander";
2786
2733
  import chalk41 from "chalk";
2734
+ var sendCommand = new Command47().name("send").description("Send a message to a Slack channel").requiredOption("-c, --channel <id>", "Channel ID").option("-t, --text <message>", "Message text").option("--thread <ts>", "Thread timestamp for replies").option("--blocks <json>", "Block Kit JSON string").action(
2735
+ withErrorHandler(
2736
+ async (options) => {
2737
+ let text = options.text;
2738
+ const { channel, thread, blocks: blocksStr } = options;
2739
+ if (!text && process.stdin.isTTY === false) {
2740
+ text = readFileSync3("/dev/stdin", "utf8").trim();
2741
+ }
2742
+ let blocks;
2743
+ if (blocksStr) {
2744
+ try {
2745
+ blocks = JSON.parse(blocksStr);
2746
+ } catch {
2747
+ throw new Error("Invalid JSON for --blocks flag", {
2748
+ cause: new Error(
2749
+ "Provide a valid JSON array of Block Kit blocks"
2750
+ )
2751
+ });
2752
+ }
2753
+ }
2754
+ if (!text && !blocks) {
2755
+ throw new Error("Either --text or --blocks must be provided", {
2756
+ cause: new Error(
2757
+ 'Usage: zero slack message send -c CHANNEL_ID -t "your message"'
2758
+ )
2759
+ });
2760
+ }
2761
+ const result = await sendSlackMessage({
2762
+ channel,
2763
+ text: text || void 0,
2764
+ threadTs: thread,
2765
+ blocks
2766
+ });
2767
+ const tsInfo = result.ts ? ` (ts: ${result.ts})` : "";
2768
+ console.log(chalk41.green(`\u2713 Message sent${tsInfo}`));
2769
+ }
2770
+ )
2771
+ );
2772
+
2773
+ // src/commands/zero/slack/message/index.ts
2774
+ var zeroSlackMessageCommand = new Command48().name("message").description("Manage Slack messages").addCommand(sendCommand);
2775
+
2776
+ // src/commands/zero/slack/index.ts
2777
+ var zeroSlackCommand = new Command49().name("slack").description("Manage Slack integrations").addCommand(zeroSlackMessageCommand);
2778
+
2779
+ // src/commands/zero/variable/index.ts
2780
+ import { Command as Command53 } from "commander";
2781
+
2782
+ // src/commands/zero/variable/list.ts
2783
+ import { Command as Command50 } from "commander";
2784
+ import chalk42 from "chalk";
2787
2785
  function truncateValue2(value, maxLength = 60) {
2788
2786
  if (value.length <= maxLength) {
2789
2787
  return value;
2790
2788
  }
2791
2789
  return value.slice(0, maxLength - 15) + "... [truncated]";
2792
2790
  }
2793
- var listCommand9 = new Command47().name("list").alias("ls").description("List all variables").action(
2791
+ var listCommand9 = new Command50().name("list").alias("ls").description("List all variables").action(
2794
2792
  withErrorHandler(async () => {
2795
2793
  const result = await listZeroVariables();
2796
2794
  if (result.variables.length === 0) {
2797
- console.log(chalk41.dim("No variables found"));
2795
+ console.log(chalk42.dim("No variables found"));
2798
2796
  console.log();
2799
2797
  console.log("To add a variable:");
2800
- console.log(chalk41.cyan(" zero variable set MY_VAR <value>"));
2798
+ console.log(chalk42.cyan(" zero variable set MY_VAR <value>"));
2801
2799
  return;
2802
2800
  }
2803
- console.log(chalk41.bold("Variables:"));
2801
+ console.log(chalk42.bold("Variables:"));
2804
2802
  console.log();
2805
2803
  for (const variable of result.variables) {
2806
2804
  const displayValue = truncateValue2(variable.value);
2807
- console.log(` ${chalk41.cyan(variable.name)} = ${displayValue}`);
2805
+ console.log(` ${chalk42.cyan(variable.name)} = ${displayValue}`);
2808
2806
  if (variable.description) {
2809
- console.log(` ${chalk41.dim(variable.description)}`);
2807
+ console.log(` ${chalk42.dim(variable.description)}`);
2810
2808
  }
2811
2809
  console.log(
2812
- ` ${chalk41.dim(`Updated: ${new Date(variable.updatedAt).toLocaleString()}`)}`
2810
+ ` ${chalk42.dim(`Updated: ${new Date(variable.updatedAt).toLocaleString()}`)}`
2813
2811
  );
2814
2812
  console.log();
2815
2813
  }
2816
- console.log(chalk41.dim(`Total: ${result.variables.length} variable(s)`));
2814
+ console.log(chalk42.dim(`Total: ${result.variables.length} variable(s)`));
2817
2815
  })
2818
2816
  );
2819
2817
 
2820
2818
  // src/commands/zero/variable/set.ts
2821
- import { Command as Command48 } from "commander";
2822
- import chalk42 from "chalk";
2823
- var setCommand5 = new Command48().name("set").description("Create or update a variable").argument("<name>", "Variable name (uppercase, e.g., MY_VAR)").argument("<value>", "Variable value").option("-d, --description <description>", "Optional description").action(
2819
+ import { Command as Command51 } from "commander";
2820
+ import chalk43 from "chalk";
2821
+ var setCommand5 = new Command51().name("set").description("Create or update a variable").argument("<name>", "Variable name (uppercase, e.g., MY_VAR)").argument("<value>", "Variable value").option("-d, --description <description>", "Optional description").action(
2824
2822
  withErrorHandler(
2825
2823
  async (name, value, options) => {
2826
2824
  let variable;
@@ -2840,19 +2838,15 @@ var setCommand5 = new Command48().name("set").description("Create or update a va
2840
2838
  }
2841
2839
  throw error;
2842
2840
  }
2843
- console.log(chalk42.green(`\u2713 Variable "${variable.name}" saved`));
2844
- console.log();
2845
- console.log("Use in vm0.yaml:");
2846
- console.log(chalk42.cyan(` environment:`));
2847
- console.log(chalk42.cyan(` ${name}: \${{ vars.${name} }}`));
2841
+ console.log(chalk43.green(`\u2713 Variable "${variable.name}" saved`));
2848
2842
  }
2849
2843
  )
2850
2844
  );
2851
2845
 
2852
2846
  // src/commands/zero/variable/delete.ts
2853
- import { Command as Command49 } from "commander";
2854
- import chalk43 from "chalk";
2855
- var deleteCommand5 = new Command49().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
2847
+ import { Command as Command52 } from "commander";
2848
+ import chalk44 from "chalk";
2849
+ var deleteCommand5 = new Command52().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
2856
2850
  withErrorHandler(async (name, options) => {
2857
2851
  if (!options.yes) {
2858
2852
  if (!isInteractive()) {
@@ -2863,28 +2857,117 @@ var deleteCommand5 = new Command49().name("delete").description("Delete a variab
2863
2857
  false
2864
2858
  );
2865
2859
  if (!confirmed) {
2866
- console.log(chalk43.dim("Cancelled"));
2860
+ console.log(chalk44.dim("Cancelled"));
2867
2861
  return;
2868
2862
  }
2869
2863
  }
2870
2864
  await deleteZeroVariable(name);
2871
- console.log(chalk43.green(`\u2713 Variable "${name}" deleted`));
2865
+ console.log(chalk44.green(`\u2713 Variable "${name}" deleted`));
2872
2866
  })
2873
2867
  );
2874
2868
 
2875
2869
  // src/commands/zero/variable/index.ts
2876
- var zeroVariableCommand = new Command50().name("variable").description("Manage variables").addCommand(listCommand9).addCommand(setCommand5).addCommand(deleteCommand5);
2870
+ var zeroVariableCommand = new Command53().name("variable").description("Manage variables").addCommand(listCommand9).addCommand(setCommand5).addCommand(deleteCommand5);
2871
+
2872
+ // src/commands/zero/whoami.ts
2873
+ import { Command as Command54 } from "commander";
2874
+ import chalk45 from "chalk";
2875
+ function isInsideSandbox() {
2876
+ return !!process.env.ZERO_AGENT_ID;
2877
+ }
2878
+ async function showSandboxInfo() {
2879
+ const agentId = process.env.ZERO_AGENT_ID;
2880
+ const payload = decodeZeroTokenPayload();
2881
+ console.log(chalk45.bold("Agent:"));
2882
+ console.log(` ID: ${agentId}`);
2883
+ console.log();
2884
+ console.log(chalk45.bold("Run:"));
2885
+ console.log(` ID: ${payload?.runId ?? chalk45.dim("unavailable")}`);
2886
+ console.log(` Org: ${payload?.orgId ?? chalk45.dim("unavailable")}`);
2887
+ if (payload?.capabilities?.length) {
2888
+ console.log();
2889
+ console.log(chalk45.bold("Capabilities:"));
2890
+ console.log(` ${payload.capabilities.join(", ")}`);
2891
+ }
2892
+ }
2893
+ async function showLocalInfo() {
2894
+ const token = await getToken();
2895
+ const apiUrl = await getApiUrl();
2896
+ const activeOrg = await getActiveOrg();
2897
+ console.log(chalk45.bold("Auth:"));
2898
+ if (token) {
2899
+ const tokenSource = process.env.ZERO_TOKEN ? "ZERO_TOKEN env var" : process.env.VM0_TOKEN ? "VM0_TOKEN env var" : "config file";
2900
+ console.log(
2901
+ ` Status: ${chalk45.green("Authenticated")} (via ${tokenSource})`
2902
+ );
2903
+ } else {
2904
+ console.log(` Status: ${chalk45.dim("Not authenticated")}`);
2905
+ }
2906
+ console.log(` API: ${apiUrl}`);
2907
+ console.log();
2908
+ if (activeOrg) {
2909
+ console.log(chalk45.bold("Org:"));
2910
+ console.log(` Active: ${activeOrg}`);
2911
+ }
2912
+ }
2913
+ var zeroWhoamiCommand = new Command54().name("whoami").description("Show current identity and environment information").action(
2914
+ withErrorHandler(async () => {
2915
+ if (isInsideSandbox()) {
2916
+ await showSandboxInfo();
2917
+ } else {
2918
+ await showLocalInfo();
2919
+ }
2920
+ })
2921
+ );
2877
2922
 
2878
2923
  // src/zero.ts
2879
- var program = new Command51();
2880
- program.name("zero").description("Zero CLI - Manage your zero platform").version("9.80.0");
2924
+ var COMMAND_CAPABILITY_MAP = {
2925
+ agent: "agent:read",
2926
+ schedule: "schedule:read",
2927
+ whoami: null
2928
+ };
2929
+ function decodeCapabilitiesFromZeroToken(token) {
2930
+ const prefix = "vm0_sandbox_";
2931
+ if (!token.startsWith(prefix)) return null;
2932
+ const jwt = token.slice(prefix.length);
2933
+ const parts = jwt.split(".");
2934
+ if (parts.length !== 3) return null;
2935
+ try {
2936
+ const payload = JSON.parse(
2937
+ Buffer.from(parts[1], "base64url").toString()
2938
+ );
2939
+ if (payload.scope === "zero" && Array.isArray(payload.capabilities)) {
2940
+ return payload.capabilities;
2941
+ }
2942
+ } catch {
2943
+ }
2944
+ return null;
2945
+ }
2946
+ function applyCapabilityVisibility(prog) {
2947
+ const token = process.env.ZERO_TOKEN;
2948
+ if (!token) return;
2949
+ const capabilities = decodeCapabilitiesFromZeroToken(token);
2950
+ if (!capabilities) return;
2951
+ for (const cmd of prog.commands) {
2952
+ const requiredCap = COMMAND_CAPABILITY_MAP[cmd.name()];
2953
+ if (requiredCap === void 0) {
2954
+ cmd._hidden = true;
2955
+ } else if (requiredCap !== null && !capabilities.includes(requiredCap)) {
2956
+ cmd._hidden = true;
2957
+ }
2958
+ }
2959
+ }
2960
+ var program = new Command55();
2961
+ program.name("zero").description("Zero CLI - Manage your zero platform").version("9.82.0");
2881
2962
  program.addCommand(zeroOrgCommand);
2882
2963
  program.addCommand(agentCommand);
2883
2964
  program.addCommand(zeroConnectorCommand);
2884
2965
  program.addCommand(zeroPreferenceCommand);
2885
2966
  program.addCommand(zeroScheduleCommand);
2886
2967
  program.addCommand(zeroSecretCommand);
2968
+ program.addCommand(zeroSlackCommand);
2887
2969
  program.addCommand(zeroVariableCommand);
2970
+ program.addCommand(zeroWhoamiCommand);
2888
2971
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {
2889
2972
  process.stdout.on("error", (err) => {
2890
2973
  if (err.code === "EPIPE") process.exit(0);
@@ -2895,9 +2978,12 @@ if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts")
2895
2978
  throw err;
2896
2979
  });
2897
2980
  configureGlobalProxyFromEnv();
2981
+ applyCapabilityVisibility(program);
2898
2982
  program.parse();
2899
2983
  }
2900
2984
  export {
2985
+ applyCapabilityVisibility,
2986
+ decodeCapabilitiesFromZeroToken,
2901
2987
  program
2902
2988
  };
2903
2989
  //# sourceMappingURL=zero.js.map