@vm0/cli 9.203.0 → 9.204.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/zero.js CHANGED
@@ -13,7 +13,6 @@ import {
13
13
  Option,
14
14
  PRESENTATION_REQUIRED_RESOURCE_IDS,
15
15
  UNKNOWN_PERMISSION_GRANT,
16
- addAutomationTrigger,
17
16
  blockGoal,
18
17
  callZeroBanking,
19
18
  callZeroMaps,
@@ -38,6 +37,7 @@ import {
38
37
  createWorkflowTrigger,
39
38
  createZeroAgent,
40
39
  createZeroCreditCheckout,
40
+ customConnectorProposalSchema,
41
41
  decodeZeroTokenPayload,
42
42
  deleteAutomation,
43
43
  deleteGithubLabelListener,
@@ -51,7 +51,6 @@ import {
51
51
  deleteZeroSecret,
52
52
  deleteZeroVariable,
53
53
  disableAutomation,
54
- disableAutomationTrigger,
55
54
  disableWorkflowTrigger,
56
55
  downloadGithubFile,
57
56
  downloadPhoneFile,
@@ -60,7 +59,6 @@ import {
60
59
  downloadWebFile,
61
60
  editGoal,
62
61
  enableAutomation,
63
- enableAutomationTrigger,
64
62
  enableWorkflowTrigger,
65
63
  extractSecretNamesFromApis,
66
64
  fetchComputerUseScreenshot,
@@ -99,10 +97,12 @@ import {
99
97
  getWorkflow,
100
98
  getWorkflowTrigger,
101
99
  getZeroAgent,
100
+ getZeroAgentCustomConnectors,
102
101
  getZeroAgentInstructions,
103
102
  getZeroAgentUserConnectors,
104
103
  getZeroBillingStatus,
105
104
  getZeroConnector,
105
+ getZeroCustomConnector,
106
106
  getZeroOrg,
107
107
  getZeroOrgMembers,
108
108
  getZeroRunAgentEvents,
@@ -120,7 +120,6 @@ import {
120
120
  isInteractive,
121
121
  isUUID,
122
122
  leaveZeroOrg,
123
- listAutomationTriggers,
124
123
  listAutomations,
125
124
  listDesignSystems,
126
125
  listImageStyles,
@@ -131,6 +130,7 @@ import {
131
130
  listWorkflows,
132
131
  listZeroAgents,
133
132
  listZeroConnectors,
133
+ listZeroCustomConnectors,
134
134
  listZeroLogs,
135
135
  listZeroModelPolicies,
136
136
  listZeroOrgModelProviders,
@@ -149,7 +149,6 @@ import {
149
149
  promptConfirm,
150
150
  promptPassword,
151
151
  promptText,
152
- removeAutomationTrigger,
153
152
  removeZeroOrgMember,
154
153
  requestDeveloperSupportConsent,
155
154
  require_prompts,
@@ -173,7 +172,6 @@ import {
173
172
  setZeroSecret,
174
173
  setZeroVariable,
175
174
  showAutomation,
176
- showAutomationTrigger,
177
175
  source_default,
178
176
  submitDeveloperSupport,
179
177
  switchZeroOrg,
@@ -192,7 +190,7 @@ import {
192
190
  uploadWebFile,
193
191
  upsertZeroOrgModelProvider,
194
192
  withErrorHandler
195
- } from "./chunk-QVNEGQGL.js";
193
+ } from "./chunk-NQ6BMAY6.js";
196
194
  import "./chunk-NR42YJMI.js";
197
195
  import {
198
196
  __toESM,
@@ -2370,8 +2368,157 @@ var statusCommand2 = new Command().name("status").description("Show detailed sta
2370
2368
  })
2371
2369
  );
2372
2370
 
2371
+ // src/commands/zero/connector/custom/index.ts
2372
+ init_esm_shims();
2373
+ import { readFile } from "fs/promises";
2374
+ var LABEL_WIDTH2 = 18;
2375
+ function renderConnected(connector) {
2376
+ if (connector.connected) {
2377
+ return source_default.green("connected");
2378
+ }
2379
+ if (connector.missingRequiredFields.length === 0) {
2380
+ return source_default.dim("not connected");
2381
+ }
2382
+ return source_default.yellow(`missing ${connector.missingRequiredFields.join(", ")}`);
2383
+ }
2384
+ function encodeBase64UrlJson(value) {
2385
+ return Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
2386
+ }
2387
+ function isJsonObject(value) {
2388
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2389
+ }
2390
+ async function resolveCustomAgentContext(agentId) {
2391
+ const resolvedAgentId = agentId ?? process.env.ZERO_AGENT_ID;
2392
+ if (!resolvedAgentId) {
2393
+ return null;
2394
+ }
2395
+ const [agent, enabledIds] = await Promise.all([
2396
+ getZeroAgent(resolvedAgentId),
2397
+ getZeroAgentCustomConnectors(resolvedAgentId)
2398
+ ]);
2399
+ return {
2400
+ agentId: agent.agentId,
2401
+ displayName: agent.displayName ?? agent.agentId,
2402
+ authorizedIds: new Set(enabledIds)
2403
+ };
2404
+ }
2405
+ var listCommand7 = new Command().name("list").alias("ls").description("List org custom connectors").option("--agent <id>", "Show per-agent authorization column").action(
2406
+ withErrorHandler(async (options) => {
2407
+ const [connectors, agentCtx] = await Promise.all([
2408
+ listZeroCustomConnectors(),
2409
+ resolveCustomAgentContext(options.agent)
2410
+ ]);
2411
+ const idWidth = Math.max(
2412
+ 2,
2413
+ ...connectors.map((connector) => {
2414
+ return connector.id.length;
2415
+ })
2416
+ );
2417
+ const nameWidth = Math.max(
2418
+ 4,
2419
+ ...connectors.map((connector) => {
2420
+ return connector.displayName.length;
2421
+ })
2422
+ );
2423
+ const header = ["ID".padEnd(idWidth), "NAME".padEnd(nameWidth), "STATUS"];
2424
+ if (agentCtx) {
2425
+ header.push(`AUTHORIZED FOR ${agentCtx.displayName}`);
2426
+ }
2427
+ console.log(source_default.dim(header.join(" ")));
2428
+ for (const connector of connectors) {
2429
+ const row = [
2430
+ connector.id.padEnd(idWidth),
2431
+ connector.displayName.padEnd(nameWidth),
2432
+ renderConnected(connector)
2433
+ ];
2434
+ if (agentCtx) {
2435
+ row.push(
2436
+ agentCtx.authorizedIds.has(connector.id) ? source_default.green("\u2713") : source_default.dim("-")
2437
+ );
2438
+ }
2439
+ console.log(row.join(" "));
2440
+ }
2441
+ })
2442
+ );
2443
+ var statusCommand3 = new Command().name("status").description("Show detailed status of a custom connector").argument("<connector-id>", "Custom connector id").option("--agent <id>", "Show authorization state for the given agent").action(
2444
+ withErrorHandler(
2445
+ async (connectorId, options) => {
2446
+ const [connector, agentCtx] = await Promise.all([
2447
+ getZeroCustomConnector(connectorId),
2448
+ resolveCustomAgentContext(options.agent)
2449
+ ]);
2450
+ if (!connector) {
2451
+ throw new Error(`Custom connector not found: ${connectorId}`);
2452
+ }
2453
+ console.log(`Custom connector: ${source_default.cyan(connector.displayName)}`);
2454
+ console.log();
2455
+ console.log(`${"ID:".padEnd(LABEL_WIDTH2)}${connector.id}`);
2456
+ console.log(
2457
+ `${"Status:".padEnd(LABEL_WIDTH2)}${renderConnected(connector)}`
2458
+ );
2459
+ console.log(
2460
+ `${"Prefixes:".padEnd(LABEL_WIDTH2)}${connector.prefixTemplates.join(", ")}`
2461
+ );
2462
+ console.log(
2463
+ `${"Fields:".padEnd(LABEL_WIDTH2)}${connector.fields.map((field) => {
2464
+ return `${field.kind}:${field.key}${field.required ? "" : "?"}`;
2465
+ }).join(", ")}`
2466
+ );
2467
+ if (connector.headerInjections.length > 0) {
2468
+ console.log(
2469
+ `${"Headers:".padEnd(LABEL_WIDTH2)}${connector.headerInjections.map((header) => {
2470
+ return header.name;
2471
+ }).join(", ")}`
2472
+ );
2473
+ }
2474
+ if (connector.queryInjections.length > 0) {
2475
+ console.log(
2476
+ `${"Query params:".padEnd(LABEL_WIDTH2)}${connector.queryInjections.map((query) => {
2477
+ return query.name;
2478
+ }).join(", ")}`
2479
+ );
2480
+ }
2481
+ if (agentCtx) {
2482
+ console.log(
2483
+ `${"Authorized:".padEnd(LABEL_WIDTH2)}${agentCtx.authorizedIds.has(connector.id) ? source_default.green("yes") : source_default.yellow("no")}`
2484
+ );
2485
+ }
2486
+ }
2487
+ )
2488
+ );
2489
+ var proposeCommand = new Command().name("propose").description("Create a browser save link for a custom connector proposal").requiredOption("--proposal-file <path>", "JSON proposal file").option("--connector-id <id>", "Override connector id for update proposals").option("--agent <id>", "Authorize this agent when the proposal is saved").action(
2490
+ withErrorHandler(
2491
+ async (options) => {
2492
+ const raw = await readFile(options.proposalFile, "utf8");
2493
+ const proposalJson = JSON.parse(raw);
2494
+ if (!isJsonObject(proposalJson)) {
2495
+ throw new Error("Proposal file must contain a JSON object");
2496
+ }
2497
+ const parsed = customConnectorProposalSchema.parse({
2498
+ ...proposalJson,
2499
+ ...options.connectorId ? { connectorId: options.connectorId } : {}
2500
+ });
2501
+ const origin = await getPlatformOrigin();
2502
+ const params = new URLSearchParams({
2503
+ p: encodeBase64UrlJson(parsed)
2504
+ });
2505
+ const agentId = options.agent ?? process.env.ZERO_AGENT_ID;
2506
+ if (agentId) {
2507
+ params.set("agentId", agentId);
2508
+ }
2509
+ const url = `${origin}/connectors/custom/proposal?${params.toString()}`;
2510
+ console.log(`[Configure ${parsed.displayName}](${url})`);
2511
+ console.log();
2512
+ console.log(
2513
+ "Open this link to review, save values, and authorize the connector."
2514
+ );
2515
+ }
2516
+ )
2517
+ );
2518
+ var customConnectorCommand = new Command().name("custom").description("Inspect and propose org custom connectors").addCommand(listCommand7).addCommand(statusCommand3).addCommand(proposeCommand);
2519
+
2373
2520
  // src/commands/zero/connector/index.ts
2374
- var zeroConnectorCommand = new Command().name("connector").description("Check third-party service connections (GitHub, Slack, etc.)").addCommand(connectCommand).addCommand(listCommand6).addCommand(searchCommand).addCommand(statusCommand2);
2521
+ var zeroConnectorCommand = new Command().name("connector").description("Check third-party service connections (GitHub, Slack, etc.)").addCommand(customConnectorCommand).addCommand(connectCommand).addCommand(listCommand6).addCommand(searchCommand).addCommand(statusCommand2);
2375
2522
 
2376
2523
  // src/commands/zero/credit.ts
2377
2524
  init_esm_shims();
@@ -3512,33 +3659,6 @@ function printTriggersTable(triggers) {
3512
3659
  );
3513
3660
  }
3514
3661
  }
3515
- function printTriggerDetails(trigger) {
3516
- const status = trigger.enabled ? source_default.green("enabled") : source_default.yellow("disabled");
3517
- console.log(`${"Kind:".padEnd(14)}${trigger.kind}`);
3518
- console.log(`${"ID:".padEnd(14)}${trigger.id}`);
3519
- console.log(`${"Automation:".padEnd(14)}${trigger.automationId}`);
3520
- console.log(`${"Status:".padEnd(14)}${status}`);
3521
- switch (trigger.kind) {
3522
- case "cron":
3523
- console.log(`${"Cron:".padEnd(14)}${trigger.cronExpression}`);
3524
- break;
3525
- case "once":
3526
- console.log(`${"At:".padEnd(14)}${trigger.atTime}`);
3527
- break;
3528
- case "loop":
3529
- console.log(
3530
- `${"Every:".padEnd(14)}${formatDurationSeconds(trigger.intervalSeconds)}`
3531
- );
3532
- break;
3533
- }
3534
- console.log(`${"Timezone:".padEnd(14)}${trigger.timezone}`);
3535
- console.log(
3536
- `${"Next run:".padEnd(14)}${trigger.nextRunAt ? formatRelativeTime(trigger.nextRunAt) : source_default.dim("-")}`
3537
- );
3538
- console.log(
3539
- `${"Last run:".padEnd(14)}${trigger.lastRunAt ? formatRelativeTime(trigger.lastRunAt) : source_default.dim("-")}`
3540
- );
3541
- }
3542
3662
 
3543
3663
  // src/commands/zero/automation/create.ts
3544
3664
  function buildInlineTrigger(options) {
@@ -3547,8 +3667,8 @@ function buildInlineTrigger(options) {
3547
3667
  return value !== void 0;
3548
3668
  }
3549
3669
  ).length;
3550
- if (sugarCount > 1) {
3551
- throw new Error("Use at most one of --cron, --once, --loop");
3670
+ if (sugarCount !== 1) {
3671
+ throw new Error("Use exactly one of --cron, --once, --loop");
3552
3672
  }
3553
3673
  if (options.timezone && !options.cron && !options.once) {
3554
3674
  throw new Error("--timezone requires --cron or --once");
@@ -3570,9 +3690,9 @@ function buildInlineTrigger(options) {
3570
3690
  intervalSeconds: parseDurationSeconds(options.loop)
3571
3691
  };
3572
3692
  }
3573
- return void 0;
3693
+ throw new Error("Use exactly one of --cron, --once, --loop");
3574
3694
  }
3575
- var createCommand2 = new Command().name("create").description("Create an automation (optionally with its first trigger)").requiredOption("-n, --name <name>", "Automation name").requiredOption("--agent <id>", "Agent ID or name to run").requiredOption(
3695
+ var createCommand2 = new Command().name("create").description("Create an automation with a schedule trigger").requiredOption("-n, --name <name>", "Automation name").requiredOption("--agent <id>", "Agent ID or name to run").requiredOption(
3576
3696
  "-p, --prompt <instruction>",
3577
3697
  "Instruction the agent runs when the automation fires"
3578
3698
  ).option("--description <text>", "Optional description").option("--cron <expression>", 'Add a cron trigger (e.g. "0 9 * * *")').option(
@@ -3582,13 +3702,12 @@ var createCommand2 = new Command().name("create").description("Create an automat
3582
3702
  "after",
3583
3703
  `
3584
3704
  Examples:
3585
- Triggerless: zero automation create -n alerts --agent my-agent -p "Summarize alerts"
3586
3705
  Daily at 9am: zero automation create -n alerts --agent my-agent -p "..." --cron "0 9 * * *"
3587
3706
  One-time: zero automation create -n alerts --agent my-agent -p "..." --once "2026-06-10T09:00" -z UTC
3588
3707
  Every 15 min: zero automation create -n alerts --agent my-agent -p "..." --loop 15m
3589
3708
 
3590
3709
  Notes:
3591
- - At most one of --cron, --once, --loop; add more triggers later with: zero automation trigger add`
3710
+ - Exactly one of --cron, --once, --loop is required`
3592
3711
  ).action(
3593
3712
  withErrorHandler(async (options) => {
3594
3713
  const trigger = buildInlineTrigger(options);
@@ -3617,11 +3736,6 @@ Notes:
3617
3736
  );
3618
3737
  }
3619
3738
  console.log();
3620
- if (!createdTrigger) {
3621
- console.log(
3622
- ` Add a trigger: ${source_default.cyan(`zero automation trigger add ${automation.name} cron --expr "0 9 * * *"`)}`
3623
- );
3624
- }
3625
3739
  console.log(
3626
3740
  ` Run manually: ${source_default.cyan(`zero automation run ${automation.name}`)}`
3627
3741
  );
@@ -3631,14 +3745,13 @@ Notes:
3631
3745
  // src/commands/zero/automation/list.ts
3632
3746
  init_esm_shims();
3633
3747
  function formatTriggerSummary(automation) {
3634
- if (automation.triggers.length === 0) {
3748
+ const [trigger] = automation.triggers;
3749
+ if (!trigger) {
3635
3750
  return source_default.dim("-");
3636
3751
  }
3637
- return automation.triggers.map((t) => {
3638
- return t.kind;
3639
- }).join(", ");
3752
+ return trigger.kind;
3640
3753
  }
3641
- var listCommand7 = new Command().name("list").alias("ls").description("List automations with their triggers").addHelpText(
3754
+ var listCommand8 = new Command().name("list").alias("ls").description("List automations with their schedule trigger").addHelpText(
3642
3755
  "after",
3643
3756
  `
3644
3757
  Examples:
@@ -3680,7 +3793,7 @@ Examples:
3680
3793
  "ID".padEnd(idWidth),
3681
3794
  "AGENT".padEnd(agentWidth),
3682
3795
  "STATUS".padEnd(8),
3683
- "TRIGGERS"
3796
+ "TRIGGER"
3684
3797
  ].join(" ")
3685
3798
  )
3686
3799
  );
@@ -3705,7 +3818,7 @@ Examples:
3705
3818
 
3706
3819
  // src/commands/zero/automation/show.ts
3707
3820
  init_esm_shims();
3708
- var showCommand = new Command().name("show").description("Show an automation and its triggers").argument("<automation>", "Automation ID or name").addHelpText(
3821
+ var showCommand = new Command().name("show").description("Show an automation and its schedule").argument("<automation>", "Automation ID or name").addHelpText(
3709
3822
  "after",
3710
3823
  `
3711
3824
  Examples:
@@ -3731,16 +3844,12 @@ Notes:
3731
3844
  );
3732
3845
  console.log(`${"Thread:".padEnd(14)}${automation.chatThreadId}`);
3733
3846
  console.log();
3734
- if (automation.triggers.length === 0) {
3735
- console.log(source_default.dim("No triggers"));
3736
- console.log(
3737
- source_default.dim(
3738
- ` Add one with: zero automation trigger add ${automation.name} cron --expr "0 9 * * *"`
3739
- )
3740
- );
3847
+ const [trigger] = automation.triggers;
3848
+ if (!trigger) {
3849
+ console.log(source_default.dim("No schedule trigger"));
3741
3850
  return;
3742
3851
  }
3743
- printTriggersTable(automation.triggers);
3852
+ printTriggersTable([trigger]);
3744
3853
  })
3745
3854
  );
3746
3855
 
@@ -3789,8 +3898,7 @@ Examples:
3789
3898
  zero automation update alerts --loop 10m
3790
3899
 
3791
3900
  Notes:
3792
- - At most one of --cron, --once, --loop; it replaces the automation's single time trigger in place (the kind may switch, run history is kept)
3793
- - With multiple time triggers, address one directly: zero automation trigger update <trigger-id>`
3901
+ - At most one of --cron, --once, --loop; it replaces the automation's schedule trigger in place (the kind may switch, run history is kept)`
3794
3902
  ).action(
3795
3903
  withErrorHandler(async (ref, options) => {
3796
3904
  const timing = buildTimingUpdate(options);
@@ -3806,17 +3914,7 @@ Notes:
3806
3914
  const timeTriggers = automation.triggers;
3807
3915
  const [first] = timeTriggers;
3808
3916
  if (!first) {
3809
- throw new Error(
3810
- `No time trigger to update; add one with: zero automation trigger add ${ref} cron --expr "0 9 * * *"`
3811
- );
3812
- }
3813
- if (timeTriggers.length > 1) {
3814
- const ids = timeTriggers.map((trigger) => {
3815
- return trigger.id;
3816
- }).join(", ");
3817
- throw new Error(
3818
- `Multiple time triggers; update one explicitly: zero automation trigger update <id> ... (ids: ${ids})`
3819
- );
3917
+ throw new Error(`Automation ${ref} has no schedule trigger`);
3820
3918
  }
3821
3919
  timeTriggerId = first.id;
3822
3920
  }
@@ -3858,7 +3956,7 @@ Notes:
3858
3956
  throw new Error("--yes flag is required in non-interactive mode");
3859
3957
  }
3860
3958
  const confirmed = await promptConfirm(
3861
- `Delete automation ${source_default.cyan(ref)} and all of its triggers?`,
3959
+ `Delete automation ${source_default.cyan(ref)} and its schedule trigger?`,
3862
3960
  false
3863
3961
  );
3864
3962
  if (!confirmed) {
@@ -3873,14 +3971,11 @@ Notes:
3873
3971
 
3874
3972
  // src/commands/zero/automation/enable.ts
3875
3973
  init_esm_shims();
3876
- var enableCommand = new Command().name("enable").description("Enable an automation (all of its triggers resume)").argument("<automation>", "Automation ID or name").addHelpText(
3974
+ var enableCommand = new Command().name("enable").description("Enable an automation").argument("<automation>", "Automation ID or name").addHelpText(
3877
3975
  "after",
3878
3976
  `
3879
3977
  Examples:
3880
- zero automation enable alerts
3881
-
3882
- Notes:
3883
- - To enable a single trigger instead: zero automation trigger enable <trigger-id>`
3978
+ zero automation enable alerts`
3884
3979
  ).action(
3885
3980
  withErrorHandler(async (ref) => {
3886
3981
  const automation = await enableAutomation(ref);
@@ -3890,14 +3985,11 @@ Notes:
3890
3985
 
3891
3986
  // src/commands/zero/automation/disable.ts
3892
3987
  init_esm_shims();
3893
- var disableCommand = new Command().name("disable").description("Disable an automation (suspends all of its triggers)").argument("<automation>", "Automation ID or name").addHelpText(
3988
+ var disableCommand = new Command().name("disable").description("Disable an automation").argument("<automation>", "Automation ID or name").addHelpText(
3894
3989
  "after",
3895
3990
  `
3896
3991
  Examples:
3897
- zero automation disable alerts
3898
-
3899
- Notes:
3900
- - To disable a single trigger instead: zero automation trigger disable <trigger-id>`
3992
+ zero automation disable alerts`
3901
3993
  ).action(
3902
3994
  withErrorHandler(async (ref) => {
3903
3995
  const automation = await disableAutomation(ref);
@@ -3920,206 +4012,8 @@ Examples:
3920
4012
  })
3921
4013
  );
3922
4014
 
3923
- // src/commands/zero/automation/trigger/index.ts
3924
- init_esm_shims();
3925
-
3926
- // src/commands/zero/automation/trigger/add.ts
3927
- init_esm_shims();
3928
- var TRIGGER_KINDS = ["cron", "once", "loop"];
3929
- function buildTrigger(kind, options) {
3930
- switch (kind) {
3931
- case "cron":
3932
- if (!options.expr) {
3933
- throw new Error(
3934
- 'cron triggers require --expr (e.g. --expr "0 9 * * *")'
3935
- );
3936
- }
3937
- return {
3938
- kind: "cron",
3939
- cronExpression: options.expr,
3940
- timezone: options.timezone
3941
- };
3942
- case "once":
3943
- if (!options.at) {
3944
- throw new Error(
3945
- 'once triggers require --at (e.g. --at "2026-06-10T09:00")'
3946
- );
3947
- }
3948
- requireTimezoneForLocalAtTime(options.at, options.timezone, "--at");
3949
- return { kind: "once", atTime: options.at, timezone: options.timezone };
3950
- case "loop":
3951
- if (!options.every) {
3952
- throw new Error("loop triggers require --every (e.g. --every 15m)");
3953
- }
3954
- return {
3955
- kind: "loop",
3956
- intervalSeconds: parseDurationSeconds(options.every)
3957
- };
3958
- default:
3959
- throw new Error(
3960
- `Unknown trigger kind: "${kind}". Use one of: ${TRIGGER_KINDS.join(", ")}`
3961
- );
3962
- }
3963
- }
3964
- var addCommand = new Command().name("add").description("Add a trigger (cron | once | loop) to an automation").argument("<automation>", "Automation ID or name").argument("<kind>", `Trigger kind: ${TRIGGER_KINDS.join(" | ")}`).option(
3965
- "--expr <expression>",
3966
- 'Cron expression for kind "cron" (e.g. "0 9 * * *")'
3967
- ).option(
3968
- "--at <iso-time>",
3969
- 'Fire time for kind "once" (e.g. "2026-06-10T09:00")'
3970
- ).option("--every <duration>", 'Interval for kind "loop" (e.g. 15m, 1h, 90s)').option("-z, --timezone <tz>", "IANA timezone for cron/once").addHelpText(
3971
- "after",
3972
- `
3973
- Trigger kinds:
3974
- cron Recurring schedule: zero automation trigger add alerts cron --expr "0 9 * * *" [--timezone Asia/Shanghai]
3975
- once One-time fire: zero automation trigger add alerts once --at "2026-06-10T09:00" [--timezone UTC]
3976
- loop Fixed interval: zero automation trigger add alerts loop --every 15m`
3977
- ).action(
3978
- withErrorHandler(async (ref, kind, options) => {
3979
- if (options.timezone && kind !== "cron" && kind !== "once") {
3980
- throw new Error("--timezone only applies to cron and once triggers");
3981
- }
3982
- const body = buildTrigger(kind, options);
3983
- const { trigger } = await addAutomationTrigger(ref, body);
3984
- console.log(source_default.green(`\u2713 Trigger added to automation "${ref}"`));
3985
- printTriggerDetails(trigger);
3986
- })
3987
- );
3988
-
3989
- // src/commands/zero/automation/trigger/update.ts
3990
- init_esm_shims();
3991
- var EXACTLY_ONE_FLAG_MESSAGE = "Provide exactly one of --expr (cron), --at (once), --every (loop)";
3992
- function buildUpdate(options) {
3993
- const flagCount = [options.expr, options.at, options.every].filter(
3994
- (value) => {
3995
- return value !== void 0;
3996
- }
3997
- ).length;
3998
- if (flagCount > 1) {
3999
- throw new Error(EXACTLY_ONE_FLAG_MESSAGE);
4000
- }
4001
- if (options.timezone && !options.expr && !options.at) {
4002
- throw new Error("--timezone only applies to --expr and --at");
4003
- }
4004
- if (options.expr) {
4005
- return {
4006
- kind: "cron",
4007
- cronExpression: options.expr,
4008
- timezone: options.timezone
4009
- };
4010
- }
4011
- if (options.at) {
4012
- requireTimezoneForLocalAtTime(options.at, options.timezone, "--at");
4013
- return { kind: "once", atTime: options.at, timezone: options.timezone };
4014
- }
4015
- if (options.every) {
4016
- return {
4017
- kind: "loop",
4018
- intervalSeconds: parseDurationSeconds(options.every)
4019
- };
4020
- }
4021
- throw new Error(EXACTLY_ONE_FLAG_MESSAGE);
4022
- }
4023
- var updateCommand2 = new Command().name("update").description(
4024
- "Replace a time trigger's schedule in place (kind may switch among cron/once/loop)"
4025
- ).argument("<trigger>", "Trigger ID").option("--expr <expression>", 'New cron schedule (e.g. "0 9 * * *")').option("--at <iso-time>", 'New one-time fire (e.g. "2026-06-10T09:00")').option("--every <duration>", "New loop interval (e.g. 15m, 1h, 90s)").option("-z, --timezone <tz>", "IANA timezone for --expr / --at").addHelpText(
4026
- "after",
4027
- `
4028
- Examples:
4029
- zero automation trigger update 22222222-2222-4222-8222-222222222222 --expr "0 9 * * *" -z Asia/Shanghai
4030
- zero automation trigger update 22222222-2222-4222-8222-222222222222 --at "2026-06-10T09:00"
4031
- zero automation trigger update 22222222-2222-4222-8222-222222222222 --every 10m
4032
-
4033
- Notes:
4034
- - Exactly one of --expr (cron), --at (once), --every (loop); the trigger's kind switches to match
4035
- - The trigger keeps its id, enabled flag, and run history; the next run is recomputed and the failure counter resets`
4036
- ).action(
4037
- withErrorHandler(async (id, options) => {
4038
- const body = buildUpdate(options);
4039
- const trigger = await updateAutomationTrigger(id, body);
4040
- console.log(source_default.green(`\u2713 Trigger ${trigger.id} updated`));
4041
- printTriggerDetails(trigger);
4042
- })
4043
- );
4044
-
4045
- // src/commands/zero/automation/trigger/index.ts
4046
- var listCommand8 = new Command().name("list").alias("ls").description("List an automation's triggers").argument("<automation>", "Automation ID or name").addHelpText(
4047
- "after",
4048
- `
4049
- Examples:
4050
- zero automation trigger list alerts`
4051
- ).action(
4052
- withErrorHandler(async (ref) => {
4053
- const { triggers } = await listAutomationTriggers(ref);
4054
- if (triggers.length === 0) {
4055
- console.log(source_default.dim("No triggers"));
4056
- console.log(
4057
- source_default.dim(
4058
- ` Add one with: zero automation trigger add ${ref} cron --expr "0 9 * * *"`
4059
- )
4060
- );
4061
- return;
4062
- }
4063
- printTriggersTable(triggers);
4064
- })
4065
- );
4066
- var showCommand2 = new Command().name("show").description("Show a trigger").argument("<trigger>", "Trigger ID").addHelpText(
4067
- "after",
4068
- `
4069
- Examples:
4070
- zero automation trigger show 22222222-2222-4222-8222-222222222222`
4071
- ).action(
4072
- withErrorHandler(async (id) => {
4073
- const trigger = await showAutomationTrigger(id);
4074
- printTriggerDetails(trigger);
4075
- })
4076
- );
4077
- var rmCommand = new Command().name("rm").alias("remove").description("Remove a trigger").argument("<trigger>", "Trigger ID").addHelpText(
4078
- "after",
4079
- `
4080
- Examples:
4081
- zero automation trigger rm 22222222-2222-4222-8222-222222222222`
4082
- ).action(
4083
- withErrorHandler(async (id) => {
4084
- await removeAutomationTrigger(id);
4085
- console.log(source_default.green(`\u2713 Trigger ${id} removed`));
4086
- })
4087
- );
4088
- var enableCommand2 = new Command().name("enable").description("Enable a single trigger").argument("<trigger>", "Trigger ID").addHelpText(
4089
- "after",
4090
- `
4091
- Examples:
4092
- zero automation trigger enable 22222222-2222-4222-8222-222222222222`
4093
- ).action(
4094
- withErrorHandler(async (id) => {
4095
- const trigger = await enableAutomationTrigger(id);
4096
- console.log(source_default.green(`\u2713 Trigger ${trigger.id} enabled`));
4097
- })
4098
- );
4099
- var disableCommand2 = new Command().name("disable").description("Disable a single trigger").argument("<trigger>", "Trigger ID").addHelpText(
4100
- "after",
4101
- `
4102
- Examples:
4103
- zero automation trigger disable 22222222-2222-4222-8222-222222222222`
4104
- ).action(
4105
- withErrorHandler(async (id) => {
4106
- const trigger = await disableAutomationTrigger(id);
4107
- console.log(source_default.green(`\u2713 Trigger ${trigger.id} disabled`));
4108
- })
4109
- );
4110
- var triggerCommand = new Command().name("trigger").description("Manage an automation's triggers").addCommand(addCommand).addCommand(updateCommand2).addCommand(listCommand8).addCommand(showCommand2).addCommand(rmCommand).addCommand(enableCommand2).addCommand(disableCommand2).addHelpText(
4111
- "after",
4112
- `
4113
- Examples:
4114
- Add a trigger: zero automation trigger add <automation> cron --expr "0 9 * * *"
4115
- Update a schedule: zero automation trigger update <trigger-id> --every 10m (kind switches to match the flag)
4116
- List triggers: zero automation trigger list <automation>
4117
- Inspect a trigger: zero automation trigger show <trigger-id>
4118
- Pause one trigger: zero automation trigger disable <trigger-id>`
4119
- );
4120
-
4121
4015
  // src/commands/zero/automation/index.ts
4122
- var zeroAutomationCommand = new Command().name("automation").description("Create or manage automations and their triggers").addCommand(createCommand2).addCommand(listCommand7).addCommand(showCommand).addCommand(updateCommand).addCommand(deleteCommand3).addCommand(enableCommand).addCommand(disableCommand).addCommand(runCommand).addCommand(triggerCommand).addHelpText(
4016
+ var zeroAutomationCommand = new Command().name("automation").description("Create or manage scheduled automations").addCommand(createCommand2).addCommand(listCommand8).addCommand(showCommand).addCommand(updateCommand).addCommand(deleteCommand3).addCommand(enableCommand).addCommand(disableCommand).addCommand(runCommand).addHelpText(
4123
4017
  "after",
4124
4018
  `
4125
4019
  Examples:
@@ -4127,7 +4021,6 @@ Examples:
4127
4021
  List automations: zero automation list
4128
4022
  Inspect one: zero automation show alerts
4129
4023
  Fire manually: zero automation run alerts
4130
- Manage triggers: zero automation trigger --help
4131
4024
  Pause an automation: zero automation disable alerts
4132
4025
  Resume an automation: zero automation enable alerts
4133
4026
  Delete an automation: zero automation delete alerts`
@@ -4432,7 +4325,7 @@ var createCommand3 = new Command().name("create").description("Create a GitHub l
4432
4325
  }
4433
4326
  )
4434
4327
  );
4435
- var updateCommand3 = new Command().name("update").alias("edit").description("Update a GitHub label listener").argument("<listener-id>", "GitHub label listener ID").option("--label <name>", "New GitHub label name").option("--agent-id <id>", "New agent ID").option("--prompt <text>", "New prompt").option(
4328
+ var updateCommand2 = new Command().name("update").alias("edit").description("Update a GitHub label listener").argument("<listener-id>", "GitHub label listener ID").option("--label <name>", "New GitHub label name").option("--agent-id <id>", "New agent ID").option("--prompt <text>", "New prompt").option(
4436
4329
  "--trigger-mode <mode>",
4437
4330
  "Who can trigger the listener: anyone | created_by_me"
4438
4331
  ).option("--enable", "Enable the listener").option("--disable", "Disable the listener").option("--json", "Print raw JSON").action(
@@ -4476,7 +4369,7 @@ var deleteCommand5 = new Command().name("delete").alias("rm").description("Delet
4476
4369
  }
4477
4370
  )
4478
4371
  );
4479
- var labelListenerCommand = new Command().name("label-listener").alias("label-listeners").alias("labels").description("Manage GitHub label listeners").addCommand(listCommand10).addCommand(createCommand3).addCommand(updateCommand3).addCommand(deleteCommand5).addHelpText(
4372
+ var labelListenerCommand = new Command().name("label-listener").alias("label-listeners").alias("labels").description("Manage GitHub label listeners").addCommand(listCommand10).addCommand(createCommand3).addCommand(updateCommand2).addCommand(deleteCommand5).addHelpText(
4480
4373
  "after",
4481
4374
  `
4482
4375
  Examples:
@@ -6201,8 +6094,8 @@ function buildGmailNewMessageEventConfig(options) {
6201
6094
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
6202
6095
  var SCHEDULE_KINDS = ["cron", "once", "loop"];
6203
6096
  var EVENT_KINDS = ["gmail-new-message"];
6204
- var TRIGGER_KINDS2 = [...SCHEDULE_KINDS, ...EVENT_KINDS];
6205
- var EXACTLY_ONE_FLAG_MESSAGE2 = "Provide exactly one of --expr (cron), --at (once), --every (loop)";
6097
+ var TRIGGER_KINDS = [...SCHEDULE_KINDS, ...EVENT_KINDS];
6098
+ var EXACTLY_ONE_FLAG_MESSAGE = "Provide exactly one of --expr (cron), --at (once), --every (loop)";
6206
6099
  function timezoneOrUtc(timezone) {
6207
6100
  return timezone ?? "UTC";
6208
6101
  }
@@ -6335,7 +6228,7 @@ function buildSchedule(kind, options) {
6335
6228
  };
6336
6229
  default:
6337
6230
  throw new Error(
6338
- `Unknown trigger kind: "${kind}". Use one of: ${TRIGGER_KINDS2.join(", ")}`
6231
+ `Unknown trigger kind: "${kind}". Use one of: ${TRIGGER_KINDS.join(", ")}`
6339
6232
  );
6340
6233
  }
6341
6234
  }
@@ -6362,14 +6255,14 @@ function buildCreateRequest(kind, options) {
6362
6255
  }
6363
6256
  return { schedule: buildSchedule(kind, options) };
6364
6257
  }
6365
- function buildUpdate2(options) {
6258
+ function buildUpdate(options) {
6366
6259
  const flagCount = [options.expr, options.at, options.every].filter(
6367
6260
  (value) => {
6368
6261
  return value !== void 0;
6369
6262
  }
6370
6263
  ).length;
6371
6264
  if (flagCount !== 1) {
6372
- throw new Error(EXACTLY_ONE_FLAG_MESSAGE2);
6265
+ throw new Error(EXACTLY_ONE_FLAG_MESSAGE);
6373
6266
  }
6374
6267
  if (options.timezone && !options.expr && !options.at) {
6375
6268
  throw new Error("--timezone only applies to --expr and --at");
@@ -6402,7 +6295,7 @@ async function resolveWorkflowId(ref, options) {
6402
6295
  }
6403
6296
  return matches[0].id;
6404
6297
  }
6405
- var addCommand2 = new Command().name("add").description("Add a trigger to a workflow").argument("<workflow>", "Workflow ID or name").argument("<kind>", `Trigger type: ${TRIGGER_KINDS2.join(" | ")}`).option("--expr <expression>", 'Cron expression for kind "cron"').option("--at <iso-time>", 'Fire time for kind "once"').option("--every <duration>", 'Interval for kind "loop" (e.g. 15m, 1h, 90s)').option("-z, --timezone <tz>", "IANA timezone for cron/once (default: UTC)").option("--config <path>", "Path to a Gmail new message trigger config JSON").option("--from-contains <text>", "Require the From header to contain text").option(
6298
+ var addCommand = new Command().name("add").description("Add a trigger to a workflow").argument("<workflow>", "Workflow ID or name").argument("<kind>", `Trigger type: ${TRIGGER_KINDS.join(" | ")}`).option("--expr <expression>", 'Cron expression for kind "cron"').option("--at <iso-time>", 'Fire time for kind "once"').option("--every <duration>", 'Interval for kind "loop" (e.g. 15m, 1h, 90s)').option("-z, --timezone <tz>", "IANA timezone for cron/once (default: UTC)").option("--config <path>", "Path to a Gmail new message trigger config JSON").option("--from-contains <text>", "Require the From header to contain text").option(
6406
6299
  "--from-not-contains <text>",
6407
6300
  "Require the From header not to contain text"
6408
6301
  ).option(
@@ -6450,7 +6343,7 @@ Notes:
6450
6343
  }
6451
6344
  )
6452
6345
  );
6453
- var updateCommand4 = new Command().name("update").description("Replace a workflow trigger's schedule").argument("<trigger>", "Workflow trigger ID").option("--expr <expression>", 'New cron schedule (e.g. "0 9 * * *")').option("--at <iso-time>", 'New one-time fire (e.g. "2026-06-10T09:00")').option("--every <duration>", "New loop interval (e.g. 15m, 1h, 90s)").option("-z, --timezone <tz>", "IANA timezone for --expr / --at").addHelpText(
6346
+ var updateCommand3 = new Command().name("update").description("Replace a workflow trigger's schedule").argument("<trigger>", "Workflow trigger ID").option("--expr <expression>", 'New cron schedule (e.g. "0 9 * * *")').option("--at <iso-time>", 'New one-time fire (e.g. "2026-06-10T09:00")').option("--every <duration>", "New loop interval (e.g. 15m, 1h, 90s)").option("-z, --timezone <tz>", "IANA timezone for --expr / --at").addHelpText(
6454
6347
  "after",
6455
6348
  `
6456
6349
  Examples:
@@ -6459,7 +6352,7 @@ Examples:
6459
6352
  zero workflow trigger update 22222222-2222-4222-8222-222222222222 --every 10m`
6460
6353
  ).action(
6461
6354
  withErrorHandler(async (id, options) => {
6462
- const trigger = await updateWorkflowTrigger(id, buildUpdate2(options));
6355
+ const trigger = await updateWorkflowTrigger(id, buildUpdate(options));
6463
6356
  console.log(source_default.green(`\u2713 Trigger ${trigger.id} updated`));
6464
6357
  printWorkflowTriggerDetails(trigger);
6465
6358
  })
@@ -6488,25 +6381,25 @@ Examples:
6488
6381
  }
6489
6382
  )
6490
6383
  );
6491
- var showCommand3 = new Command().name("show").description("Show a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6384
+ var showCommand2 = new Command().name("show").description("Show a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6492
6385
  withErrorHandler(async (id) => {
6493
6386
  const trigger = await getWorkflowTrigger(id);
6494
6387
  printWorkflowTriggerDetails(trigger);
6495
6388
  })
6496
6389
  );
6497
- var rmCommand2 = new Command().name("rm").alias("remove").description("Remove a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6390
+ var rmCommand = new Command().name("rm").alias("remove").description("Remove a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6498
6391
  withErrorHandler(async (id) => {
6499
6392
  await deleteWorkflowTrigger(id);
6500
6393
  console.log(source_default.green(`\u2713 Trigger ${id} removed`));
6501
6394
  })
6502
6395
  );
6503
- var enableCommand3 = new Command().name("enable").description("Enable a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6396
+ var enableCommand2 = new Command().name("enable").description("Enable a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6504
6397
  withErrorHandler(async (id) => {
6505
6398
  const trigger = await enableWorkflowTrigger(id);
6506
6399
  console.log(source_default.green(`\u2713 Trigger ${trigger.id} enabled`));
6507
6400
  })
6508
6401
  );
6509
- var disableCommand3 = new Command().name("disable").description("Disable a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6402
+ var disableCommand2 = new Command().name("disable").description("Disable a workflow trigger").argument("<trigger>", "Workflow trigger ID").action(
6510
6403
  withErrorHandler(async (id) => {
6511
6404
  const trigger = await disableWorkflowTrigger(id);
6512
6405
  console.log(source_default.green(`\u2713 Trigger ${trigger.id} disabled`));
@@ -6521,7 +6414,7 @@ var runCommand3 = new Command().name("run").description("Fire a workflow trigger
6521
6414
  console.log(`Stream logs: zero logs ${result.runId}`);
6522
6415
  })
6523
6416
  );
6524
- var triggerCommand2 = new Command().name("trigger").description("Manage a workflow's triggers").addCommand(addCommand2).addCommand(updateCommand4).addCommand(listCommand14).addCommand(showCommand3).addCommand(rmCommand2).addCommand(enableCommand3).addCommand(disableCommand3).addCommand(runCommand3).addHelpText(
6417
+ var triggerCommand = new Command().name("trigger").description("Manage a workflow's triggers").addCommand(addCommand).addCommand(updateCommand3).addCommand(listCommand14).addCommand(showCommand2).addCommand(rmCommand).addCommand(enableCommand2).addCommand(disableCommand2).addCommand(runCommand3).addHelpText(
6525
6418
  "after",
6526
6419
  `
6527
6420
  Examples:
@@ -6534,7 +6427,7 @@ Examples:
6534
6427
  );
6535
6428
 
6536
6429
  // src/commands/zero/workflow/index.ts
6537
- var zeroWorkflowCommand = new Command("workflow").description("Manage workflows").addCommand(createCommand4).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand13).addCommand(deleteCommand7).addCommand(copyCommand).addCommand(runCommand2).addCommand(triggerCommand2).addHelpText(
6430
+ var zeroWorkflowCommand = new Command("workflow").description("Manage workflows").addCommand(createCommand4).addCommand(editCommand2).addCommand(viewCommand2).addCommand(listCommand13).addCommand(deleteCommand7).addCommand(copyCommand).addCommand(runCommand2).addCommand(triggerCommand).addHelpText(
6538
6431
  "after",
6539
6432
  `
6540
6433
  Examples:
@@ -10314,12 +10207,12 @@ init_esm_shims();
10314
10207
 
10315
10208
  // src/lib/host/publish-static-site.ts
10316
10209
  init_esm_shims();
10317
- import { readFile as readFile2 } from "fs/promises";
10210
+ import { readFile as readFile3 } from "fs/promises";
10318
10211
 
10319
10212
  // src/lib/host/static-site.ts
10320
10213
  init_esm_shims();
10321
10214
  import { createHash } from "crypto";
10322
- import { readdir, readFile, stat } from "fs/promises";
10215
+ import { readdir, readFile as readFile2, stat } from "fs/promises";
10323
10216
  import { extname as extname4, relative, resolve, sep, dirname, posix } from "path";
10324
10217
  var MIME_BY_EXTENSION4 = {
10325
10218
  ".html": "text/html; charset=utf-8",
@@ -10443,7 +10336,7 @@ function collectReferences(ext, text) {
10443
10336
  return isHtmlExtension(ext) ? collectHtmlReferences(text) : collectCssReferences(text);
10444
10337
  }
10445
10338
  async function hashFile(path2) {
10446
- const bytes = await readFile(path2);
10339
+ const bytes = await readFile2(path2);
10447
10340
  return createHash("sha256").update(bytes).digest("hex");
10448
10341
  }
10449
10342
  async function walk(root, dir, files) {
@@ -10483,7 +10376,7 @@ async function assertReferencesExist(files) {
10483
10376
  if (!shouldValidateReferences(ext)) {
10484
10377
  continue;
10485
10378
  }
10486
- const text = await readFile(file.absolutePath, "utf8");
10379
+ const text = await readFile2(file.absolutePath, "utf8");
10487
10380
  const references = collectReferences(ext, text);
10488
10381
  for (const reference of references) {
10489
10382
  const normalized = normalizeReference(file.path, reference);
@@ -10559,7 +10452,7 @@ async function publishStaticSite(options) {
10559
10452
  throw new Error(`Missing upload URL for ${file.path}`);
10560
10453
  }
10561
10454
  options.onProgress?.({ phase: "uploading", path: file.path });
10562
- const bytes = await readFile2(file.absolutePath);
10455
+ const bytes = await readFile3(file.absolutePath);
10563
10456
  const response = await fetch(uploadUrl, {
10564
10457
  method: "PUT",
10565
10458
  headers: { "Content-Type": file.contentType },
@@ -11668,7 +11561,7 @@ function registerZeroCommands(prog, commands) {
11668
11561
  var program = new Command();
11669
11562
  program.name("zero").description(
11670
11563
  "Zero CLI \u2014 interact with the zero platform from inside the sandbox"
11671
- ).version("9.203.0").addHelpText("after", () => {
11564
+ ).version("9.204.0").addHelpText("after", () => {
11672
11565
  return buildZeroHelpText();
11673
11566
  });
11674
11567
  if (process.argv[1]?.endsWith("zero.js") || process.argv[1]?.endsWith("zero.ts") || process.argv[1]?.endsWith("zero")) {