@vm0/cli 9.93.0 → 9.94.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/zero.js CHANGED
@@ -102,10 +102,10 @@ import {
102
102
  updateZeroUserPreferences,
103
103
  upsertZeroOrgModelProvider,
104
104
  withErrorHandler
105
- } from "./chunk-UEVD4XR7.js";
105
+ } from "./chunk-OYO75U5W.js";
106
106
 
107
107
  // src/zero.ts
108
- import { Command as Command69 } from "commander";
108
+ import { Command as Command70 } from "commander";
109
109
 
110
110
  // src/commands/zero/org/index.ts
111
111
  import { Command as Command23 } from "commander";
@@ -229,10 +229,21 @@ var membersCommand = new Command5().name("members").description("View organizati
229
229
  // src/commands/zero/org/invite.ts
230
230
  import { Command as Command6 } from "commander";
231
231
  import chalk6 from "chalk";
232
- var inviteCommand = new Command6().name("invite").description("Invite a member to the current organization").requiredOption("--email <email>", "Email address of the member to invite").action(
232
+ var inviteCommand = new Command6().name("invite").description("Invite a member to the current organization").requiredOption("--email <email>", "Email address of the member to invite").option(
233
+ "--role <role>",
234
+ "Role for the invited member (member or admin)",
235
+ "member"
236
+ ).action(
233
237
  withErrorHandler(async (options) => {
234
- await inviteZeroOrgMember(options.email);
235
- console.log(chalk6.green(`\u2713 Invitation sent to ${options.email}`));
238
+ if (options.role !== "member" && options.role !== "admin") {
239
+ throw new Error(
240
+ `Invalid role "${options.role}". Must be "member" or "admin".`
241
+ );
242
+ }
243
+ await inviteZeroOrgMember(options.email, options.role);
244
+ console.log(
245
+ chalk6.green(`\u2713 Invitation sent to ${options.email} as ${options.role}`)
246
+ );
236
247
  })
237
248
  );
238
249
 
@@ -2019,7 +2030,7 @@ var disconnectCommand = new Command33().name("disconnect").description("Disconne
2019
2030
  var zeroConnectorCommand = new Command34().name("connector").description("Check or connect third-party services (GitHub, Slack, etc.)").addCommand(listCommand6).addCommand(statusCommand2).addCommand(connectCommand).addCommand(disconnectCommand);
2020
2031
 
2021
2032
  // src/commands/zero/doctor/index.ts
2022
- import { Command as Command37 } from "commander";
2033
+ import { Command as Command38 } from "commander";
2023
2034
 
2024
2035
  // src/commands/zero/doctor/missing-token.ts
2025
2036
  import { Command as Command35 } from "commander";
@@ -2116,6 +2127,22 @@ Notes:
2116
2127
 
2117
2128
  // src/commands/zero/doctor/firewall-deny.ts
2118
2129
  import { Command as Command36, Option } from "commander";
2130
+
2131
+ // src/commands/zero/doctor/resolve-role.ts
2132
+ async function resolveRole() {
2133
+ try {
2134
+ const org = await getZeroOrg();
2135
+ if (org.role === "admin" || org.role === "member") {
2136
+ return org.role;
2137
+ }
2138
+ return "unknown";
2139
+ } catch (error) {
2140
+ console.debug("resolveRole failed, falling back to unknown:", error);
2141
+ return "unknown";
2142
+ }
2143
+ }
2144
+
2145
+ // src/commands/zero/doctor/firewall-deny.ts
2119
2146
  var firewallDenyCommand = new Command36().name("firewall-deny").description(
2120
2147
  "Diagnose a firewall denial and find the permission that covers it"
2121
2148
  ).argument("<firewall-ref>", "The firewall connector type (e.g. github)").addOption(
@@ -2181,20 +2208,116 @@ Notes:
2181
2208
  );
2182
2209
  console.log("");
2183
2210
  }
2184
- console.log(
2185
- `Ask the user to allow it at: [Allow ${label} access](${url})`
2186
- );
2211
+ const role = agentId ? await resolveRole() : "unknown";
2212
+ if (role === "admin") {
2213
+ console.log(
2214
+ `You can allow this permission directly: [Manage ${label} firewall](${url})`
2215
+ );
2216
+ } else if (role === "member") {
2217
+ console.log(
2218
+ `This change requires admin approval. Request access at: [Request ${label} access](${url})`
2219
+ );
2220
+ } else {
2221
+ console.log(
2222
+ `Ask the user to allow it at: [Allow ${label} access](${url})`
2223
+ );
2224
+ }
2225
+ }
2226
+ )
2227
+ );
2228
+
2229
+ // src/commands/zero/doctor/firewall-permissions-change.ts
2230
+ import { Command as Command37, Option as Option2 } from "commander";
2231
+ function findPermissionInConfig(ref, permissionName) {
2232
+ if (!isFirewallConnectorType(ref)) return false;
2233
+ const config = getConnectorFirewall(ref);
2234
+ for (const api of config.apis) {
2235
+ if (!api.permissions) continue;
2236
+ for (const p of api.permissions) {
2237
+ if (p.name === permissionName) return true;
2238
+ }
2239
+ }
2240
+ return false;
2241
+ }
2242
+ var firewallPermissionsChangeCommand = new Command37().name("firewall-permissions-change").description("Request a firewall permission change (enable or disable)").argument("<firewall-ref>", "The firewall connector type (e.g. github)").addOption(
2243
+ new Option2(
2244
+ "--permission <name>",
2245
+ "The permission name to change"
2246
+ ).makeOptionMandatory()
2247
+ ).addOption(
2248
+ new Option2("--enable", "Request to enable the permission").conflicts(
2249
+ "disable"
2250
+ )
2251
+ ).addOption(
2252
+ new Option2("--disable", "Request to disable the permission").conflicts(
2253
+ "enable"
2254
+ )
2255
+ ).addHelpText(
2256
+ "after",
2257
+ `
2258
+ Examples:
2259
+ zero doctor firewall-permissions-change github --permission contents:read --enable
2260
+ zero doctor firewall-permissions-change slack --permission chat:write --disable
2261
+
2262
+ Notes:
2263
+ - Outputs a platform URL for the user to adjust the permission
2264
+ - Admins can change permissions directly; members must request approval`
2265
+ ).action(
2266
+ withErrorHandler(
2267
+ async (firewallRef, opts) => {
2268
+ if (!opts.enable && !opts.disable) {
2269
+ throw new Error("Either --enable or --disable is required");
2270
+ }
2271
+ if (!isFirewallConnectorType(firewallRef)) {
2272
+ throw new Error(`Unknown firewall connector type: ${firewallRef}`);
2273
+ }
2274
+ if (!findPermissionInConfig(firewallRef, opts.permission)) {
2275
+ throw new Error(
2276
+ `Unknown permission "${opts.permission}" for ${firewallRef} firewall`
2277
+ );
2278
+ }
2279
+ const { label } = CONNECTOR_TYPES[firewallRef];
2280
+ const action = opts.enable ? "enable" : "disable";
2281
+ const platformOrigin = await getPlatformOrigin();
2282
+ const agentId = process.env.ZERO_AGENT_ID;
2283
+ const urlParams = new URLSearchParams({
2284
+ ref: firewallRef,
2285
+ permission: opts.permission
2286
+ });
2287
+ const pagePath = agentId ? `/firewall-allow/${agentId}` : "/firewall-allow";
2288
+ const url = `${platformOrigin}${pagePath}?${urlParams.toString()}`;
2289
+ const role = agentId ? await resolveRole() : "unknown";
2290
+ if (role === "admin") {
2291
+ console.log(
2292
+ `You can ${action} the "${opts.permission}" permission directly: [Manage ${label} firewall](${url})`
2293
+ );
2294
+ } else if (role === "member") {
2295
+ if (action === "enable") {
2296
+ console.log(
2297
+ `Permission changes require admin approval. Request access at: [Request ${label} access](${url})`
2298
+ );
2299
+ } else {
2300
+ console.log(
2301
+ `Permission changes require admin approval. Contact an org admin to disable this permission: [View ${label} firewall](${url})`
2302
+ );
2303
+ }
2304
+ } else {
2305
+ console.log(
2306
+ `To ${action} the "${opts.permission}" permission on the ${label} firewall: [Manage ${label} firewall](${url})`
2307
+ );
2308
+ }
2187
2309
  }
2188
2310
  )
2189
2311
  );
