@vm0/cli 9.151.0 → 9.153.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-VUZYX6DE.js → chunk-7B5CZ4YO.js} +262 -19
- package/{chunk-VUZYX6DE.js.map → chunk-7B5CZ4YO.js.map} +1 -1
- package/index.js +9 -9
- package/package.json +1 -1
- package/zero.js +402 -30
- package/zero.js.map +1 -1
package/zero.js
CHANGED
|
@@ -17,11 +17,13 @@ import {
|
|
|
17
17
|
configureGlobalProxyFromEnv,
|
|
18
18
|
connectorTypeSchema,
|
|
19
19
|
createLocalBrowserReadCommand,
|
|
20
|
+
createLocalBrowserWriteCommand,
|
|
20
21
|
createSkill,
|
|
21
22
|
createZeroAgent,
|
|
22
23
|
createZeroRun,
|
|
23
24
|
decodeCliTokenPayload,
|
|
24
25
|
decodeZeroTokenPayload,
|
|
26
|
+
deleteLocalBrowserHost,
|
|
25
27
|
deleteSkill,
|
|
26
28
|
deleteZeroAgent,
|
|
27
29
|
deleteZeroOrg,
|
|
@@ -79,6 +81,8 @@ import {
|
|
|
79
81
|
isInteractive,
|
|
80
82
|
isUUID,
|
|
81
83
|
leaveZeroOrg,
|
|
84
|
+
listLocalBrowserAuditEvents,
|
|
85
|
+
listLocalBrowserHosts,
|
|
82
86
|
listSkills,
|
|
83
87
|
listTelegramBots,
|
|
84
88
|
listZeroAgents,
|
|
@@ -134,7 +138,7 @@ import {
|
|
|
134
138
|
withErrorHandler,
|
|
135
139
|
zeroAgentCustomSkillNameSchema,
|
|
136
140
|
zeroRemoteAgentCommand
|
|
137
|
-
} from "./chunk-
|
|
141
|
+
} from "./chunk-7B5CZ4YO.js";
|
|
138
142
|
import {
|
|
139
143
|
__toESM,
|
|
140
144
|
init_esm_shims
|
|
@@ -2538,9 +2542,51 @@ init_esm_shims();
|
|
|
2538
2542
|
var BUILT_IN_GENERATION_PROVIDERS = {
|
|
2539
2543
|
image: [
|
|
2540
2544
|
{
|
|
2541
|
-
label: "Built-in",
|
|
2545
|
+
label: "Built-in OpenAI",
|
|
2542
2546
|
model: "gpt-image-2",
|
|
2543
|
-
command: "zero built-in generate image -h",
|
|
2547
|
+
command: "zero built-in generate image --model gpt-image-2 -h",
|
|
2548
|
+
reason: "available without connector setup"
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
label: "Built-in OpenAI",
|
|
2552
|
+
model: "gpt-image-1.5",
|
|
2553
|
+
command: "zero built-in generate image --model gpt-image-1.5 -h",
|
|
2554
|
+
reason: "available without connector setup"
|
|
2555
|
+
},
|
|
2556
|
+
{
|
|
2557
|
+
label: "Built-in OpenAI",
|
|
2558
|
+
model: "gpt-image-1",
|
|
2559
|
+
command: "zero built-in generate image --model gpt-image-1 -h",
|
|
2560
|
+
reason: "available without connector setup"
|
|
2561
|
+
},
|
|
2562
|
+
{
|
|
2563
|
+
label: "Built-in OpenAI",
|
|
2564
|
+
model: "gpt-image-1-mini",
|
|
2565
|
+
command: "zero built-in generate image --model gpt-image-1-mini -h",
|
|
2566
|
+
reason: "available without connector setup"
|
|
2567
|
+
},
|
|
2568
|
+
{
|
|
2569
|
+
label: "Built-in fal.ai",
|
|
2570
|
+
model: "fal-ai/flux-pro/v1.1",
|
|
2571
|
+
command: "zero built-in generate image --model flux-pro-1.1 -h",
|
|
2572
|
+
reason: "available without connector setup"
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
label: "Built-in fal.ai",
|
|
2576
|
+
model: "fal-ai/flux-pro/v1.1-ultra",
|
|
2577
|
+
command: "zero built-in generate image --model flux-pro-1.1-ultra -h",
|
|
2578
|
+
reason: "available without connector setup"
|
|
2579
|
+
},
|
|
2580
|
+
{
|
|
2581
|
+
label: "Built-in fal.ai",
|
|
2582
|
+
model: "fal-ai/qwen-image",
|
|
2583
|
+
command: "zero built-in generate image --model qwen-image -h",
|
|
2584
|
+
reason: "available without connector setup"
|
|
2585
|
+
},
|
|
2586
|
+
{
|
|
2587
|
+
label: "Built-in fal.ai",
|
|
2588
|
+
model: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
2589
|
+
command: "zero built-in generate image --model seedream4 -h",
|
|
2544
2590
|
reason: "available without connector setup"
|
|
2545
2591
|
}
|
|
2546
2592
|
],
|
|
@@ -2599,6 +2645,28 @@ var BUILT_IN_GENERATION_PROVIDERS = {
|
|
|
2599
2645
|
}
|
|
2600
2646
|
]
|
|
2601
2647
|
};
|
|
2648
|
+
var BUILT_IN_GENERATION_COMMANDS = {
|
|
2649
|
+
image: {
|
|
2650
|
+
label: "Built-in image generation",
|
|
2651
|
+
command: "zero built-in generate image -h",
|
|
2652
|
+
models: "OpenAI: gpt-image-2, gpt-image-1.5, gpt-image-1, gpt-image-1-mini; fal.ai: flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, seedream4"
|
|
2653
|
+
},
|
|
2654
|
+
video: {
|
|
2655
|
+
label: "Built-in video generation",
|
|
2656
|
+
command: "zero built-in generate video -h",
|
|
2657
|
+
models: "veo3.1-fast, veo3.1, kling-o3-standard, kling-v3-4k, seedance2.0, seedance2.0-fast"
|
|
2658
|
+
},
|
|
2659
|
+
presentation: {
|
|
2660
|
+
label: "Built-in presentation generation",
|
|
2661
|
+
command: "zero built-in generate presentation -h",
|
|
2662
|
+
models: "gpt-5.5"
|
|
2663
|
+
},
|
|
2664
|
+
voice: {
|
|
2665
|
+
label: "Built-in voice generation",
|
|
2666
|
+
command: "zero built-in generate voice -h",
|
|
2667
|
+
models: "gpt-4o-mini-tts"
|
|
2668
|
+
}
|
|
2669
|
+
};
|
|
2602
2670
|
var GENERATION_TYPE_ORDER = [
|
|
2603
2671
|
"image",
|
|
2604
2672
|
"video",
|
|
@@ -2630,6 +2698,9 @@ function getConnectorGenerationType(generationType) {
|
|
|
2630
2698
|
function getBuiltInProviders(generationType) {
|
|
2631
2699
|
return BUILT_IN_GENERATION_PROVIDERS[generationType] ?? [];
|
|
2632
2700
|
}
|
|
2701
|
+
function getBuiltInCommand(generationType) {
|
|
2702
|
+
return BUILT_IN_GENERATION_COMMANDS[generationType] ?? null;
|
|
2703
|
+
}
|
|
2633
2704
|
function getAvailableGenerationTypes() {
|
|
2634
2705
|
const available = /* @__PURE__ */ new Set();
|
|
2635
2706
|
for (const config of Object.values(CONNECTOR_TYPES)) {
|
|
@@ -2760,6 +2831,15 @@ function renderActions(candidates) {
|
|
|
2760
2831
|
}
|
|
2761
2832
|
}
|
|
2762
2833
|
function renderBuiltInProvider(generationType) {
|
|
2834
|
+
const command = getBuiltInCommand(generationType);
|
|
2835
|
+
if (command) {
|
|
2836
|
+
console.log("");
|
|
2837
|
+
console.log("Built-in command:");
|
|
2838
|
+
console.log(` vm0 ${command.label}`);
|
|
2839
|
+
console.log(` Models: ${command.models}`);
|
|
2840
|
+
console.log(` Use: ${command.command}`);
|
|
2841
|
+
return;
|
|
2842
|
+
}
|
|
2763
2843
|
const providers = getBuiltInProviders(generationType);
|
|
2764
2844
|
if (providers.length === 0) return;
|
|
2765
2845
|
console.log("");
|
|
@@ -7223,20 +7303,35 @@ function parseCompression(value) {
|
|
|
7223
7303
|
}
|
|
7224
7304
|
return compression;
|
|
7225
7305
|
}
|
|
7306
|
+
function parseSeed(value) {
|
|
7307
|
+
const seed = Number(value);
|
|
7308
|
+
if (!Number.isInteger(seed) || seed < 0 || !Number.isSafeInteger(seed)) {
|
|
7309
|
+
throw new InvalidArgumentError("seed must be a non-negative safe integer");
|
|
7310
|
+
}
|
|
7311
|
+
return seed;
|
|
7312
|
+
}
|
|
7226
7313
|
function createImageGenerateCommand(config) {
|
|
7227
7314
|
return new Command().name(config.name).description("Generate a billed image file from a prompt").option("--prompt <text>", "Image prompt; can also be piped via stdin").option(
|
|
7315
|
+
"--model <model>",
|
|
7316
|
+
"Model: gpt-image-2, gpt-image-1.5, gpt-image-1, gpt-image-1-mini, flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, or seedream4",
|
|
7317
|
+
"gpt-image-2"
|
|
7318
|
+
).option(
|
|
7228
7319
|
"--size <size>",
|
|
7229
|
-
"Image size: auto or
|
|
7320
|
+
"Image size: auto or WIDTHxHEIGHT; support varies by model",
|
|
7230
7321
|
"1024x1024"
|
|
7231
7322
|
).option(
|
|
7232
7323
|
"--quality <quality>",
|
|
7233
7324
|
"Image quality: low, medium, high, or auto",
|
|
7234
7325
|
"medium"
|
|
7235
|
-
).option(
|
|
7326
|
+
).option(
|
|
7327
|
+
"--background <background>",
|
|
7328
|
+
"Background: auto, opaque, or transparent when supported",
|
|
7329
|
+
"auto"
|
|
7330
|
+
).option("--format <format>", "Output format: png, webp, or jpeg", "png").option("--compression <0-100>", "Output compression for jpeg/webp only").option(
|
|
7236
7331
|
"--moderation <moderation>",
|
|
7237
7332
|
"Moderation strictness: auto or low",
|
|
7238
7333
|
"auto"
|
|
7239
|
-
).option("--json", "Print metadata as JSON").addHelpText(
|
|
7334
|
+
).option("--seed <integer>", "Deterministic seed for fal models", parseSeed).option("--safety-tolerance <level>", "fal safety tolerance: 1-6", "4").option("--enhance-prompt", "Enable fal prompt enhancement when supported").option("--json", "Print metadata as JSON").addHelpText(
|
|
7240
7335
|
"after",
|
|
7241
7336
|
`
|
|
7242
7337
|
Examples:
|
|
@@ -7248,23 +7343,34 @@ Output:
|
|
|
7248
7343
|
Notes:
|
|
7249
7344
|
- Authenticates via ZERO_TOKEN (requires file:write capability)
|
|
7250
7345
|
- Charges org credits after successful image generation
|
|
7251
|
-
- Uses OpenAI
|
|
7346
|
+
- Uses OpenAI for GPT Image models and fal.ai for non-OpenAI models
|
|
7347
|
+
|
|
7348
|
+
Models:
|
|
7349
|
+
- OpenAI: gpt-image-2 (default), gpt-image-1.5, gpt-image-1,
|
|
7350
|
+
gpt-image-1-mini. OpenAI generations bill returned text/image/output
|
|
7351
|
+
token usage.
|
|
7352
|
+
- fal.ai: flux-pro-1.1, flux-pro-1.1-ultra, qwen-image, seedream4.
|
|
7353
|
+
fal generations bill by output image or rounded-up output megapixel,
|
|
7354
|
+
depending on the model.
|
|
7252
7355
|
|
|
7253
|
-
|
|
7356
|
+
Options:
|
|
7254
7357
|
- Prompt: required, up to 32,000 characters; stdin is supported.
|
|
7255
|
-
- Size:
|
|
7358
|
+
- Size: gpt-image-2 accepts auto or WIDTHxHEIGHT. Popular sizes include
|
|
7359
|
+
1024x1024,
|
|
7256
7360
|
1536x1024, 1024x1536, 2048x2048, 2048x1152, 3840x2160,
|
|
7257
7361
|
and 2160x3840. Custom sizes must have edges <= 3840px, both
|
|
7258
7362
|
edges divisible by 16, long:short ratio <= 3:1, and total pixels
|
|
7259
|
-
between 655,360 and 8,294,400.
|
|
7260
|
-
|
|
7363
|
+
between 655,360 and 8,294,400. gpt-image-1.5, gpt-image-1, and
|
|
7364
|
+
gpt-image-1-mini use auto, 1024x1024, 1536x1024, or 1024x1536.
|
|
7261
7365
|
- Quality: low, medium, high, or auto. Low is fastest for drafts.
|
|
7262
|
-
- Background: auto or
|
|
7263
|
-
backgrounds.
|
|
7264
|
-
- Format: png, jpeg, or webp
|
|
7265
|
-
|
|
7266
|
-
- Moderation: auto or low.
|
|
7267
|
-
-
|
|
7366
|
+
- Background: auto, opaque, or transparent. gpt-image-2 and fal models do
|
|
7367
|
+
not support transparent backgrounds.
|
|
7368
|
+
- Format: png, jpeg, or webp for OpenAI; png or jpeg for fal. Use
|
|
7369
|
+
--compression 0-100 only with OpenAI jpeg or webp outputs.
|
|
7370
|
+
- Moderation: auto or low for OpenAI models.
|
|
7371
|
+
- fal-only controls: --seed, --safety-tolerance for Flux, and
|
|
7372
|
+
--enhance-prompt for flux-pro-1.1.
|
|
7373
|
+
- This command generates one text-to-image result. GPT Image also
|
|
7268
7374
|
supports image edits, reference images, masks, partial-image streaming,
|
|
7269
7375
|
and multiple images per request, but those are not exposed by this
|
|
7270
7376
|
built-in Zero command yet.`
|
|
@@ -7274,12 +7380,16 @@ GPT Image 2 options:
|
|
|
7274
7380
|
const compression = parseCompression(options.compression);
|
|
7275
7381
|
const result = await generateWebImage({
|
|
7276
7382
|
prompt,
|
|
7383
|
+
model: options.model,
|
|
7277
7384
|
size: options.size,
|
|
7278
7385
|
quality: options.quality,
|
|
7279
7386
|
background: options.background,
|
|
7280
7387
|
outputFormat: options.format,
|
|
7281
7388
|
outputCompression: compression,
|
|
7282
|
-
moderation: options.moderation
|
|
7389
|
+
moderation: options.moderation,
|
|
7390
|
+
seed: options.seed,
|
|
7391
|
+
safetyTolerance: options.safetyTolerance,
|
|
7392
|
+
enhancePrompt: options.enhancePrompt
|
|
7283
7393
|
});
|
|
7284
7394
|
if (options.json) {
|
|
7285
7395
|
console.log(JSON.stringify(result));
|
|
@@ -7296,8 +7406,17 @@ GPT Image 2 options:
|
|
|
7296
7406
|
if (result.moderation) {
|
|
7297
7407
|
console.log(source_default.dim(` Moderation: ${result.moderation}`));
|
|
7298
7408
|
}
|
|
7409
|
+
if (result.safetyTolerance) {
|
|
7410
|
+
console.log(
|
|
7411
|
+
source_default.dim(` Safety tolerance: ${result.safetyTolerance}`)
|
|
7412
|
+
);
|
|
7413
|
+
}
|
|
7414
|
+
if (result.seed !== void 0) {
|
|
7415
|
+
console.log(source_default.dim(` Seed: ${result.seed}`));
|
|
7416
|
+
}
|
|
7299
7417
|
console.log(source_default.dim(` Credits charged: ${result.creditsCharged}`));
|
|
7300
7418
|
console.log(source_default.dim(` Model: ${result.model}`));
|
|
7419
|
+
console.log(source_default.dim(` Provider: ${result.provider}`));
|
|
7301
7420
|
})
|
|
7302
7421
|
);
|
|
7303
7422
|
}
|
|
@@ -7308,7 +7427,8 @@ var imageCommand = createImageGenerateCommand({
|
|
|
7308
7427
|
usageCommand: "zero built-in generate image",
|
|
7309
7428
|
examples: ` Generate image: zero built-in generate image --prompt "A watercolor fox"
|
|
7310
7429
|
Pipe prompt: cat prompt.txt | zero built-in generate image
|
|
7311
|
-
|
|
7430
|
+
OpenAI model: zero built-in generate image --model gpt-image-1.5 --prompt "A poster" --size 1024x1536 --quality high
|
|
7431
|
+
fal model: zero built-in generate image --model flux-pro-1.1 --prompt "A product hero shot" --seed 42`
|
|
7312
7432
|
});
|
|
7313
7433
|
|
|
7314
7434
|
// src/commands/zero/built-in/generate/presentation.ts
|
|
@@ -7421,7 +7541,7 @@ init_esm_shims();
|
|
|
7421
7541
|
// src/commands/zero/shared/video-generate.ts
|
|
7422
7542
|
init_esm_shims();
|
|
7423
7543
|
import { readFileSync as readFileSync14 } from "fs";
|
|
7424
|
-
function
|
|
7544
|
+
function parseSeed2(value) {
|
|
7425
7545
|
const seed = Number(value);
|
|
7426
7546
|
if (!Number.isInteger(seed) || seed < 0 || !Number.isSafeInteger(seed)) {
|
|
7427
7547
|
throw new InvalidArgumentError("seed must be a non-negative safe integer");
|
|
@@ -7455,7 +7575,7 @@ function createVideoGenerateCommand(config) {
|
|
|
7455
7575
|
"--duration <duration>",
|
|
7456
7576
|
"Duration: 3s-15s; Veo supports 4s/6s/8s",
|
|
7457
7577
|
"8s"
|
|
7458
|
-
).option("--resolution <resolution>", "Resolution: 720p, 1080p, or 4k").option("--no-audio", "Generate a silent video").option("--negative-prompt <text>", "Negative prompt").option("--seed <integer>", "Deterministic seed",
|
|
7578
|
+
).option("--resolution <resolution>", "Resolution: 720p, 1080p, or 4k").option("--no-audio", "Generate a silent video").option("--negative-prompt <text>", "Negative prompt").option("--seed <integer>", "Deterministic seed", parseSeed2).option("--no-auto-fix", "Disable fal prompt auto-fix").option("--safety-tolerance <level>", "Safety tolerance: 1-6", "4").option("--json", "Print metadata as JSON").addHelpText(
|
|
7459
7579
|
"after",
|
|
7460
7580
|
`
|
|
7461
7581
|
Examples:
|
|
@@ -7467,7 +7587,18 @@ Output:
|
|
|
7467
7587
|
Notes:
|
|
7468
7588
|
- Authenticates via ZERO_TOKEN (requires file:write capability)
|
|
7469
7589
|
- Charges org credits after successful video generation
|
|
7470
|
-
- Uses fal video models with configured usage pricing
|
|
7590
|
+
- Uses fal video models with configured usage pricing
|
|
7591
|
+
|
|
7592
|
+
Models:
|
|
7593
|
+
- Veo: veo3.1-fast (default), veo3.1. Supports 4s/6s/8s,
|
|
7594
|
+
16:9 or 9:16, 720p/1080p/4k, negative prompts, seed,
|
|
7595
|
+
auto-fix, safety tolerance, and optional audio.
|
|
7596
|
+
- Kling: kling-o3-standard, kling-v3-4k. Supports 3s-15s and
|
|
7597
|
+
16:9 or 9:16. kling-v3-4k uses 4k output; kling-o3-standard
|
|
7598
|
+
uses 1080p output.
|
|
7599
|
+
- Seedance: seedance2.0, seedance2.0-fast. Supports 4s-15s,
|
|
7600
|
+
480p/720p, seed, and aspect ratios 21:9, 16:9, 4:3, 1:1,
|
|
7601
|
+
3:4, or 9:16.`
|
|
7471
7602
|
).action(
|
|
7472
7603
|
withErrorHandler(async (options) => {
|
|
7473
7604
|
const prompt = readPrompt3(options, config.usageCommand);
|
|
@@ -7700,6 +7831,34 @@ function parseTimeoutSeconds(value) {
|
|
|
7700
7831
|
}
|
|
7701
7832
|
return seconds;
|
|
7702
7833
|
}
|
|
7834
|
+
function parseOptionalNonNegativeInteger(value, label) {
|
|
7835
|
+
if (value === void 0) return void 0;
|
|
7836
|
+
const parsed = Number.parseInt(value, 10);
|
|
7837
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
7838
|
+
throw new Error(`${label} must be a non-negative integer`);
|
|
7839
|
+
}
|
|
7840
|
+
return parsed;
|
|
7841
|
+
}
|
|
7842
|
+
function parsePositiveInteger2(value, label) {
|
|
7843
|
+
if (value === void 0) {
|
|
7844
|
+
throw new Error(`${label} is required`);
|
|
7845
|
+
}
|
|
7846
|
+
const parsed = Number.parseInt(value, 10);
|
|
7847
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
7848
|
+
throw new Error(`${label} must be a positive integer`);
|
|
7849
|
+
}
|
|
7850
|
+
return parsed;
|
|
7851
|
+
}
|
|
7852
|
+
function parseLimit4(value) {
|
|
7853
|
+
if (value === void 0) {
|
|
7854
|
+
return 50;
|
|
7855
|
+
}
|
|
7856
|
+
const parsed = parsePositiveInteger2(value, "limit");
|
|
7857
|
+
if (parsed > 200) {
|
|
7858
|
+
throw new Error("limit must be 200 or less");
|
|
7859
|
+
}
|
|
7860
|
+
return parsed;
|
|
7861
|
+
}
|
|
7703
7862
|
function resultText(command) {
|
|
7704
7863
|
if (!command.result) {
|
|
7705
7864
|
return "";
|
|
@@ -7741,9 +7900,52 @@ async function runReadCommand(kind, options) {
|
|
|
7741
7900
|
}
|
|
7742
7901
|
throw new Error(`Local-browser command timed out: ${created.commandId}`);
|
|
7743
7902
|
}
|
|
7903
|
+
async function waitForCommand(commandId, timeoutSeconds) {
|
|
7904
|
+
const deadline = Date.now() + timeoutSeconds * 1e3;
|
|
7905
|
+
while (Date.now() <= deadline) {
|
|
7906
|
+
const command = await getLocalBrowserReadCommand(commandId);
|
|
7907
|
+
if (command.status === "pending_approval" || command.status === "queued" || command.status === "running") {
|
|
7908
|
+
if (process.stdout.isTTY) {
|
|
7909
|
+
process.stdout.write(".");
|
|
7910
|
+
}
|
|
7911
|
+
await sleep3(1e3);
|
|
7912
|
+
continue;
|
|
7913
|
+
}
|
|
7914
|
+
if (process.stdout.isTTY) {
|
|
7915
|
+
process.stdout.write("\n");
|
|
7916
|
+
}
|
|
7917
|
+
if (command.status === "failed") {
|
|
7918
|
+
throw new Error(
|
|
7919
|
+
command.error ? `${command.error.code}: ${command.error.message}` : "Local-browser command failed"
|
|
7920
|
+
);
|
|
7921
|
+
}
|
|
7922
|
+
const text = resultText(command);
|
|
7923
|
+
if (text) {
|
|
7924
|
+
console.log(text);
|
|
7925
|
+
}
|
|
7926
|
+
return;
|
|
7927
|
+
}
|
|
7928
|
+
throw new Error(`Local-browser command timed out: ${commandId}`);
|
|
7929
|
+
}
|
|
7930
|
+
async function runWriteCommand(kind, options, payload) {
|
|
7931
|
+
const timeoutSeconds = parseTimeoutSeconds(options.timeout);
|
|
7932
|
+
const created = await createLocalBrowserWriteCommand({
|
|
7933
|
+
kind,
|
|
7934
|
+
timeoutMs: timeoutSeconds * 1e3,
|
|
7935
|
+
...options.tabId ? { tabId: options.tabId } : {},
|
|
7936
|
+
...options.host ? { hostName: options.host } : {},
|
|
7937
|
+
...options.hostId ? { hostId: options.hostId } : {},
|
|
7938
|
+
...payload
|
|
7939
|
+
});
|
|
7940
|
+
await waitForCommand(created.commandId, timeoutSeconds);
|
|
7941
|
+
}
|
|
7744
7942
|
function addReadOptions(command) {
|
|
7745
7943
|
return command.option("--host <name>", "Run on a named local-browser host").option("--host-id <id>", "Run on a specific local-browser host id").option("--tab-id <id>", "Target a specific browser tab").option("--timeout <seconds>", "Maximum time to wait", "30");
|
|
7746
7944
|
}
|
|
7945
|
+
function addWriteOptions(command, options = {}) {
|
|
7946
|
+
const withHostOptions = command.option("--host <name>", "Run on a named local-browser host").option("--host-id <id>", "Run on a specific local-browser host id").option("--timeout <seconds>", "Maximum time to wait", "30");
|
|
7947
|
+
return options.tabId === false ? withHostOptions : withHostOptions.option("--tab-id <id>", "Target a specific browser tab");
|
|
7948
|
+
}
|
|
7747
7949
|
function readCommand(name, kind) {
|
|
7748
7950
|
return addReadOptions(
|
|
7749
7951
|
new Command().name(name).description(`Run ${kind}`).action(
|
|
@@ -7753,17 +7955,187 @@ function readCommand(name, kind) {
|
|
|
7753
7955
|
)
|
|
7754
7956
|
);
|
|
7755
7957
|
}
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7958
|
+
function formatCapabilities(capabilities) {
|
|
7959
|
+
return capabilities.length > 0 ? capabilities.join(", ") : "none";
|
|
7960
|
+
}
|
|
7961
|
+
function formatHost(host) {
|
|
7962
|
+
const status = host.status === "online" ? source_default.green("online") : source_default.dim("offline");
|
|
7963
|
+
return [
|
|
7964
|
+
`${status} ${host.displayName}`,
|
|
7965
|
+
` id: ${host.id}`,
|
|
7966
|
+
` browser: ${host.browser}`,
|
|
7967
|
+
` extension: ${host.extensionVersion}`,
|
|
7968
|
+
` last seen: ${host.lastSeenAt}`,
|
|
7969
|
+
` capabilities: ${formatCapabilities(host.supportedCapabilities)}`
|
|
7970
|
+
].join("\n");
|
|
7971
|
+
}
|
|
7972
|
+
function formatAuditEvent(event) {
|
|
7973
|
+
const parts = [
|
|
7974
|
+
event.createdAt,
|
|
7975
|
+
event.event,
|
|
7976
|
+
event.kind,
|
|
7977
|
+
`command=${event.commandId}`
|
|
7978
|
+
];
|
|
7979
|
+
if (event.hostId) {
|
|
7980
|
+
parts.push(`host=${event.hostId}`);
|
|
7981
|
+
}
|
|
7982
|
+
if (event.runId) {
|
|
7983
|
+
parts.push(`run=${event.runId}`);
|
|
7984
|
+
}
|
|
7985
|
+
if (event.tabId) {
|
|
7986
|
+
parts.push(`tab=${event.tabId}`);
|
|
7987
|
+
}
|
|
7988
|
+
if (event.targetUrl) {
|
|
7989
|
+
parts.push(`url=${event.targetUrl}`);
|
|
7990
|
+
}
|
|
7991
|
+
if (event.approvalOutcome) {
|
|
7992
|
+
parts.push(`approval=${event.approvalOutcome}`);
|
|
7993
|
+
}
|
|
7994
|
+
if (event.error) {
|
|
7995
|
+
parts.push(`error=${JSON.stringify(event.error)}`);
|
|
7996
|
+
}
|
|
7997
|
+
return parts.join(" ");
|
|
7998
|
+
}
|
|
7999
|
+
var hostsCommand = new Command().name("hosts").description("List and revoke linked local-browser hosts").addCommand(
|
|
8000
|
+
new Command().name("list").description("List linked local-browser hosts").option("--json", "Output hosts as JSON").action(
|
|
8001
|
+
withErrorHandler(async (options) => {
|
|
8002
|
+
const result = await listLocalBrowserHosts();
|
|
8003
|
+
if (options.json) {
|
|
8004
|
+
console.log(JSON.stringify(result));
|
|
8005
|
+
return;
|
|
8006
|
+
}
|
|
8007
|
+
if (result.hosts.length === 0) {
|
|
8008
|
+
console.log(source_default.dim("No linked local-browser hosts."));
|
|
8009
|
+
return;
|
|
8010
|
+
}
|
|
8011
|
+
console.log(result.hosts.map(formatHost).join("\n\n"));
|
|
8012
|
+
})
|
|
8013
|
+
)
|
|
8014
|
+
).addCommand(
|
|
8015
|
+
new Command().name("revoke").description("Revoke a linked local-browser host").argument("<host-id>", "Local-browser host id").option("--json", "Output the revoke result as JSON").action(
|
|
8016
|
+
withErrorHandler(async (hostId, options) => {
|
|
8017
|
+
const result = await deleteLocalBrowserHost(hostId);
|
|
8018
|
+
if (options.json) {
|
|
8019
|
+
console.log(JSON.stringify(result));
|
|
8020
|
+
return;
|
|
8021
|
+
}
|
|
8022
|
+
console.log(source_default.green("Local-browser host revoked"));
|
|
8023
|
+
console.log(source_default.dim(` Host: ${hostId}`));
|
|
8024
|
+
})
|
|
8025
|
+
)
|
|
8026
|
+
);
|
|
8027
|
+
var auditCommand = new Command().name("audit").description("Inspect local-browser write command audit events").addCommand(
|
|
8028
|
+
new Command().name("list").description("List local-browser write command audit events").option("--limit <count>", "Maximum events to show", "50").option("--command-id <id>", "Filter by command id").option("--host-id <id>", "Filter by host id").option("--run-id <id>", "Filter by run id").option("--json", "Output audit events as JSON").action(
|
|
8029
|
+
withErrorHandler(async (options) => {
|
|
8030
|
+
const result = await listLocalBrowserAuditEvents({
|
|
8031
|
+
limit: parseLimit4(options.limit),
|
|
8032
|
+
...options.commandId ? { commandId: options.commandId } : {},
|
|
8033
|
+
...options.hostId ? { hostId: options.hostId } : {},
|
|
8034
|
+
...options.runId ? { runId: options.runId } : {}
|
|
8035
|
+
});
|
|
8036
|
+
if (options.json) {
|
|
8037
|
+
console.log(JSON.stringify(result));
|
|
8038
|
+
return;
|
|
8039
|
+
}
|
|
8040
|
+
if (result.auditEvents.length === 0) {
|
|
8041
|
+
console.log(source_default.dim("No local-browser audit events found."));
|
|
8042
|
+
return;
|
|
8043
|
+
}
|
|
8044
|
+
console.log(result.auditEvents.map(formatAuditEvent).join("\n"));
|
|
8045
|
+
})
|
|
8046
|
+
)
|
|
8047
|
+
);
|
|
8048
|
+
var tabsCommand = new Command().name("tabs").description("Read and control browser tabs").addCommand(readCommand("list", "tabs.list")).addCommand(readCommand("current", "tabs.current")).addCommand(
|
|
8049
|
+
addWriteOptions(
|
|
8050
|
+
new Command().name("activate").description("Run tabs.activate").requiredOption("--tab-id <id>", "Tab to activate").action(
|
|
8051
|
+
withErrorHandler(async (options) => {
|
|
8052
|
+
await runWriteCommand("tabs.activate", options, {});
|
|
8053
|
+
})
|
|
8054
|
+
),
|
|
8055
|
+
{ tabId: false }
|
|
8056
|
+
)
|
|
8057
|
+
).addCommand(
|
|
8058
|
+
addWriteOptions(
|
|
8059
|
+
new Command().name("open").description("Run tabs.open").requiredOption("--url <url>", "URL to open").action(
|
|
8060
|
+
withErrorHandler(async (options) => {
|
|
8061
|
+
await runWriteCommand("tabs.open", options, { url: options.url });
|
|
8062
|
+
})
|
|
8063
|
+
)
|
|
8064
|
+
)
|
|
8065
|
+
).addCommand(
|
|
8066
|
+
addWriteOptions(
|
|
8067
|
+
new Command().name("close").description("Run tabs.close").requiredOption("--tab-id <id>", "Tab to close").action(
|
|
8068
|
+
withErrorHandler(async (options) => {
|
|
8069
|
+
await runWriteCommand("tabs.close", options, {});
|
|
8070
|
+
})
|
|
8071
|
+
),
|
|
8072
|
+
{ tabId: false }
|
|
8073
|
+
)
|
|
8074
|
+
);
|
|
8075
|
+
var pageCommand = new Command().name("page").description("Read and control the active browser page").addCommand(readCommand("snapshot", "page.snapshot")).addCommand(readCommand("screenshot", "page.screenshot")).addCommand(readCommand("selection", "page.selection")).addCommand(readCommand("metadata", "page.metadata")).addCommand(
|
|
8076
|
+
addWriteOptions(
|
|
8077
|
+
new Command().name("click").description("Run page.click").option("--selector <selector>", "CSS selector to click").option("--x <pixels>", "X coordinate to click").option("--y <pixels>", "Y coordinate to click").action(
|
|
8078
|
+
withErrorHandler(async (options) => {
|
|
8079
|
+
await runWriteCommand("page.click", options, {
|
|
8080
|
+
...options.selector ? { selector: options.selector } : {},
|
|
8081
|
+
...options.x !== void 0 ? { x: parseOptionalNonNegativeInteger(options.x, "x") } : {},
|
|
8082
|
+
...options.y !== void 0 ? { y: parseOptionalNonNegativeInteger(options.y, "y") } : {}
|
|
8083
|
+
});
|
|
8084
|
+
})
|
|
8085
|
+
)
|
|
8086
|
+
)
|
|
8087
|
+
).addCommand(
|
|
8088
|
+
addWriteOptions(
|
|
8089
|
+
new Command().name("type").description("Run page.type").requiredOption("--selector <selector>", "CSS selector to type into").requiredOption("--text <text>", "Text to type").action(
|
|
8090
|
+
withErrorHandler(async (options) => {
|
|
8091
|
+
await runWriteCommand("page.type", options, {
|
|
8092
|
+
selector: options.selector,
|
|
8093
|
+
text: options.text
|
|
8094
|
+
});
|
|
8095
|
+
})
|
|
8096
|
+
)
|
|
8097
|
+
)
|
|
8098
|
+
).addCommand(
|
|
8099
|
+
addWriteOptions(
|
|
8100
|
+
new Command().name("scroll").description("Run page.scroll").option(
|
|
8101
|
+
"--direction <direction>",
|
|
8102
|
+
"Scroll direction: up or down",
|
|
8103
|
+
"down"
|
|
8104
|
+
).option("--amount <pixels>", "Scroll amount in pixels", "600").action(
|
|
8105
|
+
withErrorHandler(async (options) => {
|
|
8106
|
+
if (options.direction !== "up" && options.direction !== "down") {
|
|
8107
|
+
throw new Error("direction must be up or down");
|
|
8108
|
+
}
|
|
8109
|
+
await runWriteCommand("page.scroll", options, {
|
|
8110
|
+
direction: options.direction,
|
|
8111
|
+
amount: parsePositiveInteger2(options.amount, "amount")
|
|
8112
|
+
});
|
|
8113
|
+
})
|
|
8114
|
+
)
|
|
8115
|
+
)
|
|
8116
|
+
).addCommand(
|
|
8117
|
+
addWriteOptions(
|
|
8118
|
+
new Command().name("navigate").description("Run page.navigate").requiredOption("--url <url>", "URL to navigate to").action(
|
|
8119
|
+
withErrorHandler(async (options) => {
|
|
8120
|
+
await runWriteCommand("page.navigate", options, {
|
|
8121
|
+
url: options.url
|
|
8122
|
+
});
|
|
8123
|
+
})
|
|
8124
|
+
)
|
|
8125
|
+
)
|
|
8126
|
+
);
|
|
8127
|
+
var zeroLocalBrowserCommand = new Command().name("local-browser").description("Read and manage authorized browser context").addHelpText(
|
|
7759
8128
|
"after",
|
|
7760
8129
|
`
|
|
7761
8130
|
Examples:
|
|
8131
|
+
List hosts? zero local-browser hosts list
|
|
8132
|
+
Revoke host? zero local-browser hosts revoke <host-id>
|
|
7762
8133
|
List tabs? zero local-browser tabs list
|
|
7763
8134
|
Current tab? zero local-browser tabs current
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
8135
|
+
Click page? zero local-browser page click --selector button
|
|
8136
|
+
Open tab? zero local-browser tabs open --url https://example.com
|
|
8137
|
+
Audit actions? zero local-browser audit list`
|
|
8138
|
+
).addCommand(hostsCommand).addCommand(auditCommand).addCommand(tabsCommand).addCommand(pageCommand);
|
|
7767
8139
|
|
|
7768
8140
|
// src/commands/zero/host/index.ts
|
|
7769
8141
|
init_esm_shims();
|
|
@@ -8084,7 +8456,7 @@ var COMMAND_CAPABILITY_MAP = {
|
|
|
8084
8456
|
web: null,
|
|
8085
8457
|
host: "host:write",
|
|
8086
8458
|
"remote-agent": ["remote-agent:read", "remote-agent:write"],
|
|
8087
|
-
"local-browser": "local-browser:read"
|
|
8459
|
+
"local-browser": ["local-browser:read", "local-browser:write"]
|
|
8088
8460
|
};
|
|
8089
8461
|
var DEFAULT_COMMANDS = [
|
|
8090
8462
|
zeroOrgCommand,
|
|
@@ -8159,7 +8531,7 @@ function registerZeroCommands(prog, commands) {
|
|
|
8159
8531
|
var program = new Command();
|
|
8160
8532
|
program.name("zero").description(
|
|
8161
8533
|
"Zero CLI \u2014 interact with the zero platform from inside the sandbox"
|
|
8162
|
-
).version("9.
|
|
8534
|
+
).version("9.153.0").addHelpText("after", () => {
|
|
8163
8535
|
return buildZeroHelpText();
|
|
8164
8536
|
});
|
|
8165
8537
|
if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {
|