@belvador/mcp 0.4.0 → 0.6.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.
Files changed (2) hide show
  1. package/dist/cli.js +1749 -954
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -182,7 +182,7 @@ function cleanUntrustedText(raw, maxBytes = MCP_LIMITS.untrustedStringMaxBytes)
182
182
  const { text, cut } = cutUtf8(escaped, maxBytes);
183
183
  return { text, cut, suspicious };
184
184
  }
185
- var MCP_TOOLS_VERSION = 4;
185
+ var MCP_TOOLS_VERSION = 6;
186
186
  var MCP_TOOLS = [
187
187
  { name: "get_workspace", toolset: "investigate", scope: "org:read", readOnly: true, destructive: false, idempotent: true },
188
188
  { name: "list_projects", toolset: "investigate", scope: "projects:read", readOnly: true, destructive: false, idempotent: true },
@@ -211,10 +211,7 @@ var MCP_TOOLS = [
211
211
  { name: "search_docs", toolset: "docs", scope: null, readOnly: true, destructive: false, idempotent: true },
212
212
  { name: "get_doc", toolset: "docs", scope: null, readOnly: true, destructive: false, idempotent: true }
213
213
  ];
214
- var MCP_TOOLS_PENDING = {
215
- query_metrics: "P14",
216
- release_health: "P15"
217
- };
214
+ var MCP_TOOLS_PENDING = {};
218
215
 
219
216
  // ../src/shared/mcp/docs.ts
220
217
  var DOCS_MAX_BYTES = 512 * 1024;
@@ -258,7 +255,7 @@ function docsFetcher(siteUrl, fetcher = fetch, now = () => Date.now()) {
258
255
  import { CLIENT_CAPABILITIES_META_KEY, inputRequired, McpServer } from "@modelcontextprotocol/server";
259
256
 
260
257
  // ../src/shared/contracts/mcp-tools.ts
261
- import { z as z28 } from "zod";
258
+ import { z as z31 } from "zod";
262
259
 
263
260
  // ../src/shared/contracts/api-ops/access.ts
264
261
  import { z as z3 } from "zod";
@@ -646,7 +643,8 @@ var MONITOR_RULE_KINDS = [
646
643
  "count",
647
644
  "assertion",
648
645
  "deadline",
649
- "stalled"
646
+ "stalled",
647
+ "metric"
650
648
  ];
651
649
  var SLO_RULE_SEVERITIES = ["page", "ticket"];
652
650
  function validRuleTriggers(triggers) {
@@ -1149,10 +1147,10 @@ var COVERAGE_OPERATIONS = [
1149
1147
  ];
1150
1148
 
1151
1149
  // ../src/shared/contracts/api-ops/incidents.ts
1152
- import { z as z13 } from "zod";
1150
+ import { z as z14 } from "zod";
1153
1151
 
1154
1152
  // ../src/shared/contracts/notifications.ts
1155
- import { z as z12 } from "zod";
1153
+ import { z as z13 } from "zod";
1156
1154
 
1157
1155
  // ../src/shared/contracts/maintenance.ts
1158
1156
  import { z as z9 } from "zod";
@@ -1211,15 +1209,182 @@ function validTimeZone(tz) {
1211
1209
  var fmtCache = new Map;
1212
1210
 
1213
1211
  // ../src/shared/contracts/signal-monitors.ts
1214
- import { z as z11 } from "zod";
1212
+ import { z as z12 } from "zod";
1215
1213
 
1216
- // ../src/shared/contracts/monitors.ts
1214
+ // ../src/shared/contracts/metrics.ts
1217
1215
  import { z as z10 } from "zod";
1218
1216
 
1217
+ // ../src/shared/contracts/vocab/telemetry.ts
1218
+ var TELEMETRY_MAX_WINDOW_MS = 7 * 24 * 3600 * 1000;
1219
+ var ATTR_OPS = ["=", "!=", "exists"];
1220
+ var ATTR_FILTERS_MAX = 5;
1221
+ var TELEMETRY_PLAN_DEFAULTS = {
1222
+ traces_retention_days: 7,
1223
+ logs_retention_days: 7,
1224
+ traces_monthly_bytes: 5 * 1000 ** 3,
1225
+ logs_monthly_bytes: 5 * 1000 ** 3,
1226
+ metrics_retention_days: 14,
1227
+ metrics_monthly_bytes: 2 * 1000 ** 3,
1228
+ metric_series_max: 1e4,
1229
+ metric_names_max: 1000,
1230
+ telemetry_rate_bytes_per_sec: 1024 * 1024,
1231
+ telemetry_burst_bytes: 8 * 1024 * 1024,
1232
+ telemetry_buffer_minutes: 15,
1233
+ max_ingest_keys_per_project: 10
1234
+ };
1235
+
1236
+ // ../src/shared/contracts/vocab/metrics.ts
1237
+ var METRIC_TYPES = ["gauge", "sum", "histogram", "exp_histogram"];
1238
+ var METRIC_KINDS = ["gauge", "counter", "histogram", "exp_histogram"];
1239
+ var METRIC_AGGREGATIONS = ["avg", "sum", "min", "max", "count", "rate", "p50", "p90", "p95", "p99"];
1240
+ var METRIC_NAME_RE = /^[A-Za-z_][A-Za-z0-9_.:\-/]{0,254}$/;
1241
+ var METRIC_ATTR_KEY_RE = /^[A-Za-z0-9_.:\-/@]{1,256}$/;
1242
+ var METRIC_GROUP_BY_MAX = 2;
1243
+ function defaultAggregation(kind) {
1244
+ return kind === "counter" ? "rate" : kind === "histogram" || kind === "exp_histogram" ? "p95" : "avg";
1245
+ }
1246
+
1247
+ // ../src/shared/contracts/metrics.ts
1248
+ var METRIC_TEMPORALITIES = ["unspecified", "delta", "cumulative"];
1249
+ var METRIC_LIMITS = {
1250
+ attributesPerSeries: 32,
1251
+ attributeValueMaxChars: 256,
1252
+ nameMaxChars: 255,
1253
+ unitMaxChars: 63,
1254
+ descriptionMaxChars: 512,
1255
+ bucketsMax: 320,
1256
+ seriesActiveMs: 24 * 3600 * 1000,
1257
+ seriesTouchMs: 3600 * 1000,
1258
+ expMaxStoredScale: 3,
1259
+ expMinScale: -10,
1260
+ expMaxScale: 20,
1261
+ resourceKeys: ["service.name", "service.namespace", "deployment.environment.name", "host.name"],
1262
+ limitedNamesKept: 50
1263
+ };
1264
+ var METRIC_PLAN_DEFAULTS = {
1265
+ metrics_retention_days: TELEMETRY_PLAN_DEFAULTS.metrics_retention_days,
1266
+ metrics_monthly_bytes: TELEMETRY_PLAN_DEFAULTS.metrics_monthly_bytes,
1267
+ metric_series_max: TELEMETRY_PLAN_DEFAULTS.metric_series_max,
1268
+ metric_names_max: TELEMETRY_PLAN_DEFAULTS.metric_names_max
1269
+ };
1270
+ var METRIC_SERIES_MAX_RANGE = { min: 100, max: 1e6 };
1271
+ var METRIC_NAMES_MAX_RANGE = { min: 10, max: 1e5 };
1272
+ var metricsConfigSchema = z10.object({
1273
+ retention_days: z10.number().int().min(1).max(90),
1274
+ series_max: z10.number().int().min(METRIC_SERIES_MAX_RANGE.min).max(METRIC_SERIES_MAX_RANGE.max),
1275
+ names_max: z10.number().int().min(METRIC_NAMES_MAX_RANGE.min).max(METRIC_NAMES_MAX_RANGE.max)
1276
+ });
1277
+ var METRIC_QUERY = {
1278
+ filtersMax: ATTR_FILTERS_MAX,
1279
+ groupByMax: METRIC_GROUP_BY_MAX,
1280
+ minStepSeconds: 60,
1281
+ maxStepSeconds: 86400,
1282
+ maxWindowMs: 7 * 24 * 3600 * 1000,
1283
+ defaultWindowMs: 3600 * 1000,
1284
+ groupsMax: 50,
1285
+ pointsMax: 1e4,
1286
+ namesMax: 1000,
1287
+ seriesPageSize: 100,
1288
+ exemplarsMax: 50,
1289
+ queryMaxSeconds: 3
1290
+ };
1291
+ var metricName = z10.string().min(1).max(METRIC_LIMITS.nameMaxChars).regex(METRIC_NAME_RE);
1292
+ var attrKey = z10.string().regex(METRIC_ATTR_KEY_RE);
1293
+ var metricFilterSchema = z10.object({
1294
+ k: attrKey,
1295
+ op: z10.enum(ATTR_OPS),
1296
+ v: z10.string().max(512).optional()
1297
+ });
1298
+ var metricQuerySchema = z10.object({
1299
+ name: metricName,
1300
+ aggregation: z10.enum(METRIC_AGGREGATIONS),
1301
+ filter: z10.array(metricFilterSchema).max(METRIC_QUERY.filtersMax),
1302
+ group_by: z10.array(attrKey).max(METRIC_QUERY.groupByMax)
1303
+ }).superRefine((q, ctx) => {
1304
+ q.filter.forEach((f, i) => {
1305
+ if (f.op === "exists" !== (f.v === undefined))
1306
+ ctx.addIssue({ code: "custom", path: ["filter", i, "v"], message: "value" });
1307
+ });
1308
+ if (new Set(q.group_by).size !== q.group_by.length)
1309
+ ctx.addIssue({ code: "custom", path: ["group_by"], message: "unique" });
1310
+ });
1311
+ var ts = z10.string().max(40);
1312
+ var count2 = z10.coerce.number().int().nonnegative().catch(0);
1313
+ var label = z10.string().max(METRIC_LIMITS.attributeValueMaxChars);
1314
+ var completeness = {
1315
+ complete: z10.boolean(),
1316
+ reason: z10.enum(["time_budget", "row_cap", "groups", "points"]).optional().catch(undefined)
1317
+ };
1318
+ var metricNameRowSchema = z10.object({
1319
+ name: metricName,
1320
+ type: z10.enum(METRIC_TYPES),
1321
+ kind: z10.enum(METRIC_KINDS),
1322
+ unit: z10.string().max(METRIC_LIMITS.unitMaxChars).catch(""),
1323
+ description: z10.string().max(METRIC_LIMITS.descriptionMaxChars).catch(""),
1324
+ series: count2,
1325
+ last_seen: ts
1326
+ });
1327
+ var metricCardinalitySchema = z10.object({
1328
+ series_active: count2,
1329
+ series_max: count2,
1330
+ names_active: count2,
1331
+ names_max: count2,
1332
+ limited: z10.array(z10.object({ name: z10.string().max(METRIC_LIMITS.nameMaxChars), points: count2 })).max(METRIC_LIMITS.limitedNamesKept).catch([])
1333
+ });
1334
+ var metricNamesSchema = z10.object({
1335
+ names: z10.array(metricNameRowSchema).max(METRIC_QUERY.namesMax),
1336
+ cardinality: metricCardinalitySchema,
1337
+ ...completeness
1338
+ });
1339
+ var metricSeriesRowSchema = z10.object({
1340
+ series_id: z10.string().regex(/^[0-9a-f]{16}$/),
1341
+ name: metricName,
1342
+ type: z10.enum(METRIC_TYPES),
1343
+ kind: z10.enum(METRIC_KINDS),
1344
+ temporality: z10.enum(METRIC_TEMPORALITIES).catch("unspecified"),
1345
+ unit: z10.string().max(METRIC_LIMITS.unitMaxChars).catch(""),
1346
+ service: label.catch(""),
1347
+ environment: z10.string().max(64).catch(""),
1348
+ attributes: z10.record(z10.string().max(256), label).catch({}),
1349
+ first_seen: ts,
1350
+ last_seen: ts
1351
+ });
1352
+ var metricSeriesListSchema = z10.object({
1353
+ series: z10.array(metricSeriesRowSchema).max(METRIC_QUERY.seriesPageSize),
1354
+ next_cursor: z10.string().max(64).nullable(),
1355
+ ...completeness
1356
+ });
1357
+ var metricExemplarSchema = z10.object({
1358
+ t: ts,
1359
+ value: z10.number(),
1360
+ trace_id: z10.string().regex(/^[0-9a-f]{32}$/),
1361
+ span_id: z10.union([z10.string().regex(/^[0-9a-f]{16}$/), z10.literal("")]),
1362
+ group: z10.number().int().nonnegative()
1363
+ });
1364
+ var metricResultSchema = z10.object({
1365
+ name: metricName,
1366
+ aggregation: z10.enum(METRIC_AGGREGATIONS),
1367
+ kind: z10.enum(METRIC_KINDS),
1368
+ unit: z10.string().max(METRIC_LIMITS.unitMaxChars).catch(""),
1369
+ step_seconds: z10.number().int().positive(),
1370
+ from: ts,
1371
+ to: ts,
1372
+ groups: z10.array(z10.object({
1373
+ key: z10.record(z10.string().max(256), label),
1374
+ points: z10.array(z10.object({ t: ts, v: z10.number().nullable() })).max(METRIC_QUERY.pointsMax)
1375
+ })).max(METRIC_QUERY.groupsMax),
1376
+ exemplars: z10.array(metricExemplarSchema).max(METRIC_QUERY.exemplarsMax).catch([]),
1377
+ ...completeness
1378
+ });
1379
+ var HIST_OVERFLOW = Number.MAX_VALUE;
1380
+
1381
+ // ../src/shared/contracts/monitors.ts
1382
+ import { z as z11 } from "zod";
1383
+
1219
1384
  // ../src/shared/contracts/vocab/monitors.ts
1220
1385
  var MONITOR_MODES = ["check_in", "heartbeat"];
1221
- var MONITOR_TYPES = ["job", "count", "assertion", "deadline", "progress"];
1222
- var SIGNAL_MONITOR_TYPES = ["count", "assertion", "deadline", "progress"];
1386
+ var MONITOR_TYPES = ["job", "count", "assertion", "deadline", "progress", "metric"];
1387
+ var SIGNAL_MONITOR_TYPES = ["count", "assertion", "deadline", "progress", "metric"];
1223
1388
 
1224
1389
  // ../src/shared/contracts/monitors.ts
1225
1390
  var MONITOR_KINDS = ["crontab", "interval", "on_demand"];
@@ -1233,7 +1398,8 @@ var MONITOR_INCIDENT_CODES = [
1233
1398
  "MONITOR_COUNT",
1234
1399
  "MONITOR_ASSERTION",
1235
1400
  "MONITOR_DEADLINE_MISSED",
1236
- "MONITOR_STALLED"
1401
+ "MONITOR_STALLED",
1402
+ "MONITOR_METRIC"
1237
1403
  ];
1238
1404
  var FAILURE_INCIDENT_CODES = MONITOR_INCIDENT_CODES.filter((c) => c !== "MONITOR_UNKNOWN");
1239
1405
  var INCIDENT_EVENTS = ["opened", "updated", "resolved"];
@@ -1286,112 +1452,114 @@ function crontabShapeOk(value) {
1286
1452
  const fields = value.trim().split(/\s+/);
1287
1453
  return value.length <= 120 && fields.length === 5 && fields.every((f) => /^[0-9A-Za-z*,/?#LW-]+$/.test(f));
1288
1454
  }
1289
- var crontabScheduleSchema = z10.object({
1290
- type: z10.literal("crontab"),
1291
- value: z10.string().refine(crontabShapeOk, "crontab")
1455
+ var crontabScheduleSchema = z11.object({
1456
+ type: z11.literal("crontab"),
1457
+ value: z11.string().refine(crontabShapeOk, "crontab")
1292
1458
  });
1293
- var intervalScheduleSchema = z10.object({
1294
- type: z10.literal("interval"),
1295
- value: z10.number().int().min(1).max(MONITOR_LIMITS.intervalValueMax),
1296
- unit: z10.enum(INTERVAL_UNITS)
1459
+ var intervalScheduleSchema = z11.object({
1460
+ type: z11.literal("interval"),
1461
+ value: z11.number().int().min(1).max(MONITOR_LIMITS.intervalValueMax),
1462
+ unit: z11.enum(INTERVAL_UNITS)
1297
1463
  });
1298
- var scheduleSchema = z10.discriminatedUnion("type", [
1464
+ var scheduleSchema = z11.discriminatedUnion("type", [
1299
1465
  crontabScheduleSchema,
1300
1466
  intervalScheduleSchema
1301
1467
  ]);
1302
- var monitorSettingsSchema = z10.object({
1468
+ var monitorSettingsSchema = z11.object({
1303
1469
  schedule: scheduleSchema.nullable(),
1304
- timezone: z10.string().min(1).max(64),
1305
- checkin_margin: z10.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
1306
- max_runtime: z10.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
1307
- failure_issue_threshold: z10.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1308
- recovery_threshold: z10.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax)
1470
+ timezone: z11.string().min(1).max(64),
1471
+ checkin_margin: z11.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
1472
+ max_runtime: z11.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
1473
+ failure_issue_threshold: z11.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1474
+ recovery_threshold: z11.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax)
1309
1475
  });
1310
- var iso3 = z10.string().datetime();
1311
- var projectId3 = z10.number().int().positive();
1312
- var envName = z10.string().min(1).max(MONITOR_LIMITS.environmentMax);
1476
+ var iso3 = z11.string().datetime();
1477
+ var projectId3 = z11.number().int().positive();
1478
+ var envName = z11.string().min(1).max(MONITOR_LIMITS.environmentMax);
1313
1479
  var monitorDefinitionSchema = monitorSettingsSchema.extend({
1314
- id: z10.guid(),
1480
+ id: z11.guid(),
1315
1481
  project_id: projectId3,
1316
- slug: z10.string().regex(SLUG_RE),
1317
- kind: z10.enum(MONITOR_KINDS),
1318
- expected_environments: z10.array(envName).max(MONITOR_LIMITS.expectedEnvironmentsMax),
1482
+ slug: z11.string().regex(SLUG_RE),
1483
+ kind: z11.enum(MONITOR_KINDS),
1484
+ expected_environments: z11.array(envName).max(MONITOR_LIMITS.expectedEnvironmentsMax),
1319
1485
  paused_until: iso3.nullable(),
1320
1486
  created_at: iso3,
1321
- config_source: z10.enum(CONFIG_SOURCES),
1322
- config_hash: z10.string().regex(/^[0-9a-f]{64}$/).nullable()
1487
+ config_source: z11.enum(CONFIG_SOURCES),
1488
+ config_hash: z11.string().regex(/^[0-9a-f]{64}$/).nullable()
1323
1489
  });
1324
- var outcomeCounts = z10.object({
1325
- ok: z10.number().int().nonnegative(),
1326
- skipped: z10.number().int().nonnegative(),
1327
- error: z10.number().int().nonnegative(),
1328
- timeout: z10.number().int().nonnegative(),
1329
- missed: z10.number().int().nonnegative(),
1330
- unknown: z10.number().int().nonnegative()
1490
+ var outcomeCounts = z11.object({
1491
+ ok: z11.number().int().nonnegative(),
1492
+ skipped: z11.number().int().nonnegative(),
1493
+ error: z11.number().int().nonnegative(),
1494
+ timeout: z11.number().int().nonnegative(),
1495
+ missed: z11.number().int().nonnegative(),
1496
+ unknown: z11.number().int().nonnegative()
1331
1497
  });
1332
- var signalStatusSchema = z10.object({
1333
- type: z10.enum(SIGNAL_MONITOR_TYPES),
1334
- value: z10.number().int().nonnegative().max(1e9).nullable(),
1335
- threshold: z10.number().int().nonnegative().max(1e9).nullable(),
1498
+ var MONITOR_NUMBER_MAX = 1000000000000000;
1499
+ var monitorNumber = z11.number().finite().min(-MONITOR_NUMBER_MAX).max(MONITOR_NUMBER_MAX);
1500
+ var signalStatusSchema = z11.object({
1501
+ type: z11.enum(SIGNAL_MONITOR_TYPES),
1502
+ value: monitorNumber.nullable(),
1503
+ threshold: monitorNumber.nullable(),
1336
1504
  window_end: iso3.nullable(),
1337
- pending: z10.number().int().nonnegative().max(1e6).nullable(),
1338
- stalled: z10.number().int().nonnegative().max(1e6).nullable(),
1339
- refused_24h: z10.number().int().nonnegative().max(1e9).nullable()
1505
+ pending: z11.number().int().nonnegative().max(1e6).nullable(),
1506
+ stalled: z11.number().int().nonnegative().max(1e6).nullable(),
1507
+ refused_24h: z11.number().int().nonnegative().max(1e9).nullable()
1340
1508
  });
1341
- var monitorStatusSchema = z10.object({
1342
- monitor_id: z10.guid(),
1509
+ var monitorStatusSchema = z11.object({
1510
+ monitor_id: z11.guid(),
1343
1511
  project_id: projectId3,
1344
1512
  environment: envName,
1345
- open_failure: z10.enum(FAILURE_INCIDENT_CODES).nullable(),
1346
- open_unknown: z10.boolean(),
1347
- unobservable: z10.enum(UNOBSERVABLE_REASONS).nullable(),
1348
- last_outcome: z10.enum(RUN_OUTCOMES).nullable(),
1513
+ open_failure: z11.enum(FAILURE_INCIDENT_CODES).nullable(),
1514
+ open_unknown: z11.boolean(),
1515
+ unobservable: z11.enum(UNOBSERVABLE_REASONS).nullable(),
1516
+ last_outcome: z11.enum(RUN_OUTCOMES).nullable(),
1349
1517
  last_check_in_at: iso3.nullable(),
1350
1518
  last_healthy_at: iso3.nullable(),
1351
1519
  next_deadline_at: iso3.nullable(),
1352
1520
  next_due_at: iso3.nullable().optional(),
1353
- in_progress: z10.boolean(),
1521
+ in_progress: z11.boolean(),
1354
1522
  counts_24h: outcomeCounts,
1355
1523
  signal: signalStatusSchema.optional(),
1356
1524
  evaluated_at: iso3
1357
1525
  });
1358
- var monitorIncidentSchema = z10.object({
1359
- incident_id: z10.guid(),
1360
- monitor_id: z10.guid(),
1526
+ var monitorIncidentSchema = z11.object({
1527
+ incident_id: z11.guid(),
1528
+ monitor_id: z11.guid(),
1361
1529
  project_id: projectId3,
1362
1530
  environment: envName,
1363
- code: z10.enum(MONITOR_INCIDENT_CODES),
1364
- event: z10.enum(INCIDENT_EVENTS),
1531
+ code: z11.enum(MONITOR_INCIDENT_CODES),
1532
+ event: z11.enum(INCIDENT_EVENTS),
1365
1533
  occurred_at: iso3,
1366
- detected_late: z10.boolean(),
1367
- reason: z10.string().regex(REASON_RE).nullable(),
1368
- duration_ms: z10.number().int().nonnegative().nullable(),
1369
- consecutive: z10.number().int().min(1).max(1e5),
1370
- reviewed_by: z10.guid().nullable(),
1371
- observed: z10.number().int().min(0).max(1e9).nullable().optional(),
1372
- threshold: z10.number().int().min(0).max(1e9).nullable().optional()
1534
+ detected_late: z11.boolean(),
1535
+ reason: z11.string().regex(REASON_RE).nullable(),
1536
+ duration_ms: z11.number().int().nonnegative().nullable(),
1537
+ consecutive: z11.number().int().min(1).max(1e5),
1538
+ reviewed_by: z11.guid().nullable(),
1539
+ observed: monitorNumber.nullable().optional(),
1540
+ threshold: monitorNumber.nullable().optional()
1373
1541
  });
1374
- var monitorDiscoverySchema = z10.object({
1542
+ var monitorDiscoverySchema = z11.object({
1375
1543
  project_id: projectId3,
1376
- slug: z10.string().regex(SLUG_RE),
1544
+ slug: z11.string().regex(SLUG_RE),
1377
1545
  settings: monitorSettingsSchema.nullable(),
1378
- config_hash: z10.string().regex(/^[0-9a-f]{64}$/).nullable(),
1379
- check_ins: z10.number().int().nonnegative(),
1546
+ config_hash: z11.string().regex(/^[0-9a-f]{64}$/).nullable(),
1547
+ check_ins: z11.number().int().nonnegative(),
1380
1548
  last_seen_at: iso3
1381
1549
  });
1382
1550
  var MONITOR_NAME_MAX = MONITOR_LIMITS.nameMax;
1383
- var environmentName = z10.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/);
1384
- var monitorInputSchema = z10.object({
1385
- name: z10.string().trim().min(1).max(MONITOR_LIMITS.nameMax),
1386
- mode: z10.enum(MONITOR_MODES).default("check_in"),
1387
- kind: z10.enum(MONITOR_KINDS),
1551
+ var environmentName = z11.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/);
1552
+ var monitorInputSchema = z11.object({
1553
+ name: z11.string().trim().min(1).max(MONITOR_LIMITS.nameMax),
1554
+ mode: z11.enum(MONITOR_MODES).default("check_in"),
1555
+ kind: z11.enum(MONITOR_KINDS),
1388
1556
  schedule: scheduleSchema.nullable(),
1389
- timezone: z10.string().trim().min(1).max(64),
1390
- checkinMarginMin: z10.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
1391
- maxRuntimeMin: z10.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
1392
- failureThreshold: z10.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1393
- recoveryThreshold: z10.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1394
- expectedEnvironments: z10.array(environmentName).min(1).max(MONITOR_LIMITS.expectedEnvironmentsMax)
1557
+ timezone: z11.string().trim().min(1).max(64),
1558
+ checkinMarginMin: z11.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
1559
+ maxRuntimeMin: z11.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
1560
+ failureThreshold: z11.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1561
+ recoveryThreshold: z11.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
1562
+ expectedEnvironments: z11.array(environmentName).min(1).max(MONITOR_LIMITS.expectedEnvironmentsMax)
1395
1563
  }).refine((v) => v.kind === "on_demand" ? v.schedule === null : v.schedule?.type === v.kind, {
1396
1564
  path: ["schedule"],
1397
1565
  message: "schedule"
@@ -1406,88 +1574,88 @@ var MONITOR_INPUT_DEFAULTS = {
1406
1574
  recoveryThreshold: MONITOR_LIMITS.recoveryThresholdDefault,
1407
1575
  expectedEnvironments: [DEFAULT_CHECK_IN_ENVIRONMENT]
1408
1576
  };
1409
- var runOutcome = z10.enum(RUN_OUTCOMES);
1410
- var runFlags = z10.array(z10.string().max(32)).max(16);
1411
- var monitorRunSchema = z10.object({
1412
- id: z10.number().int().positive(),
1413
- kind: z10.enum(["run", "missed"]),
1577
+ var runOutcome = z11.enum(RUN_OUTCOMES);
1578
+ var runFlags = z11.array(z11.string().max(32)).max(16);
1579
+ var monitorRunSchema = z11.object({
1580
+ id: z11.number().int().positive(),
1581
+ kind: z11.enum(["run", "missed"]),
1414
1582
  outcome: runOutcome,
1415
1583
  started_at: iso3,
1416
1584
  ended_at: iso3,
1417
- attempts: z10.number().int().nonnegative(),
1418
- duration_ms: z10.number().int().nonnegative().nullable(),
1419
- reason: z10.string().max(64).nullable(),
1420
- check_in_id: z10.string().max(64).nullable(),
1421
- trace_id: z10.string().max(32).nullable(),
1422
- release: z10.string().max(MONITOR_LIMITS.releaseMax).nullable(),
1585
+ attempts: z11.number().int().nonnegative(),
1586
+ duration_ms: z11.number().int().nonnegative().nullable(),
1587
+ reason: z11.string().max(64).nullable(),
1588
+ check_in_id: z11.string().max(64).nullable(),
1589
+ trace_id: z11.string().max(32).nullable(),
1590
+ release: z11.string().max(MONITOR_LIMITS.releaseMax).nullable(),
1423
1591
  flags: runFlags
1424
1592
  });
1425
- var openAttemptSchema = z10.object({
1426
- check_in_id: z10.string().max(64),
1427
- run_key: z10.string().max(64),
1428
- attempt: z10.number().int().nonnegative(),
1429
- state: z10.string().max(16),
1593
+ var openAttemptSchema = z11.object({
1594
+ check_in_id: z11.string().max(64),
1595
+ run_key: z11.string().max(64),
1596
+ attempt: z11.number().int().nonnegative(),
1597
+ state: z11.string().max(16),
1430
1598
  started_at: iso3,
1431
1599
  deadline_at: iso3
1432
1600
  });
1433
- var monitorRunsResponseSchema = z10.object({
1434
- open: z10.array(openAttemptSchema).max(100),
1435
- runs: z10.array(monitorRunSchema).max(MONITOR_LIMITS.runsPageSize),
1436
- next_cursor: z10.string().max(32).nullable()
1601
+ var monitorRunsResponseSchema = z11.object({
1602
+ open: z11.array(openAttemptSchema).max(100),
1603
+ runs: z11.array(monitorRunSchema).max(MONITOR_LIMITS.runsPageSize),
1604
+ next_cursor: z11.string().max(32).nullable()
1437
1605
  });
1438
- var timelineRunSchema = z10.object({
1439
- id: z10.number().int().positive(),
1440
- kind: z10.enum(["run", "missed"]),
1606
+ var timelineRunSchema = z11.object({
1607
+ id: z11.number().int().positive(),
1608
+ kind: z11.enum(["run", "missed"]),
1441
1609
  outcome: runOutcome,
1442
1610
  ended_at: iso3,
1443
1611
  flags: runFlags
1444
1612
  });
1445
- var monitorTimelineResponseSchema = z10.object({
1446
- runs: z10.array(timelineRunSchema).max(MONITOR_LIMITS.timelineRuns)
1613
+ var monitorTimelineResponseSchema = z11.object({
1614
+ runs: z11.array(timelineRunSchema).max(MONITOR_LIMITS.timelineRuns)
1447
1615
  });
1448
- var monitorStripsResponseSchema = z10.object({
1449
- strips: z10.array(z10.object({
1450
- monitor_id: z10.guid(),
1616
+ var monitorStripsResponseSchema = z11.object({
1617
+ strips: z11.array(z11.object({
1618
+ monitor_id: z11.guid(),
1451
1619
  environment: envName,
1452
- runs: z10.array(timelineRunSchema).max(MONITOR_LIMITS.listStripRuns)
1620
+ runs: z11.array(timelineRunSchema).max(MONITOR_LIMITS.listStripRuns)
1453
1621
  })).max(5000)
1454
1622
  });
1455
- var monitorDiagnosticSchema = z10.object({
1456
- id: z10.string().regex(/^\d{1,19}$/),
1457
- check_in_id: z10.string().max(64).nullable(),
1458
- signal: z10.string().max(16),
1459
- exit_code: z10.number().int().min(0).max(255).nullable(),
1623
+ var monitorDiagnosticSchema = z11.object({
1624
+ id: z11.string().regex(/^\d{1,19}$/),
1625
+ check_in_id: z11.string().max(64).nullable(),
1626
+ signal: z11.string().max(16),
1627
+ exit_code: z11.number().int().min(0).max(255).nullable(),
1460
1628
  received_at: iso3,
1461
- body: z10.string().max(MONITOR_LIMITS.diagnosticMaxBytes * 2)
1629
+ body: z11.string().max(MONITOR_LIMITS.diagnosticMaxBytes * 2)
1462
1630
  });
1463
- var monitorDiagnosticsResponseSchema = z10.object({
1464
- diagnostics: z10.array(monitorDiagnosticSchema).max(50),
1465
- next_cursor: z10.string().regex(/^\d{1,19}$/).nullable()
1631
+ var monitorDiagnosticsResponseSchema = z11.object({
1632
+ diagnostics: z11.array(monitorDiagnosticSchema).max(50),
1633
+ next_cursor: z11.string().regex(/^\d{1,19}$/).nullable()
1466
1634
  });
1467
- var checkInDetailSchema = z10.object({
1468
- run_key: z10.string().max(64),
1469
- attempts: z10.array(z10.object({
1470
- check_in_id: z10.string().max(64),
1471
- attempt: z10.number().int().nonnegative(),
1472
- result: z10.string().max(16),
1635
+ var checkInDetailSchema = z11.object({
1636
+ run_key: z11.string().max(64),
1637
+ attempts: z11.array(z11.object({
1638
+ check_in_id: z11.string().max(64),
1639
+ attempt: z11.number().int().nonnegative(),
1640
+ result: z11.string().max(16),
1473
1641
  started_at: iso3,
1474
1642
  ended_at: iso3.nullable(),
1475
- duration_ms: z10.number().int().nonnegative().nullable(),
1476
- reason: z10.string().max(64).nullable(),
1477
- trace_id: z10.string().max(32).nullable(),
1478
- release: z10.string().max(MONITOR_LIMITS.releaseMax).nullable()
1643
+ duration_ms: z11.number().int().nonnegative().nullable(),
1644
+ reason: z11.string().max(64).nullable(),
1645
+ trace_id: z11.string().max(32).nullable(),
1646
+ release: z11.string().max(MONITOR_LIMITS.releaseMax).nullable()
1479
1647
  })).max(1000),
1480
- errors: z10.array(z10.object({
1481
- event_id: z10.string().max(64),
1482
- issue_id: z10.number().int().nonnegative(),
1483
- title: z10.string().max(1024),
1484
- level: z10.string().max(16),
1648
+ errors: z11.array(z11.object({
1649
+ event_id: z11.string().max(64),
1650
+ issue_id: z11.number().int().nonnegative(),
1651
+ title: z11.string().max(1024),
1652
+ level: z11.string().max(16),
1485
1653
  timestamp: iso3,
1486
- same_trace: z10.boolean()
1654
+ same_trace: z11.boolean()
1487
1655
  })).max(50),
1488
- diagnostics: z10.array(monitorDiagnosticSchema).max(20).default([])
1656
+ diagnostics: z11.array(monitorDiagnosticSchema).max(20).default([])
1489
1657
  });
1490
- var incidentReviewSchema = z10.object({ incident_id: z10.guid() });
1658
+ var incidentReviewSchema = z11.object({ incident_id: z11.guid() });
1491
1659
 
1492
1660
  // ../src/shared/contracts/signal-monitors.ts
1493
1661
  var isSignalMonitorType = (t) => SIGNAL_MONITOR_TYPES.includes(t);
@@ -1527,6 +1695,7 @@ var SIGNAL_LIMITS = {
1527
1695
  evaluateEverySeconds: 15,
1528
1696
  settleSeconds: 20,
1529
1697
  countMaxDelayMinutes: 10,
1698
+ metricDelaySeconds: 120,
1530
1699
  countMinutesPerTick: 60,
1531
1700
  windowsPerTick: 120,
1532
1701
  monitorsPerQuery: 50,
@@ -1540,11 +1709,11 @@ var SIGNAL_LIMITS = {
1540
1709
  queryMaxSeconds: 5
1541
1710
  };
1542
1711
  var SELECTOR_KEY_RE = /^(?:tags\.[A-Za-z0-9_.:-]{1,100}|[A-Za-z_][A-Za-z0-9_.:-]{0,127})$/;
1543
- var scalar = z11.union([z11.string().max(SIGNAL_LIMITS.valueMax), z11.number().finite(), z11.boolean()]);
1544
- var selectorConditionSchema = z11.object({
1545
- key: z11.string().min(1).max(SIGNAL_LIMITS.keyMax).regex(SELECTOR_KEY_RE),
1546
- op: z11.enum(SELECTOR_OPS),
1547
- value: z11.union([scalar, z11.array(z11.string().max(SIGNAL_LIMITS.valueMax)).min(1).max(SIGNAL_LIMITS.inValuesMax)]).optional()
1712
+ var scalar = z12.union([z12.string().max(SIGNAL_LIMITS.valueMax), z12.number().finite(), z12.boolean()]);
1713
+ var selectorConditionSchema = z12.object({
1714
+ key: z12.string().min(1).max(SIGNAL_LIMITS.keyMax).regex(SELECTOR_KEY_RE),
1715
+ op: z12.enum(SELECTOR_OPS),
1716
+ value: z12.union([scalar, z12.array(z12.string().max(SIGNAL_LIMITS.valueMax)).min(1).max(SIGNAL_LIMITS.inValuesMax)]).optional()
1548
1717
  }).superRefine((c, ctx) => {
1549
1718
  const bad = (message) => ctx.addIssue({ code: "custom", path: ["value"], message });
1550
1719
  if (VALUELESS_OPS.has(c.op)) {
@@ -1566,10 +1735,10 @@ var selectorConditionSchema = z11.object({
1566
1735
  if (c.op === "prefix" && (typeof c.value !== "string" || c.value.length === 0))
1567
1736
  bad("text");
1568
1737
  });
1569
- var environmentListSchema = z11.array(z11.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/)).min(1).max(SIGNAL_LIMITS.environmentsMax).refine((v) => new Set(v).size === v.length, "unique");
1570
- var selectorSchema = z11.object({
1571
- signal: z11.enum(SIGNAL_KINDS),
1572
- match: z11.array(selectorConditionSchema).max(SIGNAL_LIMITS.matchMax)
1738
+ var environmentListSchema = z12.array(z12.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/)).min(1).max(SIGNAL_LIMITS.environmentsMax).refine((v) => new Set(v).size === v.length, "unique");
1739
+ var selectorSchema = z12.object({
1740
+ signal: z12.enum(SIGNAL_KINDS),
1741
+ match: z12.array(selectorConditionSchema).max(SIGNAL_LIMITS.matchMax)
1573
1742
  });
1574
1743
  function toNumber(v) {
1575
1744
  if (typeof v === "number")
@@ -1580,22 +1749,22 @@ function toNumber(v) {
1580
1749
  }
1581
1750
  return null;
1582
1751
  }
1583
- var minutes = (min, max) => z11.number().int().min(min).max(max);
1584
- var threshold = z11.number().int().min(0).max(SIGNAL_LIMITS.thresholdMax);
1585
- var recovery = z11.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax);
1752
+ var minutes = (min, max) => z12.number().int().min(min).max(max);
1753
+ var threshold = z12.number().int().min(0).max(SIGNAL_LIMITS.thresholdMax);
1754
+ var recovery = z12.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax);
1586
1755
  var common = {
1587
1756
  environments: environmentListSchema,
1588
- severity: z11.enum(SEVERITIES),
1757
+ severity: z12.enum(SEVERITIES),
1589
1758
  recovery_threshold: recovery
1590
1759
  };
1591
- var countSettingsSchema = z11.object({
1592
- type: z11.literal("count"),
1760
+ var countSettingsSchema = z12.object({
1761
+ type: z12.literal("count"),
1593
1762
  selector: selectorSchema,
1594
1763
  window_minutes: minutes(SIGNAL_LIMITS.windowMinutesMin, SIGNAL_LIMITS.windowMinutesMax),
1595
- comparator: z11.enum(COMPARATORS),
1764
+ comparator: z12.enum(COMPARATORS),
1596
1765
  threshold,
1597
1766
  threshold_high: threshold.nullable(),
1598
- missing_data: z11.enum(MISSING_DATA_POLICIES),
1767
+ missing_data: z12.enum(MISSING_DATA_POLICIES),
1599
1768
  ...common
1600
1769
  }).superRefine((s, ctx) => {
1601
1770
  if (s.comparator === "outside" && (s.threshold_high === null || s.threshold_high <= s.threshold)) {
@@ -1608,31 +1777,48 @@ var countSettingsSchema = z11.object({
1608
1777
  ctx.addIssue({ code: "custom", path: ["threshold"], message: "threshold" });
1609
1778
  }
1610
1779
  });
1611
- var assertionSettingsSchema = z11.object({
1612
- type: z11.literal("assertion"),
1780
+ var assertionSettingsSchema = z12.object({
1781
+ type: z12.literal("assertion"),
1613
1782
  selector: selectorSchema,
1614
- assert: z11.array(selectorConditionSchema).min(1).max(SIGNAL_LIMITS.assertMax),
1783
+ assert: z12.array(selectorConditionSchema).min(1).max(SIGNAL_LIMITS.assertMax),
1615
1784
  window_minutes: minutes(SIGNAL_LIMITS.windowMinutesMin, SIGNAL_LIMITS.windowMinutesMax),
1616
- threshold: z11.number().int().min(1).max(SIGNAL_LIMITS.thresholdMax),
1617
- missing_data: z11.enum(MISSING_DATA_POLICIES),
1785
+ threshold: z12.number().int().min(1).max(SIGNAL_LIMITS.thresholdMax),
1786
+ missing_data: z12.enum(MISSING_DATA_POLICIES),
1618
1787
  ...common
1619
1788
  });
1620
- var deadlineSettingsSchema = z11.object({
1621
- type: z11.literal("deadline"),
1789
+ var deadlineSettingsSchema = z12.object({
1790
+ type: z12.literal("deadline"),
1622
1791
  occurrence_grace_minutes: minutes(0, SIGNAL_LIMITS.graceMinutesMax),
1623
1792
  progress_timeout_minutes: minutes(SIGNAL_LIMITS.progressMinutesMin, SIGNAL_LIMITS.progressMinutesMax).nullable(),
1624
1793
  ...common
1625
1794
  });
1626
- var progressSettingsSchema = z11.object({
1627
- type: z11.literal("progress"),
1795
+ var progressSettingsSchema = z12.object({
1796
+ type: z12.literal("progress"),
1628
1797
  progress_timeout_minutes: minutes(SIGNAL_LIMITS.progressMinutesMin, SIGNAL_LIMITS.progressMinutesMax),
1629
1798
  ...common
1630
1799
  });
1631
- var signalSettingsSchema = z11.discriminatedUnion("type", [
1800
+ var metricThreshold = z12.number().finite().min(-MONITOR_NUMBER_MAX).max(MONITOR_NUMBER_MAX);
1801
+ var metricSettingsSchema = z12.object({
1802
+ type: z12.literal("metric"),
1803
+ metric_query: metricQuerySchema,
1804
+ window_minutes: minutes(SIGNAL_LIMITS.windowMinutesMin, SIGNAL_LIMITS.windowMinutesMax),
1805
+ comparator: z12.enum(COMPARATORS),
1806
+ threshold: metricThreshold,
1807
+ threshold_high: metricThreshold.nullable(),
1808
+ missing_data: z12.enum(MISSING_DATA_POLICIES),
1809
+ ...common
1810
+ }).superRefine((s, ctx) => {
1811
+ if (s.comparator === "outside" && (s.threshold_high === null || s.threshold_high <= s.threshold))
1812
+ ctx.addIssue({ code: "custom", path: ["threshold_high"], message: "threshold_high" });
1813
+ if (s.comparator !== "outside" && s.threshold_high !== null)
1814
+ ctx.addIssue({ code: "custom", path: ["threshold_high"], message: "threshold_high" });
1815
+ });
1816
+ var signalSettingsSchema = z12.discriminatedUnion("type", [
1632
1817
  countSettingsSchema,
1633
1818
  assertionSettingsSchema,
1634
1819
  deadlineSettingsSchema,
1635
- progressSettingsSchema
1820
+ progressSettingsSchema,
1821
+ metricSettingsSchema
1636
1822
  ]);
1637
1823
  function settingsFromRow(row) {
1638
1824
  if (!isSignalMonitorType(row.type) || !row.signal_settings || typeof row.signal_settings !== "object")
@@ -1646,76 +1832,76 @@ function settingsFromRow(row) {
1646
1832
  });
1647
1833
  return r.success ? r.data : null;
1648
1834
  }
1649
- var signalMonitorInputSchema = z11.object({
1650
- name: z11.string().trim().min(1).max(MONITOR_LIMITS.nameMax),
1835
+ var signalMonitorInputSchema = z12.object({
1836
+ name: z12.string().trim().min(1).max(MONITOR_LIMITS.nameMax),
1651
1837
  settings: signalSettingsSchema
1652
1838
  });
1653
- var signalMonitorDefinitionSchema = z11.object({
1654
- id: z11.guid(),
1655
- project_id: z11.number().int().positive(),
1656
- slug: z11.string().regex(SLUG_RE),
1839
+ var signalMonitorDefinitionSchema = z12.object({
1840
+ id: z12.guid(),
1841
+ project_id: z12.number().int().positive(),
1842
+ slug: z12.string().regex(SLUG_RE),
1657
1843
  settings: signalSettingsSchema,
1658
- paused_until: z11.string().datetime().nullable(),
1659
- created_at: z11.string().datetime(),
1660
- revision: z11.number().int().nonnegative()
1844
+ paused_until: z12.string().datetime().nullable(),
1845
+ created_at: z12.string().datetime(),
1846
+ revision: z12.number().int().nonnegative()
1661
1847
  });
1662
- var signalLimitsConfigSchema = z11.object({
1663
- pending_occurrences_per_monitor: z11.number().int().min(1).max(1e6),
1664
- pending_occurrences_per_project: z11.number().int().min(1).max(1e7)
1848
+ var signalLimitsConfigSchema = z12.object({
1849
+ pending_occurrences_per_monitor: z12.number().int().min(1).max(1e6),
1850
+ pending_occurrences_per_project: z12.number().int().min(1).max(1e7)
1665
1851
  });
1666
1852
  var OCCURRENCE_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
1667
- var occurrenceInputSchema = z11.object({
1668
- monitor_slug: z11.string().regex(SLUG_RE),
1669
- occurrence_id: z11.string().regex(OCCURRENCE_ID_RE),
1670
- due_at: z11.string().datetime({ offset: true }),
1671
- environment: z11.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/).optional()
1853
+ var occurrenceInputSchema = z12.object({
1854
+ monitor_slug: z12.string().regex(SLUG_RE),
1855
+ occurrence_id: z12.string().regex(OCCURRENCE_ID_RE),
1856
+ due_at: z12.string().datetime({ offset: true }),
1857
+ environment: z12.string().trim().min(1).max(MONITOR_LIMITS.environmentMax).regex(/^[A-Za-z0-9._-]+$/).optional()
1672
1858
  });
1673
1859
  var occurrenceCancelSchema = occurrenceInputSchema.pick({ monitor_slug: true, occurrence_id: true, environment: true });
1674
1860
  var OCCURRENCE_PAST_SKEW_MS = 5 * 60000;
1675
- var occurrenceRowSchema = z11.object({
1676
- occurrence_id: z11.string().max(SIGNAL_LIMITS.occurrenceIdMax),
1677
- environment: z11.string().max(MONITOR_LIMITS.environmentMax),
1678
- state: z11.enum(OCCURRENCE_STATES),
1679
- due_at: z11.string().datetime(),
1680
- deadline_at: z11.string().datetime(),
1681
- registered_at: z11.string().datetime(),
1682
- started_at: z11.string().datetime().nullable(),
1683
- last_signal_at: z11.string().datetime().nullable(),
1684
- ended_at: z11.string().datetime().nullable(),
1685
- stalled: z11.boolean()
1861
+ var occurrenceRowSchema = z12.object({
1862
+ occurrence_id: z12.string().max(SIGNAL_LIMITS.occurrenceIdMax),
1863
+ environment: z12.string().max(MONITOR_LIMITS.environmentMax),
1864
+ state: z12.enum(OCCURRENCE_STATES),
1865
+ due_at: z12.string().datetime(),
1866
+ deadline_at: z12.string().datetime(),
1867
+ registered_at: z12.string().datetime(),
1868
+ started_at: z12.string().datetime().nullable(),
1869
+ last_signal_at: z12.string().datetime().nullable(),
1870
+ ended_at: z12.string().datetime().nullable(),
1871
+ stalled: z12.boolean()
1686
1872
  });
1687
- var occurrencesResponseSchema = z11.object({
1688
- occurrences: z11.array(occurrenceRowSchema).max(SIGNAL_LIMITS.occurrencesPageSize),
1689
- pending: z11.number().int().nonnegative(),
1690
- next_due_at: z11.string().datetime().nullable(),
1691
- next_cursor: z11.string().max(64).nullable(),
1692
- refused_24h: z11.number().int().nonnegative()
1873
+ var occurrencesResponseSchema = z12.object({
1874
+ occurrences: z12.array(occurrenceRowSchema).max(SIGNAL_LIMITS.occurrencesPageSize),
1875
+ pending: z12.number().int().nonnegative(),
1876
+ next_due_at: z12.string().datetime().nullable(),
1877
+ next_cursor: z12.string().max(64).nullable(),
1878
+ refused_24h: z12.number().int().nonnegative()
1693
1879
  });
1694
- var signalSeriesSchema = z11.object({
1695
- environment: z11.string().max(MONITOR_LIMITS.environmentMax),
1696
- buckets: z11.array(z11.object({ minute: z11.string().datetime(), matched: z11.number().int().nonnegative(), violations: z11.number().int().nonnegative(), lossy: z11.boolean() })).max(1440),
1697
- counted_through: z11.string().datetime().nullable()
1880
+ var signalSeriesSchema = z12.object({
1881
+ environment: z12.string().max(MONITOR_LIMITS.environmentMax),
1882
+ buckets: z12.array(z12.object({ minute: z12.string().datetime(), matched: z12.number().int().nonnegative(), violations: z12.number().int().nonnegative(), lossy: z12.boolean() })).max(1440),
1883
+ counted_through: z12.string().datetime().nullable()
1698
1884
  });
1699
- var signalResponseSchema = z11.object({
1700
- series: z11.array(signalSeriesSchema).max(SIGNAL_LIMITS.environmentsMax),
1701
- runs: z11.array(z11.object({
1702
- run_id: z11.string().max(SIGNAL_LIMITS.occurrenceIdMax),
1703
- environment: z11.string().max(MONITOR_LIMITS.environmentMax),
1704
- started_at: z11.string().datetime(),
1705
- last_signal_at: z11.string().datetime(),
1706
- stalled: z11.boolean()
1885
+ var signalResponseSchema = z12.object({
1886
+ series: z12.array(signalSeriesSchema).max(SIGNAL_LIMITS.environmentsMax),
1887
+ runs: z12.array(z12.object({
1888
+ run_id: z12.string().max(SIGNAL_LIMITS.occurrenceIdMax),
1889
+ environment: z12.string().max(MONITOR_LIMITS.environmentMax),
1890
+ started_at: z12.string().datetime(),
1891
+ last_signal_at: z12.string().datetime(),
1892
+ stalled: z12.boolean()
1707
1893
  })).max(SIGNAL_LIMITS.occurrencesPageSize)
1708
1894
  });
1709
- var backtestSettingsSchema = z11.union([countSettingsSchema, assertionSettingsSchema]);
1710
- var backtestResponseSchema = z11.object({
1711
- alerts: z11.number().int().nonnegative(),
1712
- windows: z11.number().int().nonnegative(),
1713
- violated_windows: z11.number().int().nonnegative(),
1714
- first_at: z11.string().datetime().nullable(),
1715
- last_at: z11.string().datetime().nullable(),
1716
- days: z11.number().nonnegative(),
1717
- matched_total: z11.number().int().nonnegative(),
1718
- violations_total: z11.number().int().nonnegative()
1895
+ var backtestSettingsSchema = z12.union([countSettingsSchema, assertionSettingsSchema]);
1896
+ var backtestResponseSchema = z12.object({
1897
+ alerts: z12.number().int().nonnegative(),
1898
+ windows: z12.number().int().nonnegative(),
1899
+ violated_windows: z12.number().int().nonnegative(),
1900
+ first_at: z12.string().datetime().nullable(),
1901
+ last_at: z12.string().datetime().nullable(),
1902
+ days: z12.number().nonnegative(),
1903
+ matched_total: z12.number().int().nonnegative(),
1904
+ violations_total: z12.number().int().nonnegative()
1719
1905
  });
1720
1906
 
1721
1907
  // ../src/shared/contracts/notifications.ts
@@ -1730,24 +1916,24 @@ var NOTIFY_LIMITS = {
1730
1916
  };
1731
1917
  var HOLDABLE_SEVERITIES = ["medium", "low"];
1732
1918
  var DIGEST_MODES = ["off", "hourly", "daily"];
1733
- var timeOfDay2 = z12.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
1919
+ var timeOfDay2 = z13.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
1734
1920
  var unique = (xs) => new Set(xs).size === xs.length;
1735
- var quietHoursSchema = z12.object({
1736
- days: z12.array(weekdaySchema).min(1).max(7).refine(unique),
1921
+ var quietHoursSchema = z13.object({
1922
+ days: z13.array(weekdaySchema).min(1).max(7).refine(unique),
1737
1923
  start: timeOfDay2,
1738
1924
  end: timeOfDay2
1739
1925
  }).refine((q) => q.start !== q.end, { path: ["end"] });
1740
- var policyInputSchema = z12.object({
1741
- name: z12.string().trim().min(1).max(NOTIFY_LIMITS.nameMax).regex(/^[^\p{Cc}]*$/u),
1742
- timezone: z12.string().trim().min(1).max(64).refine(validTimeZone),
1926
+ var policyInputSchema = z13.object({
1927
+ name: z13.string().trim().min(1).max(NOTIFY_LIMITS.nameMax).regex(/^[^\p{Cc}]*$/u),
1928
+ timezone: z13.string().trim().min(1).max(64).refine(validTimeZone),
1743
1929
  quietHours: quietHoursSchema.nullable(),
1744
- quietSeverities: z12.array(z12.enum(HOLDABLE_SEVERITIES)).max(2).refine(unique),
1745
- digest: z12.enum(DIGEST_MODES),
1930
+ quietSeverities: z13.array(z13.enum(HOLDABLE_SEVERITIES)).max(2).refine(unique),
1931
+ digest: z13.enum(DIGEST_MODES),
1746
1932
  digestAt: timeOfDay2.nullable(),
1747
- digestSeverities: z12.array(z12.enum(HOLDABLE_SEVERITIES)).max(2).refine(unique),
1748
- fallback: z12.array(z12.guid()).max(NOTIFY_LIMITS.chainMax).refine(unique),
1749
- escalateAfterMinutes: z12.number().int().min(NOTIFY_LIMITS.escalateMinutesMin).max(NOTIFY_LIMITS.escalateMinutesMax).nullable(),
1750
- escalation: z12.array(z12.guid()).max(NOTIFY_LIMITS.chainMax).refine(unique)
1933
+ digestSeverities: z13.array(z13.enum(HOLDABLE_SEVERITIES)).max(2).refine(unique),
1934
+ fallback: z13.array(z13.guid()).max(NOTIFY_LIMITS.chainMax).refine(unique),
1935
+ escalateAfterMinutes: z13.number().int().min(NOTIFY_LIMITS.escalateMinutesMin).max(NOTIFY_LIMITS.escalateMinutesMax).nullable(),
1936
+ escalation: z13.array(z13.guid()).max(NOTIFY_LIMITS.chainMax).refine(unique)
1751
1937
  }).superRefine((p, ctx) => {
1752
1938
  if (p.digest === "daily" !== (p.digestAt !== null))
1753
1939
  ctx.addIssue({ code: "custom", path: ["digestAt"], message: "digest_at" });
@@ -1759,46 +1945,46 @@ var HOUR = 60 * MIN;
1759
1945
  var DAY = 24 * HOUR;
1760
1946
 
1761
1947
  // ../src/shared/contracts/api-ops/incidents.ts
1762
- var incidentOnly = z13.object({ workspaceId: uuid, incidentId: uuid });
1763
- var note2 = z13.string().trim().min(1).max(2000).regex(/^[^\u0000-\u0008\u000b\u000c\u000e-\u001f]*$/);
1948
+ var incidentOnly = z14.object({ workspaceId: uuid, incidentId: uuid });
1949
+ var note2 = z14.string().trim().min(1).max(2000).regex(/^[^\u0000-\u0008\u000b\u000c\u000e-\u001f]*$/);
1764
1950
  var INCIDENT_KINDS = ["monitor", "uptime", "slo", "issue"];
1765
1951
  var INCIDENT_GROUP_BY = ["monitor", "project_env"];
1766
- var incidentRuleInputSchema = z13.object({
1767
- name: z13.string().trim().min(1).max(80).regex(/^[^\p{Cc}]*$/u),
1768
- isEnabled: z13.boolean(),
1769
- position: z13.number().int().min(0).max(1000).default(0),
1770
- projectIds: z13.array(z13.number().int().positive()).max(50),
1771
- environments: z13.array(z13.string().trim().min(1).max(64)).max(20),
1772
- kinds: z13.array(z13.enum(INCIDENT_KINDS)).min(1).max(4),
1773
- minSeverity: z13.enum(SEVERITIES),
1774
- groupBy: z13.enum(INCIDENT_GROUP_BY),
1775
- windowMinutes: z13.number().int().min(5).max(240),
1776
- recoveryHoldMinutes: z13.number().int().min(0).max(1440)
1952
+ var incidentRuleInputSchema = z14.object({
1953
+ name: z14.string().trim().min(1).max(80).regex(/^[^\p{Cc}]*$/u),
1954
+ isEnabled: z14.boolean(),
1955
+ position: z14.number().int().min(0).max(1000).default(0),
1956
+ projectIds: z14.array(z14.number().int().positive()).max(50),
1957
+ environments: z14.array(z14.string().trim().min(1).max(64)).max(20),
1958
+ kinds: z14.array(z14.enum(INCIDENT_KINDS)).min(1).max(4),
1959
+ minSeverity: z14.enum(SEVERITIES),
1960
+ groupBy: z14.enum(INCIDENT_GROUP_BY),
1961
+ windowMinutes: z14.number().int().min(5).max(240),
1962
+ recoveryHoldMinutes: z14.number().int().min(0).max(1440)
1777
1963
  });
1778
1964
  var INCIDENT_INPUTS = {
1779
- list: z13.object({
1965
+ list: z14.object({
1780
1966
  workspaceId: uuid,
1781
1967
  limit: pageLimit,
1782
1968
  cursor,
1783
- state: z13.enum(["active", "resolved", "all"]).default("all")
1969
+ state: z14.enum(["active", "resolved", "all"]).default("all")
1784
1970
  }),
1785
1971
  incidentOnly,
1786
1972
  resolve: incidentOnly.extend({ note: note2.max(500) }),
1787
1973
  note: incidentOnly.extend({ note: note2 }),
1788
1974
  update: incidentOnly.extend({
1789
- title: z13.string().trim().min(1).max(120).regex(/^[^\p{Cc}]*$/u).optional(),
1975
+ title: z14.string().trim().min(1).max(120).regex(/^[^\p{Cc}]*$/u).optional(),
1790
1976
  ownerUserId: uuid.nullable().optional()
1791
1977
  }),
1792
- workspace: z13.object({ workspaceId: uuid }),
1793
- saveRule: z13.object({ workspaceId: uuid, ruleId: uuid.nullable(), input: incidentRuleInputSchema }),
1794
- ruleOnly: z13.object({ workspaceId: uuid, ruleId: uuid }),
1795
- savePolicy: z13.object({
1978
+ workspace: z14.object({ workspaceId: uuid }),
1979
+ saveRule: z14.object({ workspaceId: uuid, ruleId: uuid.nullable(), input: incidentRuleInputSchema }),
1980
+ ruleOnly: z14.object({ workspaceId: uuid, ruleId: uuid }),
1981
+ savePolicy: z14.object({
1796
1982
  workspaceId: uuid,
1797
1983
  policyId: uuid.nullable(),
1798
- isDefault: z13.boolean(),
1984
+ isDefault: z14.boolean(),
1799
1985
  input: policyInputSchema
1800
1986
  }),
1801
- policyOnly: z13.object({ workspaceId: uuid, policyId: uuid })
1987
+ policyOnly: z14.object({ workspaceId: uuid, policyId: uuid })
1802
1988
  };
1803
1989
  var I = INCIDENT_INPUTS;
1804
1990
  var w = "incidents:write";
@@ -1987,20 +2173,62 @@ var INCIDENT_OPERATIONS = [
1987
2173
  ];
1988
2174
 
1989
2175
  // ../src/shared/contracts/api-ops/monitors.ts
1990
- import { z as z18 } from "zod";
2176
+ import { z as z19 } from "zod";
1991
2177
 
1992
2178
  // ../src/shared/contracts/heartbeat.ts
2179
+ import { z as z16 } from "zod";
2180
+
2181
+ // ../src/shared/contracts/signed-message.ts
1993
2182
  import { z as z15 } from "zod";
1994
2183
 
2184
+ // ../src/shared/contracts/limits.ts
2185
+ var INGEST_LIMITS = {
2186
+ envelopeCompressedMaxBytes: 20 * 1024 * 1024,
2187
+ decompressedMaxBytes: 200 * 1024 * 1024,
2188
+ maxCompressionRatio: 50,
2189
+ eventItemMaxBytes: 1024 * 1024,
2190
+ attachmentMaxBytes: 5 * 1024 * 1024,
2191
+ jsonMaxDepth: 20,
2192
+ jsonMaxKeysPerObject: 1000,
2193
+ jsonMaxKeysTotal: 1e4,
2194
+ jsonHardMaxDepth: 128,
2195
+ stringMaxChars: 8192,
2196
+ framesMaxPerException: 250,
2197
+ exceptionsMax: 10,
2198
+ breadcrumbsMax: 100,
2199
+ tagsMax: 20,
2200
+ tagKeyMaxChars: 32,
2201
+ tagValueMaxChars: 200,
2202
+ sourceMapMaxBytes: 10 * 1024 * 1024,
2203
+ sourceMapSegmentMaxChars: 1024,
2204
+ envelopeItemsMax: 100
2205
+ };
2206
+ var BUFFER_LIMITS = {
2207
+ queueInlineMaxBytes: 100 * 1024,
2208
+ maxAgeDays: 14,
2209
+ nodeMaxBytes: 8 * 1024 ** 3,
2210
+ alertRatio: 0.8,
2211
+ alertInflowPerSecond: 5000
2212
+ };
2213
+ var RELAY_LIMITS = {
2214
+ chunkBytes: 512 * 1024,
2215
+ maxInflightMessages: 4,
2216
+ maxInflightBytes: 24 * 1024 * 1024,
2217
+ clockSkewSeconds: 60,
2218
+ nonceMemorySeconds: 600,
2219
+ ackTimeoutMs: 2000,
2220
+ heartbeatSeconds: 30,
2221
+ reconnectMaxSeconds: 30
2222
+ };
2223
+
1995
2224
  // ../src/shared/contracts/signed-message.ts
1996
- import { z as z14 } from "zod";
1997
- var nodeIdSchema = z14.guid();
1998
- var signedEnvelopeSchema = z14.object({
2225
+ var nodeIdSchema = z15.guid();
2226
+ var signedEnvelopeSchema = z15.object({
1999
2227
  node_id: nodeIdSchema,
2000
- ts: z14.number().int().positive(),
2001
- nonce: z14.string().regex(/^[A-Za-z0-9_-]{16,64}$/),
2002
- payload: z14.record(z14.string(), z14.unknown()),
2003
- sig: z14.string().regex(/^[A-Za-z0-9_-]{86}$/)
2228
+ ts: z15.number().int().positive(),
2229
+ nonce: z15.string().regex(/^[A-Za-z0-9_-]{16,64}$/),
2230
+ payload: z15.record(z15.string(), z15.unknown()),
2231
+ sig: z15.string().regex(/^[A-Za-z0-9_-]{86}$/)
2004
2232
  });
2005
2233
 
2006
2234
  // ../src/shared/contracts/heartbeat.ts
@@ -2038,78 +2266,78 @@ var HEARTBEAT_LIMITS = {
2038
2266
  diagnosticsPerRun: 5
2039
2267
  };
2040
2268
  var PAUSED_FOREVER_MS = Date.parse("9999-12-31T00:00:00.000Z");
2041
- var uuid2 = z15.guid();
2042
- var ms = z15.number().int().nonnegative();
2043
- var hex64 = z15.string().regex(/^[0-9a-f]{64}$/);
2044
- var envName2 = z15.string().min(1).max(MONITOR_LIMITS.environmentMax);
2045
- var heartbeatMonitorConfigSchema = z15.object({
2269
+ var uuid2 = z16.guid();
2270
+ var ms = z16.number().int().nonnegative();
2271
+ var hex64 = z16.string().regex(/^[0-9a-f]{64}$/);
2272
+ var envName2 = z16.string().min(1).max(MONITOR_LIMITS.environmentMax);
2273
+ var heartbeatMonitorConfigSchema = z16.object({
2046
2274
  id: uuid2,
2047
- project_id: z15.number().int().positive(),
2048
- slug: z15.string().regex(SLUG_RE),
2275
+ project_id: z16.number().int().positive(),
2276
+ slug: z16.string().regex(SLUG_RE),
2049
2277
  environment: envName2,
2050
2278
  schedule: scheduleSchema,
2051
- timezone: z15.string().min(1).max(64),
2052
- grace_min: z15.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
2053
- max_runtime_min: z15.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
2054
- failure_threshold: z15.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
2055
- recovery_threshold: z15.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
2279
+ timezone: z16.string().min(1).max(64),
2280
+ grace_min: z16.number().int().min(MONITOR_LIMITS.checkinMarginMin).max(MONITOR_LIMITS.checkinMarginMax),
2281
+ max_runtime_min: z16.number().int().min(MONITOR_LIMITS.maxRuntimeMin).max(MONITOR_LIMITS.maxRuntimeMax),
2282
+ failure_threshold: z16.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
2283
+ recovery_threshold: z16.number().int().min(MONITOR_LIMITS.thresholdMin).max(MONITOR_LIMITS.thresholdMax),
2056
2284
  paused_until: ms.nullable(),
2057
2285
  created_at: ms
2058
2286
  });
2059
- var heartbeatTokenConfigSchema = z15.object({
2287
+ var heartbeatTokenConfigSchema = z16.object({
2060
2288
  id: uuid2,
2061
2289
  monitor_id: uuid2,
2062
2290
  hash: hex64,
2063
2291
  expires_at: ms.nullable()
2064
2292
  });
2065
- var heartbeatSyncSchema = z15.object({
2066
- v: z15.literal(1),
2293
+ var heartbeatSyncSchema = z16.object({
2294
+ v: z16.literal(1),
2067
2295
  workspace_id: uuid2,
2068
- route: z15.string().regex(PING_ROUTE_RE),
2069
- revision: z15.number().int().positive(),
2070
- workspace_status: z15.enum(["active", "suspended", "deleting"]),
2071
- ingest_kill: z15.boolean(),
2072
- limits: z15.object({
2073
- check_in_rate_per_sec: z15.number().int().positive(),
2074
- check_in_burst: z15.number().int().positive(),
2075
- monthly_check_in_cap: z15.number().int().positive()
2076
- }),
2077
- projects: z15.array(z15.object({ id: z15.number().int().positive(), node_id: nodeIdSchema.nullable() })).max(1000),
2078
- monitors: z15.array(heartbeatMonitorConfigSchema).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace),
2079
- tokens: z15.array(heartbeatTokenConfigSchema).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace * 2)
2296
+ route: z16.string().regex(PING_ROUTE_RE),
2297
+ revision: z16.number().int().positive(),
2298
+ workspace_status: z16.enum(["active", "suspended", "deleting"]),
2299
+ ingest_kill: z16.boolean(),
2300
+ limits: z16.object({
2301
+ check_in_rate_per_sec: z16.number().int().positive(),
2302
+ check_in_burst: z16.number().int().positive(),
2303
+ monthly_check_in_cap: z16.number().int().positive()
2304
+ }),
2305
+ projects: z16.array(z16.object({ id: z16.number().int().positive(), node_id: nodeIdSchema.nullable() })).max(1000),
2306
+ monitors: z16.array(heartbeatMonitorConfigSchema).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace),
2307
+ tokens: z16.array(heartbeatTokenConfigSchema).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace * 2)
2080
2308
  });
2081
- var signedHeartbeatSyncSchema = z15.object({
2082
- body: z15.string().min(2).max(4 * 1024 * 1024),
2083
- ts: z15.number().int().positive(),
2084
- kid: z15.string().regex(/^[A-Za-z0-9_-]{1,40}$/),
2085
- sig: z15.string().regex(/^[A-Za-z0-9_-]{86}$/)
2309
+ var signedHeartbeatSyncSchema = z16.object({
2310
+ body: z16.string().min(2).max(4 * 1024 * 1024),
2311
+ ts: z16.number().int().positive(),
2312
+ kid: z16.string().regex(/^[A-Za-z0-9_-]{1,40}$/),
2313
+ sig: z16.string().regex(/^[A-Za-z0-9_-]{86}$/)
2086
2314
  });
2087
- var heartbeatHourSchema = z15.object({
2315
+ var heartbeatHourSchema = z16.object({
2088
2316
  monitor_id: uuid2,
2089
- hour: z15.string().datetime(),
2090
- ok: z15.number().int().nonnegative(),
2091
- failed: z15.number().int().nonnegative(),
2092
- started: z15.number().int().nonnegative(),
2093
- missed: z15.number().int().nonnegative(),
2094
- logs: z15.number().int().nonnegative()
2317
+ hour: z16.string().datetime(),
2318
+ ok: z16.number().int().nonnegative(),
2319
+ failed: z16.number().int().nonnegative(),
2320
+ started: z16.number().int().nonnegative(),
2321
+ missed: z16.number().int().nonnegative(),
2322
+ logs: z16.number().int().nonnegative()
2095
2323
  });
2096
- var heartbeatReportSchema = z15.object({
2097
- v: z15.literal(1),
2324
+ var heartbeatReportSchema = z16.object({
2325
+ v: z16.literal(1),
2098
2326
  workspace_id: uuid2,
2099
- route: z15.string().regex(PING_ROUTE_RE),
2100
- revision: z15.number().int().nonnegative(),
2101
- sent_at: z15.string().datetime(),
2102
- incidents: z15.array(monitorIncidentSchema).max(HEARTBEAT_LIMITS.reportMaxIncidents),
2103
- statuses: z15.array(monitorStatusSchema).max(HEARTBEAT_LIMITS.reportMaxStatuses),
2104
- hours: z15.array(heartbeatHourSchema).max(HEARTBEAT_LIMITS.reportMaxHours),
2105
- token_uses: z15.array(z15.object({ token_id: uuid2, last_used_at: z15.string().datetime() })).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace * 2)
2327
+ route: z16.string().regex(PING_ROUTE_RE),
2328
+ revision: z16.number().int().nonnegative(),
2329
+ sent_at: z16.string().datetime(),
2330
+ incidents: z16.array(monitorIncidentSchema).max(HEARTBEAT_LIMITS.reportMaxIncidents),
2331
+ statuses: z16.array(monitorStatusSchema).max(HEARTBEAT_LIMITS.reportMaxStatuses),
2332
+ hours: z16.array(heartbeatHourSchema).max(HEARTBEAT_LIMITS.reportMaxHours),
2333
+ token_uses: z16.array(z16.object({ token_id: uuid2, last_used_at: z16.string().datetime() })).max(HEARTBEAT_LIMITS.maxMonitorsPerWorkspace * 2)
2106
2334
  });
2107
2335
  var ENCODER = new TextEncoder;
2108
2336
  var UTF8 = new TextDecoder("utf-8", { fatal: false, ignoreBOM: false });
2109
2337
  var TOKEN_IN_TEXT = new RegExp(PING_TOKEN_PATTERN, "g");
2110
2338
 
2111
2339
  // ../src/shared/contracts/slo.ts
2112
- import { z as z16 } from "zod";
2340
+ import { z as z17 } from "zod";
2113
2341
 
2114
2342
  // ../src/shared/contracts/vocab/slo.ts
2115
2343
  var SLO_SOURCES = ["uptime", "monitor", "heartbeat", "spans"];
@@ -2141,17 +2369,17 @@ var SLO_SOURCE_META = {
2141
2369
  heartbeat: { provenance: "ping_token", estimated: false, slis: ["availability"], budgeting: "Occurrences" },
2142
2370
  spans: { provenance: "ingest_key", estimated: true, slis: ["availability", "latency"], budgeting: "Occurrences" }
2143
2371
  };
2144
- var nodeSloSchema = z16.object({
2145
- slo_id: z16.guid(),
2146
- project_id: z16.number().int().positive(),
2147
- source: z16.enum(["monitor", "spans"]),
2148
- sli: z16.enum(SLO_SLIS),
2149
- monitor_id: z16.guid().optional(),
2150
- environment: z16.string().min(1).max(SLO_LIMITS.environmentMaxChars).optional(),
2151
- service: z16.string().min(1).max(128).optional(),
2152
- operation: z16.string().min(1).max(256).optional(),
2153
- latency_threshold_ms: z16.number().int().min(1).max(60000).optional(),
2154
- public_sources: z16.boolean()
2372
+ var nodeSloSchema = z17.object({
2373
+ slo_id: z17.guid(),
2374
+ project_id: z17.number().int().positive(),
2375
+ source: z17.enum(["monitor", "spans"]),
2376
+ sli: z17.enum(SLO_SLIS),
2377
+ monitor_id: z17.guid().optional(),
2378
+ environment: z17.string().min(1).max(SLO_LIMITS.environmentMaxChars).optional(),
2379
+ service: z17.string().min(1).max(128).optional(),
2380
+ operation: z17.string().min(1).max(256).optional(),
2381
+ latency_threshold_ms: z17.number().int().min(1).max(60000).optional(),
2382
+ public_sources: z17.boolean()
2155
2383
  }).superRefine((v, ctx) => {
2156
2384
  if (v.source === "monitor" && (!v.monitor_id || v.sli !== "availability"))
2157
2385
  ctx.addIssue({ code: "custom", path: ["monitor_id"], message: "INVALID_INPUT" });
@@ -2160,27 +2388,27 @@ var nodeSloSchema = z16.object({
2160
2388
  if (v.sli === "latency" !== (v.latency_threshold_ms !== undefined))
2161
2389
  ctx.addIssue({ code: "custom", path: ["latency_threshold_ms"], message: "INVALID_INPUT" });
2162
2390
  });
2163
- var sliCountsSchema = z16.object({
2164
- minute: z16.string().datetime(),
2165
- items: z16.array(z16.object({ slo_id: z16.guid(), good: z16.number().int().min(0), total: z16.number().int().min(0) }).refine((x) => x.good <= x.total, { message: "INVALID_INPUT" })).max(SLO_LIMITS.sliItemsPerMessage)
2391
+ var sliCountsSchema = z17.object({
2392
+ minute: z17.string().datetime(),
2393
+ items: z17.array(z17.object({ slo_id: z17.guid(), good: z17.number().int().min(0), total: z17.number().int().min(0) }).refine((x) => x.good <= x.total, { message: "INVALID_INPUT" })).max(SLO_LIMITS.sliItemsPerMessage)
2166
2394
  });
2167
- var sloInputSchema = z16.object({
2168
- name: z16.string().trim().min(1).max(SLO_LIMITS.nameMaxChars),
2169
- description: z16.string().max(SLO_LIMITS.descriptionMaxChars).default(""),
2170
- source: z16.enum(SLO_SOURCES),
2171
- sourceRef: z16.object({
2172
- id: z16.guid().optional(),
2173
- projectId: z16.number().int().positive().optional(),
2174
- service: z16.string().max(128).optional(),
2175
- operation: z16.string().max(256).optional(),
2176
- environment: z16.string().max(SLO_LIMITS.environmentMaxChars).optional()
2177
- }),
2178
- sli: z16.enum(SLO_SLIS),
2179
- latencyThresholdMs: z16.number().int().min(1).max(60000).nullable(),
2180
- objective: z16.number().min(SLO_LIMITS.objectiveMin).max(SLO_LIMITS.objectiveMax),
2181
- windowDays: z16.union([z16.literal(7), z16.literal(28), z16.literal(30)]),
2182
- alertPolicy: z16.enum(SLO_ALERT_POLICIES),
2183
- allowPublicSources: z16.boolean().default(false)
2395
+ var sloInputSchema = z17.object({
2396
+ name: z17.string().trim().min(1).max(SLO_LIMITS.nameMaxChars),
2397
+ description: z17.string().max(SLO_LIMITS.descriptionMaxChars).default(""),
2398
+ source: z17.enum(SLO_SOURCES),
2399
+ sourceRef: z17.object({
2400
+ id: z17.guid().optional(),
2401
+ projectId: z17.number().int().positive().optional(),
2402
+ service: z17.string().max(128).optional(),
2403
+ operation: z17.string().max(256).optional(),
2404
+ environment: z17.string().max(SLO_LIMITS.environmentMaxChars).optional()
2405
+ }),
2406
+ sli: z17.enum(SLO_SLIS),
2407
+ latencyThresholdMs: z17.number().int().min(1).max(60000).nullable(),
2408
+ objective: z17.number().min(SLO_LIMITS.objectiveMin).max(SLO_LIMITS.objectiveMax),
2409
+ windowDays: z17.union([z17.literal(7), z17.literal(28), z17.literal(30)]),
2410
+ alertPolicy: z17.enum(SLO_ALERT_POLICIES),
2411
+ allowPublicSources: z17.boolean().default(false)
2184
2412
  }).superRefine((v, ctx) => {
2185
2413
  if (!SLO_SOURCE_META[v.source].slis.includes(v.sli))
2186
2414
  ctx.addIssue({ code: "custom", path: ["sli"], message: "INVALID_INPUT" });
@@ -2195,7 +2423,7 @@ var sloInputSchema = z16.object({
2195
2423
  });
2196
2424
 
2197
2425
  // ../src/shared/contracts/uptime.ts
2198
- import { z as z17 } from "zod";
2426
+ import { z as z18 } from "zod";
2199
2427
 
2200
2428
  // ../src/shared/contracts/vocab/uptime.ts
2201
2429
  var UPTIME_STATUSES = ["up", "degraded", "down", "unknown", "paused", "pending"];
@@ -2268,51 +2496,51 @@ function isForbiddenHeader(name) {
2268
2496
  const n = name.trim().toLowerCase();
2269
2497
  return UPTIME_FORBIDDEN_HEADERS.includes(n) || n.startsWith("proxy-") || n.startsWith("sec-");
2270
2498
  }
2271
- var text = z17.string().min(1).max(UPTIME_LIMITS.assertionTextMax);
2272
- var statusRange = z17.string().regex(/^[1-5][0-9]{2}(-[1-5][0-9]{2})?$/);
2273
- var assertionSchema = z17.discriminatedUnion("type", [
2274
- z17.object({ type: z17.literal("status"), in: z17.array(statusRange).min(1).max(10) }),
2275
- z17.object({ type: z17.literal("body_contains"), value: text, case_sensitive: z17.boolean().default(true) }),
2276
- z17.object({ type: z17.literal("body_not_contains"), value: text, case_sensitive: z17.boolean().default(true) }),
2277
- z17.object({
2278
- type: z17.literal("json_pointer"),
2279
- pointer: z17.string().max(256).regex(/^(\/([^~/]|~0|~1)*)*$/),
2280
- op: z17.enum(["exists", "equals", "type"]),
2281
- value: z17.string().max(UPTIME_LIMITS.assertionTextMax).optional()
2282
- }),
2283
- z17.object({
2284
- type: z17.literal("header"),
2285
- name: z17.string().min(1).max(UPTIME_LIMITS.headerNameMax).regex(/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/),
2286
- op: z17.enum(["equals", "contains", "exists"]),
2287
- value: z17.string().max(UPTIME_LIMITS.assertionTextMax).optional()
2288
- }),
2289
- z17.object({ type: z17.literal("latency_ms"), lt: z17.number().int().min(1).max(60000) }),
2290
- z17.object({ type: z17.literal("tls_valid") })
2499
+ var text = z18.string().min(1).max(UPTIME_LIMITS.assertionTextMax);
2500
+ var statusRange = z18.string().regex(/^[1-5][0-9]{2}(-[1-5][0-9]{2})?$/);
2501
+ var assertionSchema = z18.discriminatedUnion("type", [
2502
+ z18.object({ type: z18.literal("status"), in: z18.array(statusRange).min(1).max(10) }),
2503
+ z18.object({ type: z18.literal("body_contains"), value: text, case_sensitive: z18.boolean().default(true) }),
2504
+ z18.object({ type: z18.literal("body_not_contains"), value: text, case_sensitive: z18.boolean().default(true) }),
2505
+ z18.object({
2506
+ type: z18.literal("json_pointer"),
2507
+ pointer: z18.string().max(256).regex(/^(\/([^~/]|~0|~1)*)*$/),
2508
+ op: z18.enum(["exists", "equals", "type"]),
2509
+ value: z18.string().max(UPTIME_LIMITS.assertionTextMax).optional()
2510
+ }),
2511
+ z18.object({
2512
+ type: z18.literal("header"),
2513
+ name: z18.string().min(1).max(UPTIME_LIMITS.headerNameMax).regex(/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/),
2514
+ op: z18.enum(["equals", "contains", "exists"]),
2515
+ value: z18.string().max(UPTIME_LIMITS.assertionTextMax).optional()
2516
+ }),
2517
+ z18.object({ type: z18.literal("latency_ms"), lt: z18.number().int().min(1).max(60000) }),
2518
+ z18.object({ type: z18.literal("tls_valid") })
2291
2519
  ]);
2292
- var header = z17.object({
2293
- name: z17.string().min(1).max(UPTIME_LIMITS.headerNameMax).regex(/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/),
2294
- value: z17.string().max(UPTIME_LIMITS.headerValueMax).regex(/^[^\r\n\u0000]*$/)
2520
+ var header = z18.object({
2521
+ name: z18.string().min(1).max(UPTIME_LIMITS.headerNameMax).regex(/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/),
2522
+ value: z18.string().max(UPTIME_LIMITS.headerValueMax).regex(/^[^\r\n\u0000]*$/)
2295
2523
  });
2296
- var uptimeCheckInputSchema = z17.object({
2297
- projectId: z17.number().int().positive(),
2298
- name: z17.string().trim().min(1).max(UPTIME_LIMITS.nameMaxChars),
2299
- kind: z17.enum(UPTIME_KINDS),
2300
- url: z17.string().max(UPTIME_LIMITS.urlMaxChars).nullable(),
2301
- host: z17.string().max(253).nullable(),
2302
- port: z17.number().int().min(1).max(65535).nullable(),
2303
- method: z17.enum(UPTIME_METHODS).default("GET"),
2304
- headers: z17.array(header).max(UPTIME_LIMITS.headersMax).default([]),
2305
- followRedirects: z17.boolean().default(false),
2306
- timeoutMs: z17.number().int().min(UPTIME_LIMITS.timeoutMs.min).max(UPTIME_LIMITS.timeoutMs.max),
2307
- intervalSeconds: z17.number().int().refine((n) => UPTIME_INTERVALS.includes(n)),
2308
- regions: z17.array(z17.enum(UPTIME_REGIONS)).min(UPTIME_LIMITS.minRegions).max(UPTIME_REGIONS.length),
2309
- assertions: z17.array(assertionSchema).max(UPTIME_LIMITS.assertionsMax).default([]),
2310
- failureThreshold: z17.number().int().min(1).max(5),
2311
- recoveryThreshold: z17.number().int().min(1).max(5),
2312
- certWarningDays: z17.number().int().min(1).max(60),
2313
- environment: z17.string().trim().max(64).default(""),
2314
- strictMetadata: z17.boolean().default(false),
2315
- evidenceOnFailure: z17.boolean().default(true)
2524
+ var uptimeCheckInputSchema = z18.object({
2525
+ projectId: z18.number().int().positive(),
2526
+ name: z18.string().trim().min(1).max(UPTIME_LIMITS.nameMaxChars),
2527
+ kind: z18.enum(UPTIME_KINDS),
2528
+ url: z18.string().max(UPTIME_LIMITS.urlMaxChars).nullable(),
2529
+ host: z18.string().max(253).nullable(),
2530
+ port: z18.number().int().min(1).max(65535).nullable(),
2531
+ method: z18.enum(UPTIME_METHODS).default("GET"),
2532
+ headers: z18.array(header).max(UPTIME_LIMITS.headersMax).default([]),
2533
+ followRedirects: z18.boolean().default(false),
2534
+ timeoutMs: z18.number().int().min(UPTIME_LIMITS.timeoutMs.min).max(UPTIME_LIMITS.timeoutMs.max),
2535
+ intervalSeconds: z18.number().int().refine((n) => UPTIME_INTERVALS.includes(n)),
2536
+ regions: z18.array(z18.enum(UPTIME_REGIONS)).min(UPTIME_LIMITS.minRegions).max(UPTIME_REGIONS.length),
2537
+ assertions: z18.array(assertionSchema).max(UPTIME_LIMITS.assertionsMax).default([]),
2538
+ failureThreshold: z18.number().int().min(1).max(5),
2539
+ recoveryThreshold: z18.number().int().min(1).max(5),
2540
+ certWarningDays: z18.number().int().min(1).max(60),
2541
+ environment: z18.string().trim().max(64).default(""),
2542
+ strictMetadata: z18.boolean().default(false),
2543
+ evidenceOnFailure: z18.boolean().default(true)
2316
2544
  }).superRefine((v, ctx) => {
2317
2545
  if (v.kind === "http" && !v.url)
2318
2546
  ctx.addIssue({ code: "custom", path: ["url"], message: "INVALID_INPUT" });
@@ -2323,243 +2551,243 @@ var uptimeCheckInputSchema = z17.object({
2323
2551
  if (v.headers.some((h) => isForbiddenHeader(h.name)))
2324
2552
  ctx.addIssue({ code: "custom", path: ["headers"], message: "UPTIME_HEADER_FORBIDDEN" });
2325
2553
  });
2326
- var uptimeDefinitionSchema = z17.object({
2327
- check_id: z17.guid(),
2328
- workspace_id: z17.guid(),
2329
- project_id: z17.number().int().positive(),
2330
- revision: z17.number().int().nonnegative(),
2331
- kind: z17.enum(UPTIME_KINDS),
2332
- url: z17.string().max(UPTIME_LIMITS.urlMaxChars).nullable(),
2333
- host: z17.string().max(253).nullable(),
2334
- port: z17.number().int().min(1).max(65535).nullable(),
2335
- method: z17.enum(UPTIME_METHODS),
2336
- headers: z17.array(header).max(UPTIME_LIMITS.headersMax),
2337
- follow_redirects: z17.boolean(),
2338
- timeout_ms: z17.number().int().min(UPTIME_LIMITS.timeoutMs.min).max(UPTIME_LIMITS.timeoutMs.max),
2339
- interval_seconds: z17.number().int().positive(),
2340
- regions: z17.array(z17.enum(UPTIME_REGIONS)).min(1).max(3),
2341
- assertions: z17.array(assertionSchema).max(UPTIME_LIMITS.assertionsMax),
2342
- failure_threshold: z17.number().int().min(1).max(5),
2343
- recovery_threshold: z17.number().int().min(1).max(5),
2344
- cert_warning_days: z17.number().int().min(1).max(60),
2345
- strict_metadata: z17.boolean(),
2346
- evidence_on_failure: z17.boolean(),
2347
- paused_until: z17.string().nullable(),
2348
- muted_until: z17.string().nullable()
2554
+ var uptimeDefinitionSchema = z18.object({
2555
+ check_id: z18.guid(),
2556
+ workspace_id: z18.guid(),
2557
+ project_id: z18.number().int().positive(),
2558
+ revision: z18.number().int().nonnegative(),
2559
+ kind: z18.enum(UPTIME_KINDS),
2560
+ url: z18.string().max(UPTIME_LIMITS.urlMaxChars).nullable(),
2561
+ host: z18.string().max(253).nullable(),
2562
+ port: z18.number().int().min(1).max(65535).nullable(),
2563
+ method: z18.enum(UPTIME_METHODS),
2564
+ headers: z18.array(header).max(UPTIME_LIMITS.headersMax),
2565
+ follow_redirects: z18.boolean(),
2566
+ timeout_ms: z18.number().int().min(UPTIME_LIMITS.timeoutMs.min).max(UPTIME_LIMITS.timeoutMs.max),
2567
+ interval_seconds: z18.number().int().positive(),
2568
+ regions: z18.array(z18.enum(UPTIME_REGIONS)).min(1).max(3),
2569
+ assertions: z18.array(assertionSchema).max(UPTIME_LIMITS.assertionsMax),
2570
+ failure_threshold: z18.number().int().min(1).max(5),
2571
+ recovery_threshold: z18.number().int().min(1).max(5),
2572
+ cert_warning_days: z18.number().int().min(1).max(60),
2573
+ strict_metadata: z18.boolean(),
2574
+ evidence_on_failure: z18.boolean(),
2575
+ paused_until: z18.string().nullable(),
2576
+ muted_until: z18.string().nullable()
2349
2577
  });
2350
- var timingsSchema = z17.object({
2351
- dns_ms: z17.number().nonnegative().max(60000).nullable(),
2352
- connect_ms: z17.number().nonnegative().max(60000).nullable(),
2353
- tls_ms: z17.number().nonnegative().max(60000).nullable(),
2354
- ttfb_ms: z17.number().nonnegative().max(60000).nullable(),
2355
- download_ms: z17.number().nonnegative().max(60000).nullable(),
2356
- total_ms: z17.number().nonnegative().max(60000)
2578
+ var timingsSchema = z18.object({
2579
+ dns_ms: z18.number().nonnegative().max(60000).nullable(),
2580
+ connect_ms: z18.number().nonnegative().max(60000).nullable(),
2581
+ tls_ms: z18.number().nonnegative().max(60000).nullable(),
2582
+ ttfb_ms: z18.number().nonnegative().max(60000).nullable(),
2583
+ download_ms: z18.number().nonnegative().max(60000).nullable(),
2584
+ total_ms: z18.number().nonnegative().max(60000)
2357
2585
  });
2358
- var probeResultSchema = z17.object({
2359
- check_id: z17.guid(),
2360
- revision: z17.number().int().nonnegative(),
2361
- slot: z17.number().int().nonnegative(),
2362
- region: z17.enum(UPTIME_REGIONS),
2363
- run_now: z17.string().max(64).optional(),
2364
- scheduled_at: z17.number().int().positive(),
2365
- started_at: z17.number().int().positive(),
2366
- outcome: z17.enum(UPTIME_OUTCOMES),
2367
- reason: z17.enum(UPTIME_REASONS).nullable(),
2368
- reason_group: z17.enum(UPTIME_REASON_GROUPS).nullable(),
2369
- status_code: z17.number().int().min(100).max(599).nullable(),
2586
+ var probeResultSchema = z18.object({
2587
+ check_id: z18.guid(),
2588
+ revision: z18.number().int().nonnegative(),
2589
+ slot: z18.number().int().nonnegative(),
2590
+ region: z18.enum(UPTIME_REGIONS),
2591
+ run_now: z18.string().max(64).optional(),
2592
+ scheduled_at: z18.number().int().positive(),
2593
+ started_at: z18.number().int().positive(),
2594
+ outcome: z18.enum(UPTIME_OUTCOMES),
2595
+ reason: z18.enum(UPTIME_REASONS).nullable(),
2596
+ reason_group: z18.enum(UPTIME_REASON_GROUPS).nullable(),
2597
+ status_code: z18.number().int().min(100).max(599).nullable(),
2370
2598
  timings: timingsSchema.nullable(),
2371
- ip_family: z17.enum(["v4", "v6"]).nullable(),
2372
- http_version: z17.string().max(8).nullable(),
2373
- cert_not_after: z17.number().int().positive().nullable(),
2374
- cert_issuer: z17.string().max(200).nullable(),
2375
- cert_expiring: z17.boolean(),
2376
- evidence_sealed: z17.string().max(16384).nullable()
2599
+ ip_family: z18.enum(["v4", "v6"]).nullable(),
2600
+ http_version: z18.string().max(8).nullable(),
2601
+ cert_not_after: z18.number().int().positive().nullable(),
2602
+ cert_issuer: z18.string().max(200).nullable(),
2603
+ cert_expiring: z18.boolean(),
2604
+ evidence_sealed: z18.string().max(16384).nullable()
2377
2605
  });
2378
- var probeIdSchema = z17.string().regex(/^probe-(eu|us|ap)-[a-z0-9]{4,16}$/);
2379
- var resultBatchSchema = z17.object({
2380
- v: z17.literal(1),
2606
+ var probeIdSchema = z18.string().regex(/^probe-(eu|us|ap)-[a-z0-9]{4,16}$/);
2607
+ var resultBatchSchema = z18.object({
2608
+ v: z18.literal(1),
2381
2609
  probe_id: probeIdSchema,
2382
- region: z17.enum(UPTIME_REGIONS),
2383
- version: z17.string().max(40),
2384
- sent_at: z17.number().int().positive(),
2385
- results: z17.array(probeResultSchema).max(UPTIME_LIMITS.resultsBatchMax),
2386
- stats: z17.object({ lag_p99_ms: z17.number().nonnegative(), checks_per_min: z17.number().nonnegative() })
2610
+ region: z18.enum(UPTIME_REGIONS),
2611
+ version: z18.string().max(40),
2612
+ sent_at: z18.number().int().positive(),
2613
+ results: z18.array(probeResultSchema).max(UPTIME_LIMITS.resultsBatchMax),
2614
+ stats: z18.object({ lag_p99_ms: z18.number().nonnegative(), checks_per_min: z18.number().nonnegative() })
2387
2615
  });
2388
2616
  var assignmentSchema = uptimeDefinitionSchema.omit({ workspace_id: true, paused_until: true, muted_until: true }).extend({
2389
- seal_public_key: z17.string().regex(/^[A-Za-z0-9_-]{43}$/).nullable()
2617
+ seal_public_key: z18.string().regex(/^[A-Za-z0-9_-]{43}$/).nullable()
2390
2618
  });
2391
- var assignmentsSchema = z17.object({
2392
- v: z17.literal(1),
2393
- region: z17.enum(UPTIME_REGIONS),
2394
- revision: z17.number().int().nonnegative(),
2395
- issued_at: z17.number().int().positive(),
2396
- checks: z17.array(assignmentSchema).max(50000),
2397
- denied_hosts: z17.array(z17.string().max(253)).max(1e4),
2398
- run_now: z17.array(z17.object({ id: z17.string().max(64), check_id: z17.guid(), expires_at: z17.number().int() })).max(500)
2619
+ var assignmentsSchema = z18.object({
2620
+ v: z18.literal(1),
2621
+ region: z18.enum(UPTIME_REGIONS),
2622
+ revision: z18.number().int().nonnegative(),
2623
+ issued_at: z18.number().int().positive(),
2624
+ checks: z18.array(assignmentSchema).max(50000),
2625
+ denied_hosts: z18.array(z18.string().max(253)).max(1e4),
2626
+ run_now: z18.array(z18.object({ id: z18.string().max(64), check_id: z18.guid(), expires_at: z18.number().int() })).max(500)
2399
2627
  });
2400
- var uuid3 = z17.guid();
2401
- var b64key = z17.string().regex(/^[A-Za-z0-9_-]{43}$/);
2402
- var iso4 = z17.string().datetime();
2403
- var uptimeSyncSchema = z17.object({
2404
- v: z17.literal(1),
2628
+ var uuid3 = z18.guid();
2629
+ var b64key = z18.string().regex(/^[A-Za-z0-9_-]{43}$/);
2630
+ var iso4 = z18.string().datetime();
2631
+ var uptimeSyncSchema = z18.object({
2632
+ v: z18.literal(1),
2405
2633
  workspace_id: uuid3,
2406
- revision: z17.number().int().positive(),
2407
- workspace_status: z17.enum(["active", "suspended", "deleting"]),
2408
- suspended: z17.boolean(),
2409
- checks: z17.array(uptimeDefinitionSchema).max(UPTIME_LIMITS.maxChecksPerWorkspace),
2410
- projects: z17.array(z17.object({ id: z17.number().int().positive(), node_id: z17.guid().nullable(), seal_public_key: b64key.nullable() })).max(1000)
2634
+ revision: z18.number().int().positive(),
2635
+ workspace_status: z18.enum(["active", "suspended", "deleting"]),
2636
+ suspended: z18.boolean(),
2637
+ checks: z18.array(uptimeDefinitionSchema).max(UPTIME_LIMITS.maxChecksPerWorkspace),
2638
+ projects: z18.array(z18.object({ id: z18.number().int().positive(), node_id: z18.guid().nullable(), seal_public_key: b64key.nullable() })).max(1000)
2411
2639
  });
2412
- var uptimeReconcileSchema = z17.object({
2413
- v: z17.literal(1),
2414
- as_of: z17.number().int().positive(),
2415
- workspace_ids: z17.array(uuid3).max(UPTIME_LIMITS.reconcileMaxWorkspaces),
2416
- heartbeat_routes: z17.array(z17.string().regex(PING_ROUTE_RE)).max(UPTIME_LIMITS.reconcileMaxWorkspaces).optional()
2640
+ var uptimeReconcileSchema = z18.object({
2641
+ v: z18.literal(1),
2642
+ as_of: z18.number().int().positive(),
2643
+ workspace_ids: z18.array(uuid3).max(UPTIME_LIMITS.reconcileMaxWorkspaces),
2644
+ heartbeat_routes: z18.array(z18.string().regex(PING_ROUTE_RE)).max(UPTIME_LIMITS.reconcileMaxWorkspaces).optional()
2417
2645
  });
2418
- var probeDirectorySyncSchema = z17.object({
2419
- v: z17.literal(1),
2420
- revision: z17.number().int().positive(),
2421
- probes: z17.array(z17.object({ probe_id: probeIdSchema, region: z17.enum(UPTIME_REGIONS), public_key: b64key, status: z17.enum(["active", "revoked"]) })).max(30),
2422
- denied_hosts: z17.array(z17.string().min(1).max(253)).max(1e4)
2646
+ var probeDirectorySyncSchema = z18.object({
2647
+ v: z18.literal(1),
2648
+ revision: z18.number().int().positive(),
2649
+ probes: z18.array(z18.object({ probe_id: probeIdSchema, region: z18.enum(UPTIME_REGIONS), public_key: b64key, status: z18.enum(["active", "revoked"]) })).max(30),
2650
+ denied_hosts: z18.array(z18.string().min(1).max(253)).max(1e4)
2423
2651
  });
2424
- var runNowRequestSchema = z17.object({ v: z17.literal(1), workspace_id: uuid3, check_id: uuid3, run_id: z17.string().regex(/^[A-Za-z0-9_-]{8,64}$/) });
2425
- var signedAssignmentsSchema = z17.object({ assignments: assignmentsSchema, sig: z17.string().regex(/^[A-Za-z0-9_-]{86}$/) });
2426
- var uptimeRegionStateSchema = z17.object({
2427
- region: z17.enum(UPTIME_REGIONS),
2428
- outcome: z17.enum(UPTIME_OUTCOMES),
2429
- reason: z17.enum(UPTIME_REASONS).nullable(),
2430
- status_code: z17.number().int().min(100).max(599).nullable(),
2431
- total_ms: z17.number().nonnegative().max(60000).nullable(),
2652
+ var runNowRequestSchema = z18.object({ v: z18.literal(1), workspace_id: uuid3, check_id: uuid3, run_id: z18.string().regex(/^[A-Za-z0-9_-]{8,64}$/) });
2653
+ var signedAssignmentsSchema = z18.object({ assignments: assignmentsSchema, sig: z18.string().regex(/^[A-Za-z0-9_-]{86}$/) });
2654
+ var uptimeRegionStateSchema = z18.object({
2655
+ region: z18.enum(UPTIME_REGIONS),
2656
+ outcome: z18.enum(UPTIME_OUTCOMES),
2657
+ reason: z18.enum(UPTIME_REASONS).nullable(),
2658
+ status_code: z18.number().int().min(100).max(599).nullable(),
2659
+ total_ms: z18.number().nonnegative().max(60000).nullable(),
2432
2660
  timings: timingsSchema.nullable().optional(),
2433
2661
  at: iso4
2434
2662
  });
2435
- var uptimeStatusReportSchema = z17.object({
2663
+ var uptimeStatusReportSchema = z18.object({
2436
2664
  check_id: uuid3,
2437
- revision: z17.number().int().nonnegative(),
2438
- status: z17.enum(UPTIME_STATUSES),
2439
- last_verdict: z17.enum(SLOT_VERDICTS).nullable(),
2665
+ revision: z18.number().int().nonnegative(),
2666
+ status: z18.enum(UPTIME_STATUSES),
2667
+ last_verdict: z18.enum(SLOT_VERDICTS).nullable(),
2440
2668
  last_slot_at: iso4.nullable(),
2441
2669
  incident_id: uuid3.nullable(),
2442
- down_streak: z17.number().int().nonnegative(),
2443
- up_streak: z17.number().int().nonnegative(),
2444
- regions: z17.array(uptimeRegionStateSchema).max(3),
2445
- unobserved_regions: z17.array(z17.enum(UPTIME_REGIONS)).max(3),
2670
+ down_streak: z18.number().int().nonnegative(),
2671
+ up_streak: z18.number().int().nonnegative(),
2672
+ regions: z18.array(uptimeRegionStateSchema).max(3),
2673
+ unobserved_regions: z18.array(z18.enum(UPTIME_REGIONS)).max(3),
2446
2674
  cert_not_after: iso4.nullable(),
2447
- cert_expiring: z17.boolean(),
2448
- run_now: z17.object({ run_id: z17.string().max(64), results: z17.array(uptimeRegionStateSchema).max(3) }).nullable()
2675
+ cert_expiring: z18.boolean(),
2676
+ run_now: z18.object({ run_id: z18.string().max(64), results: z18.array(uptimeRegionStateSchema).max(3) }).nullable()
2449
2677
  });
2450
2678
  var UPTIME_EVENT_KINDS = ["opened", "resolved", "cert_expiring"];
2451
- var uptimeEventSchema = z17.object({
2452
- event_id: z17.string().regex(/^[A-Za-z0-9:_-]{8,96}$/),
2679
+ var uptimeEventSchema = z18.object({
2680
+ event_id: z18.string().regex(/^[A-Za-z0-9:_-]{8,96}$/),
2453
2681
  check_id: uuid3,
2454
- kind: z17.enum(UPTIME_EVENT_KINDS),
2682
+ kind: z18.enum(UPTIME_EVENT_KINDS),
2455
2683
  incident_id: uuid3.nullable(),
2456
2684
  at: iso4,
2457
- reason: z17.enum(UPTIME_REASONS).nullable(),
2458
- regions: z17.array(z17.enum(UPTIME_REGIONS)).max(3),
2459
- cert_days_left: z17.number().int().nullable()
2685
+ reason: z18.enum(UPTIME_REASONS).nullable(),
2686
+ regions: z18.array(z18.enum(UPTIME_REGIONS)).max(3),
2687
+ cert_days_left: z18.number().int().nullable()
2460
2688
  });
2461
- var uptimeMinuteSchema = z17.object({
2689
+ var uptimeMinuteSchema = z18.object({
2462
2690
  check_id: uuid3,
2463
2691
  minute: iso4,
2464
- up: z17.number().int().nonnegative(),
2465
- degraded: z17.number().int().nonnegative(),
2466
- down: z17.number().int().nonnegative(),
2467
- unknown: z17.number().int().nonnegative(),
2468
- latency: z17.array(z17.object({ region: z17.enum(UPTIME_REGIONS), n: z17.number().int().positive(), p50_ms: z17.number().nonnegative(), p95_ms: z17.number().nonnegative() })).max(3)
2692
+ up: z18.number().int().nonnegative(),
2693
+ degraded: z18.number().int().nonnegative(),
2694
+ down: z18.number().int().nonnegative(),
2695
+ unknown: z18.number().int().nonnegative(),
2696
+ latency: z18.array(z18.object({ region: z18.enum(UPTIME_REGIONS), n: z18.number().int().positive(), p50_ms: z18.number().nonnegative(), p95_ms: z18.number().nonnegative() })).max(3)
2469
2697
  });
2470
- var uptimeReportSchema = z17.object({
2471
- v: z17.literal(1),
2698
+ var uptimeReportSchema = z18.object({
2699
+ v: z18.literal(1),
2472
2700
  workspace_id: uuid3,
2473
- revision: z17.number().int().nonnegative(),
2701
+ revision: z18.number().int().nonnegative(),
2474
2702
  sent_at: iso4,
2475
- events: z17.array(uptimeEventSchema).max(UPTIME_LIMITS.reportMaxEvents),
2476
- statuses: z17.array(uptimeStatusReportSchema).max(UPTIME_LIMITS.reportMaxStatuses),
2477
- minutes: z17.array(uptimeMinuteSchema).max(UPTIME_LIMITS.reportMaxMinutes)
2703
+ events: z18.array(uptimeEventSchema).max(UPTIME_LIMITS.reportMaxEvents),
2704
+ statuses: z18.array(uptimeStatusReportSchema).max(UPTIME_LIMITS.reportMaxStatuses),
2705
+ minutes: z18.array(uptimeMinuteSchema).max(UPTIME_LIMITS.reportMaxMinutes)
2478
2706
  });
2479
- var probeFleetReportSchema = z17.object({
2480
- v: z17.literal(1),
2707
+ var probeFleetReportSchema = z18.object({
2708
+ v: z18.literal(1),
2481
2709
  sent_at: iso4,
2482
- probes: z17.array(z17.object({
2710
+ probes: z18.array(z18.object({
2483
2711
  probe_id: probeIdSchema,
2484
- region: z17.enum(UPTIME_REGIONS),
2485
- version: z17.string().max(40).nullable(),
2712
+ region: z18.enum(UPTIME_REGIONS),
2713
+ version: z18.string().max(40).nullable(),
2486
2714
  last_seen_at: iso4.nullable(),
2487
- lag_p99_ms: z17.number().nonnegative().nullable(),
2488
- checks_per_min: z17.number().nonnegative().nullable()
2715
+ lag_p99_ms: z18.number().nonnegative().nullable(),
2716
+ checks_per_min: z18.number().nonnegative().nullable()
2489
2717
  })).max(30),
2490
- regions_alive: z17.array(z17.enum(UPTIME_REGIONS)).max(3)
2718
+ regions_alive: z18.array(z18.enum(UPTIME_REGIONS)).max(3)
2491
2719
  });
2492
- var probeEnrollSchema = z17.object({
2493
- v: z17.literal(1),
2720
+ var probeEnrollSchema = z18.object({
2721
+ v: z18.literal(1),
2494
2722
  probe_id: probeIdSchema,
2495
- public_key: z17.string().regex(/^[A-Za-z0-9_-]{43}$/),
2496
- code: z17.string().regex(/^[A-Za-z0-9_-]{43}$/),
2497
- ts: z17.number().int().positive(),
2498
- sig: z17.string().regex(/^[A-Za-z0-9_-]{86}$/)
2723
+ public_key: z18.string().regex(/^[A-Za-z0-9_-]{43}$/),
2724
+ code: z18.string().regex(/^[A-Za-z0-9_-]{43}$/),
2725
+ ts: z18.number().int().positive(),
2726
+ sig: z18.string().regex(/^[A-Za-z0-9_-]{86}$/)
2499
2727
  });
2500
- var uptimeEvidenceEnvelopeSchema = z17.object({
2501
- v: z17.literal(1),
2502
- check_id: z17.guid(),
2503
- slot: z17.number().int().nonnegative(),
2504
- region: z17.enum(UPTIME_REGIONS),
2728
+ var uptimeEvidenceEnvelopeSchema = z18.object({
2729
+ v: z18.literal(1),
2730
+ check_id: z18.guid(),
2731
+ slot: z18.number().int().nonnegative(),
2732
+ region: z18.enum(UPTIME_REGIONS),
2505
2733
  probe_id: probeIdSchema,
2506
- at: z17.number().int().positive(),
2507
- sealed: z17.string().regex(/^[A-Za-z0-9_-]+$/).max(16384)
2734
+ at: z18.number().int().positive(),
2735
+ sealed: z18.string().regex(/^[A-Za-z0-9_-]+$/).max(16384)
2508
2736
  }).strict();
2509
- var uptimeEvidenceSchema = z17.object({
2510
- v: z17.literal(1),
2511
- check_id: z17.guid(),
2512
- slot: z17.number().int().nonnegative(),
2513
- region: z17.enum(UPTIME_REGIONS),
2514
- at: z17.number().int().positive(),
2515
- reason: z17.enum(UPTIME_REASONS).nullable(),
2516
- status_line: z17.string().max(200).nullable(),
2517
- headers: z17.record(z17.string().max(64), z17.string().max(512)).refine((h) => Object.keys(h).length <= 20),
2518
- body: z17.string().max(UPTIME_LIMITS.evidenceMaxBytes * 4).nullable(),
2519
- body_truncated: z17.boolean(),
2737
+ var uptimeEvidenceSchema = z18.object({
2738
+ v: z18.literal(1),
2739
+ check_id: z18.guid(),
2740
+ slot: z18.number().int().nonnegative(),
2741
+ region: z18.enum(UPTIME_REGIONS),
2742
+ at: z18.number().int().positive(),
2743
+ reason: z18.enum(UPTIME_REASONS).nullable(),
2744
+ status_line: z18.string().max(200).nullable(),
2745
+ headers: z18.record(z18.string().max(64), z18.string().max(512)).refine((h) => Object.keys(h).length <= 20),
2746
+ body: z18.string().max(UPTIME_LIMITS.evidenceMaxBytes * 4).nullable(),
2747
+ body_truncated: z18.boolean(),
2520
2748
  timings: timingsSchema.nullable(),
2521
- ip: z17.string().max(64).nullable(),
2522
- error: z17.string().max(300).nullable()
2749
+ ip: z18.string().max(64).nullable(),
2750
+ error: z18.string().max(300).nullable()
2523
2751
  }).strict();
2524
- var uptimeEvidenceListSchema = z17.object({
2525
- items: z17.array(uptimeEvidenceSchema.extend({ received_at: z17.number().int().positive() })).max(UPTIME_LIMITS.evidenceKeepPerCheck)
2752
+ var uptimeEvidenceListSchema = z18.object({
2753
+ items: z18.array(uptimeEvidenceSchema.extend({ received_at: z18.number().int().positive() })).max(UPTIME_LIMITS.evidenceKeepPerCheck)
2526
2754
  });
2527
2755
 
2528
2756
  // ../src/shared/contracts/api-ops/monitors.ts
2529
- var anyMonitorInputSchema = z18.union([monitorInputSchema, signalMonitorInputSchema]);
2757
+ var anyMonitorInputSchema = z19.union([monitorInputSchema, signalMonitorInputSchema]);
2530
2758
  var MAINTENANCE_INPUTS = {
2531
- create: z18.object({ workspaceId: uuid, input: maintenanceInputSchema }),
2532
- update: z18.object({ workspaceId: uuid, windowId: uuid, input: maintenanceInputSchema }),
2533
- delete: z18.object({ workspaceId: uuid, windowId: uuid })
2759
+ create: z19.object({ workspaceId: uuid, input: maintenanceInputSchema }),
2760
+ update: z19.object({ workspaceId: uuid, windowId: uuid, input: maintenanceInputSchema }),
2761
+ delete: z19.object({ workspaceId: uuid, windowId: uuid })
2534
2762
  };
2535
2763
  var MONITOR_INPUTS = {
2536
- create: z18.object({ projectId, slug: z18.string().regex(SLUG_RE), input: anyMonitorInputSchema }),
2537
- update: z18.object({ monitorId: uuid, input: anyMonitorInputSchema }),
2538
- delete: z18.object({ monitorId: uuid, confirmSlug: z18.string().max(64) }),
2539
- setPause: z18.object({ monitorId: uuid, until: holdUntil }),
2540
- setMuted: z18.object({ monitorId: uuid, muted: z18.boolean() }),
2541
- dismissDiscovery: z18.object({ discoveryId: uuid }),
2542
- rotatePing: z18.object({
2764
+ create: z19.object({ projectId, slug: z19.string().regex(SLUG_RE), input: anyMonitorInputSchema }),
2765
+ update: z19.object({ monitorId: uuid, input: anyMonitorInputSchema }),
2766
+ delete: z19.object({ monitorId: uuid, confirmSlug: z19.string().max(64) }),
2767
+ setPause: z19.object({ monitorId: uuid, until: holdUntil }),
2768
+ setMuted: z19.object({ monitorId: uuid, muted: z19.boolean() }),
2769
+ dismissDiscovery: z19.object({ discoveryId: uuid }),
2770
+ rotatePing: z19.object({
2543
2771
  monitorId: uuid,
2544
- graceHours: z18.number().int().refine((h) => HEARTBEAT_LIMITS.rotationGraceHoursChoices.includes(h))
2772
+ graceHours: z19.number().int().refine((h) => HEARTBEAT_LIMITS.rotationGraceHoursChoices.includes(h))
2545
2773
  }),
2546
- monitorOnly: z18.object({ monitorId: uuid })
2774
+ monitorOnly: z19.object({ monitorId: uuid })
2547
2775
  };
2548
2776
  var UPTIME_INPUTS = {
2549
2777
  create: uptimeCheckInputSchema,
2550
- update: z18.object({ checkId: uuid, input: uptimeCheckInputSchema }),
2551
- checkOnly: z18.object({ checkId: uuid }),
2552
- setHold: z18.object({ checkId: uuid, kind: z18.enum(["pause", "mute"]), until: holdUntil })
2778
+ update: z19.object({ checkId: uuid, input: uptimeCheckInputSchema }),
2779
+ checkOnly: z19.object({ checkId: uuid }),
2780
+ setHold: z19.object({ checkId: uuid, kind: z19.enum(["pause", "mute"]), until: holdUntil })
2553
2781
  };
2554
2782
  var SLO_INPUTS = {
2555
- create: z18.object({ workspaceId: uuid, input: sloInputSchema }),
2556
- update: z18.object({ sloId: uuid, input: sloInputSchema }),
2557
- sloOnly: z18.object({ sloId: uuid }),
2558
- setHold: z18.object({ sloId: uuid, kind: z18.enum(["pause", "mute"]), until: holdUntil }),
2559
- import: z18.object({
2783
+ create: z19.object({ workspaceId: uuid, input: sloInputSchema }),
2784
+ update: z19.object({ sloId: uuid, input: sloInputSchema }),
2785
+ sloOnly: z19.object({ sloId: uuid }),
2786
+ setHold: z19.object({ sloId: uuid, kind: z19.enum(["pause", "mute"]), until: holdUntil }),
2787
+ import: z19.object({
2560
2788
  workspaceId: uuid,
2561
- text: z18.string().max(SLO_LIMITS.openSloMaxBytes * 2),
2562
- dryRun: z18.boolean()
2789
+ text: z19.string().max(SLO_LIMITS.openSloMaxBytes * 2),
2790
+ dryRun: z19.boolean()
2563
2791
  })
2564
2792
  };
2565
2793
  var m = "monitors:write";
@@ -2901,19 +3129,277 @@ var MONITOR_OPERATIONS = [
2901
3129
  ];
2902
3130
 
2903
3131
  // ../src/shared/contracts/api-ops/node-data.ts
2904
- import { z as z19 } from "zod";
2905
- var issueId = z19.number().int().positive();
2906
- var csv = z19.string().min(1).max(2000);
2907
- var name2 = z19.string().min(1).max(256);
2908
- var period = z19.enum(["1h", "24h", "7d", "14d", "30d"]);
2909
- var nodeCursor = z19.string().min(1).max(600).optional();
3132
+ import { z as z22 } from "zod";
3133
+
3134
+ // ../src/shared/contracts/release-health.ts
3135
+ import { z as z21 } from "zod";
3136
+
3137
+ // ../src/shared/contracts/sourcemaps.ts
3138
+ import { z as z20 } from "zod";
3139
+ var UPLOAD_LIMITS = {
3140
+ requestMaxBytes: RELAY_LIMITS.maxInflightBytes - 512 * 1024,
3141
+ tarMaxBytes: 64 * 1024 * 1024,
3142
+ fileMaxBytes: INGEST_LIMITS.sourceMapMaxBytes,
3143
+ filesMax: 1000,
3144
+ requestsPerHour: 60,
3145
+ retentionDays: 90
3146
+ };
3147
+ var UPLOAD_SCOPES = ["sourcemaps:write", "releases:write"];
3148
+ var UPLOAD_TOKEN_PATTERN = /^blv_sm_[A-Za-z0-9_-]{43}$/;
3149
+ var tokenHashSchema = z20.string().regex(/^[a-f0-9]{64}$/);
3150
+ var uploadTokenConfigSchema = z20.object({
3151
+ v: z20.literal(1),
3152
+ project_id: z20.number().int().positive(),
3153
+ project_public_id: z20.number().int().positive(),
3154
+ node_id: nodeIdSchema,
3155
+ workspace_id: z20.guid(),
3156
+ scopes: z20.array(z20.enum(UPLOAD_SCOPES)).min(1).max(4),
3157
+ expires_at: z20.string().datetime(),
3158
+ is_active: z20.boolean()
3159
+ });
3160
+ var releaseNameSchema = z20.string().min(1).max(200).regex(/^[^\s/\\\u0000-\u001f\u007f]+$/);
3161
+ var SENTRY_COMPAT = {
3162
+ apiRoot: "/api/0",
3163
+ chunkSize: 2 * 1024 * 1024,
3164
+ chunksPerRequest: 3,
3165
+ maxRequestSize: 7 * 1024 * 1024,
3166
+ maxFileSize: 64 * 1024 * 1024,
3167
+ maxBundleEntries: 4000,
3168
+ concurrency: 1,
3169
+ maxWaitSeconds: 60,
3170
+ chunkBytesPerHour: 1024 * 1024 * 1024,
3171
+ pendingBytesPerProject: 128 * 1024 * 1024,
3172
+ pendingTtlMs: 60 * 60 * 1000
3173
+ };
3174
+ var sha1HexSchema = z20.string().regex(/^[0-9a-f]{40}$/);
3175
+ var assembleRequestSchema = z20.object({
3176
+ checksum: sha1HexSchema,
3177
+ chunks: z20.array(sha1HexSchema).max(Math.ceil(SENTRY_COMPAT.maxFileSize / SENTRY_COMPAT.chunkSize)),
3178
+ projects: z20.array(z20.string().max(200)).max(50).optional(),
3179
+ version: releaseNameSchema.optional(),
3180
+ dist: z20.string().max(64).regex(/^[A-Za-z0-9._-]*$/).optional()
3181
+ });
3182
+ var assembleResponseSchema = z20.object({
3183
+ state: z20.enum(["ok", "created", "assembling", "not_found", "error"]),
3184
+ missingChunks: z20.array(sha1HexSchema),
3185
+ detail: z20.string().max(200).nullable()
3186
+ });
3187
+ var uploadHeaderSchema = z20.object({
3188
+ id: z20.string().regex(/^[A-Za-z0-9_-]{8,64}$/),
3189
+ project_id: z20.number().int().positive(),
3190
+ release: releaseNameSchema.optional(),
3191
+ dist: z20.string().max(64).regex(/^[A-Za-z0-9._-]*$/).optional(),
3192
+ token: z20.string().regex(UPLOAD_TOKEN_PATTERN),
3193
+ content_encoding: z20.enum(["identity", "gzip"]),
3194
+ op: z20.enum(["tar", "chunks", "assemble", "release"]).optional(),
3195
+ chunks: z20.array(z20.object({
3196
+ sha1: sha1HexSchema,
3197
+ size: z20.number().int().positive().max(SENTRY_COMPAT.chunkSize)
3198
+ })).max(SENTRY_COMPAT.chunksPerRequest).optional()
3199
+ });
3200
+ var uploadResultSchema = z20.object({
3201
+ accepted: z20.array(z20.object({ file: z20.string().max(200), debug_id: z20.guid(), size: z20.number().int() })).max(UPLOAD_LIMITS.filesMax),
3202
+ skipped: z20.array(z20.object({
3203
+ file: z20.string().max(200),
3204
+ reason: z20.enum([
3205
+ "not_a_map",
3206
+ "no_debug_id",
3207
+ "too_large",
3208
+ "invalid_json",
3209
+ "unsupported",
3210
+ "bad_name"
3211
+ ])
3212
+ })).max(UPLOAD_LIMITS.filesMax)
3213
+ });
3214
+
3215
+ // ../src/shared/contracts/release-health.ts
3216
+ var RELEASE_HEALTH = {
3217
+ verifyHours: 24,
3218
+ windowHours: 24,
3219
+ increaseFactor: 2,
3220
+ increaseMinEvents: 10,
3221
+ listMax: 50,
3222
+ candidatesMax: 500,
3223
+ releasesMax: 50,
3224
+ commitsMax: 1000,
3225
+ deploysMax: 50,
3226
+ memoryReleasesMax: 5000,
3227
+ memoryDeploysMax: 1e4,
3228
+ requestsPerHour: 600,
3229
+ bodyMaxBytes: 4 * 1024 * 1024,
3230
+ fixLookbackDays: 30
3231
+ };
3232
+ var FIX_STATUSES = ["fixed", "not_fixed", "unverified", "unknown"];
3233
+ var FIX_REASONS = [
3234
+ "verified",
3235
+ "event_in_release",
3236
+ "regressed",
3237
+ "order_unknown",
3238
+ "not_deployed",
3239
+ "no_deploy_marker",
3240
+ "not_running",
3241
+ "too_early"
3242
+ ];
3243
+ var RESOLUTION_MODES = ["now", "next_release", "in_release"];
3244
+ var RELEASE_SOURCES = ["cli", "api", "sdk"];
3245
+ var environmentNameSchema = z21.string().trim().regex(ENVIRONMENT_RE).refine((v) => !/[\s/]/.test(v));
3246
+ var isoTime = z21.string().datetime({ offset: true });
3247
+ var httpUrl = z21.string().max(500).refine((v) => /^https?:\/\/[^\s]+$/i.test(v), "http(s) URL");
3248
+ var DEPLOY_ID_RE = /^[A-Za-z0-9_.:-]{1,64}$/;
3249
+ var commitShaSchema = z21.string().regex(/^[0-9A-Za-z._-]{4,64}$/);
3250
+ var repoNameSchema = z21.string().min(1).max(200).regex(/^[^\u0000-\u001f\u007f]+$/);
3251
+ var deploymentInputSchema = z21.object({
3252
+ version: releaseNameSchema,
3253
+ environment: environmentNameSchema,
3254
+ name: z21.string().trim().min(1).max(200).optional(),
3255
+ url: httpUrl.optional(),
3256
+ started_at: isoTime.optional(),
3257
+ finished_at: isoTime.optional(),
3258
+ deploy_id: z21.string().regex(DEPLOY_ID_RE).optional()
3259
+ });
3260
+ var commitSchema = z21.object({ sha: commitShaSchema, repo: repoNameSchema.optional() });
3261
+ var releaseRelaySchema = z21.discriminatedUnion("action", [
3262
+ z21.object({
3263
+ action: z21.literal("create"),
3264
+ version: releaseNameSchema,
3265
+ date_released: isoTime.optional(),
3266
+ commits: z21.array(commitSchema).max(RELEASE_HEALTH.commitsMax).optional()
3267
+ }),
3268
+ z21.object({
3269
+ action: z21.literal("update"),
3270
+ version: releaseNameSchema,
3271
+ date_released: isoTime.optional(),
3272
+ commits: z21.array(commitSchema).max(RELEASE_HEALTH.commitsMax).optional()
3273
+ }),
3274
+ z21.object({ action: z21.literal("get"), version: releaseNameSchema }),
3275
+ z21.object({ action: z21.literal("list") }),
3276
+ z21.object({ action: z21.literal("previous"), version: releaseNameSchema }),
3277
+ z21.object({ action: z21.literal("deploy"), deploy: deploymentInputSchema }),
3278
+ z21.object({ action: z21.literal("deploys"), version: releaseNameSchema })
3279
+ ]);
3280
+ var cliCommit = z21.object({ id: z21.string().max(200), repository: z21.string().max(400).nullish() }).passthrough();
3281
+ var cliRef = z21.object({
3282
+ repository: z21.string().max(400),
3283
+ commit: z21.string().max(200),
3284
+ previousCommit: z21.string().max(200).nullish()
3285
+ }).passthrough();
3286
+ var cliReleaseCreateSchema = z21.object({
3287
+ version: releaseNameSchema,
3288
+ projects: z21.array(z21.string().max(200)).max(50).optional(),
3289
+ dateReleased: isoTime.nullish(),
3290
+ dateStarted: isoTime.nullish(),
3291
+ refs: z21.array(cliRef).max(100).optional(),
3292
+ commits: z21.array(cliCommit).max(1e4).optional()
3293
+ }).passthrough();
3294
+ var cliReleaseUpdateSchema = cliReleaseCreateSchema.omit({ version: true }).extend({ version: releaseNameSchema.optional() });
3295
+ var cliDeployCreateSchema = z21.object({
3296
+ environment: z21.string().max(64),
3297
+ name: z21.string().max(200).nullish(),
3298
+ url: z21.string().max(500).nullish(),
3299
+ dateStarted: isoTime.nullish(),
3300
+ dateFinished: isoTime.nullish()
3301
+ }).passthrough();
3302
+ var iso5 = z21.string();
3303
+ var releaseRowSchema = z21.object({
3304
+ version: z21.string(),
3305
+ source: z21.enum(RELEASE_SOURCES),
3306
+ environment: z21.string().nullable(),
3307
+ created_at: iso5.nullable(),
3308
+ date_released: iso5.nullable(),
3309
+ deployed_at: iso5.nullable(),
3310
+ last_deploy_at: iso5.nullable(),
3311
+ deploys: z21.number().int(),
3312
+ first_seen: iso5.nullable(),
3313
+ last_seen: iso5.nullable(),
3314
+ commit_count: z21.number().int(),
3315
+ events: z21.number().int(),
3316
+ events_per_hour: z21.number(),
3317
+ previous: z21.string().nullable(),
3318
+ previous_events_per_hour: z21.number().nullable(),
3319
+ new_issues: z21.number().int(),
3320
+ regressed_issues: z21.number().int(),
3321
+ increased_issues: z21.number().int()
3322
+ });
3323
+ var releaseListSchema = z21.object({
3324
+ releases: z21.array(releaseRowSchema),
3325
+ environments: z21.array(z21.string()),
3326
+ environment: z21.string().nullable(),
3327
+ has_deploy_markers: z21.boolean()
3328
+ });
3329
+ var healthIssueSchema = z21.object({
3330
+ issue_id: z21.number().int(),
3331
+ short_id: z21.string(),
3332
+ title: z21.string(),
3333
+ culprit: z21.string(),
3334
+ level: z21.string(),
3335
+ status: z21.string(),
3336
+ events: z21.number().int(),
3337
+ previous_events: z21.number().int(),
3338
+ first_seen: iso5.nullable(),
3339
+ sparkline: z21.array(z21.number().int())
3340
+ });
3341
+ var deploymentRowSchema = z21.object({
3342
+ deploy_id: z21.string(),
3343
+ version: z21.string(),
3344
+ environment: z21.string(),
3345
+ name: z21.string().nullable(),
3346
+ url: z21.string().nullable(),
3347
+ started_at: iso5,
3348
+ finished_at: iso5,
3349
+ source: z21.enum(RELEASE_SOURCES)
3350
+ });
3351
+ var releaseHealthSchema = z21.object({
3352
+ release: releaseRowSchema,
3353
+ compare: z21.string().nullable(),
3354
+ window: z21.object({
3355
+ start: iso5.nullable(),
3356
+ end: iso5.nullable(),
3357
+ hours: z21.number(),
3358
+ from_deploy: z21.boolean()
3359
+ }),
3360
+ new: z21.array(healthIssueSchema),
3361
+ regressed: z21.array(healthIssueSchema),
3362
+ increased: z21.array(healthIssueSchema),
3363
+ deploys: z21.array(deploymentRowSchema),
3364
+ commits: z21.array(commitSchema),
3365
+ truncated: z21.boolean()
3366
+ });
3367
+ var fixEnvSchema = z21.object({
3368
+ environment: z21.string(),
3369
+ status: z21.enum(FIX_STATUSES),
3370
+ reason: z21.enum(FIX_REASONS),
3371
+ target: z21.string().nullable(),
3372
+ target_deployed_at: iso5.nullable(),
3373
+ release: z21.string().nullable(),
3374
+ first_seen: iso5.nullable(),
3375
+ observed_hours: z21.number().nullable()
3376
+ });
3377
+ var fixStatusSchema = z21.object({
3378
+ issue_id: z21.number().int(),
3379
+ resolution: z21.object({
3380
+ mode: z21.enum(RESOLUTION_MODES),
3381
+ resolved_at: iso5,
3382
+ release: z21.string().nullable(),
3383
+ regressed: z21.boolean()
3384
+ }).nullable(),
3385
+ status: z21.enum(FIX_STATUSES).nullable(),
3386
+ environments: z21.array(fixEnvSchema),
3387
+ verify_hours: z21.number()
3388
+ });
3389
+
3390
+ // ../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();
2910
3396
  var windowFields = {
2911
- start: z19.string().max(40).optional(),
2912
- end: z19.string().max(40).optional()
3397
+ start: z22.string().max(40).optional(),
3398
+ end: z22.string().max(40).optional()
2913
3399
  };
2914
- var traceId = z19.string().regex(/^[0-9a-fA-F]{32}$/);
2915
- var spanId = z19.string().regex(/^[0-9a-fA-F]{16}$/);
2916
- var attrs = z19.string().max(2000).optional();
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();
2917
3403
  var telemetryCommon = {
2918
3404
  ...windowFields,
2919
3405
  project: csv.optional(),
@@ -2921,112 +3407,167 @@ var telemetryCommon = {
2921
3407
  service: csv.optional(),
2922
3408
  attrs
2923
3409
  };
2924
- var issueChange = z19.union([
2925
- z19.object({ action: z19.literal("resolve"), inNextRelease: z19.boolean().optional() }),
2926
- z19.object({ action: z19.literal("unresolve") }),
2927
- z19.object({ action: z19.literal("archive"), mode: z19.enum(["until_escalating", "forever"]) }),
2928
- z19.object({
2929
- action: z19.literal("archive"),
2930
- mode: z19.literal("until_condition"),
2931
- events: z19.number().int().min(1).max(1e6).optional(),
2932
- users: z19.number().int().min(1).max(1e5).optional(),
2933
- until: z19.string().datetime().optional()
2934
- }),
2935
- z19.object({ action: z19.literal("assign"), userId: z19.guid().nullable() }),
2936
- z19.object({ action: z19.literal("priority"), priority: z19.enum(["low", "medium", "high"]) })
3410
+ var issueChange = z22.union([
3411
+ z22.object({
3412
+ action: z22.literal("resolve"),
3413
+ inNextRelease: z22.boolean().optional(),
3414
+ inRelease: releaseNameSchema.optional()
3415
+ }),
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"]) })
2937
3427
  ]);
2938
3428
  var NODE_INPUTS = {
2939
- issuesList: z19.object({
3429
+ issuesList: z22.object({
2940
3430
  project: csv.optional(),
2941
- status: z19.enum(["unresolved", "resolved", "archived", "all"]).optional(),
3431
+ status: z22.enum(["unresolved", "resolved", "archived", "all"]).optional(),
2942
3432
  level: csv.optional(),
2943
3433
  priority: csv.optional(),
2944
3434
  environment: csv.optional(),
2945
3435
  release: csv.optional(),
2946
- assignee: z19.string().max(64).optional(),
3436
+ assignee: z22.string().max(64).optional(),
2947
3437
  period: period.optional(),
2948
- q: z19.string().max(200).optional(),
2949
- sort: z19.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
3438
+ q: z22.string().max(200).optional(),
3439
+ sort: z22.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
2950
3440
  cursor: nodeCursor,
2951
- limit: z19.number().int().min(1).max(100).optional()
3441
+ limit: z22.number().int().min(1).max(100).optional()
2952
3442
  }),
2953
- issue: z19.object({ issueId }),
2954
- issueStats: z19.object({ issueId, range: z19.enum(["24h", "30d"]).optional() }),
2955
- issueEvents: z19.object({ issueId, cursor: nodeCursor }),
2956
- issueEvent: z19.object({
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({
2957
3447
  issueId,
2958
- eventId: z19.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
3448
+ eventId: z22.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
2959
3449
  }),
2960
- issueUpdate: z19.object({ issueId, change: issueChange }),
2961
- issuesBulk: z19.object({
2962
- issueIds: z19.array(issueId).min(1).max(100),
3450
+ issueUpdate: z22.object({ issueId, change: issueChange }),
3451
+ issuesBulk: z22.object({
3452
+ issueIds: z22.array(issueId).min(1).max(100),
2963
3453
  action: issueChange
2964
3454
  }),
2965
- spansList: z19.object({
3455
+ spansList: z22.object({
2966
3456
  ...telemetryCommon,
2967
- operation: z19.string().min(1).max(1024).optional(),
2968
- status: z19.enum(["unset", "ok", "error"]).optional(),
2969
- kind: z19.enum(["internal", "server", "client", "producer", "consumer"]).optional(),
2970
- minDurationMs: z19.number().min(0).max(86400000).optional(),
2971
- maxDurationMs: z19.number().min(0).max(86400000).optional(),
2972
- mode: z19.enum(["spans", "traces"]).optional(),
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(),
2973
3463
  cursor: nodeCursor
2974
3464
  }),
2975
- spansHistogram: z19.object({
3465
+ spansHistogram: z22.object({
2976
3466
  ...telemetryCommon,
2977
- operation: z19.string().min(1).max(1024).optional(),
2978
- status: z19.enum(["unset", "ok", "error"]).optional()
3467
+ operation: z22.string().min(1).max(1024).optional(),
3468
+ status: z22.enum(["unset", "ok", "error"]).optional()
2979
3469
  }),
2980
- trace: z19.object({ traceId }),
2981
- traceSpans: z19.object({ traceId, errorsOnly: z19.enum(["1"]).optional(), ...windowFields }),
2982
- span: z19.object({ traceId, spanId, ...windowFields }),
2983
- logsList: z19.object({
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({
2984
3474
  ...telemetryCommon,
2985
- severityMin: z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3475
+ severityMin: z22.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
2986
3476
  traceId: traceId.optional(),
2987
3477
  spanId: spanId.optional(),
2988
- q: z19.string().max(500).optional(),
2989
- order: z19.enum(["asc", "desc"]).optional(),
3478
+ q: z22.string().max(500).optional(),
3479
+ order: z22.enum(["asc", "desc"]).optional(),
2990
3480
  cursor: nodeCursor
2991
3481
  }),
2992
- logsFacets: z19.object({
3482
+ logsFacets: z22.object({
2993
3483
  ...telemetryCommon,
2994
- severityMin: z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
2995
- q: z19.string().max(500).optional()
2996
- }),
2997
- logAround: z19.object({
2998
- logId: name2,
2999
- at: z19.string().max(40),
3000
- same: z19.enum(["service", "trace"]).optional(),
3001
- before: z19.number().int().min(0).max(200).optional(),
3002
- after: z19.number().int().min(0).max(200).optional()
3003
- }),
3004
- telemetryUsage: z19.object({ project: csv.optional(), days: z19.number().int().min(1).max(31).optional() }),
3005
- monitorSignal: z19.object({ monitorId: z19.guid(), hours: z19.number().int().min(1).max(24).optional() }),
3006
- monitorOccurrences: z19.object({
3007
- monitorId: z19.guid(),
3008
- state: z19.enum(["open", "finished", "all"]).optional(),
3009
- environment: z19.string().min(1).max(64).optional(),
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(),
3496
+ environment: csv.optional(),
3497
+ q: z22.string().max(255).optional()
3498
+ }),
3499
+ metricsSeries: z22.object({
3500
+ project: z22.number().int().positive(),
3501
+ name: z22.string().regex(METRIC_NAME_RE),
3502
+ environment: csv.optional(),
3503
+ attrs,
3504
+ cursor: z22.string().regex(/^[0-9a-f]{16}$/).optional()
3505
+ }),
3506
+ metricsQuery: z22.object({
3507
+ project: z22.number().int().positive(),
3508
+ name: z22.string().regex(METRIC_NAME_RE),
3509
+ aggregation: z22.enum(METRIC_AGGREGATIONS),
3510
+ ...windowFields,
3511
+ step: z22.number().int().min(METRIC_QUERY.minStepSeconds).max(METRIC_QUERY.maxStepSeconds).multipleOf(60).optional(),
3512
+ attrs,
3513
+ groupBy: z22.string().min(1).max(600).optional(),
3514
+ environment: csv.optional()
3515
+ }),
3516
+ telemetryUsage: z22.object({
3517
+ project: csv.optional(),
3518
+ days: z22.number().int().min(1).max(31).optional()
3519
+ }),
3520
+ monitorSignal: z22.object({
3521
+ monitorId: z22.guid(),
3522
+ hours: z22.number().int().min(1).max(24).optional()
3523
+ }),
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(),
3010
3528
  cursor: nodeCursor
3011
3529
  }),
3012
- monitorBacktest: z19.object({ project: z19.number().int().positive(), settings: backtestSettingsSchema }),
3013
- occurrenceCreate: z19.object({
3014
- project: z19.number().int().positive(),
3530
+ monitorBacktest: z22.object({
3531
+ project: z22.number().int().positive(),
3532
+ settings: backtestSettingsSchema
3533
+ }),
3534
+ occurrenceCreate: z22.object({
3535
+ project: z22.number().int().positive(),
3015
3536
  monitorSlug: occurrenceInputSchema.shape.monitor_slug,
3016
3537
  occurrenceId: occurrenceInputSchema.shape.occurrence_id,
3017
3538
  dueAt: occurrenceInputSchema.shape.due_at,
3018
3539
  environment: occurrenceInputSchema.shape.environment
3019
3540
  }),
3020
- occurrenceCancel: z19.object({
3021
- project: z19.number().int().positive(),
3022
- monitorSlug: z19.string().regex(SLUG_RE),
3023
- occurrenceId: z19.string().regex(OCCURRENCE_ID_RE),
3024
- environment: z19.string().min(1).max(64).optional()
3025
- }),
3026
- ticket: z19.object({
3027
- scope: z19.enum(["read", "write"]).default("read"),
3028
- project: z19.number().int().positive().optional(),
3029
- environment: z19.string().min(1).max(64).optional()
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()
3546
+ }),
3547
+ releasesList: z22.object({
3548
+ project: z22.number().int().positive(),
3549
+ environment: environmentNameSchema.optional()
3550
+ }),
3551
+ releaseHealth: z22.object({
3552
+ project: z22.number().int().positive(),
3553
+ version: releaseNameSchema,
3554
+ environment: environmentNameSchema.optional(),
3555
+ compare: releaseNameSchema.optional()
3556
+ }),
3557
+ deploymentCreate: z22.object({
3558
+ project: z22.number().int().positive(),
3559
+ version: deploymentInputSchema.shape.version,
3560
+ environment: deploymentInputSchema.shape.environment,
3561
+ name: deploymentInputSchema.shape.name,
3562
+ url: deploymentInputSchema.shape.url,
3563
+ startedAt: deploymentInputSchema.shape.started_at,
3564
+ finishedAt: deploymentInputSchema.shape.finished_at,
3565
+ deployId: deploymentInputSchema.shape.deploy_id
3566
+ }),
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()
3030
3571
  })
3031
3572
  };
3032
3573
  var N = NODE_INPUTS;
@@ -3188,6 +3729,72 @@ var NODE_OPERATIONS = [
3188
3729
  node: { path: "q/logs/{log_id}/around" },
3189
3730
  summary: "Log records just before and after one record."
3190
3731
  }),
3732
+ op({
3733
+ ...read,
3734
+ id: "metrics.names",
3735
+ path: "/v1/metrics/names",
3736
+ scope: "metrics:read",
3737
+ input: N.metricsNames,
3738
+ node: { path: "q/metrics/names" },
3739
+ summary: "The metric catalog of one project (name, type, kind, unit, series count, last seen) and the node's series and name caps with the metrics it is dropping points for."
3740
+ }),
3741
+ op({
3742
+ ...read,
3743
+ id: "metrics.series",
3744
+ path: "/v1/metrics/series",
3745
+ scope: "metrics:read",
3746
+ input: N.metricsSeries,
3747
+ node: { path: "q/metrics/series", list: "series" },
3748
+ paged: true,
3749
+ summary: "The time series of one metric (attributes, service, environment, first and last seen), 100 per page."
3750
+ }),
3751
+ op({
3752
+ ...read,
3753
+ id: "metrics.query",
3754
+ path: "/v1/metrics/query",
3755
+ scope: "metrics:read",
3756
+ input: N.metricsQuery,
3757
+ 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."
3759
+ }),
3760
+ op({
3761
+ ...read,
3762
+ id: "releases.list",
3763
+ path: "/v1/projects/{project}/releases",
3764
+ scope: "releases:read",
3765
+ input: N.releasesList,
3766
+ node: { path: "q/releases" },
3767
+ summary: "Releases of one project in one environment, newest first by deploy order (else version order): first and last deploy, events, issues, and the counts of new, regressed and increased issues in each release's first 24 hours."
3768
+ }),
3769
+ op({
3770
+ ...read,
3771
+ id: "releases.health",
3772
+ path: "/v1/projects/{project}/releases/{version}/health",
3773
+ scope: "releases:read",
3774
+ input: N.releaseHealth,
3775
+ node: { path: "q/releases/health" },
3776
+ summary: "One release in one environment against the previous one (or `compare`): new, regressed and increased issues in its first 24 hours (≤ 50 each, with hourly sparklines) and its deploy markers."
3777
+ }),
3778
+ op({
3779
+ ...read,
3780
+ id: "issues.fix_status",
3781
+ path: "/v1/issues/{issue_id}/fix-status",
3782
+ scope: "releases:read",
3783
+ input: N.issue,
3784
+ node: { path: "q/issues/{issue_id}/fix-status" },
3785
+ summary: "Whether a resolved issue is fixed in each environment it occurred in: fixed (a deploy of the target release and 24 h of its signals without the error), unverified, not fixed (with the event that broke it) or unknown; null while unresolved."
3786
+ }),
3787
+ op({
3788
+ ...read,
3789
+ id: "deployments.create",
3790
+ method: "POST",
3791
+ path: "/v1/projects/{project}/deployments",
3792
+ scope: "releases:write",
3793
+ input: N.deploymentCreate,
3794
+ node: { path: "w/releases/deployments", body: "*" },
3795
+ mcp: "configure",
3796
+ summary: "Record that a release was deployed to an environment (a deploy marker for CI without sentry-cli). Answers the marker and `created`; the same `deploy_id` again changes nothing (`created: false`)."
3797
+ }),
3191
3798
  op({
3192
3799
  ...read,
3193
3800
  id: "telemetry.usage",
@@ -3288,10 +3895,10 @@ var NODE_OPERATIONS = [
3288
3895
  ];
3289
3896
 
3290
3897
  // ../src/shared/contracts/api-ops/privacy.ts
3291
- import { z as z21 } from "zod";
3898
+ import { z as z24 } from "zod";
3292
3899
 
3293
3900
  // ../src/shared/contracts/privacy.ts
3294
- import { z as z20 } from "zod";
3901
+ import { z as z23 } from "zod";
3295
3902
 
3296
3903
  // ../src/shared/privacy/rules.ts
3297
3904
  var PRIVACY_SCHEMA = 1;
@@ -3321,44 +3928,44 @@ var IPV6_RE = new RegExp(`(^|[^0-9A-Fa-f:])((?:${H}:){7}${H}|(?:${H}:){1,6}:(?:$
3321
3928
  var REMOVE = Symbol("remove");
3322
3929
 
3323
3930
  // ../src/shared/contracts/privacy.ts
3324
- var ruleId = z20.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
3325
- var privacyRuleInputSchema = z20.object({
3931
+ var ruleId = z23.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
3932
+ var privacyRuleInputSchema = z23.object({
3326
3933
  id: ruleId,
3327
- selector: z20.string().min(1).max(PRIVACY_LIMITS.selector),
3328
- type: z20.enum(PRIVACY_RULE_TYPES),
3329
- method: z20.enum(PRIVACY_METHODS),
3330
- pattern: z20.string().min(1).max(PRIVACY_LIMITS.pattern).optional(),
3331
- ignoreCase: z20.boolean().optional(),
3332
- replaceWith: z20.string().max(PRIVACY_LIMITS.replaceWith).optional(),
3333
- enabled: z20.boolean().optional()
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()
3334
3941
  });
3335
- var privacyPolicyInputSchema = z20.object({
3336
- mode: z20.enum(PRIVACY_MODES),
3337
- rules: z20.array(privacyRuleInputSchema).max(PRIVACY_LIMITS.rules),
3338
- allowlist: z20.array(z20.string().min(1).max(PRIVACY_LIMITS.selector)).max(PRIVACY_LIMITS.allowlist)
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)
3339
3946
  });
3340
- var storedPolicySchema = z20.object({
3341
- schema: z20.literal(PRIVACY_SCHEMA),
3342
- version: z20.number().int().min(0),
3343
- mode: z20.enum(PRIVACY_MODES),
3344
- rules: z20.array(z20.record(z20.string(), z20.unknown())).max(PRIVACY_LIMITS.rules),
3345
- allowlist: z20.array(z20.string()).max(PRIVACY_LIMITS.allowlist)
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)
3346
3953
  });
3347
- var nodePrivacyBlockSchema = z20.array(z20.object({ project_id: z20.number().int().positive(), policy: z20.unknown() })).max(1000);
3348
- var privacyRollupSchema = z20.object({
3349
- applied_version: z20.number().int().min(0).nullable(),
3350
- policy_missing_24h: z20.number().int().nonnegative(),
3351
- budget_exceeded_24h: z20.number().int().nonnegative(),
3352
- sdk_versions: z20.array(z20.object({ version: z20.number().int().min(0), last_seen_at: z20.string().datetime() })).max(5)
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)
3353
3960
  });
3354
3961
 
3355
3962
  // ../src/shared/contracts/api-ops/privacy.ts
3356
3963
  var PRIVACY_INPUTS = {
3357
- get: z21.object({ workspaceId: uuid, projectId }),
3358
- set: z21.object({
3964
+ get: z24.object({ workspaceId: uuid, projectId }),
3965
+ set: z24.object({
3359
3966
  workspaceId: uuid,
3360
3967
  projectId,
3361
- expectedVersion: z21.number().int().min(0),
3968
+ expectedVersion: z24.number().int().min(0),
3362
3969
  policy: privacyPolicyInputSchema
3363
3970
  })
3364
3971
  };
@@ -3398,11 +4005,11 @@ var PRIVACY_OPERATIONS = [
3398
4005
  ];
3399
4006
 
3400
4007
  // ../src/shared/contracts/api-ops/projects.ts
3401
- import { z as z25 } from "zod";
4008
+ import { z as z28 } from "zod";
3402
4009
 
3403
4010
  // ../src/shared/contracts/ingest-keys.ts
3404
- import { z as z22 } from "zod";
3405
- var INGEST_KEY_SCOPES = ["traces", "logs", "errors", "monitors"];
4011
+ import { z as z25 } from "zod";
4012
+ var INGEST_KEY_SCOPES = ["traces", "logs", "metrics", "errors", "monitors"];
3406
4013
  var INGEST_KEY_STATES = ["active", "revoked"];
3407
4014
  var INGEST_KEY_LIMITS = {
3408
4015
  nameMaxChars: 80,
@@ -3411,91 +4018,92 @@ var INGEST_KEY_LIMITS = {
3411
4018
  edgeCacheSeconds: 60
3412
4019
  };
3413
4020
  var CHECKIN_AUTH_MODES = ["public_or_key", "key_only"];
3414
- var ingestKeyConfigSchema = z22.object({
3415
- v: z22.literal(1),
3416
- key_id: z22.guid(),
3417
- project_public_id: z22.number().int().positive(),
3418
- project_id: z22.number().int().positive(),
3419
- workspace_id: z22.guid(),
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(),
3420
4027
  node_id: nodeIdSchema,
3421
- scopes: z22.array(z22.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
3422
- environments: z22.array(z22.string().max(INGEST_KEY_LIMITS.environmentMaxChars)).max(INGEST_KEY_LIMITS.environmentsMax),
3423
- expires_at: z22.string().datetime({ offset: true }).nullable(),
3424
- state: z22.enum(INGEST_KEY_STATES),
3425
- workspace_status: z22.enum(["active", "suspended", "deleting"]),
3426
- ingest_kill: z22.boolean(),
3427
- telemetry_kill: z22.boolean(),
3428
- telemetry_rate_bytes_per_sec: z22.number().int().positive(),
3429
- telemetry_burst_bytes: z22.number().int().positive(),
3430
- traces_monthly_bytes: z22.number().int().positive(),
3431
- logs_monthly_bytes: z22.number().int().positive(),
3432
- telemetry_buffer_minutes: z22.number().int().min(1).max(1440),
3433
- revision: z22.number().int().nonnegative()
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()
3434
4042
  });
3435
- var createIngestKeyInputSchema = z22.object({
3436
- projectId: z22.number().int().positive(),
3437
- name: z22.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
3438
- scopes: z22.array(z22.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
3439
- environments: z22.array(z22.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
3440
- expiresAt: z22.string().datetime({ offset: true }).nullable()
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()
3441
4049
  });
3442
- var ingestKeyRowSchema = z22.object({
3443
- id: z22.guid(),
3444
- project_id: z22.number().int().positive(),
3445
- name: z22.string(),
3446
- prefix: z22.string(),
3447
- scopes: z22.array(z22.enum(INGEST_KEY_SCOPES)),
3448
- environments: z22.array(z22.string()),
3449
- expires_at: z22.string().nullable(),
3450
- state: z22.enum(INGEST_KEY_STATES),
3451
- created_by: z22.guid().nullable(),
3452
- created_at: z22.string(),
3453
- revoked_at: z22.string().nullable(),
3454
- last_used_at: z22.string().nullable()
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()
3455
4063
  });
3456
4064
 
3457
4065
  // ../src/shared/contracts/node-config.ts
3458
- import { z as z24 } from "zod";
4066
+ import { z as z27 } from "zod";
3459
4067
 
3460
4068
  // ../src/shared/contracts/backup.ts
3461
- import { z as z23 } from "zod";
4069
+ import { z as z26 } from "zod";
3462
4070
  var BACKUP_KINDS = ["daily", "weekly", "manual", "pre_upgrade"];
3463
- var ageRecipient = z23.string().regex(/^age1[02-9ac-hj-np-z]{58}$/);
3464
- var backupIdSchema = z23.string().regex(/^[a-z0-9-]{8,64}$/);
3465
- var nodeBackupConfigSchema = z23.object({
3466
- enabled: z23.boolean(),
3467
- hour_utc: z23.number().int().min(0).max(23),
3468
- weekly_day: z23.number().int().min(1).max(7),
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),
3469
4077
  workspace_recipient: ageRecipient
3470
4078
  });
3471
- var backupCredentialsRequestSchema = z23.object({
3472
- mode: z23.enum(["upload", "download"]),
4079
+ var backupCredentialsRequestSchema = z26.object({
4080
+ mode: z26.enum(["upload", "download"]),
3473
4081
  backup_id: backupIdSchema,
3474
- source_node_id: z23.guid().optional()
4082
+ source_node_id: z26.guid().optional()
3475
4083
  });
3476
- var backupCredentialsSchema = z23.object({
3477
- endpoint: z23.string().url(),
3478
- bucket: z23.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/),
3479
- prefix: z23.string().regex(/^backups\/[0-9a-f-]{36}\/$/),
3480
- access_key_id: z23.string().min(8).max(200),
3481
- secret_access_key: z23.string().min(8).max(200),
3482
- session_token: z23.string().min(8).max(4000),
3483
- expires_at: z23.string().datetime()
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()
3484
4092
  });
3485
- var rowCountsSchema = z23.record(z23.string().regex(/^[a-z_][a-z0-9_]{0,63}$/), z23.number().int().nonnegative());
3486
- var backupManifestSchema = z23.object({
3487
- v: z23.literal(1),
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),
3488
4096
  backup_id: backupIdSchema,
3489
- node_id: z23.guid(),
3490
- kind: z23.enum(BACKUP_KINDS),
3491
- created_at: z23.string().datetime(),
3492
- object_key: z23.string(),
3493
- size_bytes: z23.number().int().nonnegative(),
3494
- sha256: z23.string().regex(/^[0-9a-f]{64}$/),
3495
- clickhouse_version: z23.string().max(40),
3496
- schema_version: z23.number().int().nonnegative(),
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(),
3497
4105
  row_counts: rowCountsSchema,
3498
- recipients: z23.array(z23.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
4106
+ recipients: z26.array(z26.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
3499
4107
  });
3500
4108
  var BACKUP_ERROR_CODES = [
3501
4109
  "CLICKHOUSE_BACKUP_FAILED",
@@ -3509,48 +4117,48 @@ var BACKUP_ERROR_CODES = [
3509
4117
  "RESTORE_FAILED",
3510
4118
  "ROW_COUNT_MISMATCH"
3511
4119
  ];
3512
- var backupReportSchema = z23.object({
4120
+ var backupReportSchema = z26.object({
3513
4121
  backup_id: backupIdSchema,
3514
- kind: z23.enum(BACKUP_KINDS),
3515
- status: z23.enum(["succeeded", "failed"]),
3516
- started_at: z23.string().datetime(),
3517
- finished_at: z23.string().datetime(),
4122
+ kind: z26.enum(BACKUP_KINDS),
4123
+ status: z26.enum(["succeeded", "failed"]),
4124
+ started_at: z26.string().datetime(),
4125
+ finished_at: z26.string().datetime(),
3518
4126
  manifest: backupManifestSchema.nullable(),
3519
- error_code: z23.enum(BACKUP_ERROR_CODES).nullable()
4127
+ error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
3520
4128
  });
3521
- var drillReportSchema = z23.object({
4129
+ var drillReportSchema = z26.object({
3522
4130
  backup_id: backupIdSchema,
3523
- kind: z23.enum(["weekly_local", "monthly_new_machine"]),
3524
- status: z23.enum(["passed", "failed"]),
3525
- finished_at: z23.string().datetime(),
3526
- detail: z23.string().max(300),
3527
- error_code: z23.enum(BACKUP_ERROR_CODES).nullable()
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()
3528
4136
  });
3529
- var nodeIdentityEscrowSchema = z23.object({
3530
- v: z23.literal(1),
3531
- node_id: z23.guid(),
3532
- seal: z23.object({
3533
- publicKey: z23.string().regex(/^[A-Za-z0-9_-]{43}$/),
3534
- privateKey: z23.string().regex(/^[A-Za-z0-9_-]{43}$/)
3535
- }),
3536
- created_at: z23.string().datetime()
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}$/)
4143
+ }),
4144
+ created_at: z26.string().datetime()
3537
4145
  });
3538
- var restoreArgsSchema = z23.object({
3539
- job_id: z23.guid(),
3540
- workspace_id: z23.guid(),
3541
- source_node_id: z23.guid(),
4146
+ var restoreArgsSchema = z26.object({
4147
+ job_id: z26.guid(),
4148
+ workspace_id: z26.guid(),
4149
+ source_node_id: z26.guid(),
3542
4150
  manifest: backupManifestSchema,
3543
- sealed_identity: z23.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
3544
- mode: z23.enum(["rebuild", "drill"])
4151
+ sealed_identity: z26.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
4152
+ mode: z26.enum(["rebuild", "drill"])
3545
4153
  });
3546
- var restoreReportSchema = z23.object({
3547
- job_id: z23.guid(),
4154
+ var restoreReportSchema = z26.object({
4155
+ job_id: z26.guid(),
3548
4156
  backup_id: backupIdSchema,
3549
- mode: z23.enum(["rebuild", "drill"]),
3550
- status: z23.enum(["succeeded", "failed"]),
3551
- finished_at: z23.string().datetime(),
3552
- detail: z23.string().max(300),
3553
- error_code: z23.enum(BACKUP_ERROR_CODES).nullable()
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()
3554
4162
  });
3555
4163
 
3556
4164
  // ../src/shared/contracts/node-config.ts
@@ -3564,82 +4172,84 @@ var SCRUB_GROUPS = [
3564
4172
  "headers"
3565
4173
  ];
3566
4174
  var MAX_NODE_MONITORS = 5000;
3567
- var kid = z24.string().regex(/^[A-Za-z0-9_-]{1,40}$/);
3568
- var publicKey = z24.string().regex(/^[A-Za-z0-9_-]{43}$/);
3569
- var nodeConfigSchema = z24.object({
3570
- v: z24.literal(1),
3571
- config_version: z24.number().int().positive(),
3572
- node_id: z24.guid(),
3573
- workspace_id: z24.guid(),
3574
- workspace_status: z24.enum(["active", "suspended"]),
3575
- issued_at: z24.string().datetime(),
3576
- retention_days: z24.number().int().min(1).max(3650),
3577
- channel: z24.enum(["stable", "canary"]).optional(),
3578
- projects: z24.array(z24.object({
3579
- project_id: z24.number().int().positive(),
3580
- slug: z24.string().max(64),
3581
- short_prefix: z24.string().regex(/^[A-Z0-9]{1,12}$/),
3582
- user_id_salt: z24.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
3583
- scrub_disabled: z24.array(z24.enum(SCRUB_GROUPS)).max(SCRUB_GROUPS.length),
3584
- upload_tokens: z24.array(z24.object({
3585
- hash: z24.string().regex(/^[a-f0-9]{64}$/),
3586
- expires_at: z24.string().datetime()
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()
3587
4196
  })).max(10).optional()
3588
4197
  })).max(1000),
3589
- ticket_keys: z24.array(z24.object({ kid, public_key: publicKey, not_after: z24.string().datetime() })).min(1).max(5),
3590
- control_ops_keys: z24.array(z24.object({ kid, public_key: publicKey })).min(1).max(5),
3591
- kill_switches: z24.object({ ingest: z24.boolean(), alerts: z24.boolean() }),
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() }),
3592
4201
  backup: nodeBackupConfigSchema.optional(),
3593
- purged_projects: z24.array(z24.number().int().positive()).max(1000).optional(),
3594
- monitors: z24.array(monitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
3595
- purged_monitors: z24.array(z24.guid()).max(5000).optional(),
3596
- telemetry: z24.object({
3597
- traces_retention_days: z24.number().int().min(1).max(90),
3598
- logs_retention_days: z24.number().int().min(1).max(90),
3599
- traces_disk_share: z24.number().min(0.2).max(0.8)
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)
3600
4209
  }).optional(),
3601
- slos: z24.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
3602
- signal_monitors: z24.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4210
+ metrics: metricsConfigSchema.optional(),
4211
+ slos: z27.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
4212
+ signal_monitors: z27.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
3603
4213
  signal_limits: signalLimitsConfigSchema.optional(),
3604
4214
  privacy: nodePrivacyBlockSchema.optional()
3605
4215
  });
3606
- var signedNodeConfigSchema = z24.object({ config: nodeConfigSchema, kid, sig: z24.string() });
4216
+ var signedNodeConfigSchema = z27.object({ config: nodeConfigSchema, kid, sig: z27.string() });
3607
4217
 
3608
4218
  // ../src/shared/contracts/api-ops/projects.ts
3609
- var slug = z25.string().regex(/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/);
3610
- var name3 = z25.string().trim().min(1).max(60);
3611
- var label = z25.string().trim().min(1).max(40);
3612
- var platform = z25.enum(PLATFORMS);
3613
- var origin = z25.string().trim().toLowerCase().regex(/^https?:\/\/[a-z0-9.-]+(:[0-9]{1,5})?$/).max(200);
3614
- var keyId = z25.number().int().positive();
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();
3615
4225
  var PROJECT_INPUTS = {
3616
- create: z25.object({ workspaceId: uuid, name: name3, slug, platform }),
3617
- update: z25.object({ projectId, name: name3, platform, isPinned: z25.boolean() }),
3618
- updateIntake: z25.object({
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({
3619
4229
  projectId,
3620
- rateLimit: z25.number().int().positive().nullable(),
3621
- burst: z25.number().int().positive().nullable(),
3622
- allowedOrigins: z25.array(origin).max(50)
4230
+ rateLimit: z28.number().int().positive().nullable(),
4231
+ burst: z28.number().int().positive().nullable(),
4232
+ allowedOrigins: z28.array(origin).max(50)
3623
4233
  }),
3624
- updateObservability: z25.object({
4234
+ updateObservability: z28.object({
3625
4235
  projectId,
3626
- primaryEnvironment: z25.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
3627
- allowCodeMonitors: z25.boolean()
4236
+ primaryEnvironment: z28.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
4237
+ allowCodeMonitors: z28.boolean()
3628
4238
  }),
3629
- setScrub: z25.object({ projectId, group: z25.enum(SCRUB_GROUPS), enabled: z25.boolean() }),
3630
- setCheckinAuth: z25.object({ projectId, mode: z25.enum(CHECKIN_AUTH_MODES) }),
3631
- setEnvironmentHidden: z25.object({
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({
3632
4242
  projectId,
3633
- name: z25.string().min(1).max(64),
3634
- hidden: z25.boolean()
3635
- }),
3636
- scheduleDeletion: z25.object({ projectId, confirmSlug: slug }),
3637
- projectOnly: z25.object({ projectId }),
3638
- labelled: z25.object({ projectId, label }),
3639
- keyOnly: z25.object({ keyId }),
3640
- tokenOnly: z25.object({ tokenId: keyId }),
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 }),
3641
4251
  createIngestKey: createIngestKeyInputSchema,
3642
- ingestKeyOnly: z25.object({ keyId: uuid })
4252
+ ingestKeyOnly: z28.object({ keyId: uuid })
3643
4253
  };
3644
4254
  var P2 = PROJECT_INPUTS;
3645
4255
  var PROJECT_OPERATIONS = [
@@ -3894,24 +4504,24 @@ var PROJECT_OPERATIONS = [
3894
4504
  ];
3895
4505
 
3896
4506
  // ../src/shared/contracts/api-ops/reads.ts
3897
- import { z as z26 } from "zod";
3898
- var list = z26.object({ workspaceId: uuid, limit: pageLimit, cursor });
4507
+ import { z as z29 } from "zod";
4508
+ var list = z29.object({ workspaceId: uuid, limit: pageLimit, cursor });
3899
4509
  var READ_INPUTS = {
3900
- workspace: z26.object({ workspaceId: uuid }),
4510
+ workspace: z29.object({ workspaceId: uuid }),
3901
4511
  list,
3902
- projectsGet: z26.object({ workspaceId: uuid, projectId }),
4512
+ projectsGet: z29.object({ workspaceId: uuid, projectId }),
3903
4513
  monitorsList: list.extend({ projectId: projectId.optional() }),
3904
- monitorsGet: z26.object({ workspaceId: uuid, monitorId: uuid }),
3905
- uptimeGet: z26.object({ workspaceId: uuid, checkId: uuid }),
3906
- slosGet: z26.object({ workspaceId: uuid, sloId: uuid }),
4514
+ monitorsGet: z29.object({ workspaceId: uuid, monitorId: uuid }),
4515
+ uptimeGet: z29.object({ workspaceId: uuid, checkId: uuid }),
4516
+ slosGet: z29.object({ workspaceId: uuid, sloId: uuid }),
3907
4517
  alertsList: list.extend({
3908
- state: z26.enum(["open", "resolved", "all"]).default("all"),
4518
+ state: z29.enum(["open", "resolved", "all"]).default("all"),
3909
4519
  monitorId: uuid.optional()
3910
4520
  }),
3911
- approvalsGet: z26.object({ workspaceId: uuid, approvalId: uuid }),
4521
+ approvalsGet: z29.object({ workspaceId: uuid, approvalId: uuid }),
3912
4522
  monitorsListTyped: list.extend({
3913
4523
  projectId: projectId.optional(),
3914
- type: z26.enum(MONITOR_TYPES).optional()
4524
+ type: z29.enum(MONITOR_TYPES).optional()
3915
4525
  })
3916
4526
  };
3917
4527
  var R = READ_INPUTS;
@@ -4195,14 +4805,14 @@ function approvalRequestSchema(operationId, input) {
4195
4805
  }
4196
4806
 
4197
4807
  // ../src/shared/contracts/api-ops/wire.ts
4198
- import { z as z27 } from "zod";
4808
+ import { z as z30 } from "zod";
4199
4809
  var toSnake = (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
4200
4810
  var toCamel = (s) => s.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
4201
4811
  var schemaCache = new WeakMap;
4202
4812
  function inputJsonSchema(op) {
4203
4813
  let js = schemaCache.get(op.input);
4204
4814
  if (!js) {
4205
- js = z27.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4815
+ js = z30.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4206
4816
  schemaCache.set(op.input, js);
4207
4817
  }
4208
4818
  return js;
@@ -4416,7 +5026,7 @@ function wireInput(operationId, opts = {}) {
4416
5026
  for (const [k, v] of Object.entries(op.input.shape))
4417
5027
  if (!omit.has(k))
4418
5028
  shape[toSnake(k)] = v;
4419
- return z28.object(shape);
5029
+ return z31.object(shape);
4420
5030
  }
4421
5031
  var BUDGETS = [
4422
5032
  { stringBytes: MCP_LIMITS.untrustedStringMaxBytes, listMax: MCP_LIMITS.listMax },
@@ -4476,7 +5086,10 @@ function untrustedTree(value, reserveBytes = 2048) {
4476
5086
  function wrapResult(parts, extra = {}) {
4477
5087
  const t = untrustedTree(parts.data);
4478
5088
  const structuredContent = {
4479
- untrusted: { data: t.data, provenance: { source: parts.source, operations: [...parts.operations] } }
5089
+ untrusted: {
5090
+ data: t.data,
5091
+ provenance: { source: parts.source, operations: [...parts.operations] }
5092
+ }
4480
5093
  };
4481
5094
  if (extra.next_cursor !== undefined) {
4482
5095
  const c = extra.next_cursor === null ? null : cleanUntrustedText(extra.next_cursor, 600).text;
@@ -4506,40 +5119,52 @@ function errorResult(o) {
4506
5119
  }
4507
5120
  };
4508
5121
  }
4509
- var TOOL_OUTPUT_SCHEMA = z28.object({
4510
- untrusted: z28.object({
4511
- data: z28.unknown(),
4512
- provenance: z28.object({
4513
- source: z28.enum(["node", "control_plane", "docs"]),
4514
- operations: z28.array(z28.string())
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())
4515
5128
  })
4516
5129
  }).optional(),
4517
- doc: z28.object({ slug: z28.string(), locale: z28.enum(["en", "vi"]), url: z28.string(), markdown: z28.string(), truncated: z28.boolean() }).optional(),
4518
- results: z28.array(z28.object({ slug: z28.string(), title: z28.string(), description: z28.string(), section: z28.string(), url: z28.string() })).optional(),
4519
- next_cursor: z28.string().nullable().optional(),
4520
- complete: z28.boolean().optional(),
4521
- omitted: z28.array(z28.object({ part: z28.string(), reason: z28.string(), scope: z28.string().optional() })).optional(),
4522
- truncated: z28.literal(true).optional(),
4523
- suspicious_unicode: z28.literal(true).optional(),
4524
- error: z28.object({
4525
- code: z28.string(),
4526
- status: z28.number(),
4527
- detail: z28.string().optional(),
4528
- scope: z28.string().optional(),
4529
- retry_after: z28.number().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()
5136
+ }).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()
5143
+ })).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()
4530
5155
  }).optional(),
4531
- operations: z28.array(z28.record(z28.string(), z28.unknown())).optional(),
4532
- operation: z28.record(z28.string(), z28.unknown()).optional(),
4533
- plan: z28.record(z28.string(), z28.unknown()).optional(),
4534
- status: z28.enum(["done", "approval_required", "approval_pending", ...APPROVAL_STATES]).optional(),
4535
- approval: z28.object({
4536
- approval_id: z28.string(),
4537
- approval_url: z28.string(),
4538
- expires_at: z28.string(),
4539
- state: z28.enum(APPROVAL_STATES),
4540
- result_code: z28.string().nullable().optional(),
4541
- result: z28.record(z28.string(), z28.unknown()).optional(),
4542
- next: z28.string().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()
4543
5168
  }).optional()
4544
5169
  });
4545
5170
  var spec = (name) => {
@@ -4585,10 +5210,10 @@ var has = (rt, operationId) => {
4585
5210
  return !!op && rt.scopes.includes(op.scope);
4586
5211
  };
4587
5212
  var isoWindow = {
4588
- start: z28.string().max(40).describe("RFC 3339 start of the window, e.g. 2026-10-26T00:00:00Z. Required with end."),
4589
- end: z28.string().max(40).describe("RFC 3339 end of the window. The plan limits its length.")
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.")
4590
5215
  };
4591
- var traceIdSchema = z28.string().regex(/^[0-9a-fA-F]{32}$/);
5216
+ var traceIdSchema = z31.string().regex(/^[0-9a-fA-F]{32}$/);
4592
5217
  var MONITOR_KINDS2 = {
4593
5218
  cron: { list: "monitors.list", get: "monitors.get", idField: "monitor_id" },
4594
5219
  uptime: { list: "uptime.list", get: "uptime.get", idField: "check_id" },
@@ -4652,8 +5277,8 @@ function describe(op, scopes) {
4652
5277
  destructive: isDestructiveOperation(op)
4653
5278
  };
4654
5279
  }
4655
- var params = z28.record(z28.string(), z28.unknown()).default({}).describe("Operation fields in wire names (snake_case), as describe_operation's args_schema shows.");
4656
- var operationIdArg = z28.string().min(3).max(80).describe("An operation id from search_operations, e.g. `monitors.update`.");
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`.");
4657
5282
  function approvalBlock(t, next) {
4658
5283
  return {
4659
5284
  approval_id: t.approval_id,
@@ -4673,7 +5298,7 @@ var MCP_TOOL_DEFS = [
4673
5298
  title: "Workspace and node",
4674
5299
  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.",
4675
5300
  operations: ["workspace.get", "node.get"],
4676
- input: z28.object({}),
5301
+ input: z31.object({}),
4677
5302
  async run(_args, rt) {
4678
5303
  const [ws, node] = await Promise.all([rt.call("workspace.get", {}), rt.call("node.get", {})]);
4679
5304
  if (!ws.ok)
@@ -4681,7 +5306,11 @@ var MCP_TOOL_DEFS = [
4681
5306
  const omitted = [];
4682
5307
  if (!node.ok)
4683
5308
  omitted.push({ part: "node", reason: node.code });
4684
- return wrapResult({ data: { workspace: ws.body, node: node.ok ? node.body : null }, operations: ["workspace.get", "node.get"], source: "control_plane" }, { omitted });
5309
+ return wrapResult({
5310
+ data: { workspace: ws.body, node: node.ok ? node.body : null },
5311
+ operations: ["workspace.get", "node.get"],
5312
+ source: "control_plane"
5313
+ }, { omitted });
4685
5314
  }
4686
5315
  },
4687
5316
  single("list_projects", "projects.list", "List projects", "Projects this token can read, with their numeric ids (use them as `project` in other tools), platforms and environments."),
@@ -4689,11 +5318,11 @@ var MCP_TOOL_DEFS = [
4689
5318
  {
4690
5319
  ...spec("get_issue"),
4691
5320
  title: "Get an issue",
4692
- 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).",
4693
- operations: ["issues.get", "events.get"],
4694
- input: z28.object({
4695
- issue_id: z28.number().int().positive().describe("Issue id from search_issues."),
4696
- include_latest_event: z28.boolean().default(true)
5321
+ 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
+ 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)
4697
5326
  }),
4698
5327
  async run(args, rt) {
4699
5328
  const omitted = [];
@@ -4711,7 +5340,20 @@ var MCP_TOOL_DEFS = [
4711
5340
  latest = ev.body;
4712
5341
  else if (ev)
4713
5342
  omitted.push({ part: "latest_event", reason: ev.code });
4714
- return wrapResult({ data: { issue: issue.body, latest_event: latest }, operations: ["issues.get", "events.get"], source: "node" }, { omitted });
5343
+ const ops = ["issues.get", "events.get"];
5344
+ const data = { issue: issue.body, latest_event: latest };
5345
+ const resolved = issue.body?.issue?.status === "resolved";
5346
+ if (resolved && !has(rt, "issues.fix_status"))
5347
+ omitted.push({ part: "fix_status", reason: "scope", scope: "releases:read" });
5348
+ else if (resolved) {
5349
+ const fx = await rt.call("issues.fix_status", { issue_id: args["issue_id"] });
5350
+ ops.push("issues.fix_status");
5351
+ if (fx.ok)
5352
+ data["fix_status"] = fx.body;
5353
+ else
5354
+ omitted.push({ part: "fix_status", reason: fx.code });
5355
+ }
5356
+ return wrapResult({ data, operations: ops, source: "node" }, { omitted });
4715
5357
  }
4716
5358
  },
4717
5359
  single("list_events", "events.list", "List events of an issue", "Events of one issue, newest first, with a cursor for older ones."),
@@ -4721,9 +5363,9 @@ var MCP_TOOL_DEFS = [
4721
5363
  title: "Get a trace",
4722
5364
  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).",
4723
5365
  operations: ["traces.get", "traces.spans"],
4724
- input: z28.object({
5366
+ input: z31.object({
4725
5367
  trace_id: traceIdSchema.describe("W3C trace id, 32 hex characters."),
4726
- spans: z28.enum(["none", "errors", "all"]).default("none")
5368
+ spans: z31.enum(["none", "errors", "all"]).default("none")
4727
5369
  }),
4728
5370
  async run(args, rt) {
4729
5371
  const sum = await rt.call("traces.get", { trace_id: args["trace_id"] });
@@ -4741,28 +5383,139 @@ var MCP_TOOL_DEFS = [
4741
5383
  else
4742
5384
  omitted.push({ part: "spans", reason: r.code });
4743
5385
  }
4744
- return wrapResult({ data: { trace: sum.body, ...spans !== undefined ? { spans } : {} }, operations: ["traces.get", "traces.spans"], source: "node" }, { omitted });
5386
+ return wrapResult({
5387
+ data: { trace: sum.body, ...spans !== undefined ? { spans } : {} },
5388
+ operations: ["traces.get", "traces.spans"],
5389
+ source: "node"
5390
+ }, { omitted });
4745
5391
  }
4746
5392
  },
4747
5393
  single("search_spans", "spans.list", "Search spans", "OpenTelemetry spans in a time window (start and end required): filter by project, environment, service, operation, status, kind, duration or attribute filters (`attrs`, JSON list of {k, op, v}). mode=traces returns one row per trace."),
4748
5394
  single("query_logs", "logs.list", "Query logs", "OpenTelemetry logs in a time window (start and end required): filter by project, environment, service, minimum severity, trace or span id, text `q` or attribute filters. Newest first unless order=asc."),
5395
+ {
5396
+ ...spec("query_metrics"),
5397
+ title: "Query metrics",
5398
+ 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
+ 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(),
5405
+ start: isoWindow.start.optional(),
5406
+ 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.")
5411
+ }),
5412
+ async run(args, rt) {
5413
+ const scope = {
5414
+ project: args["project"],
5415
+ ...args["environment"] ? { environment: args["environment"] } : {}
5416
+ };
5417
+ const name = args["name"];
5418
+ if (!name) {
5419
+ const r = await rt.call("metrics.names", {
5420
+ ...scope,
5421
+ ...args["q"] ? { q: args["q"] } : {}
5422
+ });
5423
+ if (!r.ok)
5424
+ return errorResult(r);
5425
+ return wrapResult({ data: r.body, operations: ["metrics.names"], source: "node" }, listExtra(r.body));
5426
+ }
5427
+ const ops = ["metrics.query"];
5428
+ let aggregation = args["aggregation"];
5429
+ if (!aggregation) {
5430
+ ops.unshift("metrics.names");
5431
+ const cat = await rt.call("metrics.names", { ...scope, q: name });
5432
+ if (!cat.ok)
5433
+ return errorResult(cat);
5434
+ const rows = cat.body?.names ?? [];
5435
+ const kind = rows.find((n) => n.name === name)?.kind;
5436
+ if (!METRIC_KINDS.includes(kind))
5437
+ return errorResult({
5438
+ ok: false,
5439
+ status: 404,
5440
+ code: "NOT_FOUND",
5441
+ detail: "unknown_metric"
5442
+ });
5443
+ aggregation = defaultAggregation(kind);
5444
+ }
5445
+ const r = await rt.call("metrics.query", {
5446
+ ...scope,
5447
+ name,
5448
+ aggregation,
5449
+ start: args["start"],
5450
+ end: args["end"],
5451
+ ...args["step"] ? { step: args["step"] } : {},
5452
+ ...args["attrs"] ? { attrs: args["attrs"] } : {},
5453
+ ...args["group_by"] ? { group_by: args["group_by"] } : {}
5454
+ });
5455
+ if (!r.ok)
5456
+ return errorResult(r);
5457
+ return wrapResult({ data: r.body, operations: ops, source: "node" }, listExtra(r.body));
5458
+ }
5459
+ },
5460
+ {
5461
+ ...spec("release_health"),
5462
+ title: "Release health",
5463
+ 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
+ operations: ["releases.list", "releases.health"],
5465
+ input: z31.object({
5466
+ project: z31.number().int().positive().describe("Numeric project id from list_projects."),
5467
+ version: releaseNameSchema.optional().describe("Release name exactly as the SDK sends it, e.g. web@1.4.2."),
5468
+ environment: environmentNameSchema.optional().describe("One environment, e.g. production."),
5469
+ compare: releaseNameSchema.optional().describe("With version: compare against this release instead of the previous one.")
5470
+ }),
5471
+ async run(args, rt) {
5472
+ const scope = {
5473
+ project: args["project"],
5474
+ ...args["environment"] ? { environment: args["environment"] } : {}
5475
+ };
5476
+ const version = args["version"];
5477
+ if (!version) {
5478
+ const r = await rt.call("releases.list", scope);
5479
+ if (!r.ok)
5480
+ return errorResult(r);
5481
+ return wrapResult({ data: r.body, operations: ["releases.list"], source: "node" });
5482
+ }
5483
+ const r = await rt.call("releases.health", {
5484
+ ...scope,
5485
+ version,
5486
+ ...args["compare"] ? { compare: args["compare"] } : {}
5487
+ });
5488
+ if (!r.ok)
5489
+ return errorResult(r);
5490
+ return wrapResult({ data: r.body, operations: ["releases.health"], source: "node" });
5491
+ }
5492
+ },
4749
5493
  {
4750
5494
  ...spec("correlate"),
4751
5495
  title: "Correlate by trace or run",
4752
5496
  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.",
4753
5497
  operations: ["traces.get", "traces.spans", "spans.list", "logs.list"],
4754
- input: z28.object({
5498
+ input: z31.object({
4755
5499
  trace_id: traceIdSchema.optional(),
4756
- run_id: z28.string().min(1).max(128).optional(),
5500
+ run_id: z31.string().min(1).max(128).optional(),
4757
5501
  ...isoWindow,
4758
- project: z28.string().max(2000).optional().describe("Comma-separated project ids.")
5502
+ project: z31.string().max(2000).optional().describe("Comma-separated project ids.")
4759
5503
  }),
4760
5504
  async run(args, rt) {
4761
5505
  const trace = args["trace_id"];
4762
5506
  const run = args["run_id"];
4763
5507
  if (!!trace === !!run)
4764
- return errorResult({ ok: false, status: 400, code: "INVALID_INPUT", detail: "one_of_trace_id_or_run_id" });
4765
- const window = { start: args["start"], end: args["end"], ...args["project"] ? { project: args["project"] } : {} };
5508
+ return errorResult({
5509
+ ok: false,
5510
+ status: 400,
5511
+ code: "INVALID_INPUT",
5512
+ detail: "one_of_trace_id_or_run_id"
5513
+ });
5514
+ const window = {
5515
+ start: args["start"],
5516
+ end: args["end"],
5517
+ ...args["project"] ? { project: args["project"] } : {}
5518
+ };
4766
5519
  const attrs = run ? JSON.stringify([{ k: "belvador.run.id", op: "=", v: run }]) : undefined;
4767
5520
  const omitted = [];
4768
5521
  const data = {};
@@ -4771,7 +5524,12 @@ var MCP_TOOL_DEFS = [
4771
5524
  const none = Promise.resolve(null);
4772
5525
  const [t, s, l] = await Promise.all([
4773
5526
  trace && has(rt, "traces.get") ? rt.call("traces.get", { trace_id: trace }) : none,
4774
- has(rt, spansOp) ? trace ? rt.call("traces.spans", { trace_id: trace, errors_only: "1", start: args["start"], end: args["end"] }) : rt.call("spans.list", { ...window, status: "error", attrs }) : none,
5527
+ has(rt, spansOp) ? trace ? rt.call("traces.spans", {
5528
+ trace_id: trace,
5529
+ errors_only: "1",
5530
+ start: args["start"],
5531
+ end: args["end"]
5532
+ }) : rt.call("spans.list", { ...window, status: "error", attrs }) : none,
4775
5533
  has(rt, "logs.list") ? rt.call("logs.list", { ...window, ...trace ? { trace_id: trace } : { attrs } }) : none
4776
5534
  ]);
4777
5535
  const windowError = [s, l].find((r) => r && !r.ok && (r.code === "QUERY_WINDOW_REQUIRED" || r.code === "QUERY_WINDOW_TOO_LARGE"));
@@ -4800,10 +5558,10 @@ var MCP_TOOL_DEFS = [
4800
5558
  title: "List monitors",
4801
5559
  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).",
4802
5560
  operations: ["monitors.list", "uptime.list", "slos.list"],
4803
- input: z28.object({
4804
- kind: z28.enum(["all", "cron", "uptime", "slo"]).default("all"),
4805
- project_id: z28.number().int().positive().optional(),
4806
- limit: z28.number().int().min(1).max(200).default(50)
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)
4807
5565
  }),
4808
5566
  async run(args, rt) {
4809
5567
  const kinds = args["kind"] && args["kind"] !== "all" ? [args["kind"]] : ["cron", "uptime", "slo"];
@@ -4830,11 +5588,18 @@ var MCP_TOOL_DEFS = [
4830
5588
  ...spec("get_monitor_status"),
4831
5589
  title: "Get a monitor",
4832
5590
  description: "One monitor (any type), uptime check or SLO by id: settings, current status and recent results. For count, assertion, deadline and progress monitors it adds the last 24 h of minute counts or runs from the node, and for deadline monitors the newest occurrences. `backtest: true` (count/assertion only) also replays the current settings over the last 30 days: how often it would have alerted.",
4833
- operations: ["monitors.get", "uptime.get", "slos.get", "monitors.signal", "monitors.occurrences", "monitors.backtest"],
4834
- input: z28.object({
4835
- kind: z28.enum(["cron", "uptime", "slo"]),
4836
- id: z28.guid(),
4837
- backtest: z28.boolean().default(false)
5591
+ operations: [
5592
+ "monitors.get",
5593
+ "uptime.get",
5594
+ "slos.get",
5595
+ "monitors.signal",
5596
+ "monitors.occurrences",
5597
+ "monitors.backtest"
5598
+ ],
5599
+ input: z31.object({
5600
+ kind: z31.enum(["cron", "uptime", "slo"]),
5601
+ id: z31.guid(),
5602
+ backtest: z31.boolean().default(false)
4838
5603
  }),
4839
5604
  async run(args, rt) {
4840
5605
  const k = MONITOR_KINDS2[args["kind"]];
@@ -4878,7 +5643,11 @@ var MCP_TOOL_DEFS = [
4878
5643
  else
4879
5644
  omitted.push({ part, reason: a.code });
4880
5645
  }
4881
- return wrapResult({ data, operations: ops, source: omitted.length === parts.length ? "control_plane" : "node" }, { omitted });
5646
+ return wrapResult({
5647
+ data,
5648
+ operations: ops,
5649
+ source: omitted.length === parts.length ? "control_plane" : "node"
5650
+ }, { omitted });
4882
5651
  }
4883
5652
  },
4884
5653
  single("list_alerts", "alerts.list", "List alerts", "Alerts Belvador raised (open, resolved or all), newest first, optionally for one monitor."),
@@ -4890,15 +5659,19 @@ var MCP_TOOL_DEFS = [
4890
5659
  title: "Send a test event",
4891
5660
  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).",
4892
5661
  operations: ["projects.send_test_event"],
4893
- input: z28.object({
4894
- project_id: z28.number().int().positive(),
4895
- idempotency_key: z28.string().min(8).max(255).optional()
5662
+ input: z31.object({
5663
+ project_id: z31.number().int().positive(),
5664
+ idempotency_key: z31.string().min(8).max(255).optional()
4896
5665
  }),
4897
5666
  async run(args, rt) {
4898
5667
  const r = await rt.call("projects.send_test_event", { project_id: args["project_id"] }, { idempotencyKey: args["idempotency_key"] ?? rt.newKey() });
4899
5668
  if (!r.ok)
4900
5669
  return errorResult(r);
4901
- return wrapResult({ data: r.body, operations: ["projects.send_test_event"], source: "control_plane" });
5670
+ return wrapResult({
5671
+ data: r.body,
5672
+ operations: ["projects.send_test_event"],
5673
+ source: "control_plane"
5674
+ });
4902
5675
  }
4903
5676
  },
4904
5677
  {
@@ -4906,9 +5679,9 @@ var MCP_TOOL_DEFS = [
4906
5679
  title: "Find a configuration change",
4907
5680
  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.",
4908
5681
  operations: [],
4909
- input: z28.object({
4910
- query: z28.string().min(1).max(200).describe("Words such as `rotate dsn key`, `heartbeat monitor`, `slack alert`."),
4911
- limit: z28.number().int().min(1).max(20).default(10)
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)
4912
5685
  }),
4913
5686
  async run(args, rt) {
4914
5687
  const q = words(String(args["query"]));
@@ -4936,7 +5709,7 @@ var MCP_TOOL_DEFS = [
4936
5709
  title: "Describe a configuration change",
4937
5710
  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.",
4938
5711
  operations: [],
4939
- input: z28.object({ operation_id: operationIdArg }),
5712
+ input: z31.object({ operation_id: operationIdArg }),
4940
5713
  async run(args, rt) {
4941
5714
  const op = configureOp(args["operation_id"]);
4942
5715
  if (!op || op.method === "GET")
@@ -4965,7 +5738,7 @@ var MCP_TOOL_DEFS = [
4965
5738
  title: "Check a change before applying it",
4966
5739
  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.",
4967
5740
  operations: [],
4968
- input: z28.object({ operation_id: operationIdArg, params }),
5741
+ input: z31.object({ operation_id: operationIdArg, params }),
4969
5742
  async run(args, rt) {
4970
5743
  const op = configureOp(args["operation_id"]);
4971
5744
  if (!op || op.method === "GET")
@@ -5014,11 +5787,11 @@ var MCP_TOOL_DEFS = [
5014
5787
  title: "Apply a configuration change",
5015
5788
  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.",
5016
5789
  operations: [],
5017
- input: z28.object({
5790
+ input: z31.object({
5018
5791
  operation_id: operationIdArg,
5019
5792
  params,
5020
- idempotency_key: z28.string().min(8).max(255).describe("Unique per change; reuse it to retry or to fetch the result."),
5021
- if_match: z28.string().max(200).optional().describe("ETag from plan_change, for operations that need it.")
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.")
5022
5795
  }),
5023
5796
  async run(args, rt) {
5024
5797
  const op = configureOp(args["operation_id"]);
@@ -5027,8 +5800,15 @@ var MCP_TOOL_DEFS = [
5027
5800
  const p = args["params"] ?? {};
5028
5801
  for (const f of humanWire(op))
5029
5802
  if (f in p)
5030
- return errorResult({ ok: false, status: 400, code: "INVALID_INPUT", detail: `${f} is typed by the approving person` });
5031
- const opts = { idempotencyKey: String(args["idempotency_key"]) };
5803
+ return errorResult({
5804
+ ok: false,
5805
+ status: 400,
5806
+ code: "INVALID_INPUT",
5807
+ detail: `${f} is typed by the approving person`
5808
+ });
5809
+ const opts = {
5810
+ idempotencyKey: String(args["idempotency_key"])
5811
+ };
5032
5812
  if (typeof args["if_match"] === "string" && args["if_match"])
5033
5813
  opts.ifMatch = args["if_match"];
5034
5814
  const r = await rt.call(op.id, p, opts);
@@ -5048,7 +5828,10 @@ var MCP_TOOL_DEFS = [
5048
5828
  if (r.approval && r.approval.state === "pending") {
5049
5829
  const next = APPROVAL_SETUP_OPS.includes(op.id) ? `${NEXT_PENDING} ${NEXT_SETUP}` : NEXT_PENDING;
5050
5830
  return {
5051
- structuredContent: { status: "approval_required", approval: approvalBlock(r.approval, next) },
5831
+ structuredContent: {
5832
+ status: "approval_required",
5833
+ approval: approvalBlock(r.approval, next)
5834
+ },
5052
5835
  approval: r.approval
5053
5836
  };
5054
5837
  }
@@ -5069,7 +5852,7 @@ var MCP_TOOL_DEFS = [
5069
5852
  title: "Follow an approval",
5070
5853
  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).",
5071
5854
  operations: ["approvals.get"],
5072
- input: z28.object({ approval_id: z28.guid().describe("approval_id from apply_change.") }),
5855
+ input: z31.object({ approval_id: z31.guid().describe("approval_id from apply_change.") }),
5073
5856
  async run(args, rt) {
5074
5857
  const r = await rt.call("approvals.get", { approval_id: args["approval_id"] });
5075
5858
  if (!r.ok)
@@ -5089,10 +5872,10 @@ var MCP_TOOL_DEFS = [
5089
5872
  title: "Search Belvador docs",
5090
5873
  description: "Searches the public Belvador documentation (titles and summaries) and returns the best pages with their slugs for get_doc.",
5091
5874
  operations: [],
5092
- input: z28.object({
5093
- query: z28.string().min(1).max(200),
5094
- locale: z28.enum(["en", "vi"]).default("en"),
5095
- limit: z28.number().int().min(1).max(10).default(5)
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)
5096
5879
  }),
5097
5880
  async run(args, rt) {
5098
5881
  const locale = args["locale"] ?? "en";
@@ -5108,9 +5891,9 @@ var MCP_TOOL_DEFS = [
5108
5891
  title: "Read a docs page",
5109
5892
  description: "The Markdown of one public Belvador docs page by slug (e.g. `quickstart`, `sdk/react`, `reference/api`).",
5110
5893
  operations: [],
5111
- input: z28.object({
5112
- slug: z28.string().regex(/^[a-z0-9][a-z0-9/-]{0,120}$/),
5113
- locale: z28.enum(["en", "vi"]).default("en")
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")
5114
5897
  }),
5115
5898
  async run(args, rt) {
5116
5899
  const locale = args["locale"] ?? "en";
@@ -5123,7 +5906,13 @@ var MCP_TOOL_DEFS = [
5123
5906
  const markdown = cut ? cleanUntrustedText(md, max).text : md;
5124
5907
  return {
5125
5908
  structuredContent: {
5126
- doc: { slug, locale, url: `https://belvador.dev/${locale}/docs/${slug}`, markdown, truncated: cut }
5909
+ doc: {
5910
+ slug,
5911
+ locale,
5912
+ url: `https://belvador.dev/${locale}/docs/${slug}`,
5913
+ markdown,
5914
+ truncated: cut
5915
+ }
5127
5916
  }
5128
5917
  };
5129
5918
  }
@@ -5141,7 +5930,13 @@ function parseDocsIndex(index) {
5141
5930
  }
5142
5931
  const m = /^- \[([^\]]+)\]\(https:\/\/belvador\.dev\/api\/public\/docs\/(en|vi)\/([a-z0-9/-]+)\):\s*(.*)$/.exec(line);
5143
5932
  if (m)
5144
- out.push({ title: m[1], slug: m[3], description: m[4], section, url: `https://belvador.dev/${m[2]}/docs/${m[3]}` });
5933
+ out.push({
5934
+ title: m[1],
5935
+ slug: m[3],
5936
+ description: m[4],
5937
+ section,
5938
+ url: `https://belvador.dev/${m[2]}/docs/${m[3]}`
5939
+ });
5145
5940
  }
5146
5941
  return out;
5147
5942
  }
@@ -5292,7 +6087,7 @@ function findToken(env = process.env, keychain = keychainToken) {
5292
6087
  }
5293
6088
 
5294
6089
  // packages/mcp/src/cli.ts
5295
- var PACKAGE_VERSION = "0.4.0";
6090
+ var PACKAGE_VERSION = "0.6.0";
5296
6091
  var HELP = `belvador-mcp ${PACKAGE_VERSION} — Belvador MCP server (stdio)
5297
6092
 
5298
6093
  Usage: npx -y @belvador/mcp [--toolsets=${MCP_DEFAULT_TOOLSETS.join(",")}]