2190
2312
 
2191
2313
  // src/commands/zero/doctor/index.ts
2192
- var zeroDoctorCommand = new Command37().name("doctor").description("Diagnose runtime issues (missing tokens, firewall denials)").addCommand(missingTokenCommand).addCommand(firewallDenyCommand).addHelpText(
2314
+ var zeroDoctorCommand = new Command38().name("doctor").description("Diagnose runtime issues (missing tokens, firewall denials)").addCommand(missingTokenCommand).addCommand(firewallDenyCommand).addCommand(firewallPermissionsChangeCommand).addHelpText(
2193
2315
  "after",
2194
2316
  `
2195
2317
  Examples:
2196
2318
  Missing an API key? zero doctor missing-token GITHUB_TOKEN
2197
2319
  Firewall blocked? zero doctor firewall-deny github --method GET --path /repos/owner/repo
2320
+ Change a permission? zero doctor firewall-permissions-change github --permission contents:read --enable
2198
2321
 
2199
2322
  Notes:
2200
2323
  - Use this when your task fails due to a missing environment variable or firewall denial
@@ -2202,7 +2325,7 @@ Notes:
2202
2325
  );
2203
2326
 
2204
2327
  // src/commands/zero/preference/index.ts
2205
- import { Command as Command38 } from "commander";
2328
+ import { Command as Command39 } from "commander";
2206
2329
  import chalk31 from "chalk";
2207
2330
  function detectTimezone2() {
2208
2331
  return Intl.DateTimeFormat().resolvedOptions().timeZone;
@@ -2259,7 +2382,7 @@ System timezone detected: ${detectedTz}`));
2259
2382
  }
2260
2383
  }
2261
2384
  }
