@vm0/cli 9.92.1 → 9.94.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-KXR4BFFL.js → chunk-XQIPEDKM.js} +1573 -46
- package/chunk-XQIPEDKM.js.map +1 -0
- package/index.js +13 -28
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/zero.js +345 -197
- package/zero.js.map +1 -1
- package/chunk-KXR4BFFL.js.map +0 -1
package/zero.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
EventRenderer,
|
|
6
6
|
MODEL_PROVIDER_TYPES,
|
|
7
7
|
allowsCustomModel,
|
|
8
|
+
completeSlackFileUpload,
|
|
8
9
|
configureGlobalProxyFromEnv,
|
|
9
10
|
connectorTypeSchema,
|
|
10
11
|
createSkill,
|
|
@@ -58,6 +59,7 @@ import {
|
|
|
58
59
|
hasAuthMethods,
|
|
59
60
|
hasModelSelection,
|
|
60
61
|
hasRequiredScopes,
|
|
62
|
+
initSlackFileUpload,
|
|
61
63
|
inviteZeroOrgMember,
|
|
62
64
|
isFeatureEnabled,
|
|
63
65
|
isFirewallConnectorType,
|
|
@@ -100,10 +102,10 @@ import {
|
|
|
100
102
|
updateZeroUserPreferences,
|
|
101
103
|
upsertZeroOrgModelProvider,
|
|
102
104
|
withErrorHandler
|
|
103
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-XQIPEDKM.js";
|
|
104
106
|
|
|
105
107
|
// src/zero.ts
|
|
106
|
-
import { Command as
|
|
108
|
+
import { Command as Command70 } from "commander";
|
|
107
109
|
|
|
108
110
|
// src/commands/zero/org/index.ts
|
|
109
111
|
import { Command as Command23 } from "commander";
|
|
@@ -227,10 +229,21 @@ var membersCommand = new Command5().name("members").description("View organizati
|
|
|
227
229
|
// src/commands/zero/org/invite.ts
|
|
228
230
|
import { Command as Command6 } from "commander";
|
|
229
231
|
import chalk6 from "chalk";
|
|
230
|
-
var inviteCommand = new Command6().name("invite").description("Invite a member to the current organization").requiredOption("--email <email>", "Email address of the member to invite").
|
|
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(
|
|
231
237
|
withErrorHandler(async (options) => {
|
|
232
|
-
|
|
233
|
-
|
|
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
|
+
);
|
|
234
247
|
})
|
|
235
248
|
);
|
|
236
249
|
|
|
@@ -2017,7 +2030,7 @@ var disconnectCommand = new Command33().name("disconnect").description("Disconne
|
|
|
2017
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);
|
|
2018
2031
|
|
|
2019
2032
|
// src/commands/zero/doctor/index.ts
|
|
2020
|
-
import { Command as
|
|
2033
|
+
import { Command as Command38 } from "commander";
|
|
2021
2034
|
|
|
2022
2035
|
// src/commands/zero/doctor/missing-token.ts
|
|
2023
2036
|
import { Command as Command35 } from "commander";
|
|
@@ -2114,6 +2127,22 @@ Notes:
|
|
|
2114
2127
|
|
|
2115
2128
|
// src/commands/zero/doctor/firewall-deny.ts
|
|
2116
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
|
|
2117
2146
|
var firewallDenyCommand = new Command36().name("firewall-deny").description(
|
|
2118
2147
|
"Diagnose a firewall denial and find the permission that covers it"
|
|
2119
2148
|
).argument("<firewall-ref>", "The firewall connector type (e.g. github)").addOption(
|
|
@@ -2179,20 +2208,116 @@ Notes:
|
|
|
2179
2208
|
);
|
|
2180
2209
|
console.log("");
|
|
2181
2210
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
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
|
+
}
|
|
2185
2309
|
}
|
|
2186
2310
|
)
|
|
2187
2311
|
);
|
|
2188
2312
|
|
|
2189
2313
|
// src/commands/zero/doctor/index.ts
|
|
2190
|
-
var zeroDoctorCommand = new
|
|
2314
|
+
var zeroDoctorCommand = new Command38().name("doctor").description("Diagnose runtime issues (missing tokens, firewall denials)").addCommand(missingTokenCommand).addCommand(firewallDenyCommand).addCommand(firewallPermissionsChangeCommand).addHelpText(
|
|
2191
2315
|
"after",
|
|
2192
2316
|
`
|
|
2193
2317
|
Examples:
|
|
2194
2318
|
Missing an API key? zero doctor missing-token GITHUB_TOKEN
|
|
2195
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
|
|
2196
2321
|
|
|
2197
2322
|
Notes:
|
|
2198
2323
|
- Use this when your task fails due to a missing environment variable or firewall denial
|
|
@@ -2200,7 +2325,7 @@ Notes:
|
|
|
2200
2325
|
);
|
|
2201
2326
|
|
|
2202
2327
|
// src/commands/zero/preference/index.ts
|
|
2203
|
-
import { Command as
|
|
2328
|
+
import { Command as Command39 } from "commander";
|
|
2204
2329
|
import chalk31 from "chalk";
|
|
2205
2330
|
function detectTimezone2() {
|
|
2206
2331
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
@@ -2257,7 +2382,7 @@ System timezone detected: ${detectedTz}`));
|
|
|
2257
2382
|
}
|
|
2258
2383
|
}
|
|
2259
2384
|
}
|
|
2260
|
-
var zeroPreferenceCommand = new
|
|
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(
|
|
2261
2386
|
withErrorHandler(async (opts) => {
|
|
2262
2387
|
const updates = buildUpdates(opts);
|
|
2263
2388
|
if (updates) {
|
|
@@ -2282,7 +2407,7 @@ var zeroPreferenceCommand = new Command38().name("preference").description("View
|
|
|
2282
2407
|
);
|
|
2283
2408
|
|
|
2284
2409
|
// src/commands/zero/run/run.ts
|
|
2285
|
-
import { Command as
|
|
2410
|
+
import { Command as Command40 } from "commander";
|
|
2286
2411
|
|
|
2287
2412
|
// src/commands/zero/run/shared.ts
|
|
2288
2413
|
import chalk32 from "chalk";
|
|
@@ -2365,10 +2490,7 @@ function showZeroNextSteps(result) {
|
|
|
2365
2490
|
}
|
|
2366
2491
|
|
|
2367
2492
|
// src/commands/zero/run/run.ts
|
|
2368
|
-
var mainRunCommand = new
|
|
2369
|
-
"--append-system-prompt <text>",
|
|
2370
|
-
"Append text to the agent's system prompt"
|
|
2371
|
-
).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(
|
|
2372
2494
|
"--model-provider <type>",
|
|
2373
2495
|
"Override model provider (e.g., anthropic-api-key)"
|
|
2374
2496
|
).option("--verbose", "Show full tool inputs and outputs").addHelpText(
|
|
@@ -2395,7 +2517,6 @@ Notes:
|
|
|
2395
2517
|
const response = await createZeroRun({
|
|
2396
2518
|
agentId,
|
|
2397
2519
|
prompt,
|
|
2398
|
-
appendSystemPrompt: options.appendSystemPrompt,
|
|
2399
2520
|
modelProvider: options.modelProvider
|
|
2400
2521
|
});
|
|
2401
2522
|
if (response.status === "failed") {
|
|
@@ -2417,11 +2538,8 @@ Notes:
|
|
|
2417
2538
|
);
|
|
2418
2539
|
|
|
2419
2540
|
// src/commands/zero/run/continue.ts
|
|
2420
|
-
import { Command as
|
|
2421
|
-
var continueCommand = new
|
|
2422
|
-
"--append-system-prompt <text>",
|
|
2423
|
-
"Append text to the agent's system prompt"
|
|
2424
|
-
).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(
|
|
2425
2543
|
"--model-provider <type>",
|
|
2426
2544
|
"Override model provider (e.g., anthropic-api-key)"
|
|
2427
2545
|
).option("--verbose", "Show full tool inputs and outputs").addHelpText(
|
|
@@ -2445,7 +2563,6 @@ Notes:
|
|
|
2445
2563
|
const response = await createZeroRun({
|
|
2446
2564
|
sessionId,
|
|
2447
2565
|
prompt,
|
|
2448
|
-
appendSystemPrompt: options.appendSystemPrompt,
|
|
2449
2566
|
modelProvider: options.modelProvider
|
|
2450
2567
|
});
|
|
2451
2568
|
if (response.status === "failed") {
|
|
@@ -2479,10 +2596,10 @@ Examples:
|
|
|
2479
2596
|
var zeroRunCommand = mainRunCommand;
|
|
2480
2597
|
|
|
2481
2598
|
// src/commands/zero/schedule/index.ts
|
|
2482
|
-
import { Command as
|
|
2599
|
+
import { Command as Command48 } from "commander";
|
|
2483
2600
|
|
|
2484
2601
|
// src/commands/zero/schedule/setup.ts
|
|
2485
|
-
import { Command as
|
|
2602
|
+
import { Command as Command42 } from "commander";
|
|
2486
2603
|
import chalk33 from "chalk";
|
|
2487
2604
|
var FREQUENCY_CHOICES = [
|
|
2488
2605
|
{ title: "Daily", value: "daily", description: "Run every day" },
|
|
@@ -2720,42 +2837,6 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
2720
2837
|
existingPrompt || "let's start working."
|
|
2721
2838
|
);
|
|
2722
2839
|
}
|
|
2723
|
-
async function gatherNotificationPreferences(optionNotifyEmail, optionNotifySlack, optionNotifySlackChannelId, existingSchedule) {
|
|
2724
|
-
if (optionNotifyEmail !== void 0 && optionNotifySlack !== void 0) {
|
|
2725
|
-
return {
|
|
2726
|
-
notifyEmail: optionNotifyEmail,
|
|
2727
|
-
notifySlack: optionNotifySlack,
|
|
2728
|
-
notifySlackChannelId: optionNotifySlackChannelId
|
|
2729
|
-
};
|
|
2730
|
-
}
|
|
2731
|
-
if (!isInteractive()) {
|
|
2732
|
-
return {
|
|
2733
|
-
notifyEmail: optionNotifyEmail,
|
|
2734
|
-
notifySlack: optionNotifySlack,
|
|
2735
|
-
notifySlackChannelId: optionNotifySlackChannelId
|
|
2736
|
-
};
|
|
2737
|
-
}
|
|
2738
|
-
const notifyEmail = optionNotifyEmail ?? await promptConfirm(
|
|
2739
|
-
"Enable email notifications?",
|
|
2740
|
-
existingSchedule?.notifyEmail ?? false
|
|
2741
|
-
);
|
|
2742
|
-
const notifySlack = optionNotifySlack ?? await promptConfirm(
|
|
2743
|
-
"Enable Slack notifications?",
|
|
2744
|
-
existingSchedule?.notifySlack ?? false
|
|
2745
|
-
);
|
|
2746
|
-
let notifySlackChannelId = optionNotifySlackChannelId;
|
|
2747
|
-
if (notifySlackChannelId === void 0 && notifySlack) {
|
|
2748
|
-
const defaultChannel = existingSchedule?.notifySlackChannelId ?? "";
|
|
2749
|
-
const channelInput = await promptText(
|
|
2750
|
-
"Slack channel ID (leave empty for DM)",
|
|
2751
|
-
defaultChannel
|
|
2752
|
-
);
|
|
2753
|
-
if (channelInput) {
|
|
2754
|
-
notifySlackChannelId = channelInput;
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
return { notifyEmail, notifySlack, notifySlackChannelId };
|
|
2758
|
-
}
|
|
2759
2840
|
async function gatherInterval(optionInterval, existingInterval) {
|
|
2760
2841
|
if (optionInterval) {
|
|
2761
2842
|
const val = parseInt(optionInterval, 10);
|
|
@@ -2848,16 +2929,7 @@ Deploying schedule for agent ${chalk33.cyan(params.agentName)}...`
|
|
|
2848
2929
|
atTime: atTimeISO,
|
|
2849
2930
|
intervalSeconds: params.intervalSeconds,
|
|
2850
2931
|
timezone: params.timezone,
|
|
2851
|
-
prompt: params.prompt
|
|
2852
|
-
...params.notifyEmail !== void 0 && {
|
|
2853
|
-
notifyEmail: params.notifyEmail
|
|
2854
|
-
},
|
|
2855
|
-
...params.notifySlack !== void 0 && {
|
|
2856
|
-
notifySlack: params.notifySlack
|
|
2857
|
-
},
|
|
2858
|
-
...params.notifySlackChannelId !== void 0 && {
|
|
2859
|
-
notifySlackChannelId: params.notifySlackChannelId
|
|
2860
|
-
}
|
|
2932
|
+
prompt: params.prompt
|
|
2861
2933
|
});
|
|
2862
2934
|
return deployResult;
|
|
2863
2935
|
}
|
|
@@ -2936,10 +3008,7 @@ async function handleScheduleEnabling(params) {
|
|
|
2936
3008
|
showEnableHint(agentName);
|
|
2937
3009
|
}
|
|
2938
3010
|
}
|
|
2939
|
-
var setupCommand2 = new
|
|
2940
|
-
"--notify-slack-channel-id <channel-id>",
|
|
2941
|
-
"Slack channel ID for notifications (default: DM)"
|
|
2942
|
-
).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(
|
|
2943
3012
|
"after",
|
|
2944
3013
|
`
|
|
2945
3014
|
Examples:
|
|
@@ -2953,8 +3022,7 @@ Examples:
|
|
|
2953
3022
|
Notes:
|
|
2954
3023
|
- Re-running setup with the same agent updates the existing "default" schedule
|
|
2955
3024
|
- Use -n to manage multiple named schedules for the same agent
|
|
2956
|
-
- All flags are required in non-interactive mode; interactive mode prompts for missing values
|
|
2957
|
-
- When --notify-slack is enabled, run results are automatically posted to the Slack channel specified by --notify-slack-channel-id (or as a DM if not set). No need to include Slack delivery instructions in your prompt.`
|
|
3025
|
+
- All flags are required in non-interactive mode; interactive mode prompts for missing values`
|
|
2958
3026
|
).action(
|
|
2959
3027
|
withErrorHandler(async (agentIdentifier, options) => {
|
|
2960
3028
|
const compose = await resolveCompose(agentIdentifier);
|
|
@@ -3004,12 +3072,6 @@ Notes:
|
|
|
3004
3072
|
console.log(chalk33.dim("Cancelled"));
|
|
3005
3073
|
return;
|
|
3006
3074
|
}
|
|
3007
|
-
const { notifyEmail, notifySlack, notifySlackChannelId } = await gatherNotificationPreferences(
|
|
3008
|
-
options.notifyEmail,
|
|
3009
|
-
options.notifySlack,
|
|
3010
|
-
options.notifySlackChannelId,
|
|
3011
|
-
existingSchedule
|
|
3012
|
-
);
|
|
3013
3075
|
const deployResult = await buildAndDeploy({
|
|
3014
3076
|
scheduleName,
|
|
3015
3077
|
agentId,
|
|
@@ -3020,10 +3082,7 @@ Notes:
|
|
|
3020
3082
|
atTime,
|
|
3021
3083
|
intervalSeconds,
|
|
3022
3084
|
timezone,
|
|
3023
|
-
prompt: promptText_
|
|
3024
|
-
notifyEmail,
|
|
3025
|
-
notifySlack,
|
|
3026
|
-
notifySlackChannelId
|
|
3085
|
+
prompt: promptText_
|
|
3027
3086
|
});
|
|
3028
3087
|
displayDeployResult(scheduleName, deployResult);
|
|
3029
3088
|
const shouldPromptEnable = deployResult.created || existingSchedule !== void 0 && !existingSchedule.enabled;
|
|
@@ -3038,9 +3097,9 @@ Notes:
|
|
|
3038
3097
|
);
|
|
3039
3098
|
|
|
3040
3099
|
// src/commands/zero/schedule/list.ts
|
|
3041
|
-
import { Command as
|
|
3100
|
+
import { Command as Command43 } from "commander";
|
|
3042
3101
|
import chalk34 from "chalk";
|
|
3043
|
-
var listCommand7 = new
|
|
3102
|
+
var listCommand7 = new Command43().name("list").alias("ls").description("List all zero schedules").addHelpText(
|
|
3044
3103
|
"after",
|
|
3045
3104
|
`
|
|
3046
3105
|
Examples:
|
|
@@ -3098,7 +3157,7 @@ Examples:
|
|
|
3098
3157
|
);
|
|
3099
3158
|
|
|
3100
3159
|
// src/commands/zero/schedule/status.ts
|
|
3101
|
-
import { Command as
|
|
3160
|
+
import { Command as Command44 } from "commander";
|
|
3102
3161
|
import chalk35 from "chalk";
|
|
3103
3162
|
function formatDateTimeStyled(dateStr) {
|
|
3104
3163
|
if (!dateStr) return chalk35.dim("-");
|
|
@@ -3151,7 +3210,7 @@ function printTimeSchedule(schedule) {
|
|
|
3151
3210
|
console.log(`${"Failures:".padEnd(16)}${failureText}`);
|
|
3152
3211
|
}
|
|
3153
3212
|
}
|
|
3154
|
-
var statusCommand3 = new
|
|
3213
|
+
var statusCommand3 = new Command44().name("status").description("Show detailed status of a zero schedule").argument("<agent-id>", "Agent ID").option(
|
|
3155
3214
|
"-n, --name <schedule-name>",
|
|
3156
3215
|
"Schedule name (required when agent has multiple schedules)"
|
|
3157
3216
|
).addHelpText(
|
|
@@ -3176,9 +3235,9 @@ Examples:
|
|
|
3176
3235
|
);
|
|
3177
3236
|
|
|
3178
3237
|
// src/commands/zero/schedule/delete.ts
|
|
3179
|
-
import { Command as
|
|
3238
|
+
import { Command as Command45 } from "commander";
|
|
3180
3239
|
import chalk36 from "chalk";
|
|
3181
|
-
var deleteCommand3 = new
|
|
3240
|
+
var deleteCommand3 = new Command45().name("delete").alias("rm").description("Delete a zero schedule").argument("<agent-id>", "Agent ID").option(
|
|
3182
3241
|
"-n, --name <schedule-name>",
|
|
3183
3242
|
"Schedule name (required when agent has multiple schedules)"
|
|
3184
3243
|
).option("-y, --yes", "Skip confirmation prompt").addHelpText(
|
|
@@ -3220,9 +3279,9 @@ Notes:
|
|
|
3220
3279
|
);
|
|
3221
3280
|
|
|
3222
3281
|
// src/commands/zero/schedule/enable.ts
|
|
3223
|
-
import { Command as
|
|
3282
|
+
import { Command as Command46 } from "commander";
|
|
3224
3283
|
import chalk37 from "chalk";
|
|
3225
|
-
var enableCommand = new
|
|
3284
|
+
var enableCommand = new Command46().name("enable").description("Enable a zero schedule").argument("<agent-id>", "Agent ID").option(
|
|
3226
3285
|
"-n, --name <schedule-name>",
|
|
3227
3286
|
"Schedule name (required when agent has multiple schedules)"
|
|
3228
3287
|
).addHelpText(
|
|
@@ -3246,9 +3305,9 @@ Examples:
|
|
|
3246
3305
|
);
|
|
3247
3306
|
|
|
3248
3307
|
// src/commands/zero/schedule/disable.ts
|
|
3249
|
-
import { Command as
|
|
3308
|
+
import { Command as Command47 } from "commander";
|
|
3250
3309
|
import chalk38 from "chalk";
|
|
3251
|
-
var disableCommand = new
|
|
3310
|
+
var disableCommand = new Command47().name("disable").description("Disable a zero schedule").argument("<agent-id>", "Agent ID").option(
|
|
3252
3311
|
"-n, --name <schedule-name>",
|
|
3253
3312
|
"Schedule name (required when agent has multiple schedules)"
|
|
3254
3313
|
).addHelpText(
|
|
@@ -3272,7 +3331,7 @@ Examples:
|
|
|
3272
3331
|
);
|
|
3273
3332
|
|
|
3274
3333
|
// src/commands/zero/schedule/index.ts
|
|
3275
|
-
var zeroScheduleCommand = new
|
|
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(
|
|
3276
3335
|
"after",
|
|
3277
3336
|
`
|
|
3278
3337
|
Examples:
|
|
@@ -3285,12 +3344,12 @@ Examples:
|
|
|
3285
3344
|
);
|
|
3286
3345
|
|
|
3287
3346
|
// src/commands/zero/secret/index.ts
|
|
3288
|
-
import { Command as
|
|
3347
|
+
import { Command as Command52 } from "commander";
|
|
3289
3348
|
|
|
3290
3349
|
// src/commands/zero/secret/list.ts
|
|
3291
|
-
import { Command as
|
|
3350
|
+
import { Command as Command49 } from "commander";
|
|
3292
3351
|
import chalk39 from "chalk";
|
|
3293
|
-
var listCommand8 = new
|
|
3352
|
+
var listCommand8 = new Command49().name("list").alias("ls").description("List all secrets").action(
|
|
3294
3353
|
withErrorHandler(async () => {
|
|
3295
3354
|
const result = await listZeroSecrets();
|
|
3296
3355
|
if (result.secrets.length === 0) {
|
|
@@ -3343,9 +3402,9 @@ var listCommand8 = new Command48().name("list").alias("ls").description("List al
|
|
|
3343
3402
|
);
|
|
3344
3403
|
|
|
3345
3404
|
// src/commands/zero/secret/set.ts
|
|
3346
|
-
import { Command as
|
|
3405
|
+
import { Command as Command50 } from "commander";
|
|
3347
3406
|
import chalk40 from "chalk";
|
|
3348
|
-
var setCommand4 = new
|
|
3407
|
+
var setCommand4 = new Command50().name("set").description("Create or update a secret").argument("<name>", "Secret name (uppercase, e.g., MY_API_KEY)").option(
|
|
3349
3408
|
"-b, --body <value>",
|
|
3350
3409
|
"Secret value (required in non-interactive mode)"
|
|
3351
3410
|
).option("-d, --description <description>", "Optional description").action(
|
|
@@ -3391,9 +3450,9 @@ var setCommand4 = new Command49().name("set").description("Create or update a se
|
|
|
3391
3450
|
);
|
|
3392
3451
|
|
|
3393
3452
|
// src/commands/zero/secret/delete.ts
|
|
3394
|
-
import { Command as
|
|
3453
|
+
import { Command as Command51 } from "commander";
|
|
3395
3454
|
import chalk41 from "chalk";
|
|
3396
|
-
var deleteCommand4 = new
|
|
3455
|
+
var deleteCommand4 = new Command51().name("delete").description("Delete a secret").argument("<name>", "Secret name to delete").option("-y, --yes", "Skip confirmation prompt").action(
|
|
3397
3456
|
withErrorHandler(async (name, options) => {
|
|
3398
3457
|
if (!options.yes) {
|
|
3399
3458
|
if (!isInteractive()) {
|
|
@@ -3414,19 +3473,19 @@ var deleteCommand4 = new Command50().name("delete").description("Delete a secret
|
|
|
3414
3473
|
);
|
|
3415
3474
|
|
|
3416
3475
|
// src/commands/zero/secret/index.ts
|
|
3417
|
-
var zeroSecretCommand = new
|
|
3476
|
+
var zeroSecretCommand = new Command52().name("secret").description("Read or write secrets (API keys, tokens)").addCommand(listCommand8).addCommand(setCommand4).addCommand(deleteCommand4);
|
|
3418
3477
|
|
|
3419
3478
|
// src/commands/zero/slack/index.ts
|
|
3420
|
-
import { Command as
|
|
3479
|
+
import { Command as Command56 } from "commander";
|
|
3421
3480
|
|
|
3422
3481
|
// src/commands/zero/slack/message/index.ts
|
|
3423
|
-
import { Command as
|
|
3482
|
+
import { Command as Command54 } from "commander";
|
|
3424
3483
|
|
|
3425
3484
|
// src/commands/zero/slack/message/send.ts
|
|
3426
3485
|
import { readFileSync as readFileSync3 } from "fs";
|
|
3427
|
-
import { Command as
|
|
3486
|
+
import { Command as Command53 } from "commander";
|
|
3428
3487
|
import chalk42 from "chalk";
|
|
3429
|
-
var sendCommand = new
|
|
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(
|
|
3430
3489
|
"after",
|
|
3431
3490
|
`
|
|
3432
3491
|
Examples:
|
|
@@ -3476,65 +3535,123 @@ Notes:
|
|
|
3476
3535
|
);
|
|
3477
3536
|
|
|
3478
3537
|
// src/commands/zero/slack/message/index.ts
|
|
3479
|
-
var zeroSlackMessageCommand = new
|
|
3538
|
+
var zeroSlackMessageCommand = new Command54().name("message").description("Manage Slack messages").addCommand(sendCommand).addHelpText(
|
|
3480
3539
|
"after",
|
|
3481
3540
|
`
|
|
3482
3541
|
Examples:
|
|
3483
3542
|
zero slack message send -c <channel-id> -t "Hello!"`
|
|
3484
3543
|
);
|
|
3485
3544
|
|
|
3545
|
+
// src/commands/zero/slack/upload-file.ts
|
|
3546
|
+
import { statSync, readFileSync as readFileSync4 } from "fs";
|
|
3547
|
+
import { basename } from "path";
|
|
3548
|
+
import { Command as Command55 } from "commander";
|
|
3549
|
+
import chalk43 from "chalk";
|
|
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(
|
|
3551
|
+
"after",
|
|
3552
|
+
`
|
|
3553
|
+
Examples:
|
|
3554
|
+
Upload a file: zero slack upload-file -f /tmp/report.pdf -c C01234
|
|
3555
|
+
Upload to thread: zero slack upload-file -f /tmp/log.txt -c C01234 --thread 1234567890.123456
|
|
3556
|
+
With title and comment: zero slack upload-file -f /tmp/data.csv -c C01234 --title "Daily Report" --comment "Here's the report"
|
|
3557
|
+
|
|
3558
|
+
Notes:
|
|
3559
|
+
- Uses the bot token (not user SLACK_TOKEN), so no files:write firewall permission is needed
|
|
3560
|
+
- Returns file_id and permalink for reference`
|
|
3561
|
+
).action(
|
|
3562
|
+
withErrorHandler(
|
|
3563
|
+
async (options) => {
|
|
3564
|
+
let fileSize;
|
|
3565
|
+
try {
|
|
3566
|
+
const stat = statSync(options.file);
|
|
3567
|
+
fileSize = stat.size;
|
|
3568
|
+
} catch {
|
|
3569
|
+
throw new Error(`File not found: ${options.file}`);
|
|
3570
|
+
}
|
|
3571
|
+
if (fileSize === 0) {
|
|
3572
|
+
throw new Error("File is empty");
|
|
3573
|
+
}
|
|
3574
|
+
const filename = basename(options.file);
|
|
3575
|
+
const { uploadUrl, fileId } = await initSlackFileUpload({
|
|
3576
|
+
filename,
|
|
3577
|
+
length: fileSize
|
|
3578
|
+
});
|
|
3579
|
+
const fileContent = readFileSync4(options.file);
|
|
3580
|
+
const uploadResponse = await fetch(uploadUrl, {
|
|
3581
|
+
method: "POST",
|
|
3582
|
+
body: fileContent
|
|
3583
|
+
});
|
|
3584
|
+
if (!uploadResponse.ok) {
|
|
3585
|
+
throw new Error(
|
|
3586
|
+
`File upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
const result = await completeSlackFileUpload({
|
|
3590
|
+
fileId,
|
|
3591
|
+
channel: options.channel,
|
|
3592
|
+
threadTs: options.thread,
|
|
3593
|
+
title: options.title,
|
|
3594
|
+
initialComment: options.comment
|
|
3595
|
+
});
|
|
3596
|
+
console.log(chalk43.green(`\u2713 File uploaded (file_id: ${result.fileId})`));
|
|
3597
|
+
console.log(chalk43.dim(` permalink: ${result.permalink}`));
|
|
3598
|
+
}
|
|
3599
|
+
)
|
|
3600
|
+
);
|
|
3601
|
+
|
|
3486
3602
|
// src/commands/zero/slack/index.ts
|
|
3487
|
-
var zeroSlackCommand = new
|
|
3603
|
+
var zeroSlackCommand = new Command56().name("slack").description("Send messages and upload files to Slack channels as the bot").addCommand(zeroSlackMessageCommand).addCommand(uploadFileCommand).addHelpText(
|
|
3488
3604
|
"after",
|
|
3489
3605
|
`
|
|
3490
3606
|
Examples:
|
|
3491
3607
|
Send a message: zero slack message send -c <channel-id> -t "Hello!"
|
|
3492
|
-
Reply in a thread: zero slack message send -c <channel-id> --thread <ts> -t "reply"
|
|
3608
|
+
Reply in a thread: zero slack message send -c <channel-id> --thread <ts> -t "reply"
|
|
3609
|
+
Upload a file: zero slack upload-file -f /tmp/report.pdf -c <channel-id>`
|
|
3493
3610
|
);
|
|
3494
3611
|
|
|
3495
3612
|
// src/commands/zero/variable/index.ts
|
|
3496
|
-
import { Command as
|
|
3613
|
+
import { Command as Command60 } from "commander";
|
|
3497
3614
|
|
|
3498
3615
|
// src/commands/zero/variable/list.ts
|
|
3499
|
-
import { Command as
|
|
3500
|
-
import
|
|
3616
|
+
import { Command as Command57 } from "commander";
|
|
3617
|
+
import chalk44 from "chalk";
|
|
3501
3618
|
function truncateValue2(value, maxLength = 60) {
|
|
3502
3619
|
if (value.length <= maxLength) {
|
|
3503
3620
|
return value;
|
|
3504
3621
|
}
|
|
3505
3622
|
return value.slice(0, maxLength - 15) + "... [truncated]";
|
|
3506
3623
|
}
|
|
3507
|
-
var listCommand9 = new
|
|
3624
|
+
var listCommand9 = new Command57().name("list").alias("ls").description("List all variables").action(
|
|
3508
3625
|
withErrorHandler(async () => {
|
|
3509
3626
|
const result = await listZeroVariables();
|
|
3510
3627
|
if (result.variables.length === 0) {
|
|
3511
|
-
console.log(
|
|
3628
|
+
console.log(chalk44.dim("No variables found"));
|
|
3512
3629
|
console.log();
|
|
3513
3630
|
console.log("To add a variable:");
|
|
3514
|
-
console.log(
|
|
3631
|
+
console.log(chalk44.cyan(" zero variable set MY_VAR <value>"));
|
|
3515
3632
|
return;
|
|
3516
3633
|
}
|
|
3517
|
-
console.log(
|
|
3634
|
+
console.log(chalk44.bold("Variables:"));
|
|
3518
3635
|
console.log();
|
|
3519
3636
|
for (const variable of result.variables) {
|
|
3520
3637
|
const displayValue = truncateValue2(variable.value);
|
|
3521
|
-
console.log(` ${
|
|
3638
|
+
console.log(` ${chalk44.cyan(variable.name)} = ${displayValue}`);
|
|
3522
3639
|
if (variable.description) {
|
|
3523
|
-
console.log(` ${
|
|
3640
|
+
console.log(` ${chalk44.dim(variable.description)}`);
|
|
3524
3641
|
}
|
|
3525
3642
|
console.log(
|
|
3526
|
-
` ${
|
|
3643
|
+
` ${chalk44.dim(`Updated: ${new Date(variable.updatedAt).toLocaleString()}`)}`
|
|
3527
3644
|
);
|
|
3528
3645
|
console.log();
|
|
3529
3646
|
}
|
|
3530
|
-
console.log(
|
|
3647
|
+
console.log(chalk44.dim(`Total: ${result.variables.length} variable(s)`));
|
|
3531
3648
|
})
|
|
3532
3649
|
);
|
|
3533
3650
|
|
|
3534
3651
|
// src/commands/zero/variable/set.ts
|
|
3535
|
-
import { Command as
|
|
3536
|
-
import
|
|
3537
|
-
var setCommand5 = new
|
|
3652
|
+
import { Command as Command58 } from "commander";
|
|
3653
|
+
import chalk45 from "chalk";
|
|
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(
|
|
3538
3655
|
withErrorHandler(
|
|
3539
3656
|
async (name, value, options) => {
|
|
3540
3657
|
let variable;
|
|
@@ -3554,15 +3671,15 @@ var setCommand5 = new Command56().name("set").description("Create or update a va
|
|
|
3554
3671
|
}
|
|
3555
3672
|
throw error;
|
|
3556
3673
|
}
|
|
3557
|
-
console.log(
|
|
3674
|
+
console.log(chalk45.green(`\u2713 Variable "${variable.name}" saved`));
|
|
3558
3675
|
}
|
|
3559
3676
|
)
|
|
3560
3677
|
);
|
|
3561
3678
|
|
|
3562
3679
|
// src/commands/zero/variable/delete.ts
|
|
3563
|
-
import { Command as
|
|
3564
|
-
import
|
|
3565
|
-
var deleteCommand5 = new
|
|
3680
|
+
import { Command as Command59 } from "commander";
|
|
3681
|
+
import chalk46 from "chalk";
|
|
3682
|
+
var deleteCommand5 = new Command59().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(
|
|
3566
3683
|
withErrorHandler(async (name, options) => {
|
|
3567
3684
|
if (!options.yes) {
|
|
3568
3685
|
if (!isInteractive()) {
|
|
@@ -3573,21 +3690,21 @@ var deleteCommand5 = new Command57().name("delete").description("Delete a variab
|
|
|
3573
3690
|
false
|
|
3574
3691
|
);
|
|
3575
3692
|
if (!confirmed) {
|
|
3576
|
-
console.log(
|
|
3693
|
+
console.log(chalk46.dim("Cancelled"));
|
|
3577
3694
|
return;
|
|
3578
3695
|
}
|
|
3579
3696
|
}
|
|
3580
3697
|
await deleteZeroVariable(name);
|
|
3581
|
-
console.log(
|
|
3698
|
+
console.log(chalk46.green(`\u2713 Variable "${name}" deleted`));
|
|
3582
3699
|
})
|
|
3583
3700
|
);
|
|
3584
3701
|
|
|
3585
3702
|
// src/commands/zero/variable/index.ts
|
|
3586
|
-
var zeroVariableCommand = new
|
|
3703
|
+
var zeroVariableCommand = new Command60().name("variable").description("Read or write non-sensitive configuration values").addCommand(listCommand9).addCommand(setCommand5).addCommand(deleteCommand5);
|
|
3587
3704
|
|
|
3588
3705
|
// src/commands/zero/whoami.ts
|
|
3589
|
-
import { Command as
|
|
3590
|
-
import
|
|
3706
|
+
import { Command as Command61 } from "commander";
|
|
3707
|
+
import chalk47 from "chalk";
|
|
3591
3708
|
function isInsideSandbox() {
|
|
3592
3709
|
return !!process.env.ZERO_AGENT_ID;
|
|
3593
3710
|
}
|
|
@@ -3595,11 +3712,11 @@ async function showSandboxInfo() {
|
|
|
3595
3712
|
const agentId = process.env.ZERO_AGENT_ID;
|
|
3596
3713
|
const payload = decodeZeroTokenPayload();
|
|
3597
3714
|
console.log(`Agent ID: ${agentId}`);
|
|
3598
|
-
console.log(`Run ID: ${payload?.runId ??
|
|
3599
|
-
console.log(`Org ID: ${payload?.orgId ??
|
|
3715
|
+
console.log(`Run ID: ${payload?.runId ?? chalk47.dim("unavailable")}`);
|
|
3716
|
+
console.log(`Org ID: ${payload?.orgId ?? chalk47.dim("unavailable")}`);
|
|
3600
3717
|
if (payload?.capabilities?.length) {
|
|
3601
3718
|
console.log();
|
|
3602
|
-
console.log(
|
|
3719
|
+
console.log(chalk47.bold("Capabilities:"));
|
|
3603
3720
|
console.log(` ${payload.capabilities.join(", ")}`);
|
|
3604
3721
|
}
|
|
3605
3722
|
}
|
|
@@ -3607,23 +3724,23 @@ async function showLocalInfo() {
|
|
|
3607
3724
|
const token = await getToken();
|
|
3608
3725
|
const apiUrl = await getApiUrl();
|
|
3609
3726
|
const activeOrg = await getActiveOrg();
|
|
3610
|
-
console.log(
|
|
3727
|
+
console.log(chalk47.bold("Auth:"));
|
|
3611
3728
|
if (token) {
|
|
3612
3729
|
const tokenSource = process.env.ZERO_TOKEN ? "ZERO_TOKEN env var" : process.env.VM0_TOKEN ? "VM0_TOKEN env var" : "config file";
|
|
3613
3730
|
console.log(
|
|
3614
|
-
` Status: ${
|
|
3731
|
+
` Status: ${chalk47.green("Authenticated")} (via ${tokenSource})`
|
|
3615
3732
|
);
|
|
3616
3733
|
} else {
|
|
3617
|
-
console.log(` Status: ${
|
|
3734
|
+
console.log(` Status: ${chalk47.dim("Not authenticated")}`);
|
|
3618
3735
|
}
|
|
3619
3736
|
console.log(` API: ${apiUrl}`);
|
|
3620
3737
|
console.log();
|
|
3621
3738
|
if (activeOrg) {
|
|
3622
|
-
console.log(
|
|
3739
|
+
console.log(chalk47.bold("Org:"));
|
|
3623
3740
|
console.log(` Active: ${activeOrg}`);
|
|
3624
3741
|
}
|
|
3625
3742
|
}
|
|
3626
|
-
var zeroWhoamiCommand = new
|
|
3743
|
+
var zeroWhoamiCommand = new Command61().name("whoami").description("Show agent identity, run ID, and capabilities").addHelpText(
|
|
3627
3744
|
"after",
|
|
3628
3745
|
`
|
|
3629
3746
|
Examples:
|
|
@@ -3643,11 +3760,11 @@ Notes:
|
|
|
3643
3760
|
);
|
|
3644
3761
|
|
|
3645
3762
|
// src/commands/zero/ask-user/index.ts
|
|
3646
|
-
import { Command as
|
|
3763
|
+
import { Command as Command63 } from "commander";
|
|
3647
3764
|
|
|
3648
3765
|
// src/commands/zero/ask-user/question.ts
|
|
3649
|
-
import { Command as
|
|
3650
|
-
import
|
|
3766
|
+
import { Command as Command62 } from "commander";
|
|
3767
|
+
import chalk48 from "chalk";
|
|
3651
3768
|
function collectOption(value, previous) {
|
|
3652
3769
|
const list = previous ?? [];
|
|
3653
3770
|
list.push({ label: value });
|
|
@@ -3658,7 +3775,7 @@ function collectDesc(value, previous) {
|
|
|
3658
3775
|
list.push(value);
|
|
3659
3776
|
return list;
|
|
3660
3777
|
}
|
|
3661
|
-
var questionCommand = new
|
|
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(
|
|
3662
3779
|
"--desc <text>",
|
|
3663
3780
|
"Description for the preceding --option",
|
|
3664
3781
|
collectDesc
|
|
@@ -3714,7 +3831,7 @@ Notes:
|
|
|
3714
3831
|
questions: [questionItem]
|
|
3715
3832
|
});
|
|
3716
3833
|
console.error(
|
|
3717
|
-
|
|
3834
|
+
chalk48.dim(
|
|
3718
3835
|
`\u23F3 Waiting for user response... (pendingId: ${pendingId})`
|
|
3719
3836
|
)
|
|
3720
3837
|
);
|
|
@@ -3741,7 +3858,7 @@ Notes:
|
|
|
3741
3858
|
);
|
|
3742
3859
|
|
|
3743
3860
|
// src/commands/zero/ask-user/index.ts
|
|
3744
|
-
var zeroAskUserCommand = new
|
|
3861
|
+
var zeroAskUserCommand = new Command63().name("ask-user").description("Ask the user a question and wait for the answer").addCommand(questionCommand).addHelpText(
|
|
3745
3862
|
"after",
|
|
3746
3863
|
`
|
|
3747
3864
|
Examples:
|
|
@@ -3753,14 +3870,44 @@ Notes:
|
|
|
3753
3870
|
);
|
|
3754
3871
|
|
|
3755
3872
|
// src/commands/zero/skill/index.ts
|
|
3756
|
-
import { Command as
|
|
3873
|
+
import { Command as Command69 } from "commander";
|
|
3757
3874
|
|
|
3758
3875
|
// src/commands/zero/skill/create.ts
|
|
3759
|
-
import { Command as
|
|
3760
|
-
import
|
|
3876
|
+
import { Command as Command64 } from "commander";
|
|
3877
|
+
import chalk49 from "chalk";
|
|
3878
|
+
|
|
3879
|
+
// src/lib/skill-directory.ts
|
|
3880
|
+
import { readFileSync as readFileSync5, readdirSync } from "fs";
|
|
3761
3881
|
import { join as join2 } from "path";
|
|
3762
|
-
|
|
3763
|
-
|
|
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(
|
|
3764
3911
|
"after",
|
|
3765
3912
|
`
|
|
3766
3913
|
Examples:
|
|
@@ -3769,24 +3916,22 @@ Examples:
|
|
|
3769
3916
|
|
|
3770
3917
|
Notes:
|
|
3771
3918
|
- The directory must contain a SKILL.md file
|
|
3919
|
+
- All files in the directory are uploaded (hidden files and node_modules excluded)
|
|
3772
3920
|
- The skill is created in the organization but not bound to any agent
|
|
3773
3921
|
- Use 'zero agent edit <id> --add-skill <name>' to bind a skill to an agent`
|
|
3774
3922
|
).action(
|
|
3775
3923
|
withErrorHandler(
|
|
3776
3924
|
async (name, options) => {
|
|
3777
|
-
const
|
|
3778
|
-
if (!existsSync(skillMdPath)) {
|
|
3779
|
-
throw new Error(`SKILL.md not found in ${options.dir}`);
|
|
3780
|
-
}
|
|
3781
|
-
const content = readFileSync4(skillMdPath, "utf-8");
|
|
3925
|
+
const files = readSkillDirectory(options.dir);
|
|
3782
3926
|
const skill = await createSkill({
|
|
3783
3927
|
name,
|
|
3784
|
-
|
|
3928
|
+
files,
|
|
3785
3929
|
displayName: options.displayName,
|
|
3786
3930
|
description: options.description
|
|
3787
3931
|
});
|
|
3788
|
-
console.log(
|
|
3932
|
+
console.log(chalk49.green(`\u2713 Skill "${skill.name}" created`));
|
|
3789
3933
|
console.log(` Name: ${skill.name}`);
|
|
3934
|
+
console.log(` Files: ${files.length} file(s)`);
|
|
3790
3935
|
if (skill.displayName) {
|
|
3791
3936
|
console.log(` Display Name: ${skill.displayName}`);
|
|
3792
3937
|
}
|
|
@@ -3798,13 +3943,11 @@ Notes:
|
|
|
3798
3943
|
);
|
|
3799
3944
|
|
|
3800
3945
|
// src/commands/zero/skill/edit.ts
|
|
3801
|
-
import { Command as
|
|
3802
|
-
import
|
|
3803
|
-
|
|
3804
|
-
import chalk49 from "chalk";
|
|
3805
|
-
var editCommand2 = new Command63().name("edit").description("Update a custom skill's content").argument("<name>", "Skill name").requiredOption(
|
|
3946
|
+
import { Command as Command65 } from "commander";
|
|
3947
|
+
import chalk50 from "chalk";
|
|
3948
|
+
var editCommand2 = new Command65().name("edit").description("Update a custom skill's content").argument("<name>", "Skill name").requiredOption(
|
|
3806
3949
|
"--dir <path>",
|
|
3807
|
-
"Path to directory containing updated
|
|
3950
|
+
"Path to directory containing updated skill files"
|
|
3808
3951
|
).addHelpText(
|
|
3809
3952
|
"after",
|
|
3810
3953
|
`
|
|
@@ -3812,20 +3955,18 @@ Examples:
|
|
|
3812
3955
|
zero skill edit my-skill --dir ./skills/my-skill/`
|
|
3813
3956
|
).action(
|
|
3814
3957
|
withErrorHandler(async (name, options) => {
|
|
3815
|
-
const
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
await updateSkill(name, { content });
|
|
3821
|
-
console.log(chalk49.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
|
+
);
|
|
3822
3963
|
})
|
|
3823
3964
|
);
|
|
3824
3965
|
|
|
3825
3966
|
// src/commands/zero/skill/view.ts
|
|
3826
|
-
import { Command as
|
|
3827
|
-
import
|
|
3828
|
-
var viewCommand2 = new
|
|
3967
|
+
import { Command as Command66 } from "commander";
|
|
3968
|
+
import chalk51 from "chalk";
|
|
3969
|
+
var viewCommand2 = new Command66().name("view").description("View a custom skill").argument("<name>", "Skill name").addHelpText(
|
|
3829
3970
|
"after",
|
|
3830
3971
|
`
|
|
3831
3972
|
Examples:
|
|
@@ -3833,26 +3974,33 @@ Examples:
|
|
|
3833
3974
|
).action(
|
|
3834
3975
|
withErrorHandler(async (name) => {
|
|
3835
3976
|
const skill = await getSkill(name);
|
|
3836
|
-
console.log(
|
|
3837
|
-
if (skill.displayName) console.log(
|
|
3977
|
+
console.log(chalk51.bold(skill.name));
|
|
3978
|
+
if (skill.displayName) console.log(chalk51.dim(skill.displayName));
|
|
3838
3979
|
console.log();
|
|
3839
3980
|
console.log(`Name: ${skill.name}`);
|
|
3840
3981
|
if (skill.displayName) console.log(`Display Name: ${skill.displayName}`);
|
|
3841
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
|
+
}
|
|
3842
3990
|
console.log();
|
|
3843
3991
|
if (skill.content) {
|
|
3844
|
-
console.log(
|
|
3992
|
+
console.log(chalk51.dim("\u2500\u2500 SKILL.md \u2500\u2500"));
|
|
3845
3993
|
console.log(skill.content);
|
|
3846
3994
|
} else {
|
|
3847
|
-
console.log(
|
|
3995
|
+
console.log(chalk51.dim("No content"));
|
|
3848
3996
|
}
|
|
3849
3997
|
})
|
|
3850
3998
|
);
|
|
3851
3999
|
|
|
3852
4000
|
// src/commands/zero/skill/list.ts
|
|
3853
|
-
import { Command as
|
|
3854
|
-
import
|
|
3855
|
-
var listCommand10 = new
|
|
4001
|
+
import { Command as Command67 } from "commander";
|
|
4002
|
+
import chalk52 from "chalk";
|
|
4003
|
+
var listCommand10 = new Command67().name("list").alias("ls").description("List custom skills in the organization").addHelpText(
|
|
3856
4004
|
"after",
|
|
3857
4005
|
`
|
|
3858
4006
|
Examples:
|
|
@@ -3861,9 +4009,9 @@ Examples:
|
|
|
3861
4009
|
withErrorHandler(async () => {
|
|
3862
4010
|
const skills = await listSkills();
|
|
3863
4011
|
if (skills.length === 0) {
|
|
3864
|
-
console.log(
|
|
4012
|
+
console.log(chalk52.dim("No custom skills found"));
|
|
3865
4013
|
console.log(
|
|
3866
|
-
|
|
4014
|
+
chalk52.dim(" Create one with: zero skill create <name> --dir <path>")
|
|
3867
4015
|
);
|
|
3868
4016
|
return;
|
|
3869
4017
|
}
|
|
@@ -3884,7 +4032,7 @@ Examples:
|
|
|
3884
4032
|
"DISPLAY NAME".padEnd(displayWidth),
|
|
3885
4033
|
"DESCRIPTION"
|
|
3886
4034
|
].join(" ");
|
|
3887
|
-
console.log(
|
|
4035
|
+
console.log(chalk52.dim(header));
|
|
3888
4036
|
for (const skill of skills) {
|
|
3889
4037
|
const row = [
|
|
3890
4038
|
skill.name.padEnd(nameWidth),
|
|
@@ -3897,9 +4045,9 @@ Examples:
|
|
|
3897
4045
|
);
|
|
3898
4046
|
|
|
3899
4047
|
// src/commands/zero/skill/delete.ts
|
|
3900
|
-
import { Command as
|
|
3901
|
-
import
|
|
3902
|
-
var deleteCommand6 = new
|
|
4048
|
+
import { Command as Command68 } from "commander";
|
|
4049
|
+
import chalk53 from "chalk";
|
|
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(
|
|
3903
4051
|
"after",
|
|
3904
4052
|
`
|
|
3905
4053
|
Examples:
|
|
@@ -3921,17 +4069,17 @@ Notes:
|
|
|
3921
4069
|
false
|
|
3922
4070
|
);
|
|
3923
4071
|
if (!confirmed) {
|
|
3924
|
-
console.log(
|
|
4072
|
+
console.log(chalk53.dim("Cancelled"));
|
|
3925
4073
|
return;
|
|
3926
4074
|
}
|
|
3927
4075
|
}
|
|
3928
4076
|
await deleteSkill(name);
|
|
3929
|
-
console.log(
|
|
4077
|
+
console.log(chalk53.green(`\u2713 Skill "${name}" deleted`));
|
|
3930
4078
|
})
|
|
3931
4079
|
);
|
|
3932
4080
|
|
|
3933
4081
|
// src/commands/zero/skill/index.ts
|
|
3934
|
-
var zeroSkillCommand = new
|
|
4082
|
+
var zeroSkillCommand = new Command69("skill").description("Manage custom skills").addCommand(createCommand2).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand10).addCommand(deleteCommand6).addHelpText(
|
|
3935
4083
|
"after",
|
|
3936
4084
|
`
|
|
3937
4085
|
Examples:
|
|
@@ -3987,10 +4135,10 @@ function registerZeroCommands(prog, commands) {
|
|
|
3987
4135
|
prog.addCommand(cmd, hidden ? { hidden: true } : {});
|
|
3988
4136
|
}
|
|
3989
4137
|
}
|
|
3990
|
-
var program = new
|
|
4138
|
+
var program = new Command70();
|
|
3991
4139
|
program.name("zero").description(
|
|
3992
4140
|
"Zero CLI \u2014 interact with the zero platform from inside the sandbox"
|
|
3993
|
-
).version("9.
|
|
4141
|
+
).version("9.94.0").addHelpText(
|
|
3994
4142
|
"after",
|
|
3995
4143
|
`
|
|
3996
4144
|
Examples:
|