@vm0/cli 9.177.19 → 9.178.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/{chunk-4ILTCW7H.js → chunk-DPEOZVW6.js} +1286 -143
- package/{chunk-4ILTCW7H.js.map → chunk-DPEOZVW6.js.map} +1 -1
- package/index.js +9 -9
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/zero.js +152 -80
- package/zero.js.map +1 -1
package/package.json
CHANGED
package/zero.js
CHANGED
|
@@ -148,7 +148,7 @@ import {
|
|
|
148
148
|
upsertZeroOrgModelProvider,
|
|
149
149
|
withErrorHandler,
|
|
150
150
|
zeroAgentCustomSkillNameSchema
|
|
151
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-DPEOZVW6.js";
|
|
152
152
|
import {
|
|
153
153
|
__toESM,
|
|
154
154
|
init_esm_shims
|
|
@@ -2978,6 +2978,66 @@ How connectors work:
|
|
|
2978
2978
|
|
|
2979
2979
|
// src/commands/zero/doctor/permission-deny.ts
|
|
2980
2980
|
init_esm_shims();
|
|
2981
|
+
|
|
2982
|
+
// src/commands/zero/doctor/permission-context.ts
|
|
2983
|
+
init_esm_shims();
|
|
2984
|
+
var LEGACY_PERMISSION_GRANT_MODE = "legacy";
|
|
2985
|
+
function roleFromOrg(org) {
|
|
2986
|
+
if (org.role === "admin") return "admin";
|
|
2987
|
+
if (org.role === "member") return "member";
|
|
2988
|
+
return "unknown";
|
|
2989
|
+
}
|
|
2990
|
+
function permissionGrantModeFromOrg(org) {
|
|
2991
|
+
return org.permissionGrantMode ?? LEGACY_PERMISSION_GRANT_MODE;
|
|
2992
|
+
}
|
|
2993
|
+
async function resolveUserId() {
|
|
2994
|
+
const zeroPayload = decodeZeroTokenPayload();
|
|
2995
|
+
if (zeroPayload?.userId) return zeroPayload.userId;
|
|
2996
|
+
const token = await getToken();
|
|
2997
|
+
const cliPayload = decodeCliTokenPayload(token);
|
|
2998
|
+
return cliPayload?.userId;
|
|
2999
|
+
}
|
|
3000
|
+
async function resolvePermissionGrantMode() {
|
|
3001
|
+
try {
|
|
3002
|
+
const org = await getZeroOrg();
|
|
3003
|
+
return permissionGrantModeFromOrg(org);
|
|
3004
|
+
} catch {
|
|
3005
|
+
return LEGACY_PERMISSION_GRANT_MODE;
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
async function resolvePermissionChangeContext(agentId) {
|
|
3009
|
+
try {
|
|
3010
|
+
const org = await getZeroOrg();
|
|
3011
|
+
const permissionGrantMode = permissionGrantModeFromOrg(org);
|
|
3012
|
+
if (!agentId || permissionGrantMode === "user-grants") {
|
|
3013
|
+
return {
|
|
3014
|
+
role: roleFromOrg(org),
|
|
3015
|
+
permissionGrantMode
|
|
3016
|
+
};
|
|
3017
|
+
}
|
|
3018
|
+
if (org.role === "admin") {
|
|
3019
|
+
return { role: "admin", permissionGrantMode };
|
|
3020
|
+
}
|
|
3021
|
+
if (org.role === "member") {
|
|
3022
|
+
const userId = await resolveUserId();
|
|
3023
|
+
if (userId) {
|
|
3024
|
+
const agent = await getZeroAgent(agentId);
|
|
3025
|
+
if (agent.ownerId === userId) {
|
|
3026
|
+
return { role: "owner", permissionGrantMode };
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
return { role: "member", permissionGrantMode };
|
|
3030
|
+
}
|
|
3031
|
+
return { role: "unknown", permissionGrantMode };
|
|
3032
|
+
} catch {
|
|
3033
|
+
return {
|
|
3034
|
+
role: "unknown",
|
|
3035
|
+
permissionGrantMode: LEGACY_PERMISSION_GRANT_MODE
|
|
3036
|
+
};
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
// src/commands/zero/doctor/permission-deny.ts
|
|
2981
3041
|
var permissionDenyCommand = new Command().name("permission-deny").description(
|
|
2982
3042
|
"Diagnose a permission denial and find the permission that covers it"
|
|
2983
3043
|
).argument("<connector-ref>", "The connector type (e.g. github)").addOption(
|
|
@@ -3031,8 +3091,11 @@ Notes:
|
|
|
3031
3091
|
return (ruleCount.get(current) ?? Infinity) < (ruleCount.get(narrowest) ?? Infinity) ? current : narrowest;
|
|
3032
3092
|
});
|
|
3033
3093
|
console.log(`This is covered by the "${permission}" permission.`);
|
|
3094
|
+
const permissionGrantMode = await resolvePermissionGrantMode();
|
|
3095
|
+
const reasonArg = permissionGrantMode === "user-grants" ? "" : ' --reason "why this is needed"';
|
|
3096
|
+
const actionVerb = permissionGrantMode === "user-grants" ? "allow" : "request";
|
|
3034
3097
|
console.log(
|
|
3035
|
-
`To
|
|
3098
|
+
`To ${actionVerb} this permission, run: zero doctor permission-change ${connectorRef} --permission ${permission} --enable${reasonArg}`
|
|
3036
3099
|
);
|
|
3037
3100
|
}
|
|
3038
3101
|
)
|
|
@@ -3040,36 +3103,6 @@ Notes:
|
|
|
3040
3103
|
|
|
3041
3104
|
// src/commands/zero/doctor/permission-change.ts
|
|
3042
3105
|
init_esm_shims();
|
|
3043
|
-
|
|
3044
|
-
// src/commands/zero/doctor/resolve-role.ts
|
|
3045
|
-
init_esm_shims();
|
|
3046
|
-
async function resolveUserId() {
|
|
3047
|
-
const zeroPayload = decodeZeroTokenPayload();
|
|
3048
|
-
if (zeroPayload?.userId) return zeroPayload.userId;
|
|
3049
|
-
const token = await getToken();
|
|
3050
|
-
const cliPayload = decodeCliTokenPayload(token);
|
|
3051
|
-
return cliPayload?.userId;
|
|
3052
|
-
}
|
|
3053
|
-
async function resolveAgentRole(agentId) {
|
|
3054
|
-
try {
|
|
3055
|
-
const org = await getZeroOrg();
|
|
3056
|
-
if (org.role === "admin") return "admin";
|
|
3057
|
-
if (org.role === "member") {
|
|
3058
|
-
const userId = await resolveUserId();
|
|
3059
|
-
if (userId) {
|
|
3060
|
-
const agent = await getZeroAgent(agentId);
|
|
3061
|
-
if (agent.ownerId === userId) return "owner";
|
|
3062
|
-
}
|
|
3063
|
-
return "member";
|
|
3064
|
-
}
|
|
3065
|
-
return "unknown";
|
|
3066
|
-
} catch (error) {
|
|
3067
|
-
console.debug("resolveAgentRole failed, falling back to unknown:", error);
|
|
3068
|
-
return "unknown";
|
|
3069
|
-
}
|
|
3070
|
-
}
|
|
3071
|
-
|
|
3072
|
-
// src/commands/zero/doctor/permission-change.ts
|
|
3073
3106
|
function findPermissionInConfig(ref, permissionName) {
|
|
3074
3107
|
if (!isFirewallConnectorType(ref)) return false;
|
|
3075
3108
|
const config = getConnectorFirewall(ref);
|
|
@@ -3082,23 +3115,15 @@ function findPermissionInConfig(ref, permissionName) {
|
|
|
3082
3115
|
return false;
|
|
3083
3116
|
}
|
|
3084
3117
|
var REASON_MAX_LENGTH = 500;
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
const
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
});
|
|
3095
|
-
if (role === "member" && reason) {
|
|
3096
|
-
const truncated = reason.length > REASON_MAX_LENGTH ? reason.slice(0, REASON_MAX_LENGTH) : reason;
|
|
3097
|
-
urlParams.set("reason", truncated);
|
|
3098
|
-
}
|
|
3099
|
-
const pagePath = agentId ? `/agents/${agentId}/permissions` : "/agents";
|
|
3100
|
-
const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
|
|
3101
|
-
if (connectorRef === "slack" && permission === "chat:write" && action === "enable") {
|
|
3118
|
+
function addReasonParam(urlParams, role, usesUserGrants, reason) {
|
|
3119
|
+
if (usesUserGrants || role !== "member" || !reason) return;
|
|
3120
|
+
const truncated = reason.length > REASON_MAX_LENGTH ? reason.slice(0, REASON_MAX_LENGTH) : reason;
|
|
3121
|
+
urlParams.set("reason", truncated);
|
|
3122
|
+
}
|
|
3123
|
+
function printSensitivePermissionGuidance(connectorRef, permission, action, usesUserGrants) {
|
|
3124
|
+
if (action !== "enable") return;
|
|
3125
|
+
const approvalWording = usesUserGrants ? "Only allow this permission below" : "Only request user approval below";
|
|
3126
|
+
if (connectorRef === "slack" && permission === "chat:write") {
|
|
3102
3127
|
console.log("");
|
|
3103
3128
|
console.log(
|
|
3104
3129
|
"IMPORTANT: Granting chat:write allows sending messages AS THE USER's identity, not as a bot."
|
|
@@ -3107,11 +3132,11 @@ async function outputPermissionChangeMessage(connectorRef, permission, action, r
|
|
|
3107
3132
|
"Use `zero slack message send -c <channel> -t <text>` to send messages as the bot instead \u2014 this is the recommended approach for most use cases."
|
|
3108
3133
|
);
|
|
3109
3134
|
console.log(
|
|
3110
|
-
|
|
3135
|
+
`${approvalWording} if acting as the user is specifically required.`
|
|
3111
3136
|
);
|
|
3112
3137
|
console.log("");
|
|
3113
3138
|
}
|
|
3114
|
-
if (connectorRef === "gmail" && permission === "gmail.send"
|
|
3139
|
+
if (connectorRef === "gmail" && permission === "gmail.send") {
|
|
3115
3140
|
console.log("");
|
|
3116
3141
|
console.log(
|
|
3117
3142
|
"IMPORTANT: Granting gmail.send allows the agent to send emails directly as the user."
|
|
@@ -3120,51 +3145,98 @@ async function outputPermissionChangeMessage(connectorRef, permission, action, r
|
|
|
3120
3145
|
"Consider keeping gmail.send disabled and using gmail.compose instead \u2014 the agent can create drafts for the user to review and send manually."
|
|
3121
3146
|
);
|
|
3122
3147
|
console.log(
|
|
3123
|
-
|
|
3148
|
+
`${approvalWording} if direct sending is specifically required.`
|
|
3124
3149
|
);
|
|
3125
3150
|
console.log("");
|
|
3126
3151
|
}
|
|
3127
|
-
|
|
3152
|
+
}
|
|
3153
|
+
function printPermissionActionMessage(args) {
|
|
3154
|
+
if (args.usesUserGrants) {
|
|
3155
|
+
const grantAction = args.action === "enable" ? "allow" : "deny";
|
|
3128
3156
|
console.log(
|
|
3129
|
-
`You can ${
|
|
3157
|
+
`You can ${grantAction} the "${args.permission}" permission for your connector access: [Manage ${args.label} permissions](${args.url})`
|
|
3130
3158
|
);
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
)
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3159
|
+
return;
|
|
3160
|
+
}
|
|
3161
|
+
if (args.role === "admin" || args.role === "owner") {
|
|
3162
|
+
console.log(
|
|
3163
|
+
`You can ${args.action} the "${args.permission}" permission directly: [Manage ${args.label} permissions](${args.url})`
|
|
3164
|
+
);
|
|
3165
|
+
return;
|
|
3166
|
+
}
|
|
3167
|
+
if (args.role !== "member") {
|
|
3168
|
+
console.log(
|
|
3169
|
+
`To ${args.action} the "${args.permission}" permission for ${args.label}: [Manage ${args.label} permissions](${args.url})`
|
|
3170
|
+
);
|
|
3171
|
+
return;
|
|
3172
|
+
}
|
|
3173
|
+
if (!args.reason) {
|
|
3174
|
+
console.log(
|
|
3175
|
+
`IMPORTANT: Re-run with \`--reason "one sentence why this is needed"\` so the admin can review your request faster.`
|
|
3176
|
+
);
|
|
3177
|
+
return;
|
|
3178
|
+
}
|
|
3179
|
+
if (args.action === "enable") {
|
|
3146
3180
|
console.log(
|
|
3147
|
-
`
|
|
3181
|
+
`Permission changes require admin approval. Request access at: [Request ${args.label} access](${args.url})`
|
|
3148
3182
|
);
|
|
3183
|
+
return;
|
|
3149
3184
|
}
|
|
3185
|
+
console.log(
|
|
3186
|
+
`Permission changes require admin approval. Contact an org admin to disable this permission: [View ${args.label} permissions](${args.url})`
|
|
3187
|
+
);
|
|
3150
3188
|
}
|
|
3151
|
-
|
|
3189
|
+
async function outputPermissionChangeMessage(connectorRef, permission, action, reason) {
|
|
3190
|
+
const { label } = CONNECTOR_TYPES[connectorRef];
|
|
3191
|
+
const platformOrigin = await getPlatformOrigin();
|
|
3192
|
+
const agentId = process.env.ZERO_AGENT_ID;
|
|
3193
|
+
const context = await resolvePermissionChangeContext(agentId || void 0);
|
|
3194
|
+
const role = context.role;
|
|
3195
|
+
const permissionGrantMode = context.permissionGrantMode;
|
|
3196
|
+
const usesUserGrants = permissionGrantMode === "user-grants";
|
|
3197
|
+
const urlParams = new URLSearchParams({
|
|
3198
|
+
ref: connectorRef,
|
|
3199
|
+
permission,
|
|
3200
|
+
action: action === "enable" ? "allow" : "deny"
|
|
3201
|
+
});
|
|
3202
|
+
addReasonParam(urlParams, role, usesUserGrants, reason);
|
|
3203
|
+
const pagePath = agentId ? `/agents/${agentId}/permissions` : "/agents";
|
|
3204
|
+
const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
|
|
3205
|
+
printSensitivePermissionGuidance(
|
|
3206
|
+
connectorRef,
|
|
3207
|
+
permission,
|
|
3208
|
+
action,
|
|
3209
|
+
usesUserGrants
|
|
3210
|
+
);
|
|
3211
|
+
printPermissionActionMessage({
|
|
3212
|
+
usesUserGrants,
|
|
3213
|
+
action,
|
|
3214
|
+
role,
|
|
3215
|
+
permission,
|
|
3216
|
+
label,
|
|
3217
|
+
url,
|
|
3218
|
+
reason
|
|
3219
|
+
});
|
|
3220
|
+
}
|
|
3221
|
+
var permissionChangeCommand = new Command().name("permission-change").description("Change or request a permission (enable or disable)").argument("<connector-ref>", "The connector type (e.g. github)").addOption(
|
|
3152
3222
|
new Option(
|
|
3153
3223
|
"--permission <name>",
|
|
3154
3224
|
"The permission name to change"
|
|
3155
3225
|
).makeOptionMandatory()
|
|
3156
3226
|
).addOption(
|
|
3157
|
-
new Option(
|
|
3158
|
-
"
|
|
3159
|
-
|
|
3227
|
+
new Option(
|
|
3228
|
+
"--enable",
|
|
3229
|
+
"Enable or request enabling the permission"
|
|
3230
|
+
).conflicts("disable")
|
|
3160
3231
|
).addOption(
|
|
3161
|
-
new Option(
|
|
3162
|
-
"
|
|
3163
|
-
|
|
3232
|
+
new Option(
|
|
3233
|
+
"--disable",
|
|
3234
|
+
"Disable or request disabling the permission"
|
|
3235
|
+
).conflicts("enable")
|
|
3164
3236
|
).addOption(
|
|
3165
3237
|
new Option(
|
|
3166
3238
|
"--reason <text>",
|
|
3167
|
-
"Brief reason
|
|
3239
|
+
"Brief reason for admin approval requests (max 500 chars)"
|
|
3168
3240
|
)
|
|
3169
3241
|
).addHelpText(
|
|
3170
3242
|
"after",
|
|
@@ -3175,7 +3247,7 @@ Examples:
|
|
|
3175
3247
|
|
|
3176
3248
|
Notes:
|
|
3177
3249
|
- Outputs a platform URL for the user to adjust the permission
|
|
3178
|
-
-
|
|
3250
|
+
- Depending on rollout state, members either request approval or manage their own permission grants`
|
|
3179
3251
|
).action(
|
|
3180
3252
|
withErrorHandler(
|
|
3181
3253
|
async (connectorRef, opts) => {
|
|
@@ -13229,7 +13301,7 @@ function registerZeroCommands(prog, commands) {
|
|
|
13229
13301
|
var program = new Command();
|
|
13230
13302
|
program.name("zero").description(
|
|
13231
13303
|
"Zero CLI \u2014 interact with the zero platform from inside the sandbox"
|
|
13232
|
-
).version("9.
|
|
13304
|
+
).version("9.178.0").addHelpText("after", () => {
|
|
13233
13305
|
return buildZeroHelpText();
|
|
13234
13306
|
});
|
|
13235
13307
|
if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {
|