2262
- var zeroPreferenceCommand = new Command38().name("preference").description("View or update user preferences (timezone, notifications)").option("--timezone <timezone>", "IANA timezone (e.g., America/New_York)").action(
2385
+ var zeroPreferenceCommand = new Command39().name("preference").description("View or update user preferences (timezone, notifications)").option("--timezone <timezone>", "IANA timezone (e.g., America/New_York)").action(
2263
2386
  withErrorHandler(async (opts) => {
2264
2387
  const updates = buildUpdates(opts);
2265
2388
  if (updates) {
@@ -2284,7 +2407,7 @@ var zeroPreferenceCommand = new Command38().name("preference").description("View
2284
2407
  );
2285
2408
 
2286
2409
  // src/commands/zero/run/run.ts
2287
- import { Command as Command39 } from "commander";
2410
+ import { Command as Command40 } from "commander";
2288
2411
 
2289
2412
  // src/commands/zero/run/shared.ts
2290
2413
  import chalk32 from "chalk";
@@ -2367,7 +2490,7 @@ function showZeroNextSteps(result) {
2367
2490
  }
2368
2491
 
2369
2492
  // src/commands/zero/run/run.ts
2370
- var mainRunCommand = new Command39().name("run").description("Delegate a task to a teammate agent").argument("<agent-id>", "Agent UUID (from `zero agent list`)").argument("<prompt>", "Task prompt for the agent").option(
2493
+ var mainRunCommand = new Command40().name("run").description("Delegate a task to a teammate agent").argument("<agent-id>", "Agent UUID (from `zero agent list`)").argument("<prompt>", "Task prompt for the agent").option(
2371
2494
  "--model-provider <type>",
2372
2495
  "Override model provider (e.g., anthropic-api-key)"
2373
2496
  ).option("--verbose", "Show full tool inputs and outputs").addHelpText(
@@ -2415,8 +2538,8 @@ Notes:
2415
2538
  );
2416
2539
 
2417
2540
  // src/commands/zero/run/continue.ts
2418
- import { Command as Command40 } from "commander";
2419
- var continueCommand = new Command40().name("continue").description("Continue a previous delegation from a session").argument("<session-id>", "Session ID from a previous run").argument("<prompt>", "Follow-up prompt for the agent").option(
2541
+ import { Command as Command41 } from "commander";
2542
+ var continueCommand = new Command41().name("continue").description("Continue a previous delegation from a session").argument("<session-id>", "Session ID from a previous run").argument("<prompt>", "Follow-up prompt for the agent").option(
2420
2543
  "--model-provider <type>",
2421
2544
  "Override model provider (e.g., anthropic-api-key)"
2422
2545
  ).option("--verbose", "Show full tool inputs and outputs").addHelpText(
@@ -2473,10 +2596,10 @@ Examples:
2473
2596
  var zeroRunCommand = mainRunCommand;
2474
2597
 
2475
2598
  // src/commands/zero/schedule/index.ts
2476
- import { Command as Command47 } from "commander";
2599
+ import { Command as Command48 } from "commander";
2477
2600
 
2478
2601
  // src/commands/zero/schedule/setup.ts
2479
- import { Command as Command41 } from "commander";
2602
+ import { Command as Command42 } from "commander";
2480
2603
  import chalk33 from "chalk";
2481
2604
  var FREQUENCY_CHOICES = [
2482
2605
  { title: "Daily", value: "daily", description: "Run every day" },
@@ -2885,7 +3008,7 @@ async function handleScheduleEnabling(params) {
2885
3008
  showEnableHint(agentName);
2886
3009
  }
2887
3010
  }
2888
- var setupCommand2 = new Command41().name("setup").description("Create or edit a schedule for a zero agent").argument("<agent-id>", "Agent ID").option("-n, --name <schedule-name>", 'Schedule name (default: "default")').option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once|loop").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-i, --interval <seconds>", "Interval in seconds for loop mode").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("-e, --enable", "Enable schedule immediately after creation").addHelpText(
3011
+ var setupCommand2 = new Command42().name("setup").description("Create or edit a schedule for a zero agent").argument("<agent-id>", "Agent ID").option("-n, --name <schedule-name>", 'Schedule name (default: "default")').option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once|loop").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-i, --interval <seconds>", "Interval in seconds for loop mode").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("-e, --enable", "Enable schedule immediately after creation").addHelpText(
2889
3012
  "after",
2890
3013
  `
2891
3014
  Examples:
@@ -2974,9 +3097,9 @@ Notes:
2974
3097
  );
2975
3098
 
2976
3099
  // src/commands/zero/schedule/list.ts
2977
- import { Command as Command42 } from "commander";
3100
+ import { Command as Command43 } from "commander";
2978
3101
  import chalk34 from "chalk";
2979
- var listCommand7 = new Command42().name("list").alias("ls").description("List all zero schedules").addHelpText(
3102
+ var listCommand7 = new Command43().name("list").alias("ls").description("List all zero schedules").addHelpText(
2980
3103
  "after",
2981
3104
  `
2982
3105
  Examples:
@@ -3034,7 +3157,7 @@ Examples:
3034
3157
  );
3035
3158
 
3036
3159
  // src/commands/zero/schedule/status.ts
3037
- import { Command as Command43 } from "commander";
3160
+ import { Command as Command44 } from "commander";
3038
3161
  import chalk35 from "chalk";
3039
3162
  function formatDateTimeStyled(dateStr) {
3040
3163
  if (!dateStr) return chalk35.dim("-");
@@ -3087,7 +3210,7 @@ function printTimeSchedule(schedule) {
3087
3210
  console.log(`${"Failures:".padEnd(16)}${failureText}`);
3088
3211
  }
3089
3212
  }
3090
- var statusCommand3 = new Command43().name("status").description("Show detailed status of a zero schedule").argument("<agent-id>", "Agent ID").option(
3213
+ var statusCommand3 = new Command44().name("status").description("Show detailed status of a zero schedule").argument("<agent-id>", "Agent ID").option(
3091
3214
  "-n, --name <schedule-name>",
3092
3215
  "Schedule name (required when agent has multiple schedules)"
3093
3216
  ).addHelpText(
@@ -3112,9 +3235,9 @@ Examples:
3112
3235
  );
3113
3236
 
3114
3237
  // src/commands/zero/schedule/delete.ts
3115
- import { Command as Command44 } from "commander";
3238
+ import { Command as Command45 } from "commander";
3116
3239
  import chalk36 from "chalk";
3117
- var deleteCommand3 = new Command44().name("delete").alias("rm").description("Delete a zero schedule").argument("<agent-id>", "Agent ID").option(
3240
+ var deleteCommand3 = new Command45().name("delete").alias("rm").description("Delete a zero schedule").argument("<agent-id>", "Agent ID").option(
3118
3241
  "-n, --name <schedule-name>",
3119
3242
  "Schedule name (required when agent has multiple schedules)"
3120
3243
  ).option("-y, --yes", "Skip confirmation prompt").addHelpText(
@@ -3156,9 +3279,9 @@ Notes:
3156
3279
  );
3157
3280
 
3158
3281
  // src/commands/zero/schedule/enable.ts
3159
- import { Command as Command45 } from "commander";
3282
+ import { Command as Command46 } from "commander";
3160
3283
  import chalk37 from "chalk";
3161
- var enableCommand = new Command45().name("enable").description("Enable a zero schedule").argument("<agent-id>", "Agent ID").option(
3284
+ var enableCommand = new Command46().name("enable").description("Enable a zero schedule").argument("<agent-id>", "Agent ID").option(
3162
3285
  "-n, --name <schedule-name>",
3163
3286
  "Schedule name (required when agent has multiple schedules)"
3164
3287
  ).addHelpText(
@@ -3182,9 +3305,9 @@ Examples:
3182
3305
  );
3183
3306
 
3184
3307
  // src/commands/zero/schedule/disable.ts
3185
- import { Command as Command46 } from "commander";
3308
+ import { Command as Command47 } from "commander";
3186
3309
  import chalk38 from "chalk";
3187
- var disableCommand = new Command46().name("disable").description("Disable a zero schedule").argument("<agent-id>", "Agent ID").option(
3310
+ var disableCommand = new Command47().name("disable").description("Disable a zero schedule").argument("<agent-id>", "Agent ID").option(
3188
3311
  "-n, --name <schedule-name>",
3189
3312
  "Schedule name (required when agent has multiple schedules)"
3190
3313
  ).addHelpText(
@@ -3208,7 +3331,7 @@ Examples:
3208
3331
  );
3209
3332
 
3210
3333
  // src/commands/zero/schedule/index.ts
3211
- var zeroScheduleCommand = new Command47().name("schedule").description("Create or manage recurring scheduled tasks").addCommand(setupCommand2).addCommand(listCommand7).addCommand(statusCommand3).addCommand(deleteCommand3).addCommand(enableCommand).addCommand(disableCommand).addHelpText(
3334
+ var zeroScheduleCommand = new Command48().name("schedule").description("Create or manage recurring scheduled tasks").addCommand(setupCommand2).addCommand(listCommand7).addCommand(statusCommand3).addCommand(deleteCommand3).addCommand(enableCommand).addCommand(disableCommand).addHelpText(
3212
3335
  "after",
3213
3336
  `
3214
3337
  Examples:
@@ -3221,12 +3344,12 @@ Examples:
3221
3344
  );
3222
3345
 
3223
3346
  // src/commands/zero/secret/index.ts
3224
- import { Command as Command51 } from "commander";
3347
+ import { Command as Command52 } from "commander";
3225
3348
 
3226
3349
  // src/commands/zero/secret/list.ts
3227
- import { Command as Command48 } from "commander";
3350
+ import { Command as Command49 } from "commander";
3228
3351
  import chalk39 from "chalk";
3229
- var listCommand8 = new Command48().name("list").alias("ls").description("List all secrets").action(
3352
+ var listCommand8 = new Command49().name("list").alias("ls").description("List all secrets").action(
3230
3353
  withErrorHandler(async () => {
3231
3354
  const result = await listZeroSecrets();
3232
3355
  if (result.secrets.length === 0) {
@@ -3279,9 +3402,9 @@ var listCommand8 = new Command48().name("list").alias("ls").description("List al
3279
3402
  );
3280
3403
 
3281
3404
  // src/commands/zero/secret/set.ts
3282
- import { Command as Command49 } from "commander";
3405
+ import { Command as Command50 } from "commander";
3283
3406
  import chalk40 from "chalk";
3284
- var setCommand4 = new Command49().name("set").description("Create or update a secret").argument("<name>", "Secret name (uppercase, e.g., MY_API_KEY)").option(
3407
+ var setCommand4 = new Command50().name("set").description("Create or update a secret").argument("<name>", "Secret name (uppercase, e.g., MY_API_KEY)").option(
3285
3408
  "-b, --body <value>",
3286
3409
  "Secret value (required in non-interactive mode)"
3287
3410
  ).option("-d, --description <description>", "Optional description").action(
@@ -3327,9 +3450,9 @@ var setCommand4 = new Command49().name("set").description("Create or update a se
3327
3450
  );
3328
3451
 
3329
3452
  // src/commands/zero/secret/delete.ts
3330
- import { Command as Command50 } from "commander";
3453
+ import { Command as Command51 } from "commander";
3331
3454
  import chalk41 from "chalk";
3332
- var deleteCommand4 = new Command50().name("delete").description("Delete a secret").argument("<name>", "Secret name to delete").option("-y, --yes", "Skip confirmation prompt").action(
3455
+ var deleteCommand4 = new Command51().name("delete").description("Delete a secret").argument("<name>", "Secret name to delete").option("-y, --yes", "Skip confirmation prompt").action(
3333
3456
  withErrorHandler(async (name, options) => {
3334
3457
  if (!options.yes) {
3335
3458
  if (!isInteractive()) {
@@ -3350,19 +3473,19 @@ var deleteCommand4 = new Command50().name("delete").description("Delete a secret
3350
3473
  );
3351
3474
 
3352
3475
  // src/commands/zero/secret/index.ts
3353
- var zeroSecretCommand = new Command51().name("secret").description("Read or write secrets (API keys, tokens)").addCommand(listCommand8).addCommand(setCommand4).addCommand(deleteCommand4);
3476
+ var zeroSecretCommand = new Command52().name("secret").description("Read or write secrets (API keys, tokens)").addCommand(listCommand8).addCommand(setCommand4).addCommand(deleteCommand4);
3354
3477
 
3355
3478
  // src/commands/zero/slack/index.ts
3356
- import { Command as Command55 } from "commander";
3479
+ import { Command as Command56 } from "commander";
3357
3480
 
3358
3481
  // src/commands/zero/slack/message/index.ts
3359
- import { Command as Command53 } from "commander";
3482
+ import { Command as Command54 } from "commander";
3360
3483
 
3361
3484
  // src/commands/zero/slack/message/send.ts
3362
3485
  import { readFileSync as readFileSync3 } from "fs";
3363
- import { Command as Command52 } from "commander";
3486
+ import { Command as Command53 } from "commander";
3364
3487
  import chalk42 from "chalk";
3365
- var sendCommand = new Command52().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").addHelpText(
3488
+ var sendCommand = new Command53().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").addHelpText(
3366
3489
  "after",
3367
3490
  `
3368
3491
  Examples:
@@ -3412,7 +3535,7 @@ Notes:
3412
3535
  );
3413
3536
 
3414
3537
  // src/commands/zero/slack/message/index.ts
3415
- var zeroSlackMessageCommand = new Command53().name("message").description("Manage Slack messages").addCommand(sendCommand).addHelpText(
3538
+ var zeroSlackMessageCommand = new Command54().name("message").description("Manage Slack messages").addCommand(sendCommand).addHelpText(
3416
3539
  "after",
3417
3540
  `
3418
3541
  Examples:
@@ -3422,9 +3545,9 @@ Examples:
3422
3545
  // src/commands/zero/slack/upload-file.ts
3423
3546
  import { statSync, readFileSync as readFileSync4 } from "fs";
3424
3547
  import { basename } from "path";
3425
- import { Command as Command54 } from "commander";
3548
+ import { Command as Command55 } from "commander";
3426
3549
  import chalk43 from "chalk";
3427
- var uploadFileCommand = new Command54().name("upload-file").description("Upload a file to a Slack channel as the bot").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("-c, --channel <id>", "Slack channel ID").option("--thread <ts>", "Thread timestamp to post as a reply").option("--title <title>", "Display title for the file").option("--comment <text>", "Initial comment to accompany the file").addHelpText(
3550
+ var uploadFileCommand = new Command55().name("upload-file").description("Upload a file to a Slack channel as the bot").requiredOption("-f, --file <path>", "Local file path to upload").requiredOption("-c, --channel <id>", "Slack channel ID").option("--thread <ts>", "Thread timestamp to post as a reply").option("--title <title>", "Display title for the file").option("--comment <text>", "Initial comment to accompany the file").addHelpText(
3428
3551
  "after",
3429
3552
  `
3430
3553
  Examples:
@@ -3477,7 +3600,7 @@ Notes:
3477
3600
  );
3478
3601
 
3479
3602
  // src/commands/zero/slack/index.ts
3480
- var zeroSlackCommand = new Command55().name("slack").description("Send messages and upload files to Slack channels as the bot").addCommand(zeroSlackMessageCommand).addCommand(uploadFileCommand).addHelpText(
3603
+ var zeroSlackCommand = new Command56().name("slack").description("Send messages and upload files to Slack channels as the bot").addCommand(zeroSlackMessageCommand).addCommand(uploadFileCommand).addHelpText(
3481
3604
  "after",
3482
3605
  `
3483
3606
  Examples:
@@ -3487,10 +3610,10 @@ Examples:
3487
3610
  );
3488
3611
 
3489
3612
  // src/commands/zero/variable/index.ts
3490
- import { Command as Command59 } from "commander";
3613
+ import { Command as Command60 } from "commander";
3491
3614
 
3492
3615
  // src/commands/zero/variable/list.ts
3493
- import { Command as Command56 } from "commander";
3616
+ import { Command as Command57 } from "commander";
3494
3617
  import chalk44 from "chalk";
3495
3618
  function truncateValue2(value, maxLength = 60) {
3496
3619
  if (value.length <= maxLength) {
@@ -3498,7 +3621,7 @@ function truncateValue2(value, maxLength = 60) {
3498
3621
  }
3499
3622
  return value.slice(0, maxLength - 15) + "... [truncated]";
3500
3623
  }
3501
- var listCommand9 = new Command56().name("list").alias("ls").description("List all variables").action(
3624
+ var listCommand9 = new Command57().name("list").alias("ls").description("List all variables").action(
3502
3625
  withErrorHandler(async () => {
3503
3626
  const result = await listZeroVariables();
3504
3627
  if (result.variables.length === 0) {
@@ -3526,9 +3649,9 @@ var listCommand9 = new Command56().name("list").alias("ls").description("List al
3526
3649
  );
3527
3650
 
3528
3651
  // src/commands/zero/variable/set.ts
3529
- import { Command as Command57 } from "commander";
3652
+ import { Command as Command58 } from "commander";
3530
3653
  import chalk45 from "chalk";
3531
- var setCommand5 = new Command57().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(
3654
+ var setCommand5 = new Command58().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(
3532
3655
  withErrorHandler(
3533
3656
  async (name, value, options) => {
3534
3657
  let variable;
@@ -3554,9 +3677,9 @@ var setCommand5 = new Command57().name("set").description("Create or update a va
3554
3677
  );
3555
3678
 
3556
3679
  // src/commands/zero/variable/delete.ts
3557
- import { Command as Command58 } from "commander";
3680
+ import { Command as Command59 } from "commander";
3558
3681
  import chalk46 from "chalk";
3559
- var deleteCommand5 = new Command58().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
3682
+ var deleteCommand5 = new Command59().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
3560
3683
  withErrorHandler(async (name, options) => {
3561
3684
  if (!options.yes) {
3562
3685
  if (!isInteractive()) {
@@ -3577,10 +3700,10 @@ var deleteCommand5 = new Command58().name("delete").description("Delete a variab
3577
3700
  );
3578
3701
 
3579
3702
  // src/commands/zero/variable/index.ts
3580
- var zeroVariableCommand = new Command59().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand9).addCommand(setCommand5).addCommand(deleteCommand5);
3703
+ var zeroVariableCommand = new Command60().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand9).addCommand(setCommand5).addCommand(deleteCommand5);
3581
3704
 
3582
3705
  // src/commands/zero/whoami.ts
3583
- import { Command as Command60 } from "commander";
3706
+ import { Command as Command61 } from "commander";
3584
3707
  import chalk47 from "chalk";
3585
3708
  function isInsideSandbox() {
3586
3709
  return !!process.env.ZERO_AGENT_ID;
@@ -3617,7 +3740,7 @@ async function showLocalInfo() {
3617
3740
  console.log(` Active: ${activeOrg}`);
3618
3741
  }
3619
3742
  }
3620
- var zeroWhoamiCommand = new Command60().name("whoami").description("Show agent identity, run ID, and capabilities").addHelpText(
3743
+ var zeroWhoamiCommand = new Command61().name("whoami").description("Show agent identity, run ID, and capabilities").addHelpText(
3621
3744
  "after",
3622
3745
  `
3623
3746
  Examples:
@@ -3637,10 +3760,10 @@ Notes:
3637
3760
  );
3638
3761
 
3639
3762
  // src/commands/zero/ask-user/index.ts
3640
- import { Command as Command62 } from "commander";
3763
+ import { Command as Command63 } from "commander";
3641
3764
 
3642
3765
  // src/commands/zero/ask-user/question.ts
3643
- import { Command as Command61 } from "commander";
3766
+ import { Command as Command62 } from "commander";
3644
3767
  import chalk48 from "chalk";
3645
3768
  function collectOption(value, previous) {
3646
3769
  const list = previous ?? [];
@@ -3652,7 +3775,7 @@ function collectDesc(value, previous) {
3652
3775
  list.push(value);
3653
3776
  return list;
3654
3777
  }
3655
- var questionCommand = new Command61().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(
3778
+ var questionCommand = new Command62().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(
3656
3779
  "--desc <text>",
3657
3780
  "Description for the preceding --option",
3658
3781
  collectDesc
@@ -3735,7 +3858,7 @@ Notes:
3735
3858
  );
3736
3859
 
3737
3860
  // src/commands/zero/ask-user/index.ts
3738
- var zeroAskUserCommand = new Command62().name("ask-user").description("Ask the user a question and wait for the answer").addCommand(questionCommand).addHelpText(
3861
+ var zeroAskUserCommand = new Command63().name("ask-user").description("Ask the user a question and wait for the answer").addCommand(questionCommand).addHelpText(
3739
3862
  "after",
3740
3863
  `
3741
3864
  Examples:
@@ -3747,14 +3870,44 @@ Notes:
3747
3870
  );
3748
3871
 
3749
3872
  // src/commands/zero/skill/index.ts
3750
- import { Command as Command68 } from "commander";
3873
+ import { Command as Command69 } from "commander";
3751
3874
 
3752
3875
  // src/commands/zero/skill/create.ts
3753
- import { Command as Command63 } from "commander";
3754
- import { readFileSync as readFileSync5, existsSync } from "fs";
3755
- import { join as join2 } from "path";
3876
+ import { Command as Command64 } from "commander";
3756
3877
  import chalk49 from "chalk";
3757
- var createCommand2 = new Command63().name("create").description("Create a custom skill in the organization").argument("<name>", "Skill name (lowercase alphanumeric with hyphens)").requiredOption("--dir <path>", "Path to directory containing SKILL.md").option("--display-name <name>", "Skill display name").option("--description <text>", "Skill description").addHelpText(
3878
+
3879
+ // src/lib/skill-directory.ts
3880
+ import { readFileSync as readFileSync5, readdirSync } from "fs";
3881
+ import { join as join2 } from "path";
3882
+ var IGNORED_NAMES = /* @__PURE__ */ new Set(["node_modules", ".git", ".DS_Store"]);
3883
+ function readSkillDirectory(dirPath) {
3884
+ const files = [];
3885
+ function walk(dir, prefix) {
3886
+ const entries = readdirSync(dir, { withFileTypes: true });
3887
+ for (const entry of entries) {
3888
+ if (entry.name.startsWith(".") || IGNORED_NAMES.has(entry.name)) continue;
3889
+ const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
3890
+ if (entry.isDirectory()) {
3891
+ walk(join2(dir, entry.name), relPath);
3892
+ } else {
3893
+ files.push({
3894
+ path: relPath,
3895
+ content: readFileSync5(join2(dir, entry.name), "utf-8")
3896
+ });
3897
+ }
3898
+ }
3899
+ }
3900
+ walk(dirPath, "");
3901
+ if (!files.some((f) => {
3902
+ return f.path === "SKILL.md";
3903
+ })) {
3904
+ throw new Error(`SKILL.md not found in ${dirPath}`);
3905
+ }
3906
+ return files;
3907
+ }
3908
+
3909
+ // src/commands/zero/skill/create.ts
3910
+ var createCommand2 = new Command64().name("create").description("Create a custom skill in the organization").argument("<name>", "Skill name (lowercase alphanumeric with hyphens)").requiredOption("--dir <path>", "Path to directory containing SKILL.md").option("--display-name <name>", "Skill display name").option("--description <text>", "Skill description").addHelpText(
3758
3911
  "after",
3759
3912
  `
3760
3913
  Examples:
@@ -3763,24 +3916,22 @@ Examples:
3763
3916
 
3764
3917
  Notes:
3765
3918
  - The directory must contain a SKILL.md file
3919
+ - All files in the directory are uploaded (hidden files and node_modules excluded)
3766
3920
  - The skill is created in the organization but not bound to any agent
3767
3921
  - Use 'zero agent edit <id> --add-skill <name>' to bind a skill to an agent`
3768
3922
  ).action(
3769
3923
  withErrorHandler(
3770
3924
  async (name, options) => {
3771
- const skillMdPath = join2(options.dir, "SKILL.md");
3772
- if (!existsSync(skillMdPath)) {
3773
- throw new Error(`SKILL.md not found in ${options.dir}`);
3774
- }
3775
- const content = readFileSync5(skillMdPath, "utf-8");
3925
+ const files = readSkillDirectory(options.dir);
3776
3926
  const skill = await createSkill({
3777
3927
  name,
3778
- content,
3928
+ files,
3779
3929
  displayName: options.displayName,
3780
3930
  description: options.description
3781
3931
  });
3782
3932
  console.log(chalk49.green(`\u2713 Skill "${skill.name}" created`));
3783
3933
  console.log(` Name: ${skill.name}`);
3934
+ console.log(` Files: ${files.length} file(s)`);
3784
3935
  if (skill.displayName) {
3785
3936
  console.log(` Display Name: ${skill.displayName}`);
3786
3937
  }
@@ -3792,13 +3943,11 @@ Notes:
3792
3943
  );
3793
3944
 
3794
3945
  // src/commands/zero/skill/edit.ts
3795
- import { Command as Command64 } from "commander";
3796
- import { readFileSync as readFileSync6, existsSync as existsSync2 } from "fs";
3797
- import { join as join3 } from "path";
3946
+ import { Command as Command65 } from "commander";
3798
3947
  import chalk50 from "chalk";
3799
- var editCommand2 = new Command64().name("edit").description("Update a custom skill's content").argument("<name>", "Skill name").requiredOption(
3948
+ var editCommand2 = new Command65().name("edit").description("Update a custom skill's content").argument("<name>", "Skill name").requiredOption(
3800
3949
  "--dir <path>",
3801
- "Path to directory containing updated SKILL.md"
3950
+ "Path to directory containing updated skill files"
3802
3951
  ).addHelpText(
3803
3952
  "after",
3804
3953
  `
@@ -3806,20 +3955,18 @@ Examples:
3806
3955
  zero skill edit my-skill --dir ./skills/my-skill/`
3807
3956
  ).action(
3808
3957
  withErrorHandler(async (name, options) => {
3809
- const skillMdPath = join3(options.dir, "SKILL.md");
3810
- if (!existsSync2(skillMdPath)) {
3811
- throw new Error(`SKILL.md not found in ${options.dir}`);
3812
- }
3813
- const content = readFileSync6(skillMdPath, "utf-8");
3814
- await updateSkill(name, { content });
3815
- console.log(chalk50.green(`\u2713 Skill "${name}" updated`));
3958
+ const files = readSkillDirectory(options.dir);
3959
+ await updateSkill(name, { files });
3960
+ console.log(
3961
+ chalk50.green(`\u2713 Skill "${name}" updated (${files.length} file(s))`)
3962
+ );
3816
3963
  })
3817
3964
  );
3818
3965
 
3819
3966
  // src/commands/zero/skill/view.ts
3820
- import { Command as Command65 } from "commander";
3967
+ import { Command as Command66 } from "commander";
3821
3968
  import chalk51 from "chalk";
3822
- var viewCommand2 = new Command65().name("view").description("View a custom skill").argument("<name>", "Skill name").addHelpText(
3969
+ var viewCommand2 = new Command66().name("view").description("View a custom skill").argument("<name>", "Skill name").addHelpText(
3823
3970
  "after",
3824
3971
  `
3825
3972
  Examples:
@@ -3833,6 +3980,13 @@ Examples:
3833
3980
  console.log(`Name: ${skill.name}`);
3834
3981
  if (skill.displayName) console.log(`Display Name: ${skill.displayName}`);
3835
3982
  if (skill.description) console.log(`Description: ${skill.description}`);
3983
+ if (skill.files && skill.files.length > 0) {
3984
+ console.log();
3985
+ console.log(chalk51.dim("\u2500\u2500 Files \u2500\u2500"));
3986
+ for (const f of skill.files) {
3987
+ console.log(` ${f.path} (${f.size} bytes)`);
3988
+ }
3989
+ }
3836
3990
  console.log();
3837
3991
  if (skill.content) {
3838
3992
  console.log(chalk51.dim("\u2500\u2500 SKILL.md \u2500\u2500"));
@@ -3844,9 +3998,9 @@ Examples:
3844
3998
  );
3845
3999
 
3846
4000
  // src/commands/zero/skill/list.ts
3847
- import { Command as Command66 } from "commander";
4001
+ import { Command as Command67 } from "commander";
3848
4002
  import chalk52 from "chalk";
3849
- var listCommand10 = new Command66().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
4003
+ var listCommand10 = new Command67().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
3850
4004
  "after",
3851
4005
  `
3852
4006
  Examples:
@@ -3891,9 +4045,9 @@ Examples:
3891
4045
  );
3892
4046
 
3893
4047
  // src/commands/zero/skill/delete.ts
3894
- import { Command as Command67 } from "commander";
4048
+ import { Command as Command68 } from "commander";
3895
4049
  import chalk53 from "chalk";
3896
- var deleteCommand6 = new Command67().name("delete").alias("rm").description("Delete a custom skill from the organization").argument("<name>", "Skill name").option("-y, --yes", "Skip confirmation prompt").addHelpText(
4050
+ var deleteCommand6 = new Command68().name("delete").alias("rm").description("Delete a custom skill from the organization").argument("<name>", "Skill name").option("-y, --yes", "Skip confirmation prompt").addHelpText(
3897
4051
  "after",
3898
4052
  `
3899
4053
  Examples:
@@ -3925,7 +4079,7 @@ Notes:
3925
4079
  );
3926
4080
 
3927
4081
  // src/commands/zero/skill/index.ts
3928
- var zeroSkillCommand = new Command68("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand10).addCommand(deleteCommand6).addHelpText(
4082
+ var zeroSkillCommand = new Command69("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand10).addCommand(deleteCommand6).addHelpText(
3929
4083
  "after",
3930
4084
  `
3931
4085
  Examples:
@@ -3981,10 +4135,10 @@ function registerZeroCommands(prog, commands) {
3981
4135
  prog.addCommand(cmd, hidden ? { hidden: true } : {});
3982
4136
  }
3983
4137
  }
3984
- var program = new Command69();
4138
+ var program = new Command70();
3985
4139
  program.name("zero").description(
3986
4140
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
3987
- ).version("9.93.0").addHelpText(
4141
+ ).version("9.94.1").addHelpText(
3988
4142
  "after",
3989
4143
  `
3990
4144
  Examples: