@belvador/mcp 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +535 -434
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -255,7 +255,7 @@ function docsFetcher(siteUrl, fetcher = fetch, now = () => Date.now()) {
255
255
  import { CLIENT_CAPABILITIES_META_KEY, inputRequired, McpServer } from "@modelcontextprotocol/server";
256
256
 
257
257
  // ../src/shared/contracts/mcp-tools.ts
258
- import { z as z31 } from "zod";
258
+ import { z as z32 } from "zod";
259
259
 
260
260
  // ../src/shared/contracts/api-ops/access.ts
261
261
  import { z as z3 } from "zod";
@@ -1225,7 +1225,7 @@ var TELEMETRY_PLAN_DEFAULTS = {
1225
1225
  logs_monthly_bytes: 5 * 1000 ** 3,
1226
1226
  metrics_retention_days: 14,
1227
1227
  metrics_monthly_bytes: 2 * 1000 ** 3,
1228
- metric_series_max: 1e4,
1228
+ metric_series_max: 35000,
1229
1229
  metric_names_max: 1000,
1230
1230
  telemetry_rate_bytes_per_sec: 1024 * 1024,
1231
1231
  telemetry_burst_bytes: 8 * 1024 * 1024,
@@ -1236,7 +1236,7 @@ var TELEMETRY_PLAN_DEFAULTS = {
1236
1236
  // ../src/shared/contracts/vocab/metrics.ts
1237
1237
  var METRIC_TYPES = ["gauge", "sum", "histogram", "exp_histogram"];
1238
1238
  var METRIC_KINDS = ["gauge", "counter", "histogram", "exp_histogram"];
1239
- var METRIC_AGGREGATIONS = ["avg", "sum", "min", "max", "count", "rate", "p50", "p90", "p95", "p99"];
1239
+ var METRIC_AGGREGATIONS = ["avg", "sum", "min", "max", "count", "rate", "p50", "p75", "p90", "p95", "p99"];
1240
1240
  var METRIC_NAME_RE = /^[A-Za-z_][A-Za-z0-9_.:\-/]{0,254}$/;
1241
1241
  var METRIC_ATTR_KEY_RE = /^[A-Za-z0-9_.:\-/@]{1,256}$/;
1242
1242
  var METRIC_GROUP_BY_MAX = 2;
@@ -1288,7 +1288,8 @@ var METRIC_QUERY = {
1288
1288
  exemplarsMax: 50,
1289
1289
  queryMaxSeconds: 3
1290
1290
  };
1291
- var metricName = z10.string().min(1).max(METRIC_LIMITS.nameMaxChars).regex(METRIC_NAME_RE);
1291
+ var metricNameSchema = z10.string().min(1).max(METRIC_LIMITS.nameMaxChars).regex(METRIC_NAME_RE);
1292
+ var metricName = metricNameSchema;
1292
1293
  var attrKey = z10.string().regex(METRIC_ATTR_KEY_RE);
1293
1294
  var metricFilterSchema = z10.object({
1294
1295
  k: attrKey,
@@ -2340,7 +2341,7 @@ var TOKEN_IN_TEXT = new RegExp(PING_TOKEN_PATTERN, "g");
2340
2341
  import { z as z17 } from "zod";
2341
2342
 
2342
2343
  // ../src/shared/contracts/vocab/slo.ts
2343
- var SLO_SOURCES = ["uptime", "monitor", "heartbeat", "spans"];
2344
+ var SLO_SOURCES = ["uptime", "monitor", "heartbeat", "spans", "metric"];
2344
2345
 
2345
2346
  // ../src/shared/contracts/slo.ts
2346
2347
  var SLO_SLIS = ["availability", "latency"];
@@ -2360,6 +2361,8 @@ var SLO_LIMITS = {
2360
2361
  descriptionMaxChars: 1000,
2361
2362
  environmentMaxChars: 64,
2362
2363
  spansLagMinutes: 3,
2364
+ metricsLagMinutes: 3,
2365
+ metricSeenMinutes: 5,
2363
2366
  sliItemsPerMessage: 200,
2364
2367
  maxNodeSlos: 1000
2365
2368
  };
@@ -2367,14 +2370,30 @@ var SLO_SOURCE_META = {
2367
2370
  uptime: { provenance: "managed_probe", estimated: false, slis: ["availability", "latency"], budgeting: "Timeslices" },
2368
2371
  monitor: { provenance: "check_in", estimated: false, slis: ["availability"], budgeting: "Occurrences" },
2369
2372
  heartbeat: { provenance: "ping_token", estimated: false, slis: ["availability"], budgeting: "Occurrences" },
2370
- spans: { provenance: "ingest_key", estimated: true, slis: ["availability", "latency"], budgeting: "Occurrences" }
2373
+ spans: { provenance: "ingest_key", estimated: true, slis: ["availability", "latency"], budgeting: "Occurrences" },
2374
+ metric: { provenance: "ingest_key", estimated: false, slis: ["availability"], budgeting: "Occurrences" }
2371
2375
  };
2376
+ var sloMetricSchema = z17.object({
2377
+ name: metricNameSchema,
2378
+ filter: z17.array(metricFilterSchema).max(METRIC_QUERY.filtersMax).default([])
2379
+ }).superRefine((m, ctx) => {
2380
+ m.filter.forEach((f, i) => {
2381
+ if (f.op === "exists" !== (f.v === undefined))
2382
+ ctx.addIssue({ code: "custom", path: ["filter", i, "v"], message: "INVALID_INPUT" });
2383
+ });
2384
+ });
2385
+ function sameSloMetric(a, b) {
2386
+ const key = (m) => JSON.stringify([m.name, [...m.filter].map((f) => [f.k, f.op, f.v ?? null]).sort()]);
2387
+ return key(a) === key(b);
2388
+ }
2372
2389
  var nodeSloSchema = z17.object({
2373
2390
  slo_id: z17.guid(),
2374
2391
  project_id: z17.number().int().positive(),
2375
- source: z17.enum(["monitor", "spans"]),
2392
+ source: z17.enum(["monitor", "spans", "metric"]),
2376
2393
  sli: z17.enum(SLO_SLIS),
2377
2394
  monitor_id: z17.guid().optional(),
2395
+ good_metric: sloMetricSchema.optional(),
2396
+ total_metric: sloMetricSchema.optional(),
2378
2397
  environment: z17.string().min(1).max(SLO_LIMITS.environmentMaxChars).optional(),
2379
2398
  service: z17.string().min(1).max(128).optional(),
2380
2399
  operation: z17.string().min(1).max(256).optional(),
@@ -2385,6 +2404,8 @@ var nodeSloSchema = z17.object({
2385
2404
  ctx.addIssue({ code: "custom", path: ["monitor_id"], message: "INVALID_INPUT" });
2386
2405
  if (v.source === "spans" && !v.service)
2387
2406
  ctx.addIssue({ code: "custom", path: ["service"], message: "INVALID_INPUT" });
2407
+ if (v.source === "metric" !== Boolean(v.good_metric && v.total_metric) || v.source === "metric" && v.sli !== "availability")
2408
+ ctx.addIssue({ code: "custom", path: ["good_metric"], message: "INVALID_INPUT" });
2388
2409
  if (v.sli === "latency" !== (v.latency_threshold_ms !== undefined))
2389
2410
  ctx.addIssue({ code: "custom", path: ["latency_threshold_ms"], message: "INVALID_INPUT" });
2390
2411
  });
@@ -2401,7 +2422,9 @@ var sloInputSchema = z17.object({
2401
2422
  projectId: z17.number().int().positive().optional(),
2402
2423
  service: z17.string().max(128).optional(),
2403
2424
  operation: z17.string().max(256).optional(),
2404
- environment: z17.string().max(SLO_LIMITS.environmentMaxChars).optional()
2425
+ environment: z17.string().max(SLO_LIMITS.environmentMaxChars).optional(),
2426
+ goodMetric: sloMetricSchema.optional(),
2427
+ totalMetric: sloMetricSchema.optional()
2405
2428
  }),
2406
2429
  sli: z17.enum(SLO_SLIS),
2407
2430
  latencyThresholdMs: z17.number().int().min(1).max(60000).nullable(),
@@ -2414,9 +2437,15 @@ var sloInputSchema = z17.object({
2414
2437
  ctx.addIssue({ code: "custom", path: ["sli"], message: "INVALID_INPUT" });
2415
2438
  if (v.sli === "latency" !== Boolean(v.latencyThresholdMs))
2416
2439
  ctx.addIssue({ code: "custom", path: ["latencyThresholdMs"], message: "INVALID_INPUT" });
2417
- if (v.source === "spans" ? !(v.sourceRef.projectId && v.sourceRef.service?.trim()) : !v.sourceRef.id)
2440
+ const ref = v.sourceRef;
2441
+ const refOk = v.source === "spans" ? Boolean(ref.projectId && ref.service?.trim()) : v.source === "metric" ? Boolean(ref.projectId && ref.goodMetric && ref.totalMetric) : Boolean(ref.id);
2442
+ if (!refOk)
2418
2443
  ctx.addIssue({ code: "custom", path: ["sourceRef"], message: "INVALID_INPUT" });
2419
- if (v.sourceRef.environment !== undefined && v.source !== "monitor" && v.source !== "spans")
2444
+ if (v.source === "metric" && ref.goodMetric && ref.totalMetric && sameSloMetric(ref.goodMetric, ref.totalMetric))
2445
+ ctx.addIssue({ code: "custom", path: ["sourceRef", "goodMetric"], message: "INVALID_INPUT" });
2446
+ if (v.source !== "metric" && (ref.goodMetric || ref.totalMetric))
2447
+ ctx.addIssue({ code: "custom", path: ["sourceRef", "goodMetric"], message: "INVALID_INPUT" });
2448
+ if (ref.environment !== undefined && v.source !== "monitor" && v.source !== "spans" && v.source !== "metric")
2420
2449
  ctx.addIssue({ code: "custom", path: ["sourceRef", "environment"], message: "INVALID_INPUT" });
2421
2450
  if (v.allowPublicSources && v.source !== "monitor" && v.source !== "spans")
2422
2451
  ctx.addIssue({ code: "custom", path: ["allowPublicSources"], message: "INVALID_INPUT" });
@@ -3015,7 +3044,7 @@ var MONITOR_OPERATIONS = [
3015
3044
  idempotency: "required",
3016
3045
  status: 201,
3017
3046
  mcp: "configure",
3018
- summary: "Create an SLO over a monitor, an uptime check or spans.",
3047
+ summary: "Create an SLO over a monitor, a heartbeat, an uptime check, spans or two metric counters (good ÷ total).",
3019
3048
  ui: ["slos#createSlo"]
3020
3049
  }),
3021
3050
  op({
@@ -3129,7 +3158,7 @@ var MONITOR_OPERATIONS = [
3129
3158
  ];
3130
3159
 
3131
3160
  // ../src/shared/contracts/api-ops/node-data.ts
3132
- import { z as z22 } from "zod";
3161
+ import { z as z23 } from "zod";
3133
3162
 
3134
3163
  // ../src/shared/contracts/release-health.ts
3135
3164
  import { z as z21 } from "zod";
@@ -3387,175 +3416,234 @@ var fixStatusSchema = z21.object({
3387
3416
  verify_hours: z21.number()
3388
3417
  });
3389
3418
 
3419
+ // ../src/shared/contracts/web-vitals.ts
3420
+ import { z as z22 } from "zod";
3421
+
3422
+ // ../src/shared/contracts/vocab/web-vitals.ts
3423
+ var WEB_VITAL_NAMES = ["LCP", "INP", "CLS", "FCP", "TTFB"];
3424
+ var WEB_VITAL_RATINGS = ["good", "needs-improvement", "poor"];
3425
+ var WEB_VITAL_PATH_MAX_CHARS = 200;
3426
+
3427
+ // ../src/shared/contracts/web-vitals.ts
3428
+ var WEB_VITAL_LIMITS = {
3429
+ routesMax: 200,
3430
+ routesShown: 20,
3431
+ attributionShown: 10,
3432
+ estimateBelow: 100,
3433
+ defaultSampleRate: 0.1,
3434
+ targetMaxChars: 100,
3435
+ pathMaxChars: WEB_VITAL_PATH_MAX_CHARS,
3436
+ maxWindowMs: 7 * 24 * 3600 * 1000,
3437
+ defaultWindowMs: 24 * 3600 * 1000
3438
+ };
3439
+ var ratingCounts = z22.object({
3440
+ good: z22.number().int().nonnegative(),
3441
+ needs_improvement: z22.number().int().nonnegative(),
3442
+ poor: z22.number().int().nonnegative()
3443
+ });
3444
+ var webVitalSummarySchema = z22.object({
3445
+ name: z22.enum(WEB_VITAL_NAMES),
3446
+ metric: z22.string(),
3447
+ unit: z22.enum(["ms", "1"]),
3448
+ samples: z22.number().int().nonnegative(),
3449
+ p75: z22.number().nullable(),
3450
+ rating: z22.enum(WEB_VITAL_RATINGS).nullable(),
3451
+ estimate: z22.boolean(),
3452
+ ratings: ratingCounts,
3453
+ distribution: z22.array(z22.object({ le: z22.number().nullable(), count: z22.number().int().nonnegative() })),
3454
+ routes: z22.array(z22.object({
3455
+ path: z22.string(),
3456
+ samples: z22.number().int().nonnegative(),
3457
+ p75: z22.number().nullable(),
3458
+ rating: z22.enum(WEB_VITAL_RATINGS).nullable()
3459
+ })),
3460
+ routes_total: z22.number().int().nonnegative(),
3461
+ attribution: z22.array(z22.object({ target: z22.string(), samples: z22.number().int().nonnegative(), p75: z22.number().nullable() }))
3462
+ });
3463
+ var webVitalsSummarySchema = z22.object({
3464
+ from: z22.string(),
3465
+ to: z22.string(),
3466
+ path: z22.string().nullable(),
3467
+ vitals: z22.array(webVitalSummarySchema),
3468
+ complete: z22.boolean()
3469
+ });
3470
+
3390
3471
  // ../src/shared/contracts/api-ops/node-data.ts
3391
- var issueId = z22.number().int().positive();
3392
- var csv = z22.string().min(1).max(2000);
3393
- var name2 = z22.string().min(1).max(256);
3394
- var period = z22.enum(["1h", "24h", "7d", "14d", "30d"]);
3395
- var nodeCursor = z22.string().min(1).max(600).optional();
3472
+ var issueId = z23.number().int().positive();
3473
+ var csv = z23.string().min(1).max(2000);
3474
+ var projectIds2 = z23.string().max(2000).regex(/^[1-9][0-9]{0,15}(?:,[1-9][0-9]{0,15}){0,99}$/, "comma-separated project ids");
3475
+ var name2 = z23.string().min(1).max(256);
3476
+ var period = z23.enum(["1h", "24h", "7d", "14d", "30d"]);
3477
+ var nodeCursor = z23.string().min(1).max(600).optional();
3396
3478
  var windowFields = {
3397
- start: z22.string().max(40).optional(),
3398
- end: z22.string().max(40).optional()
3479
+ start: z23.string().max(40).optional(),
3480
+ end: z23.string().max(40).optional()
3399
3481
  };
3400
- var traceId = z22.string().regex(/^[0-9a-fA-F]{32}$/);
3401
- var spanId = z22.string().regex(/^[0-9a-fA-F]{16}$/);
3402
- var attrs = z22.string().max(2000).optional();
3482
+ var traceId = z23.string().regex(/^[0-9a-fA-F]{32}$/);
3483
+ var spanId = z23.string().regex(/^[0-9a-fA-F]{16}$/);
3484
+ var attrs = z23.string().max(2000).optional();
3403
3485
  var telemetryCommon = {
3404
3486
  ...windowFields,
3405
- project: csv.optional(),
3487
+ project: projectIds2.optional(),
3406
3488
  environment: csv.optional(),
3407
3489
  service: csv.optional(),
3408
3490
  attrs
3409
3491
  };
3410
- var issueChange = z22.union([
3411
- z22.object({
3412
- action: z22.literal("resolve"),
3413
- inNextRelease: z22.boolean().optional(),
3492
+ var issueChange = z23.union([
3493
+ z23.object({
3494
+ action: z23.literal("resolve"),
3495
+ inNextRelease: z23.boolean().optional(),
3414
3496
  inRelease: releaseNameSchema.optional()
3415
3497
  }),
3416
- z22.object({ action: z22.literal("unresolve") }),
3417
- z22.object({ action: z22.literal("archive"), mode: z22.enum(["until_escalating", "forever"]) }),
3418
- z22.object({
3419
- action: z22.literal("archive"),
3420
- mode: z22.literal("until_condition"),
3421
- events: z22.number().int().min(1).max(1e6).optional(),
3422
- users: z22.number().int().min(1).max(1e5).optional(),
3423
- until: z22.string().datetime().optional()
3424
- }),
3425
- z22.object({ action: z22.literal("assign"), userId: z22.guid().nullable() }),
3426
- z22.object({ action: z22.literal("priority"), priority: z22.enum(["low", "medium", "high"]) })
3498
+ z23.object({ action: z23.literal("unresolve") }),
3499
+ z23.object({ action: z23.literal("archive"), mode: z23.enum(["until_escalating", "forever"]) }),
3500
+ z23.object({
3501
+ action: z23.literal("archive"),
3502
+ mode: z23.literal("until_condition"),
3503
+ events: z23.number().int().min(1).max(1e6).optional(),
3504
+ users: z23.number().int().min(1).max(1e5).optional(),
3505
+ until: z23.string().datetime().optional()
3506
+ }),
3507
+ z23.object({ action: z23.literal("assign"), userId: z23.guid().nullable() }),
3508
+ z23.object({ action: z23.literal("priority"), priority: z23.enum(["low", "medium", "high"]) })
3427
3509
  ]);
3428
3510
  var NODE_INPUTS = {
3429
- issuesList: z22.object({
3430
- project: csv.optional(),
3431
- status: z22.enum(["unresolved", "resolved", "archived", "all"]).optional(),
3511
+ issuesList: z23.object({
3512
+ project: projectIds2.optional(),
3513
+ status: z23.enum(["unresolved", "resolved", "archived", "all"]).optional(),
3432
3514
  level: csv.optional(),
3433
3515
  priority: csv.optional(),
3434
3516
  environment: csv.optional(),
3435
3517
  release: csv.optional(),
3436
- assignee: z22.string().max(64).optional(),
3518
+ assignee: z23.string().max(64).optional(),
3437
3519
  period: period.optional(),
3438
- q: z22.string().max(200).optional(),
3439
- sort: z22.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
3520
+ q: z23.string().max(200).optional(),
3521
+ sort: z23.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
3440
3522
  cursor: nodeCursor,
3441
- limit: z22.number().int().min(1).max(100).optional()
3523
+ limit: z23.number().int().min(1).max(100).optional()
3442
3524
  }),
3443
- issue: z22.object({ issueId }),
3444
- issueStats: z22.object({ issueId, range: z22.enum(["24h", "30d"]).optional() }),
3445
- issueEvents: z22.object({ issueId, cursor: nodeCursor }),
3446
- issueEvent: z22.object({
3525
+ issue: z23.object({ issueId }),
3526
+ issueStats: z23.object({ issueId, range: z23.enum(["24h", "30d"]).optional() }),
3527
+ issueEvents: z23.object({ issueId, cursor: nodeCursor }),
3528
+ issueEvent: z23.object({
3447
3529
  issueId,
3448
- eventId: z22.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
3530
+ eventId: z23.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
3449
3531
  }),
3450
- issueUpdate: z22.object({ issueId, change: issueChange }),
3451
- issuesBulk: z22.object({
3452
- issueIds: z22.array(issueId).min(1).max(100),
3532
+ issueUpdate: z23.object({ issueId, change: issueChange }),
3533
+ issuesBulk: z23.object({
3534
+ issueIds: z23.array(issueId).min(1).max(100),
3453
3535
  action: issueChange
3454
3536
  }),
3455
- spansList: z22.object({
3537
+ spansList: z23.object({
3456
3538
  ...telemetryCommon,
3457
- operation: z22.string().min(1).max(1024).optional(),
3458
- status: z22.enum(["unset", "ok", "error"]).optional(),
3459
- kind: z22.enum(["internal", "server", "client", "producer", "consumer"]).optional(),
3460
- minDurationMs: z22.number().min(0).max(86400000).optional(),
3461
- maxDurationMs: z22.number().min(0).max(86400000).optional(),
3462
- mode: z22.enum(["spans", "traces"]).optional(),
3539
+ operation: z23.string().min(1).max(1024).optional(),
3540
+ status: z23.enum(["unset", "ok", "error"]).optional(),
3541
+ kind: z23.enum(["internal", "server", "client", "producer", "consumer"]).optional(),
3542
+ minDurationMs: z23.number().min(0).max(86400000).optional(),
3543
+ maxDurationMs: z23.number().min(0).max(86400000).optional(),
3544
+ mode: z23.enum(["spans", "traces"]).optional(),
3463
3545
  cursor: nodeCursor
3464
3546
  }),
3465
- spansHistogram: z22.object({
3547
+ spansHistogram: z23.object({
3466
3548
  ...telemetryCommon,
3467
- operation: z22.string().min(1).max(1024).optional(),
3468
- status: z22.enum(["unset", "ok", "error"]).optional()
3549
+ operation: z23.string().min(1).max(1024).optional(),
3550
+ status: z23.enum(["unset", "ok", "error"]).optional()
3469
3551
  }),
3470
- trace: z22.object({ traceId }),
3471
- traceSpans: z22.object({ traceId, errorsOnly: z22.enum(["1"]).optional(), ...windowFields }),
3472
- span: z22.object({ traceId, spanId, ...windowFields }),
3473
- logsList: z22.object({
3552
+ trace: z23.object({ traceId }),
3553
+ traceSpans: z23.object({ traceId, errorsOnly: z23.enum(["1"]).optional(), ...windowFields }),
3554
+ span: z23.object({ traceId, spanId, ...windowFields }),
3555
+ logsList: z23.object({
3474
3556
  ...telemetryCommon,
3475
- severityMin: z22.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3557
+ severityMin: z23.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3476
3558
  traceId: traceId.optional(),
3477
3559
  spanId: spanId.optional(),
3478
- q: z22.string().max(500).optional(),
3479
- order: z22.enum(["asc", "desc"]).optional(),
3560
+ q: z23.string().max(500).optional(),
3561
+ order: z23.enum(["asc", "desc"]).optional(),
3480
3562
  cursor: nodeCursor
3481
3563
  }),
3482
- logsFacets: z22.object({
3564
+ logsFacets: z23.object({
3483
3565
  ...telemetryCommon,
3484
- severityMin: z22.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3485
- q: z22.string().max(500).optional()
3486
- }),
3487
- logAround: z22.object({
3488
- logId: z22.guid(),
3489
- at: z22.string().max(40),
3490
- same: z22.enum(["service", "trace"]).optional(),
3491
- before: z22.number().int().min(0).max(200).optional(),
3492
- after: z22.number().int().min(0).max(200).optional()
3493
- }),
3494
- metricsNames: z22.object({
3495
- project: z22.number().int().positive(),
3566
+ severityMin: z23.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3567
+ q: z23.string().max(500).optional()
3568
+ }),
3569
+ logAround: z23.object({
3570
+ logId: z23.guid(),
3571
+ at: z23.string().max(40),
3572
+ same: z23.enum(["service", "trace"]).optional(),
3573
+ before: z23.number().int().min(0).max(200).optional(),
3574
+ after: z23.number().int().min(0).max(200).optional()
3575
+ }),
3576
+ metricsNames: z23.object({
3577
+ project: z23.number().int().positive(),
3496
3578
  environment: csv.optional(),
3497
- q: z22.string().max(255).optional()
3579
+ q: z23.string().max(255).optional()
3498
3580
  }),
3499
- metricsSeries: z22.object({
3500
- project: z22.number().int().positive(),
3501
- name: z22.string().regex(METRIC_NAME_RE),
3581
+ metricsSeries: z23.object({
3582
+ project: z23.number().int().positive(),
3583
+ name: z23.string().regex(METRIC_NAME_RE),
3502
3584
  environment: csv.optional(),
3503
3585
  attrs,
3504
- cursor: z22.string().regex(/^[0-9a-f]{16}$/).optional()
3586
+ cursor: z23.string().regex(/^[0-9a-f]{16}$/).optional()
3505
3587
  }),
3506
- metricsQuery: z22.object({
3507
- project: z22.number().int().positive(),
3508
- name: z22.string().regex(METRIC_NAME_RE),
3509
- aggregation: z22.enum(METRIC_AGGREGATIONS),
3588
+ metricsQuery: z23.object({
3589
+ project: z23.number().int().positive(),
3590
+ name: z23.string().regex(METRIC_NAME_RE),
3591
+ aggregation: z23.enum(METRIC_AGGREGATIONS),
3510
3592
  ...windowFields,
3511
- step: z22.number().int().min(METRIC_QUERY.minStepSeconds).max(METRIC_QUERY.maxStepSeconds).multipleOf(60).optional(),
3593
+ step: z23.number().int().min(METRIC_QUERY.minStepSeconds).max(METRIC_QUERY.maxStepSeconds).multipleOf(60).optional(),
3512
3594
  attrs,
3513
- groupBy: z22.string().min(1).max(600).optional(),
3595
+ groupBy: z23.string().min(1).max(600).optional(),
3514
3596
  environment: csv.optional()
3515
3597
  }),
3516
- telemetryUsage: z22.object({
3517
- project: csv.optional(),
3518
- days: z22.number().int().min(1).max(31).optional()
3598
+ telemetryUsage: z23.object({
3599
+ project: projectIds2.optional(),
3600
+ days: z23.number().int().min(1).max(31).optional()
3519
3601
  }),
3520
- monitorSignal: z22.object({
3521
- monitorId: z22.guid(),
3522
- hours: z22.number().int().min(1).max(24).optional()
3602
+ monitorSignal: z23.object({
3603
+ monitorId: z23.guid(),
3604
+ hours: z23.number().int().min(1).max(24).optional()
3523
3605
  }),
3524
- monitorOccurrences: z22.object({
3525
- monitorId: z22.guid(),
3526
- state: z22.enum(["open", "finished", "all"]).optional(),
3527
- environment: z22.string().min(1).max(64).optional(),
3606
+ monitorOccurrences: z23.object({
3607
+ monitorId: z23.guid(),
3608
+ state: z23.enum(["open", "finished", "all"]).optional(),
3609
+ environment: z23.string().min(1).max(64).optional(),
3528
3610
  cursor: nodeCursor
3529
3611
  }),
3530
- monitorBacktest: z22.object({
3531
- project: z22.number().int().positive(),
3612
+ monitorBacktest: z23.object({
3613
+ project: z23.number().int().positive(),
3532
3614
  settings: backtestSettingsSchema
3533
3615
  }),
3534
- occurrenceCreate: z22.object({
3535
- project: z22.number().int().positive(),
3616
+ occurrenceCreate: z23.object({
3617
+ project: z23.number().int().positive(),
3536
3618
  monitorSlug: occurrenceInputSchema.shape.monitor_slug,
3537
3619
  occurrenceId: occurrenceInputSchema.shape.occurrence_id,
3538
3620
  dueAt: occurrenceInputSchema.shape.due_at,
3539
3621
  environment: occurrenceInputSchema.shape.environment
3540
3622
  }),
3541
- occurrenceCancel: z22.object({
3542
- project: z22.number().int().positive(),
3543
- monitorSlug: z22.string().regex(SLUG_RE),
3544
- occurrenceId: z22.string().regex(OCCURRENCE_ID_RE),
3545
- environment: z22.string().min(1).max(64).optional()
3623
+ occurrenceCancel: z23.object({
3624
+ project: z23.number().int().positive(),
3625
+ monitorSlug: z23.string().regex(SLUG_RE),
3626
+ occurrenceId: z23.string().regex(OCCURRENCE_ID_RE),
3627
+ environment: z23.string().min(1).max(64).optional()
3628
+ }),
3629
+ webVitals: z23.object({
3630
+ project: z23.number().int().positive(),
3631
+ ...windowFields,
3632
+ environment: csv.optional(),
3633
+ path: z23.string().max(WEB_VITAL_LIMITS.pathMaxChars).regex(/^(?:\/[^\s?#]*|other)$/).optional()
3546
3634
  }),
3547
- releasesList: z22.object({
3548
- project: z22.number().int().positive(),
3635
+ releasesList: z23.object({
3636
+ project: z23.number().int().positive(),
3549
3637
  environment: environmentNameSchema.optional()
3550
3638
  }),
3551
- releaseHealth: z22.object({
3552
- project: z22.number().int().positive(),
3639
+ releaseHealth: z23.object({
3640
+ project: z23.number().int().positive(),
3553
3641
  version: releaseNameSchema,
3554
3642
  environment: environmentNameSchema.optional(),
3555
3643
  compare: releaseNameSchema.optional()
3556
3644
  }),
3557
- deploymentCreate: z22.object({
3558
- project: z22.number().int().positive(),
3645
+ deploymentCreate: z23.object({
3646
+ project: z23.number().int().positive(),
3559
3647
  version: deploymentInputSchema.shape.version,
3560
3648
  environment: deploymentInputSchema.shape.environment,
3561
3649
  name: deploymentInputSchema.shape.name,
@@ -3564,10 +3652,10 @@ var NODE_INPUTS = {
3564
3652
  finishedAt: deploymentInputSchema.shape.finished_at,
3565
3653
  deployId: deploymentInputSchema.shape.deploy_id
3566
3654
  }),
3567
- ticket: z22.object({
3568
- scope: z22.enum(["read", "write"]).default("read"),
3569
- project: z22.number().int().positive().optional(),
3570
- environment: z22.string().min(1).max(64).optional()
3655
+ ticket: z23.object({
3656
+ scope: z23.enum(["read", "write"]).default("read"),
3657
+ project: z23.number().int().positive().optional(),
3658
+ environment: z23.string().min(1).max(64).optional()
3571
3659
  })
3572
3660
  };
3573
3661
  var N = NODE_INPUTS;
@@ -3755,7 +3843,16 @@ var NODE_OPERATIONS = [
3755
3843
  scope: "metrics:read",
3756
3844
  input: N.metricsQuery,
3757
3845
  node: { path: "q/metrics/query", window: true },
3758
- summary: "One metric aggregated per step (avg, sum, min, max, count, rate, p50–p99) in a window of at most 7 days, optionally grouped by up to two attributes (≤ 50 groups, ≤ 10,000 points), with exemplar trace ids."
3846
+ summary: "One metric aggregated per step (avg, sum, min, max, count, rate, p50, p75, p90, p95, p99) in a window of at most 7 days, optionally grouped by up to two attributes (≤ 50 groups, ≤ 10,000 points), with exemplar trace ids."
3847
+ }),
3848
+ op({
3849
+ ...read,
3850
+ id: "metrics.web_vitals",
3851
+ path: "/v1/projects/{project}/web-vitals",
3852
+ scope: "metrics:read",
3853
+ input: N.webVitals,
3854
+ node: { path: "q/metrics/web-vitals", window: true },
3855
+ summary: "Core Web Vitals of real users (LCP, INP, CLS, FCP, TTFB) in a window of at most 7 days: samples, p75 with its web.dev rating, samples per rating, the distribution, the busiest routes and the elements behind slow samples. Optionally one route. Needs browser SDK `webVitals` and node agent 0.1.40."
3759
3856
  }),
3760
3857
  op({
3761
3858
  ...read,
@@ -3895,10 +3992,10 @@ var NODE_OPERATIONS = [
3895
3992
  ];
3896
3993
 
3897
3994
  // ../src/shared/contracts/api-ops/privacy.ts
3898
- import { z as z24 } from "zod";
3995
+ import { z as z25 } from "zod";
3899
3996
 
3900
3997
  // ../src/shared/contracts/privacy.ts
3901
- import { z as z23 } from "zod";
3998
+ import { z as z24 } from "zod";
3902
3999
 
3903
4000
  // ../src/shared/privacy/rules.ts
3904
4001
  var PRIVACY_SCHEMA = 1;
@@ -3928,44 +4025,47 @@ var IPV6_RE = new RegExp(`(^|[^0-9A-Fa-f:])((?:${H}:){7}${H}|(?:${H}:){1,6}:(?:$
3928
4025
  var REMOVE = Symbol("remove");
3929
4026
 
3930
4027
  // ../src/shared/contracts/privacy.ts
3931
- var ruleId = z23.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
3932
- var privacyRuleInputSchema = z23.object({
4028
+ var PRIVACY_KEY_MAX_VERSION = 1e6;
4029
+ var ruleId = z24.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
4030
+ var privacyRuleInputSchema = z24.object({
3933
4031
  id: ruleId,
3934
- selector: z23.string().min(1).max(PRIVACY_LIMITS.selector),
3935
- type: z23.enum(PRIVACY_RULE_TYPES),
3936
- method: z23.enum(PRIVACY_METHODS),
3937
- pattern: z23.string().min(1).max(PRIVACY_LIMITS.pattern).optional(),
3938
- ignoreCase: z23.boolean().optional(),
3939
- replaceWith: z23.string().max(PRIVACY_LIMITS.replaceWith).optional(),
3940
- enabled: z23.boolean().optional()
3941
- });
3942
- var privacyPolicyInputSchema = z23.object({
3943
- mode: z23.enum(PRIVACY_MODES),
3944
- rules: z23.array(privacyRuleInputSchema).max(PRIVACY_LIMITS.rules),
3945
- allowlist: z23.array(z23.string().min(1).max(PRIVACY_LIMITS.selector)).max(PRIVACY_LIMITS.allowlist)
3946
- });
3947
- var storedPolicySchema = z23.object({
3948
- schema: z23.literal(PRIVACY_SCHEMA),
3949
- version: z23.number().int().min(0),
3950
- mode: z23.enum(PRIVACY_MODES),
3951
- rules: z23.array(z23.record(z23.string(), z23.unknown())).max(PRIVACY_LIMITS.rules),
3952
- allowlist: z23.array(z23.string()).max(PRIVACY_LIMITS.allowlist)
3953
- });
3954
- var nodePrivacyBlockSchema = z23.array(z23.object({ project_id: z23.number().int().positive(), policy: z23.unknown() })).max(1000);
3955
- var privacyRollupSchema = z23.object({
3956
- applied_version: z23.number().int().min(0).nullable(),
3957
- policy_missing_24h: z23.number().int().nonnegative(),
3958
- budget_exceeded_24h: z23.number().int().nonnegative(),
3959
- sdk_versions: z23.array(z23.object({ version: z23.number().int().min(0), last_seen_at: z23.string().datetime() })).max(5)
4032
+ selector: z24.string().min(1).max(PRIVACY_LIMITS.selector),
4033
+ type: z24.enum(PRIVACY_RULE_TYPES),
4034
+ method: z24.enum(PRIVACY_METHODS),
4035
+ pattern: z24.string().min(1).max(PRIVACY_LIMITS.pattern).optional(),
4036
+ ignoreCase: z24.boolean().optional(),
4037
+ replaceWith: z24.string().max(PRIVACY_LIMITS.replaceWith).optional(),
4038
+ enabled: z24.boolean().optional()
4039
+ });
4040
+ var privacyPolicyInputSchema = z24.object({
4041
+ mode: z24.enum(PRIVACY_MODES),
4042
+ rules: z24.array(privacyRuleInputSchema).max(PRIVACY_LIMITS.rules),
4043
+ allowlist: z24.array(z24.string().min(1).max(PRIVACY_LIMITS.selector)).max(PRIVACY_LIMITS.allowlist)
4044
+ });
4045
+ var storedPolicySchema = z24.object({
4046
+ schema: z24.literal(PRIVACY_SCHEMA),
4047
+ version: z24.number().int().min(0),
4048
+ mode: z24.enum(PRIVACY_MODES),
4049
+ rules: z24.array(z24.record(z24.string(), z24.unknown())).max(PRIVACY_LIMITS.rules),
4050
+ allowlist: z24.array(z24.string()).max(PRIVACY_LIMITS.allowlist)
4051
+ });
4052
+ var nodePrivacyBlockSchema = z24.array(z24.object({ project_id: z24.number().int().positive(), policy: z24.unknown() })).max(1000);
4053
+ var privacyRollupSchema = z24.object({
4054
+ applied_version: z24.number().int().min(0).nullable(),
4055
+ policy_missing_24h: z24.number().int().nonnegative(),
4056
+ budget_exceeded_24h: z24.number().int().nonnegative(),
4057
+ sdk_versions: z24.array(z24.object({ version: z24.number().int().min(0), last_seen_at: z24.string().datetime() })).max(5),
4058
+ key_version: z24.number().int().min(1).max(PRIVACY_KEY_MAX_VERSION).optional(),
4059
+ key_created_at: z24.string().datetime().nullable().optional()
3960
4060
  });
3961
4061
 
3962
4062
  // ../src/shared/contracts/api-ops/privacy.ts
3963
4063
  var PRIVACY_INPUTS = {
3964
- get: z24.object({ workspaceId: uuid, projectId }),
3965
- set: z24.object({
4064
+ get: z25.object({ workspaceId: uuid, projectId }),
4065
+ set: z25.object({
3966
4066
  workspaceId: uuid,
3967
4067
  projectId,
3968
- expectedVersion: z24.number().int().min(0),
4068
+ expectedVersion: z25.number().int().min(0),
3969
4069
  policy: privacyPolicyInputSchema
3970
4070
  })
3971
4071
  };
@@ -3983,7 +4083,7 @@ var PRIVACY_OPERATIONS = [
3983
4083
  workspace: true,
3984
4084
  idempotency: "none",
3985
4085
  mcp: "configure",
3986
- summary: "A project's privacy policy (mode, rules, strict allowlist, version), the built-in detectors that are off, whether user ids are pseudonymised, the last 20 versions and what the node applies and counted in the last 24 h.",
4086
+ summary: "A project's privacy policy (mode, rules, strict allowlist, version), the built-in detectors that are off, whether user ids are pseudonymised, the pseudonymisation key version (never the key), the last 20 versions and what the node applies, hashes with and counted in the last 24 h.",
3987
4087
  ui: []
3988
4088
  }),
3989
4089
  op({
@@ -4005,10 +4105,10 @@ var PRIVACY_OPERATIONS = [
4005
4105
  ];
4006
4106
 
4007
4107
  // ../src/shared/contracts/api-ops/projects.ts
4008
- import { z as z28 } from "zod";
4108
+ import { z as z29 } from "zod";
4009
4109
 
4010
4110
  // ../src/shared/contracts/ingest-keys.ts
4011
- import { z as z25 } from "zod";
4111
+ import { z as z26 } from "zod";
4012
4112
  var INGEST_KEY_SCOPES = ["traces", "logs", "metrics", "errors", "monitors"];
4013
4113
  var INGEST_KEY_STATES = ["active", "revoked"];
4014
4114
  var INGEST_KEY_LIMITS = {
@@ -4018,92 +4118,92 @@ var INGEST_KEY_LIMITS = {
4018
4118
  edgeCacheSeconds: 60
4019
4119
  };
4020
4120
  var CHECKIN_AUTH_MODES = ["public_or_key", "key_only"];
4021
- var ingestKeyConfigSchema = z25.object({
4022
- v: z25.literal(1),
4023
- key_id: z25.guid(),
4024
- project_public_id: z25.number().int().positive(),
4025
- project_id: z25.number().int().positive(),
4026
- workspace_id: z25.guid(),
4121
+ var ingestKeyConfigSchema = z26.object({
4122
+ v: z26.literal(1),
4123
+ key_id: z26.guid(),
4124
+ project_public_id: z26.number().int().positive(),
4125
+ project_id: z26.number().int().positive(),
4126
+ workspace_id: z26.guid(),
4027
4127
  node_id: nodeIdSchema,
4028
- scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4029
- environments: z25.array(z25.string().max(INGEST_KEY_LIMITS.environmentMaxChars)).max(INGEST_KEY_LIMITS.environmentsMax),
4030
- expires_at: z25.string().datetime({ offset: true }).nullable(),
4031
- state: z25.enum(INGEST_KEY_STATES),
4032
- workspace_status: z25.enum(["active", "suspended", "deleting"]),
4033
- ingest_kill: z25.boolean(),
4034
- telemetry_kill: z25.boolean(),
4035
- telemetry_rate_bytes_per_sec: z25.number().int().positive(),
4036
- telemetry_burst_bytes: z25.number().int().positive(),
4037
- traces_monthly_bytes: z25.number().int().positive(),
4038
- logs_monthly_bytes: z25.number().int().positive(),
4039
- metrics_monthly_bytes: z25.number().int().positive().optional(),
4040
- telemetry_buffer_minutes: z25.number().int().min(1).max(1440),
4041
- revision: z25.number().int().nonnegative()
4042
- });
4043
- var createIngestKeyInputSchema = z25.object({
4044
- projectId: z25.number().int().positive(),
4045
- name: z25.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
4046
- scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4047
- environments: z25.array(z25.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
4048
- expiresAt: z25.string().datetime({ offset: true }).nullable()
4049
- });
4050
- var ingestKeyRowSchema = z25.object({
4051
- id: z25.guid(),
4052
- project_id: z25.number().int().positive(),
4053
- name: z25.string(),
4054
- prefix: z25.string(),
4055
- scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)),
4056
- environments: z25.array(z25.string()),
4057
- expires_at: z25.string().nullable(),
4058
- state: z25.enum(INGEST_KEY_STATES),
4059
- created_by: z25.guid().nullable(),
4060
- created_at: z25.string(),
4061
- revoked_at: z25.string().nullable(),
4062
- last_used_at: z25.string().nullable()
4128
+ scopes: z26.array(z26.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4129
+ environments: z26.array(z26.string().max(INGEST_KEY_LIMITS.environmentMaxChars)).max(INGEST_KEY_LIMITS.environmentsMax),
4130
+ expires_at: z26.string().datetime({ offset: true }).nullable(),
4131
+ state: z26.enum(INGEST_KEY_STATES),
4132
+ workspace_status: z26.enum(["active", "suspended", "deleting"]),
4133
+ ingest_kill: z26.boolean(),
4134
+ telemetry_kill: z26.boolean(),
4135
+ telemetry_rate_bytes_per_sec: z26.number().int().positive(),
4136
+ telemetry_burst_bytes: z26.number().int().positive(),
4137
+ traces_monthly_bytes: z26.number().int().positive(),
4138
+ logs_monthly_bytes: z26.number().int().positive(),
4139
+ metrics_monthly_bytes: z26.number().int().positive().optional(),
4140
+ telemetry_buffer_minutes: z26.number().int().min(1).max(1440),
4141
+ revision: z26.number().int().nonnegative()
4142
+ });
4143
+ var createIngestKeyInputSchema = z26.object({
4144
+ projectId: z26.number().int().positive(),
4145
+ name: z26.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
4146
+ scopes: z26.array(z26.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4147
+ environments: z26.array(z26.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
4148
+ expiresAt: z26.string().datetime({ offset: true }).nullable()
4149
+ });
4150
+ var ingestKeyRowSchema = z26.object({
4151
+ id: z26.guid(),
4152
+ project_id: z26.number().int().positive(),
4153
+ name: z26.string(),
4154
+ prefix: z26.string(),
4155
+ scopes: z26.array(z26.enum(INGEST_KEY_SCOPES)),
4156
+ environments: z26.array(z26.string()),
4157
+ expires_at: z26.string().nullable(),
4158
+ state: z26.enum(INGEST_KEY_STATES),
4159
+ created_by: z26.guid().nullable(),
4160
+ created_at: z26.string(),
4161
+ revoked_at: z26.string().nullable(),
4162
+ last_used_at: z26.string().nullable()
4063
4163
  });
4064
4164
 
4065
4165
  // ../src/shared/contracts/node-config.ts
4066
- import { z as z27 } from "zod";
4166
+ import { z as z28 } from "zod";
4067
4167
 
4068
4168
  // ../src/shared/contracts/backup.ts
4069
- import { z as z26 } from "zod";
4169
+ import { z as z27 } from "zod";
4070
4170
  var BACKUP_KINDS = ["daily", "weekly", "manual", "pre_upgrade"];
4071
- var ageRecipient = z26.string().regex(/^age1[02-9ac-hj-np-z]{58}$/);
4072
- var backupIdSchema = z26.string().regex(/^[a-z0-9-]{8,64}$/);
4073
- var nodeBackupConfigSchema = z26.object({
4074
- enabled: z26.boolean(),
4075
- hour_utc: z26.number().int().min(0).max(23),
4076
- weekly_day: z26.number().int().min(1).max(7),
4171
+ var ageRecipient = z27.string().regex(/^age1[02-9ac-hj-np-z]{58}$/);
4172
+ var backupIdSchema = z27.string().regex(/^[a-z0-9-]{8,64}$/);
4173
+ var nodeBackupConfigSchema = z27.object({
4174
+ enabled: z27.boolean(),
4175
+ hour_utc: z27.number().int().min(0).max(23),
4176
+ weekly_day: z27.number().int().min(1).max(7),
4077
4177
  workspace_recipient: ageRecipient
4078
4178
  });
4079
- var backupCredentialsRequestSchema = z26.object({
4080
- mode: z26.enum(["upload", "download"]),
4179
+ var backupCredentialsRequestSchema = z27.object({
4180
+ mode: z27.enum(["upload", "download"]),
4081
4181
  backup_id: backupIdSchema,
4082
- source_node_id: z26.guid().optional()
4083
- });
4084
- var backupCredentialsSchema = z26.object({
4085
- endpoint: z26.string().url(),
4086
- bucket: z26.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/),
4087
- prefix: z26.string().regex(/^backups\/[0-9a-f-]{36}\/$/),
4088
- access_key_id: z26.string().min(8).max(200),
4089
- secret_access_key: z26.string().min(8).max(200),
4090
- session_token: z26.string().min(8).max(4000),
4091
- expires_at: z26.string().datetime()
4092
- });
4093
- var rowCountsSchema = z26.record(z26.string().regex(/^[a-z_][a-z0-9_]{0,63}$/), z26.number().int().nonnegative());
4094
- var backupManifestSchema = z26.object({
4095
- v: z26.literal(1),
4182
+ source_node_id: z27.guid().optional()
4183
+ });
4184
+ var backupCredentialsSchema = z27.object({
4185
+ endpoint: z27.string().url(),
4186
+ bucket: z27.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/),
4187
+ prefix: z27.string().regex(/^backups\/[0-9a-f-]{36}\/$/),
4188
+ access_key_id: z27.string().min(8).max(200),
4189
+ secret_access_key: z27.string().min(8).max(200),
4190
+ session_token: z27.string().min(8).max(4000),
4191
+ expires_at: z27.string().datetime()
4192
+ });
4193
+ var rowCountsSchema = z27.record(z27.string().regex(/^[a-z_][a-z0-9_]{0,63}$/), z27.number().int().nonnegative());
4194
+ var backupManifestSchema = z27.object({
4195
+ v: z27.literal(1),
4096
4196
  backup_id: backupIdSchema,
4097
- node_id: z26.guid(),
4098
- kind: z26.enum(BACKUP_KINDS),
4099
- created_at: z26.string().datetime(),
4100
- object_key: z26.string(),
4101
- size_bytes: z26.number().int().nonnegative(),
4102
- sha256: z26.string().regex(/^[0-9a-f]{64}$/),
4103
- clickhouse_version: z26.string().max(40),
4104
- schema_version: z26.number().int().nonnegative(),
4197
+ node_id: z27.guid(),
4198
+ kind: z27.enum(BACKUP_KINDS),
4199
+ created_at: z27.string().datetime(),
4200
+ object_key: z27.string(),
4201
+ size_bytes: z27.number().int().nonnegative(),
4202
+ sha256: z27.string().regex(/^[0-9a-f]{64}$/),
4203
+ clickhouse_version: z27.string().max(40),
4204
+ schema_version: z27.number().int().nonnegative(),
4105
4205
  row_counts: rowCountsSchema,
4106
- recipients: z26.array(z26.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
4206
+ recipients: z27.array(z27.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
4107
4207
  });
4108
4208
  var BACKUP_ERROR_CODES = [
4109
4209
  "CLICKHOUSE_BACKUP_FAILED",
@@ -4117,48 +4217,48 @@ var BACKUP_ERROR_CODES = [
4117
4217
  "RESTORE_FAILED",
4118
4218
  "ROW_COUNT_MISMATCH"
4119
4219
  ];
4120
- var backupReportSchema = z26.object({
4220
+ var backupReportSchema = z27.object({
4121
4221
  backup_id: backupIdSchema,
4122
- kind: z26.enum(BACKUP_KINDS),
4123
- status: z26.enum(["succeeded", "failed"]),
4124
- started_at: z26.string().datetime(),
4125
- finished_at: z26.string().datetime(),
4222
+ kind: z27.enum(BACKUP_KINDS),
4223
+ status: z27.enum(["succeeded", "failed"]),
4224
+ started_at: z27.string().datetime(),
4225
+ finished_at: z27.string().datetime(),
4126
4226
  manifest: backupManifestSchema.nullable(),
4127
- error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
4227
+ error_code: z27.enum(BACKUP_ERROR_CODES).nullable()
4128
4228
  });
4129
- var drillReportSchema = z26.object({
4229
+ var drillReportSchema = z27.object({
4130
4230
  backup_id: backupIdSchema,
4131
- kind: z26.enum(["weekly_local", "monthly_new_machine"]),
4132
- status: z26.enum(["passed", "failed"]),
4133
- finished_at: z26.string().datetime(),
4134
- detail: z26.string().max(300),
4135
- error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
4231
+ kind: z27.enum(["weekly_local", "monthly_new_machine"]),
4232
+ status: z27.enum(["passed", "failed"]),
4233
+ finished_at: z27.string().datetime(),
4234
+ detail: z27.string().max(300),
4235
+ error_code: z27.enum(BACKUP_ERROR_CODES).nullable()
4136
4236
  });
4137
- var nodeIdentityEscrowSchema = z26.object({
4138
- v: z26.literal(1),
4139
- node_id: z26.guid(),
4140
- seal: z26.object({
4141
- publicKey: z26.string().regex(/^[A-Za-z0-9_-]{43}$/),
4142
- privateKey: z26.string().regex(/^[A-Za-z0-9_-]{43}$/)
4237
+ var nodeIdentityEscrowSchema = z27.object({
4238
+ v: z27.literal(1),
4239
+ node_id: z27.guid(),
4240
+ seal: z27.object({
4241
+ publicKey: z27.string().regex(/^[A-Za-z0-9_-]{43}$/),
4242
+ privateKey: z27.string().regex(/^[A-Za-z0-9_-]{43}$/)
4143
4243
  }),
4144
- created_at: z26.string().datetime()
4244
+ created_at: z27.string().datetime()
4145
4245
  });
4146
- var restoreArgsSchema = z26.object({
4147
- job_id: z26.guid(),
4148
- workspace_id: z26.guid(),
4149
- source_node_id: z26.guid(),
4246
+ var restoreArgsSchema = z27.object({
4247
+ job_id: z27.guid(),
4248
+ workspace_id: z27.guid(),
4249
+ source_node_id: z27.guid(),
4150
4250
  manifest: backupManifestSchema,
4151
- sealed_identity: z26.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
4152
- mode: z26.enum(["rebuild", "drill"])
4251
+ sealed_identity: z27.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
4252
+ mode: z27.enum(["rebuild", "drill"])
4153
4253
  });
4154
- var restoreReportSchema = z26.object({
4155
- job_id: z26.guid(),
4254
+ var restoreReportSchema = z27.object({
4255
+ job_id: z27.guid(),
4156
4256
  backup_id: backupIdSchema,
4157
- mode: z26.enum(["rebuild", "drill"]),
4158
- status: z26.enum(["succeeded", "failed"]),
4159
- finished_at: z26.string().datetime(),
4160
- detail: z26.string().max(300),
4161
- error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
4257
+ mode: z27.enum(["rebuild", "drill"]),
4258
+ status: z27.enum(["succeeded", "failed"]),
4259
+ finished_at: z27.string().datetime(),
4260
+ detail: z27.string().max(300),
4261
+ error_code: z27.enum(BACKUP_ERROR_CODES).nullable()
4162
4262
  });
4163
4263
 
4164
4264
  // ../src/shared/contracts/node-config.ts
@@ -4172,84 +4272,85 @@ var SCRUB_GROUPS = [
4172
4272
  "headers"
4173
4273
  ];
4174
4274
  var MAX_NODE_MONITORS = 5000;
4175
- var kid = z27.string().regex(/^[A-Za-z0-9_-]{1,40}$/);
4176
- var publicKey = z27.string().regex(/^[A-Za-z0-9_-]{43}$/);
4177
- var nodeConfigSchema = z27.object({
4178
- v: z27.literal(1),
4179
- config_version: z27.number().int().positive(),
4180
- node_id: z27.guid(),
4181
- workspace_id: z27.guid(),
4182
- workspace_status: z27.enum(["active", "suspended"]),
4183
- issued_at: z27.string().datetime(),
4184
- retention_days: z27.number().int().min(1).max(3650),
4185
- channel: z27.enum(["stable", "canary"]).optional(),
4186
- projects: z27.array(z27.object({
4187
- project_id: z27.number().int().positive(),
4188
- slug: z27.string().max(64),
4189
- short_prefix: z27.string().regex(/^[A-Z0-9]{1,12}$/),
4190
- user_id_salt: z27.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
4191
- scrub_disabled: z27.array(z27.enum(SCRUB_GROUPS)).max(SCRUB_GROUPS.length),
4192
- upload_tokens: z27.array(z27.object({
4193
- hash: z27.string().regex(/^[a-f0-9]{64}$/),
4194
- expires_at: z27.string().datetime(),
4195
- scopes: z27.array(z27.enum(UPLOAD_SCOPES)).min(1).max(UPLOAD_SCOPES.length).optional()
4275
+ var kid = z28.string().regex(/^[A-Za-z0-9_-]{1,40}$/);
4276
+ var publicKey = z28.string().regex(/^[A-Za-z0-9_-]{43}$/);
4277
+ var nodeConfigSchema = z28.object({
4278
+ v: z28.literal(1),
4279
+ config_version: z28.number().int().positive(),
4280
+ node_id: z28.guid(),
4281
+ workspace_id: z28.guid(),
4282
+ workspace_status: z28.enum(["active", "suspended"]),
4283
+ issued_at: z28.string().datetime(),
4284
+ retention_days: z28.number().int().min(1).max(3650),
4285
+ channel: z28.enum(["stable", "canary"]).optional(),
4286
+ projects: z28.array(z28.object({
4287
+ project_id: z28.number().int().positive(),
4288
+ slug: z28.string().max(64),
4289
+ short_prefix: z28.string().regex(/^[A-Z0-9]{1,12}$/),
4290
+ user_id_salt: z28.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
4291
+ privacy_key_version: z28.number().int().min(1).max(PRIVACY_KEY_MAX_VERSION).optional(),
4292
+ scrub_disabled: z28.array(z28.enum(SCRUB_GROUPS)).max(SCRUB_GROUPS.length),
4293
+ upload_tokens: z28.array(z28.object({
4294
+ hash: z28.string().regex(/^[a-f0-9]{64}$/),
4295
+ expires_at: z28.string().datetime(),
4296
+ scopes: z28.array(z28.enum(UPLOAD_SCOPES)).min(1).max(UPLOAD_SCOPES.length).optional()
4196
4297
  })).max(10).optional()
4197
4298
  })).max(1000),
4198
- ticket_keys: z27.array(z27.object({ kid, public_key: publicKey, not_after: z27.string().datetime() })).min(1).max(5),
4199
- control_ops_keys: z27.array(z27.object({ kid, public_key: publicKey })).min(1).max(5),
4200
- kill_switches: z27.object({ ingest: z27.boolean(), alerts: z27.boolean() }),
4299
+ ticket_keys: z28.array(z28.object({ kid, public_key: publicKey, not_after: z28.string().datetime() })).min(1).max(5),
4300
+ control_ops_keys: z28.array(z28.object({ kid, public_key: publicKey })).min(1).max(5),
4301
+ kill_switches: z28.object({ ingest: z28.boolean(), alerts: z28.boolean() }),
4201
4302
  backup: nodeBackupConfigSchema.optional(),
4202
- purged_projects: z27.array(z27.number().int().positive()).max(1000).optional(),
4203
- monitors: z27.array(monitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4204
- purged_monitors: z27.array(z27.guid()).max(5000).optional(),
4205
- telemetry: z27.object({
4206
- traces_retention_days: z27.number().int().min(1).max(90),
4207
- logs_retention_days: z27.number().int().min(1).max(90),
4208
- traces_disk_share: z27.number().min(0.2).max(0.8)
4303
+ purged_projects: z28.array(z28.number().int().positive()).max(1000).optional(),
4304
+ monitors: z28.array(monitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4305
+ purged_monitors: z28.array(z28.guid()).max(5000).optional(),
4306
+ telemetry: z28.object({
4307
+ traces_retention_days: z28.number().int().min(1).max(90),
4308
+ logs_retention_days: z28.number().int().min(1).max(90),
4309
+ traces_disk_share: z28.number().min(0.2).max(0.8)
4209
4310
  }).optional(),
4210
4311
  metrics: metricsConfigSchema.optional(),
4211
- slos: z27.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
4212
- signal_monitors: z27.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4312
+ slos: z28.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
4313
+ signal_monitors: z28.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4213
4314
  signal_limits: signalLimitsConfigSchema.optional(),
4214
4315
  privacy: nodePrivacyBlockSchema.optional()
4215
4316
  });
4216
- var signedNodeConfigSchema = z27.object({ config: nodeConfigSchema, kid, sig: z27.string() });
4317
+ var signedNodeConfigSchema = z28.object({ config: nodeConfigSchema, kid, sig: z28.string() });
4217
4318
 
4218
4319
  // ../src/shared/contracts/api-ops/projects.ts
4219
- var slug = z28.string().regex(/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/);
4220
- var name3 = z28.string().trim().min(1).max(60);
4221
- var label2 = z28.string().trim().min(1).max(40);
4222
- var platform = z28.enum(PLATFORMS);
4223
- var origin = z28.string().trim().toLowerCase().regex(/^https?:\/\/[a-z0-9.-]+(:[0-9]{1,5})?$/).max(200);
4224
- var keyId = z28.number().int().positive();
4320
+ var slug = z29.string().regex(/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/);
4321
+ var name3 = z29.string().trim().min(1).max(60);
4322
+ var label2 = z29.string().trim().min(1).max(40);
4323
+ var platform = z29.enum(PLATFORMS);
4324
+ var origin = z29.string().trim().toLowerCase().regex(/^https?:\/\/[a-z0-9.-]+(:[0-9]{1,5})?$/).max(200);
4325
+ var keyId = z29.number().int().positive();
4225
4326
  var PROJECT_INPUTS = {
4226
- create: z28.object({ workspaceId: uuid, name: name3, slug, platform }),
4227
- update: z28.object({ projectId, name: name3, platform, isPinned: z28.boolean() }),
4228
- updateIntake: z28.object({
4327
+ create: z29.object({ workspaceId: uuid, name: name3, slug, platform }),
4328
+ update: z29.object({ projectId, name: name3, platform, isPinned: z29.boolean() }),
4329
+ updateIntake: z29.object({
4229
4330
  projectId,
4230
- rateLimit: z28.number().int().positive().nullable(),
4231
- burst: z28.number().int().positive().nullable(),
4232
- allowedOrigins: z28.array(origin).max(50)
4331
+ rateLimit: z29.number().int().positive().nullable(),
4332
+ burst: z29.number().int().positive().nullable(),
4333
+ allowedOrigins: z29.array(origin).max(50)
4233
4334
  }),
4234
- updateObservability: z28.object({
4335
+ updateObservability: z29.object({
4235
4336
  projectId,
4236
- primaryEnvironment: z28.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
4237
- allowCodeMonitors: z28.boolean()
4337
+ primaryEnvironment: z29.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
4338
+ allowCodeMonitors: z29.boolean()
4238
4339
  }),
4239
- setScrub: z28.object({ projectId, group: z28.enum(SCRUB_GROUPS), enabled: z28.boolean() }),
4240
- setCheckinAuth: z28.object({ projectId, mode: z28.enum(CHECKIN_AUTH_MODES) }),
4241
- setEnvironmentHidden: z28.object({
4340
+ setScrub: z29.object({ projectId, group: z29.enum(SCRUB_GROUPS), enabled: z29.boolean() }),
4341
+ setCheckinAuth: z29.object({ projectId, mode: z29.enum(CHECKIN_AUTH_MODES) }),
4342
+ setEnvironmentHidden: z29.object({
4242
4343
  projectId,
4243
- name: z28.string().min(1).max(64),
4244
- hidden: z28.boolean()
4245
- }),
4246
- scheduleDeletion: z28.object({ projectId, confirmSlug: slug }),
4247
- projectOnly: z28.object({ projectId }),
4248
- labelled: z28.object({ projectId, label: label2 }),
4249
- keyOnly: z28.object({ keyId }),
4250
- tokenOnly: z28.object({ tokenId: keyId }),
4344
+ name: z29.string().min(1).max(64),
4345
+ hidden: z29.boolean()
4346
+ }),
4347
+ scheduleDeletion: z29.object({ projectId, confirmSlug: slug }),
4348
+ projectOnly: z29.object({ projectId }),
4349
+ labelled: z29.object({ projectId, label: label2 }),
4350
+ keyOnly: z29.object({ keyId }),
4351
+ tokenOnly: z29.object({ tokenId: keyId }),
4251
4352
  createIngestKey: createIngestKeyInputSchema,
4252
- ingestKeyOnly: z28.object({ keyId: uuid })
4353
+ ingestKeyOnly: z29.object({ keyId: uuid })
4253
4354
  };
4254
4355
  var P2 = PROJECT_INPUTS;
4255
4356
  var PROJECT_OPERATIONS = [
@@ -4504,24 +4605,24 @@ var PROJECT_OPERATIONS = [
4504
4605
  ];
4505
4606
 
4506
4607
  // ../src/shared/contracts/api-ops/reads.ts
4507
- import { z as z29 } from "zod";
4508
- var list = z29.object({ workspaceId: uuid, limit: pageLimit, cursor });
4608
+ import { z as z30 } from "zod";
4609
+ var list = z30.object({ workspaceId: uuid, limit: pageLimit, cursor });
4509
4610
  var READ_INPUTS = {
4510
- workspace: z29.object({ workspaceId: uuid }),
4611
+ workspace: z30.object({ workspaceId: uuid }),
4511
4612
  list,
4512
- projectsGet: z29.object({ workspaceId: uuid, projectId }),
4613
+ projectsGet: z30.object({ workspaceId: uuid, projectId }),
4513
4614
  monitorsList: list.extend({ projectId: projectId.optional() }),
4514
- monitorsGet: z29.object({ workspaceId: uuid, monitorId: uuid }),
4515
- uptimeGet: z29.object({ workspaceId: uuid, checkId: uuid }),
4516
- slosGet: z29.object({ workspaceId: uuid, sloId: uuid }),
4615
+ monitorsGet: z30.object({ workspaceId: uuid, monitorId: uuid }),
4616
+ uptimeGet: z30.object({ workspaceId: uuid, checkId: uuid }),
4617
+ slosGet: z30.object({ workspaceId: uuid, sloId: uuid }),
4517
4618
  alertsList: list.extend({
4518
- state: z29.enum(["open", "resolved", "all"]).default("all"),
4619
+ state: z30.enum(["open", "resolved", "all"]).default("all"),
4519
4620
  monitorId: uuid.optional()
4520
4621
  }),
4521
- approvalsGet: z29.object({ workspaceId: uuid, approvalId: uuid }),
4622
+ approvalsGet: z30.object({ workspaceId: uuid, approvalId: uuid }),
4522
4623
  monitorsListTyped: list.extend({
4523
4624
  projectId: projectId.optional(),
4524
- type: z29.enum(MONITOR_TYPES).optional()
4625
+ type: z30.enum(MONITOR_TYPES).optional()
4525
4626
  })
4526
4627
  };
4527
4628
  var R = READ_INPUTS;
@@ -4805,14 +4906,14 @@ function approvalRequestSchema(operationId, input) {
4805
4906
  }
4806
4907
 
4807
4908
  // ../src/shared/contracts/api-ops/wire.ts
4808
- import { z as z30 } from "zod";
4909
+ import { z as z31 } from "zod";
4809
4910
  var toSnake = (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
4810
4911
  var toCamel = (s) => s.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
4811
4912
  var schemaCache = new WeakMap;
4812
4913
  function inputJsonSchema(op) {
4813
4914
  let js = schemaCache.get(op.input);
4814
4915
  if (!js) {
4815
- js = z30.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4916
+ js = z31.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4816
4917
  schemaCache.set(op.input, js);
4817
4918
  }
4818
4919
  return js;
@@ -5026,7 +5127,7 @@ function wireInput(operationId, opts = {}) {
5026
5127
  for (const [k, v] of Object.entries(op.input.shape))
5027
5128
  if (!omit.has(k))
5028
5129
  shape[toSnake(k)] = v;
5029
- return z31.object(shape);
5130
+ return z32.object(shape);
5030
5131
  }
5031
5132
  var BUDGETS = [
5032
5133
  { stringBytes: MCP_LIMITS.untrustedStringMaxBytes, listMax: MCP_LIMITS.listMax },
@@ -5119,52 +5220,52 @@ function errorResult(o) {
5119
5220
  }
5120
5221
  };
5121
5222
  }
5122
- var TOOL_OUTPUT_SCHEMA = z31.object({
5123
- untrusted: z31.object({
5124
- data: z31.unknown(),
5125
- provenance: z31.object({
5126
- source: z31.enum(["node", "control_plane", "docs"]),
5127
- operations: z31.array(z31.string())
5223
+ var TOOL_OUTPUT_SCHEMA = z32.object({
5224
+ untrusted: z32.object({
5225
+ data: z32.unknown(),
5226
+ provenance: z32.object({
5227
+ source: z32.enum(["node", "control_plane", "docs"]),
5228
+ operations: z32.array(z32.string())
5128
5229
  })
5129
5230
  }).optional(),
5130
- doc: z31.object({
5131
- slug: z31.string(),
5132
- locale: z31.enum(["en", "vi"]),
5133
- url: z31.string(),
5134
- markdown: z31.string(),
5135
- truncated: z31.boolean()
5231
+ doc: z32.object({
5232
+ slug: z32.string(),
5233
+ locale: z32.enum(["en", "vi"]),
5234
+ url: z32.string(),
5235
+ markdown: z32.string(),
5236
+ truncated: z32.boolean()
5136
5237
  }).optional(),
5137
- results: z31.array(z31.object({
5138
- slug: z31.string(),
5139
- title: z31.string(),
5140
- description: z31.string(),
5141
- section: z31.string(),
5142
- url: z31.string()
5238
+ results: z32.array(z32.object({
5239
+ slug: z32.string(),
5240
+ title: z32.string(),
5241
+ description: z32.string(),
5242
+ section: z32.string(),
5243
+ url: z32.string()
5143
5244
  })).optional(),
5144
- next_cursor: z31.string().nullable().optional(),
5145
- complete: z31.boolean().optional(),
5146
- omitted: z31.array(z31.object({ part: z31.string(), reason: z31.string(), scope: z31.string().optional() })).optional(),
5147
- truncated: z31.literal(true).optional(),
5148
- suspicious_unicode: z31.literal(true).optional(),
5149
- error: z31.object({
5150
- code: z31.string(),
5151
- status: z31.number(),
5152
- detail: z31.string().optional(),
5153
- scope: z31.string().optional(),
5154
- retry_after: z31.number().optional()
5245
+ next_cursor: z32.string().nullable().optional(),
5246
+ complete: z32.boolean().optional(),
5247
+ omitted: z32.array(z32.object({ part: z32.string(), reason: z32.string(), scope: z32.string().optional() })).optional(),
5248
+ truncated: z32.literal(true).optional(),
5249
+ suspicious_unicode: z32.literal(true).optional(),
5250
+ error: z32.object({
5251
+ code: z32.string(),
5252
+ status: z32.number(),
5253
+ detail: z32.string().optional(),
5254
+ scope: z32.string().optional(),
5255
+ retry_after: z32.number().optional()
5155
5256
  }).optional(),
5156
- operations: z31.array(z31.record(z31.string(), z31.unknown())).optional(),
5157
- operation: z31.record(z31.string(), z31.unknown()).optional(),
5158
- plan: z31.record(z31.string(), z31.unknown()).optional(),
5159
- status: z31.enum(["done", "approval_required", "approval_pending", ...APPROVAL_STATES]).optional(),
5160
- approval: z31.object({
5161
- approval_id: z31.string(),
5162
- approval_url: z31.string(),
5163
- expires_at: z31.string(),
5164
- state: z31.enum(APPROVAL_STATES),
5165
- result_code: z31.string().nullable().optional(),
5166
- result: z31.record(z31.string(), z31.unknown()).optional(),
5167
- next: z31.string().optional()
5257
+ operations: z32.array(z32.record(z32.string(), z32.unknown())).optional(),
5258
+ operation: z32.record(z32.string(), z32.unknown()).optional(),
5259
+ plan: z32.record(z32.string(), z32.unknown()).optional(),
5260
+ status: z32.enum(["done", "approval_required", "approval_pending", ...APPROVAL_STATES]).optional(),
5261
+ approval: z32.object({
5262
+ approval_id: z32.string(),
5263
+ approval_url: z32.string(),
5264
+ expires_at: z32.string(),
5265
+ state: z32.enum(APPROVAL_STATES),
5266
+ result_code: z32.string().nullable().optional(),
5267
+ result: z32.record(z32.string(), z32.unknown()).optional(),
5268
+ next: z32.string().optional()
5168
5269
  }).optional()
5169
5270
  });
5170
5271
  var spec = (name) => {
@@ -5210,10 +5311,10 @@ var has = (rt, operationId) => {
5210
5311
  return !!op && rt.scopes.includes(op.scope);
5211
5312
  };
5212
5313
  var isoWindow = {
5213
- start: z31.string().max(40).describe("RFC 3339 start of the window, e.g. 2026-10-26T00:00:00Z. Required with end."),
5214
- end: z31.string().max(40).describe("RFC 3339 end of the window. The plan limits its length.")
5314
+ start: z32.string().max(40).describe("RFC 3339 start of the window, e.g. 2026-10-26T00:00:00Z. Required with end."),
5315
+ end: z32.string().max(40).describe("RFC 3339 end of the window. The plan limits its length.")
5215
5316
  };
5216
- var traceIdSchema = z31.string().regex(/^[0-9a-fA-F]{32}$/);
5317
+ var traceIdSchema = z32.string().regex(/^[0-9a-fA-F]{32}$/);
5217
5318
  var MONITOR_KINDS2 = {
5218
5319
  cron: { list: "monitors.list", get: "monitors.get", idField: "monitor_id" },
5219
5320
  uptime: { list: "uptime.list", get: "uptime.get", idField: "check_id" },
@@ -5277,8 +5378,8 @@ function describe(op, scopes) {
5277
5378
  destructive: isDestructiveOperation(op)
5278
5379
  };
5279
5380
  }
5280
- var params = z31.record(z31.string(), z31.unknown()).default({}).describe("Operation fields in wire names (snake_case), as describe_operation's args_schema shows.");
5281
- var operationIdArg = z31.string().min(3).max(80).describe("An operation id from search_operations, e.g. `monitors.update`.");
5381
+ var params = z32.record(z32.string(), z32.unknown()).default({}).describe("Operation fields in wire names (snake_case), as describe_operation's args_schema shows.");
5382
+ var operationIdArg = z32.string().min(3).max(80).describe("An operation id from search_operations, e.g. `monitors.update`.");
5282
5383
  function approvalBlock(t, next) {
5283
5384
  return {
5284
5385
  approval_id: t.approval_id,
@@ -5298,7 +5399,7 @@ var MCP_TOOL_DEFS = [
5298
5399
  title: "Workspace and node",
5299
5400
  description: "The workspace this token belongs to (name, plan, limits) and the state of its node, the server that stores errors, traces and logs. Start here to learn what the token can reach.",
5300
5401
  operations: ["workspace.get", "node.get"],
5301
- input: z31.object({}),
5402
+ input: z32.object({}),
5302
5403
  async run(_args, rt) {
5303
5404
  const [ws, node] = await Promise.all([rt.call("workspace.get", {}), rt.call("node.get", {})]);
5304
5405
  if (!ws.ok)
@@ -5320,9 +5421,9 @@ var MCP_TOOL_DEFS = [
5320
5421
  title: "Get an issue",
5321
5422
  description: "One issue with its 24 h and 30 d counts and, when the token can read events, its latest event (stack trace, request, breadcrumbs — scrubbed on the node). A resolved issue also carries `fix_status` when the token can read releases: fixed, unverified, not_fixed (with the event that broke it) or unknown, per environment.",
5322
5423
  operations: ["issues.get", "events.get", "issues.fix_status"],
5323
- input: z31.object({
5324
- issue_id: z31.number().int().positive().describe("Issue id from search_issues."),
5325
- include_latest_event: z31.boolean().default(true)
5424
+ input: z32.object({
5425
+ issue_id: z32.number().int().positive().describe("Issue id from search_issues."),
5426
+ include_latest_event: z32.boolean().default(true)
5326
5427
  }),
5327
5428
  async run(args, rt) {
5328
5429
  const omitted = [];
@@ -5363,9 +5464,9 @@ var MCP_TOOL_DEFS = [
5363
5464
  title: "Get a trace",
5364
5465
  description: "Summary of one distributed trace (services, duration, errors) by its 32-hex trace id, and optionally its spans (errors only, or the first page).",
5365
5466
  operations: ["traces.get", "traces.spans"],
5366
- input: z31.object({
5467
+ input: z32.object({
5367
5468
  trace_id: traceIdSchema.describe("W3C trace id, 32 hex characters."),
5368
- spans: z31.enum(["none", "errors", "all"]).default("none")
5469
+ spans: z32.enum(["none", "errors", "all"]).default("none")
5369
5470
  }),
5370
5471
  async run(args, rt) {
5371
5472
  const sum = await rt.call("traces.get", { trace_id: args["trace_id"] });
@@ -5397,17 +5498,17 @@ var MCP_TOOL_DEFS = [
5397
5498
  title: "Query metrics",
5398
5499
  description: "OpenTelemetry metrics of one project. Without `name`: the metric catalog (name, type, unit, series count, last seen; `q` narrows by name) and the node's series caps. With `name` plus start and end: the metric aggregated per step — `aggregation` defaults to rate for counters, p95 for histograms and avg for gauges — optionally filtered by attributes (`attrs`, JSON list of {k, op, v}) and grouped by up to two attribute keys (`group_by`, comma-separated). Exemplar trace ids open with get_trace.",
5399
5500
  operations: ["metrics.names", "metrics.query"],
5400
- input: z31.object({
5401
- project: z31.number().int().positive().describe("Numeric project id from list_projects."),
5402
- name: z31.string().regex(METRIC_NAME_RE).optional().describe("Metric name from the catalog, e.g. http.server.request.duration."),
5403
- q: z31.string().max(255).optional().describe("Catalog only: part of a metric name."),
5404
- aggregation: z31.enum(METRIC_AGGREGATIONS).optional(),
5501
+ input: z32.object({
5502
+ project: z32.number().int().positive().describe("Numeric project id from list_projects."),
5503
+ name: z32.string().regex(METRIC_NAME_RE).optional().describe("Metric name from the catalog, e.g. http.server.request.duration."),
5504
+ q: z32.string().max(255).optional().describe("Catalog only: part of a metric name."),
5505
+ aggregation: z32.enum(METRIC_AGGREGATIONS).optional(),
5405
5506
  start: isoWindow.start.optional(),
5406
5507
  end: isoWindow.end.optional(),
5407
- step: z31.number().int().min(60).max(86400).multipleOf(60).optional().describe("Seconds per point (whole minutes); picked from the window when absent."),
5408
- attrs: z31.string().max(2000).optional(),
5409
- group_by: z31.string().max(600).optional(),
5410
- environment: z31.string().max(2000).optional().describe("Comma-separated environments.")
5508
+ step: z32.number().int().min(60).max(86400).multipleOf(60).optional().describe("Seconds per point (whole minutes); picked from the window when absent."),
5509
+ attrs: z32.string().max(2000).optional(),
5510
+ group_by: z32.string().max(600).optional(),
5511
+ environment: z32.string().max(2000).optional().describe("Comma-separated environments.")
5411
5512
  }),
5412
5513
  async run(args, rt) {
5413
5514
  const scope = {
@@ -5462,8 +5563,8 @@ var MCP_TOOL_DEFS = [
5462
5563
  title: "Release health",
5463
5564
  description: "What changed with a release (spec 13). With `version`: that release in one environment against the previous one (or `compare`) — three lists for its first 24 hours: new issues, regressed issues and increased issues (≥ 2× events per hour and ≥ 10 events), up to 50 each with hourly sparklines, plus its deploy markers. Without `version`: the project's releases, newest deploy first, with those three counts. `environment` defaults to production (else the busiest). Whether a resolved issue is really fixed: get_issue returns its fix status.",
5464
5565
  operations: ["releases.list", "releases.health"],
5465
- input: z31.object({
5466
- project: z31.number().int().positive().describe("Numeric project id from list_projects."),
5566
+ input: z32.object({
5567
+ project: z32.number().int().positive().describe("Numeric project id from list_projects."),
5467
5568
  version: releaseNameSchema.optional().describe("Release name exactly as the SDK sends it, e.g. web@1.4.2."),
5468
5569
  environment: environmentNameSchema.optional().describe("One environment, e.g. production."),
5469
5570
  compare: releaseNameSchema.optional().describe("With version: compare against this release instead of the previous one.")
@@ -5495,11 +5596,11 @@ var MCP_TOOL_DEFS = [
5495
5596
  title: "Correlate by trace or run",
5496
5597
  description: "Everything that shares one W3C trace id or one Belvador run id (`belvador.run.id`, set by job monitors) in a time window: the trace summary, its error spans and the logs. Give exactly one of trace_id or run_id.",
5497
5598
  operations: ["traces.get", "traces.spans", "spans.list", "logs.list"],
5498
- input: z31.object({
5599
+ input: z32.object({
5499
5600
  trace_id: traceIdSchema.optional(),
5500
- run_id: z31.string().min(1).max(128).optional(),
5601
+ run_id: z32.string().min(1).max(128).optional(),
5501
5602
  ...isoWindow,
5502
- project: z31.string().max(2000).optional().describe("Comma-separated project ids.")
5603
+ project: z32.string().max(2000).optional().describe("Comma-separated project ids.")
5503
5604
  }),
5504
5605
  async run(args, rt) {
5505
5606
  const trace = args["trace_id"];
@@ -5558,10 +5659,10 @@ var MCP_TOOL_DEFS = [
5558
5659
  title: "List monitors",
5559
5660
  description: "Monitors (cron, heartbeat, count, assertion, deadline, progress), uptime checks and SLOs with their current status. `kind` narrows to one family; `project_id` to one project (cron and uptime).",
5560
5661
  operations: ["monitors.list", "uptime.list", "slos.list"],
5561
- input: z31.object({
5562
- kind: z31.enum(["all", "cron", "uptime", "slo"]).default("all"),
5563
- project_id: z31.number().int().positive().optional(),
5564
- limit: z31.number().int().min(1).max(200).default(50)
5662
+ input: z32.object({
5663
+ kind: z32.enum(["all", "cron", "uptime", "slo"]).default("all"),
5664
+ project_id: z32.number().int().positive().optional(),
5665
+ limit: z32.number().int().min(1).max(200).default(50)
5565
5666
  }),
5566
5667
  async run(args, rt) {
5567
5668
  const kinds = args["kind"] && args["kind"] !== "all" ? [args["kind"]] : ["cron", "uptime", "slo"];
@@ -5596,10 +5697,10 @@ var MCP_TOOL_DEFS = [
5596
5697
  "monitors.occurrences",
5597
5698
  "monitors.backtest"
5598
5699
  ],
5599
- input: z31.object({
5600
- kind: z31.enum(["cron", "uptime", "slo"]),
5601
- id: z31.guid(),
5602
- backtest: z31.boolean().default(false)
5700
+ input: z32.object({
5701
+ kind: z32.enum(["cron", "uptime", "slo"]),
5702
+ id: z32.guid(),
5703
+ backtest: z32.boolean().default(false)
5603
5704
  }),
5604
5705
  async run(args, rt) {
5605
5706
  const k = MONITOR_KINDS2[args["kind"]];
@@ -5659,9 +5760,9 @@ var MCP_TOOL_DEFS = [
5659
5760
  title: "Send a test event",
5660
5761
  description: "Asks the node to send one tagged test error through the public intake of a project, proving the path real errors take. Not read-only: it creates one test event (reuse idempotency_key to retry without a second one).",
5661
5762
  operations: ["projects.send_test_event"],
5662
- input: z31.object({
5663
- project_id: z31.number().int().positive(),
5664
- idempotency_key: z31.string().min(8).max(255).optional()
5763
+ input: z32.object({
5764
+ project_id: z32.number().int().positive(),
5765
+ idempotency_key: z32.string().min(8).max(255).optional()
5665
5766
  }),
5666
5767
  async run(args, rt) {
5667
5768
  const r = await rt.call("projects.send_test_event", { project_id: args["project_id"] }, { idempotencyKey: args["idempotency_key"] ?? rt.newKey() });
@@ -5679,9 +5780,9 @@ var MCP_TOOL_DEFS = [
5679
5780
  title: "Find a configuration change",
5680
5781
  description: "Searches what this token can change in its Belvador workspace: projects, keys and tokens, monitors of every type, maintenance windows, occurrences, uptime checks, SLOs, alert rules and destinations, members, service accounts and the node. Returns operation ids for describe_operation and plan_change, whether a person must approve the change, and whether this token holds the scope.",
5681
5782
  operations: [],
5682
- input: z31.object({
5683
- query: z31.string().min(1).max(200).describe("Words such as `rotate dsn key`, `heartbeat monitor`, `slack alert`."),
5684
- limit: z31.number().int().min(1).max(20).default(10)
5783
+ input: z32.object({
5784
+ query: z32.string().min(1).max(200).describe("Words such as `rotate dsn key`, `heartbeat monitor`, `slack alert`."),
5785
+ limit: z32.number().int().min(1).max(20).default(10)
5685
5786
  }),
5686
5787
  async run(args, rt) {
5687
5788
  const q = words(String(args["query"]));
@@ -5709,7 +5810,7 @@ var MCP_TOOL_DEFS = [
5709
5810
  title: "Describe a configuration change",
5710
5811
  description: "Everything needed to call one operation: its fields (JSON Schema, wire names), the scope, whether it needs If-Match (call plan_change for the current ETag), an idempotency key, or a person's approval, and which fields the approving person types on belvador.dev instead of the agent.",
5711
5812
  operations: [],
5712
- input: z31.object({ operation_id: operationIdArg }),
5813
+ input: z32.object({ operation_id: operationIdArg }),
5713
5814
  async run(args, rt) {
5714
5815
  const op = configureOp(args["operation_id"]);
5715
5816
  if (!op || op.method === "GET")
@@ -5738,7 +5839,7 @@ var MCP_TOOL_DEFS = [
5738
5839
  title: "Check a change before applying it",
5739
5840
  description: "Validates params for one operation without changing anything: field errors, missing scope, whether a person must approve, and — when the resource can be read — its current state, the fields that would change and the ETag to pass as if_match.",
5740
5841
  operations: [],
5741
- input: z31.object({ operation_id: operationIdArg, params }),
5842
+ input: z32.object({ operation_id: operationIdArg, params }),
5742
5843
  async run(args, rt) {
5743
5844
  const op = configureOp(args["operation_id"]);
5744
5845
  if (!op || op.method === "GET")
@@ -5787,11 +5888,11 @@ var MCP_TOOL_DEFS = [
5787
5888
  title: "Apply a configuration change",
5788
5889
  description: "Runs one operation with params (validate first with plan_change). Always send idempotency_key: repeating a call with the same key never applies it twice. Sensitive operations answer approval_required with an approval_url a person opens on belvador.dev; nothing changes until they approve with their authenticator code.",
5789
5890
  operations: [],
5790
- input: z31.object({
5891
+ input: z32.object({
5791
5892
  operation_id: operationIdArg,
5792
5893
  params,
5793
- idempotency_key: z31.string().min(8).max(255).describe("Unique per change; reuse it to retry or to fetch the result."),
5794
- if_match: z31.string().max(200).optional().describe("ETag from plan_change, for operations that need it.")
5894
+ idempotency_key: z32.string().min(8).max(255).describe("Unique per change; reuse it to retry or to fetch the result."),
5895
+ if_match: z32.string().max(200).optional().describe("ETag from plan_change, for operations that need it.")
5795
5896
  }),
5796
5897
  async run(args, rt) {
5797
5898
  const op = configureOp(args["operation_id"]);
@@ -5852,7 +5953,7 @@ var MCP_TOOL_DEFS = [
5852
5953
  title: "Follow an approval",
5853
5954
  description: "State of a change waiting for a person's approval: pending, approved, executed (with the ids it produced), rejected, expired or failed (with the error code).",
5854
5955
  operations: ["approvals.get"],
5855
- input: z31.object({ approval_id: z31.guid().describe("approval_id from apply_change.") }),
5956
+ input: z32.object({ approval_id: z32.guid().describe("approval_id from apply_change.") }),
5856
5957
  async run(args, rt) {
5857
5958
  const r = await rt.call("approvals.get", { approval_id: args["approval_id"] });
5858
5959
  if (!r.ok)
@@ -5872,10 +5973,10 @@ var MCP_TOOL_DEFS = [
5872
5973
  title: "Search Belvador docs",
5873
5974
  description: "Searches the public Belvador documentation (titles and summaries) and returns the best pages with their slugs for get_doc.",
5874
5975
  operations: [],
5875
- input: z31.object({
5876
- query: z31.string().min(1).max(200),
5877
- locale: z31.enum(["en", "vi"]).default("en"),
5878
- limit: z31.number().int().min(1).max(10).default(5)
5976
+ input: z32.object({
5977
+ query: z32.string().min(1).max(200),
5978
+ locale: z32.enum(["en", "vi"]).default("en"),
5979
+ limit: z32.number().int().min(1).max(10).default(5)
5879
5980
  }),
5880
5981
  async run(args, rt) {
5881
5982
  const locale = args["locale"] ?? "en";
@@ -5891,9 +5992,9 @@ var MCP_TOOL_DEFS = [
5891
5992
  title: "Read a docs page",
5892
5993
  description: "The Markdown of one public Belvador docs page by slug (e.g. `quickstart`, `sdk/react`, `reference/api`).",
5893
5994
  operations: [],
5894
- input: z31.object({
5895
- slug: z31.string().regex(/^[a-z0-9][a-z0-9/-]{0,120}$/),
5896
- locale: z31.enum(["en", "vi"]).default("en")
5995
+ input: z32.object({
5996
+ slug: z32.string().regex(/^[a-z0-9][a-z0-9/-]{0,120}$/),
5997
+ locale: z32.enum(["en", "vi"]).default("en")
5897
5998
  }),
5898
5999
  async run(args, rt) {
5899
6000
  const locale = args["locale"] ?? "en";
@@ -6087,7 +6188,7 @@ function findToken(env = process.env, keychain = keychainToken) {
6087
6188
  }
6088
6189
 
6089
6190
  // packages/mcp/src/cli.ts
6090
- var PACKAGE_VERSION = "0.6.0";
6191
+ var PACKAGE_VERSION = "0.7.1";
6091
6192
  var HELP = `belvador-mcp ${PACKAGE_VERSION} — Belvador MCP server (stdio)
6092
6193
 
6093
6194
  Usage: npx -y @belvador/mcp [--toolsets=${MCP_DEFAULT_TOOLSETS.join(",")}]