@vm0/cli 9.107.0 → 9.107.2

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.107.0",
3
+ "version": "9.107.2",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",
package/zero.js CHANGED
@@ -123,7 +123,7 @@ import {
123
123
  upsertZeroOrgModelProvider,
124
124
  withErrorHandler,
125
125
  zeroAgentCustomSkillNameSchema
126
- } from "./chunk-DCKQ3GVE.js";
126
+ } from "./chunk-AJN5ZMHZ.js";
127
127
 
128
128
  // src/zero.ts
129
129
  init_esm_shims();
@@ -1288,7 +1288,7 @@ function getConnectorPermissionInfo(type, resolvedPolicies) {
1288
1288
  if (!isFirewallConnectorType(type)) {
1289
1289
  return {
1290
1290
  type,
1291
- hasFirewall: false,
1291
+ hasPermissions: false,
1292
1292
  permissions: [],
1293
1293
  policies: null,
1294
1294
  allowed: 0,
@@ -1304,7 +1304,7 @@ function getConnectorPermissionInfo(type, resolvedPolicies) {
1304
1304
  const allowed = policies ? permissions.filter((p) => {
1305
1305
  return policies[p.name] === "allow";
1306
1306
  }).length : 0;
1307
- return { type, hasFirewall: true, permissions, policies, allowed, total };
1307
+ return { type, hasPermissions: true, permissions, policies, allowed, total };
1308
1308
  }
1309
1309
  function formatConnectorIdentity(connector) {
1310
1310
  if (!connector) return "";
@@ -1315,7 +1315,7 @@ function formatConnectorIdentity(connector) {
1315
1315
  function formatConnectorSummary(info, identity) {
1316
1316
  const id = formatConnectorIdentity(identity);
1317
1317
  const idStr = id ? ` ${id}` : "";
1318
- if (!info.hasFirewall) return `${info.type}${idStr}`;
1318
+ if (!info.hasPermissions) return `${info.type}${idStr}`;
1319
1319
  if (!info.policies) return `${info.type}${idStr} (full access)`;
1320
1320
  return `${info.type}${idStr} (${info.allowed}/${info.total} allowed)`;
1321
1321
  }
@@ -1363,7 +1363,7 @@ Examples:
1363
1363
  console.log();
1364
1364
  console.log(`Agent ID: ${agent.agentId}`);
1365
1365
  const resolvedPolicies = resolveFirewallPolicies(
1366
- agent.firewallPolicies,
1366
+ agent.permissionPolicies,
1367
1367
  connectorTypes
1368
1368
  );
1369
1369
  const connectorInfos = connectorTypes.map((type) => {
@@ -1387,7 +1387,7 @@ Examples:
1387
1387
  for (const info of connectorInfos) {
1388
1388
  const identity = formatDetailIdentity(identityMap.get(info.type));
1389
1389
  console.log(` ${info.type.padEnd(14)}${identity}`);
1390
- if (!info.hasFirewall) continue;
1390
+ if (!info.hasPermissions) continue;
1391
1391
  if (!info.policies) {
1392
1392
  console.log(
1393
1393
  source_default.dim(" full access \u2014 no permission rules configured")
@@ -2251,11 +2251,11 @@ ${rediagnoseHint}`
2251
2251
  })
2252
2252
  );
2253
2253
 
2254
- // src/commands/zero/doctor/firewall-deny.ts
2254
+ // src/commands/zero/doctor/permission-deny.ts
2255
2255
  init_esm_shims();
2256
- var firewallDenyCommand = new Command().name("firewall-deny").description(
2257
- "Diagnose a firewall denial and find the permission that covers it"
2258
- ).argument("<firewall-ref>", "The firewall connector type (e.g. github)").addOption(
2256
+ var permissionDenyCommand = new Command().name("permission-deny").description(
2257
+ "Diagnose a permission denial and find the permission that covers it"
2258
+ ).argument("<connector-ref>", "The connector type (e.g. github)").addOption(
2259
2259
  new Option(
2260
2260
  "--method <method>",
2261
2261
  "The denied HTTP method"
@@ -2266,42 +2266,54 @@ var firewallDenyCommand = new Command().name("firewall-deny").description(
2266
2266
  "after",
2267
2267
  `
2268
2268
  Examples:
2269
- zero doctor firewall-deny github --method GET --path /repos/owner/repo/pulls
2270
- zero doctor firewall-deny slack --method POST --path /chat.postMessage
2269
+ zero doctor permission-deny github --method GET --path /repos/owner/repo/pulls
2270
+ zero doctor permission-deny slack --method POST --path /chat.postMessage
2271
2271
 
2272
2272
  Notes:
2273
2273
  - Identifies which named permission covers a denied request
2274
- - Use firewall-permissions-change to request or enable the permission`
2274
+ - Use permission-change to request or enable the permission`
2275
2275
  ).action(
2276
2276
  withErrorHandler(
2277
- async (firewallRef, opts) => {
2278
- if (!isFirewallConnectorType(firewallRef)) {
2279
- throw new Error(`Unknown firewall connector type: ${firewallRef}`);
2277
+ async (connectorRef, opts) => {
2278
+ if (!isFirewallConnectorType(connectorRef)) {
2279
+ throw new Error(`Unknown connector type: ${connectorRef}`);
2280
2280
  }
2281
- const { label } = CONNECTOR_TYPES[firewallRef];
2282
- const config = getConnectorFirewall(firewallRef);
2281
+ const { label } = CONNECTOR_TYPES[connectorRef];
2282
+ const config = getConnectorFirewall(connectorRef);
2283
2283
  const permissions = findMatchingPermissions(
2284
2284
  opts.method,
2285
2285
  opts.path,
2286
2286
  config
2287
2287
  );
2288
2288
  console.log(
2289
- `The ${label} firewall blocked ${opts.method} ${opts.path}.`
2289
+ `The ${label} permission filtered ${opts.method} ${opts.path}.`
2290
2290
  );
2291
2291
  if (permissions.length === 0) {
2292
2292
  console.log("No named permission was found covering this request.");
2293
2293
  return;
2294
2294
  }
2295
- const permission = permissions[0];
2295
+ const ruleCount = /* @__PURE__ */ new Map();
2296
+ for (const api of config.apis) {
2297
+ if (!api.permissions) continue;
2298
+ for (const perm of api.permissions) {
2299
+ ruleCount.set(
2300
+ perm.name,
2301
+ (ruleCount.get(perm.name) ?? 0) + perm.rules.length
2302
+ );
2303
+ }
2304
+ }
2305
+ const permission = permissions.reduce((narrowest, current) => {
2306
+ return (ruleCount.get(current) ?? Infinity) < (ruleCount.get(narrowest) ?? Infinity) ? current : narrowest;
2307
+ });
2296
2308
  console.log(`This is covered by the "${permission}" permission.`);
2297
2309
  console.log(
2298
- `To request this permission, run: zero doctor firewall-permissions-change ${firewallRef} --permission ${permission} --enable --reason "why this is needed"`
2310
+ `To request this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable --reason "why this is needed"`
2299
2311
  );
2300
2312
  }
2301
2313
  )
2302
2314
  );
2303
2315
 
2304
- // src/commands/zero/doctor/firewall-permissions-change.ts
2316
+ // src/commands/zero/doctor/permission-change.ts
2305
2317
  init_esm_shims();
2306
2318
 
2307
2319
  // src/commands/zero/doctor/resolve-role.ts
@@ -2332,7 +2344,7 @@ async function resolveAgentRole(agentId) {
2332
2344
  }
2333
2345
  }
2334
2346
 
2335
- // src/commands/zero/doctor/firewall-permissions-change.ts
2347
+ // src/commands/zero/doctor/permission-change.ts
2336
2348
  function findPermissionInConfig(ref, permissionName) {
2337
2349
  if (!isFirewallConnectorType(ref)) return false;
2338
2350
  const config = getConnectorFirewall(ref);
@@ -2345,13 +2357,13 @@ function findPermissionInConfig(ref, permissionName) {
2345
2357
  return false;
2346
2358
  }
2347
2359
  var REASON_MAX_LENGTH = 500;
2348
- async function outputPermissionChangeMessage(firewallRef, permission, action, reason) {
2349
- const { label } = CONNECTOR_TYPES[firewallRef];
2360
+ async function outputPermissionChangeMessage(connectorRef, permission, action, reason) {
2361
+ const { label } = CONNECTOR_TYPES[connectorRef];
2350
2362
  const platformOrigin = await getPlatformOrigin();
2351
2363
  const agentId = process.env.ZERO_AGENT_ID;
2352
2364
  const role = agentId ? await resolveAgentRole(agentId) : "unknown";
2353
2365
  const urlParams = new URLSearchParams({
2354
- ref: firewallRef,
2366
+ ref: connectorRef,
2355
2367
  permission,
2356
2368
  action: action === "enable" ? "allow" : "deny"
2357
2369
  });
@@ -2361,7 +2373,7 @@ async function outputPermissionChangeMessage(firewallRef, permission, action, re
2361
2373
  }
2362
2374
  const pagePath = agentId ? `/agents/${agentId}/permissions` : "/agents";
2363
2375
  const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
2364
- if (firewallRef === "slack" && permission === "chat:write" && action === "enable") {
2376
+ if (connectorRef === "slack" && permission === "chat:write" && action === "enable") {
2365
2377
  console.log("");
2366
2378
  console.log(
2367
2379
  "IMPORTANT: Granting chat:write allows sending messages AS THE USER's identity, not as a bot."
@@ -2374,7 +2386,7 @@ async function outputPermissionChangeMessage(firewallRef, permission, action, re
2374
2386
  );
2375
2387
  console.log("");
2376
2388
  }
2377
- if (firewallRef === "gmail" && permission === "gmail.send" && action === "enable") {
2389
+ if (connectorRef === "gmail" && permission === "gmail.send" && action === "enable") {
2378
2390
  console.log("");
2379
2391
  console.log(
2380
2392
  "IMPORTANT: Granting gmail.send allows the agent to send emails directly as the user."
@@ -2389,7 +2401,7 @@ async function outputPermissionChangeMessage(firewallRef, permission, action, re
2389
2401
  }
2390
2402
  if (role === "admin" || role === "owner") {
2391
2403
  console.log(
2392
- `You can ${action} the "${permission}" permission directly: [Manage ${label} firewall](${url})`
2404
+ `You can ${action} the "${permission}" permission directly: [Manage ${label} permissions](${url})`
2393
2405
  );
2394
2406
  } else if (role === "member") {
2395
2407
  if (!reason) {
@@ -2402,16 +2414,16 @@ async function outputPermissionChangeMessage(firewallRef, permission, action, re
2402
2414
  );
2403
2415
  } else {
2404
2416
  console.log(
2405
- `Permission changes require admin approval. Contact an org admin to disable this permission: [View ${label} firewall](${url})`
2417
+ `Permission changes require admin approval. Contact an org admin to disable this permission: [View ${label} permissions](${url})`
2406
2418
  );
2407
2419
  }
2408
2420
  } else {
2409
2421
  console.log(
2410
- `To ${action} the "${permission}" permission on the ${label} firewall: [Manage ${label} firewall](${url})`
2422
+ `To ${action} the "${permission}" permission for ${label}: [Manage ${label} permissions](${url})`
2411
2423
  );
2412
2424
  }
2413
2425
  }
2414
- var firewallPermissionsChangeCommand = new Command().name("firewall-permissions-change").description("Request a firewall permission change (enable or disable)").argument("<firewall-ref>", "The firewall connector type (e.g. github)").addOption(
2426
+ var permissionChangeCommand = new Command().name("permission-change").description("Request a permission change (enable or disable)").argument("<connector-ref>", "The connector type (e.g. github)").addOption(
2415
2427
  new Option(
2416
2428
  "--permission <name>",
2417
2429
  "The permission name to change"
@@ -2433,29 +2445,29 @@ var firewallPermissionsChangeCommand = new Command().name("firewall-permissions-
2433
2445
  "after",
2434
2446
  `
2435
2447
  Examples:
2436
- zero doctor firewall-permissions-change github --permission contents:read --enable
2437
- zero doctor firewall-permissions-change slack --permission chat:write --disable
2448
+ zero doctor permission-change github --permission contents:read --enable
2449
+ zero doctor permission-change slack --permission chat:write --disable
2438
2450
 
2439
2451
  Notes:
2440
2452
  - Outputs a platform URL for the user to adjust the permission
2441
2453
  - Admins can change permissions directly; members must request approval`
2442
2454
  ).action(
2443
2455
  withErrorHandler(
2444
- async (firewallRef, opts) => {
2456
+ async (connectorRef, opts) => {
2445
2457
  if (!opts.enable && !opts.disable) {
2446
2458
  throw new Error("Either --enable or --disable is required");
2447
2459
  }
2448
- if (!isFirewallConnectorType(firewallRef)) {
2449
- throw new Error(`Unknown firewall connector type: ${firewallRef}`);
2460
+ if (!isFirewallConnectorType(connectorRef)) {
2461
+ throw new Error(`Unknown connector type: ${connectorRef}`);
2450
2462
  }
2451
- if (!findPermissionInConfig(firewallRef, opts.permission)) {
2463
+ if (!findPermissionInConfig(connectorRef, opts.permission)) {
2452
2464
  throw new Error(
2453
- `Unknown permission "${opts.permission}" for ${firewallRef} firewall`
2465
+ `Unknown permission "${opts.permission}" for ${connectorRef}`
2454
2466
  );
2455
2467
  }
2456
2468
  const action = opts.enable ? "enable" : "disable";
2457
2469
  await outputPermissionChangeMessage(
2458
- firewallRef,
2470
+ connectorRef,
2459
2471
  opts.permission,
2460
2472
  action,
2461
2473
  opts.reason
@@ -2465,16 +2477,16 @@ Notes:
2465
2477
  );
2466
2478
 
2467
2479
  // src/commands/zero/doctor/index.ts
2468
- var zeroDoctorCommand = new Command().name("doctor").description("Diagnose runtime issues (missing tokens, firewall denials)").addCommand(missingTokenCommand).addCommand(firewallDenyCommand).addCommand(firewallPermissionsChangeCommand).addHelpText(
2480
+ var zeroDoctorCommand = new Command().name("doctor").description("Diagnose runtime issues (missing tokens, permission denials)").addCommand(missingTokenCommand).addCommand(permissionDenyCommand).addCommand(permissionChangeCommand).addHelpText(
2469
2481
  "after",
2470
2482
  `
2471
2483
  Examples:
2472
2484
  Missing an API key? zero doctor missing-token GITHUB_TOKEN
2473
- Firewall blocked? zero doctor firewall-deny github --method GET --path /repos/owner/repo
2474
- Change a permission? zero doctor firewall-permissions-change github --permission contents:read --enable
2485
+ Permission denied? zero doctor permission-deny github --method GET --path /repos/owner/repo
2486
+ Change a permission? zero doctor permission-change github --permission contents:read --enable
2475
2487
 
2476
2488
  Notes:
2477
- - Use this when your task fails due to a missing environment variable or firewall denial
2489
+ - Use this when your task fails due to a missing environment variable or permission denial
2478
2490
  - The doctor will identify the issue and give the user a link to resolve it`
2479
2491
  );
2480
2492
 
@@ -3718,7 +3730,7 @@ Examples:
3718
3730
  With title and comment: zero slack upload-file -f /tmp/data.csv -c C01234 --title "Daily Report" --comment "Here's the report"
3719
3731
 
3720
3732
  Notes:
3721
- - Uses the bot token (not user SLACK_TOKEN), so no files:write firewall permission is needed
3733
+ - Uses the bot token (not user SLACK_TOKEN), so no files:write permission is needed
3722
3734
  - Returns file_id and permalink for reference`
3723
3735
  ).action(
3724
3736
  withErrorHandler(
@@ -3931,7 +3943,7 @@ async function showSandboxInfo(showPermissions) {
3931
3943
  const permissionDataAvailable = agentResult.status === "fulfilled" && enabledResult.status === "fulfilled";
3932
3944
  if (permissionDataAvailable) {
3933
3945
  resolvedPolicies = resolveFirewallPolicies(
3934
- agentResult.value.firewallPolicies,
3946
+ agentResult.value.permissionPolicies,
3935
3947
  enabledResult.value
3936
3948
  );
3937
3949
  }
@@ -5789,7 +5801,7 @@ function registerZeroCommands(prog, commands) {
5789
5801
  var program = new Command();
5790
5802
  program.name("zero").description(
5791
5803
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
5792
- ).version("9.107.0").addHelpText(
5804
+ ).version("9.107.2").addHelpText(
5793
5805
  "after",
5794
5806
  `
5795
5807
  Examples: