@belvador/mcp 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2030 -918
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -124,8 +124,12 @@ var API_ERROR_STATUS = {
|
|
|
124
124
|
INCIDENT_STATE_INVALID: 409,
|
|
125
125
|
NOTIFICATION_POLICY_INVALID: 400,
|
|
126
126
|
COVERAGE_EXPECTATION_INVALID: 400,
|
|
127
|
+
COVERAGE_SIGNAL_UNAVAILABLE: 400,
|
|
128
|
+
COVERAGE_CODE_OWNED: 409,
|
|
129
|
+
COVERAGE_LIMIT: 409,
|
|
127
130
|
PRIVACY_RULE_INVALID: 400,
|
|
128
131
|
PRIVACY_REGEX_UNSAFE: 400,
|
|
132
|
+
PRIVACY_VERSION_CONFLICT: 409,
|
|
129
133
|
METRIC_CARDINALITY_LIMIT: 429,
|
|
130
134
|
RELEASE_NOT_FOUND: 404,
|
|
131
135
|
PUBLIC_API_PAUSED: 503,
|
|
@@ -178,7 +182,7 @@ function cleanUntrustedText(raw, maxBytes = MCP_LIMITS.untrustedStringMaxBytes)
|
|
|
178
182
|
const { text, cut } = cutUtf8(escaped, maxBytes);
|
|
179
183
|
return { text, cut, suspicious };
|
|
180
184
|
}
|
|
181
|
-
var MCP_TOOLS_VERSION =
|
|
185
|
+
var MCP_TOOLS_VERSION = 4;
|
|
182
186
|
var MCP_TOOLS = [
|
|
183
187
|
{ name: "get_workspace", toolset: "investigate", scope: "org:read", readOnly: true, destructive: false, idempotent: true },
|
|
184
188
|
{ name: "list_projects", toolset: "investigate", scope: "projects:read", readOnly: true, destructive: false, idempotent: true },
|
|
@@ -209,10 +213,7 @@ var MCP_TOOLS = [
|
|
|
209
213
|
];
|
|
210
214
|
var MCP_TOOLS_PENDING = {
|
|
211
215
|
query_metrics: "P14",
|
|
212
|
-
release_health: "P15"
|
|
213
|
-
list_incidents: "P9",
|
|
214
|
-
get_incident: "P9",
|
|
215
|
-
get_coverage: "P10"
|
|
216
|
+
release_health: "P15"
|
|
216
217
|
};
|
|
217
218
|
|
|
218
219
|
// ../src/shared/mcp/docs.ts
|
|
@@ -257,7 +258,7 @@ function docsFetcher(siteUrl, fetcher = fetch, now = () => Date.now()) {
|
|
|
257
258
|
import { CLIENT_CAPABILITIES_META_KEY, inputRequired, McpServer } from "@modelcontextprotocol/server";
|
|
258
259
|
|
|
259
260
|
// ../src/shared/contracts/mcp-tools.ts
|
|
260
|
-
import { z as
|
|
261
|
+
import { z as z28 } from "zod";
|
|
261
262
|
|
|
262
263
|
// ../src/shared/contracts/api-ops/access.ts
|
|
263
264
|
import { z as z3 } from "zod";
|
|
@@ -637,7 +638,16 @@ var UPTIME_TRIGGER = "uptime_problem";
|
|
|
637
638
|
var SLO_TRIGGER = "slo_burn";
|
|
638
639
|
var RULE_TRIGGERS = [...ALERT_TRIGGERS, INTEGRATION_TRIGGER, MONITOR_TRIGGER, UPTIME_TRIGGER, SLO_TRIGGER];
|
|
639
640
|
var SOLO_TRIGGERS = [INTEGRATION_TRIGGER, MONITOR_TRIGGER, UPTIME_TRIGGER, SLO_TRIGGER];
|
|
640
|
-
var MONITOR_RULE_KINDS = [
|
|
641
|
+
var MONITOR_RULE_KINDS = [
|
|
642
|
+
"missed",
|
|
643
|
+
"failed",
|
|
644
|
+
"timeout",
|
|
645
|
+
"unknown",
|
|
646
|
+
"count",
|
|
647
|
+
"assertion",
|
|
648
|
+
"deadline",
|
|
649
|
+
"stalled"
|
|
650
|
+
];
|
|
641
651
|
var SLO_RULE_SEVERITIES = ["page", "ticket"];
|
|
642
652
|
function validRuleTriggers(triggers) {
|
|
643
653
|
if (triggers.length === 1 && SOLO_TRIGGERS.includes(triggers[0]))
|
|
@@ -658,8 +668,9 @@ var ruleInputSchema = z4.object({
|
|
|
658
668
|
isEnabled: z4.boolean(),
|
|
659
669
|
notifyAll: z4.boolean(),
|
|
660
670
|
destinationIds: z4.array(z4.guid()).max(20),
|
|
661
|
-
monitorKinds: z4.array(z4.enum(MONITOR_RULE_KINDS)).min(1).max(
|
|
662
|
-
sloSeverities: z4.array(z4.enum(SLO_RULE_SEVERITIES)).min(1).max(2).default([...SLO_RULE_SEVERITIES])
|
|
671
|
+
monitorKinds: z4.array(z4.enum(MONITOR_RULE_KINDS)).min(1).max(MONITOR_RULE_KINDS.length).default([...MONITOR_RULE_KINDS]),
|
|
672
|
+
sloSeverities: z4.array(z4.enum(SLO_RULE_SEVERITIES)).min(1).max(2).default([...SLO_RULE_SEVERITIES]),
|
|
673
|
+
policyId: z4.guid().nullable().default(null)
|
|
663
674
|
});
|
|
664
675
|
|
|
665
676
|
// ../src/shared/contracts/api-ops/alerts.ts
|
|
@@ -676,7 +687,7 @@ var ALERT_INPUTS = {
|
|
|
676
687
|
destinationOnly: z5.object({ destinationId: uuid }),
|
|
677
688
|
createDestination: z5.object({
|
|
678
689
|
workspaceId: uuid,
|
|
679
|
-
provider: z5.enum(["telegram", "slack", "email", "webhook"]),
|
|
690
|
+
provider: z5.enum(["telegram", "slack", "email", "webhook", "pagerduty", "incident_io"]),
|
|
680
691
|
name,
|
|
681
692
|
projectIds,
|
|
682
693
|
locale
|
|
@@ -758,12 +769,14 @@ var ALERT_OPERATIONS = [
|
|
|
758
769
|
idempotency: "required",
|
|
759
770
|
status: 201,
|
|
760
771
|
mcp: "configure",
|
|
761
|
-
summary: "Start adding a Telegram, Slack, email or
|
|
772
|
+
summary: "Start adding a Telegram, Slack, email, webhook, PagerDuty or incident.io destination; a person enters its secrets.",
|
|
762
773
|
ui: [
|
|
763
774
|
"alerts#createSlackDestination",
|
|
764
775
|
"alerts#createWebhookDestination",
|
|
765
776
|
"alerts#createTelegramDestination",
|
|
766
|
-
"alerts#createEmailDestination"
|
|
777
|
+
"alerts#createEmailDestination",
|
|
778
|
+
"alerts#createPagerDutyDestination",
|
|
779
|
+
"alerts#createIncidentIoDestination"
|
|
767
780
|
]
|
|
768
781
|
}),
|
|
769
782
|
op({
|
|
@@ -852,17 +865,361 @@ var ALERT_OPERATIONS = [
|
|
|
852
865
|
})
|
|
853
866
|
];
|
|
854
867
|
|
|
855
|
-
// ../src/shared/contracts/api-ops/
|
|
856
|
-
import { z as z11 } from "zod";
|
|
857
|
-
|
|
858
|
-
// ../src/shared/contracts/heartbeat.ts
|
|
868
|
+
// ../src/shared/contracts/api-ops/coverage.ts
|
|
859
869
|
import { z as z8 } from "zod";
|
|
860
870
|
|
|
861
|
-
// ../src/shared/contracts/
|
|
871
|
+
// ../src/shared/contracts/coverage.ts
|
|
872
|
+
import { z as z7 } from "zod";
|
|
873
|
+
|
|
874
|
+
// ../src/shared/contracts/integration-health.ts
|
|
862
875
|
import { z as z6 } from "zod";
|
|
863
876
|
|
|
877
|
+
// ../src/shared/contracts/platforms.ts
|
|
878
|
+
var PLATFORMS = [
|
|
879
|
+
"javascript-browser",
|
|
880
|
+
"react",
|
|
881
|
+
"node",
|
|
882
|
+
"python",
|
|
883
|
+
"tanstack-start",
|
|
884
|
+
"other"
|
|
885
|
+
];
|
|
886
|
+
|
|
887
|
+
// ../src/shared/contracts/integration-health.ts
|
|
888
|
+
var VERIFICATION_ID_RE = /^bv1_[0-9a-f]{32}$/;
|
|
889
|
+
var verificationIdSchema = z6.string().regex(VERIFICATION_ID_RE);
|
|
890
|
+
var SURFACES = ["browser", "server"];
|
|
891
|
+
var RECEIPT_SURFACES = ["browser", "server", "belvador"];
|
|
892
|
+
var CHECKS = ["delivery", "uncaught", "pipeline"];
|
|
893
|
+
var HOOK_STATES = ["ok", "missing", "unknown"];
|
|
894
|
+
var verificationContextSchema = z6.object({
|
|
895
|
+
v: z6.literal(1),
|
|
896
|
+
surface: z6.enum(RECEIPT_SURFACES),
|
|
897
|
+
check: z6.enum(CHECKS),
|
|
898
|
+
hook: z6.enum(HOOK_STATES).optional(),
|
|
899
|
+
uncaught_expected: z6.boolean().optional()
|
|
900
|
+
});
|
|
901
|
+
var iso = z6.string().datetime();
|
|
902
|
+
var projectId2 = z6.number().int().positive();
|
|
903
|
+
var verificationReceiptSchema = z6.object({
|
|
904
|
+
project_id: projectId2,
|
|
905
|
+
verification_id: verificationIdSchema,
|
|
906
|
+
surface: z6.enum(RECEIPT_SURFACES),
|
|
907
|
+
check: z6.enum(CHECKS),
|
|
908
|
+
hook: z6.enum(HOOK_STATES),
|
|
909
|
+
uncaught_expected: z6.boolean(),
|
|
910
|
+
sdk_name: z6.string().max(80),
|
|
911
|
+
sdk_version: z6.string().max(40),
|
|
912
|
+
environment: z6.string().max(64),
|
|
913
|
+
release: z6.string().max(200),
|
|
914
|
+
source_host: z6.string().max(253),
|
|
915
|
+
received_at: iso
|
|
916
|
+
});
|
|
917
|
+
var SDK_DELIVERY_DROP_REASONS = ["network_error", "queue_overflow", "send_error"];
|
|
918
|
+
var clientDiscardSchema = z6.object({
|
|
919
|
+
hour: iso,
|
|
920
|
+
reason: z6.enum(SDK_DELIVERY_DROP_REASONS),
|
|
921
|
+
n: z6.number().int().nonnegative()
|
|
922
|
+
});
|
|
923
|
+
var edgeVerificationRequestSchema = z6.object({
|
|
924
|
+
v: z6.literal(1),
|
|
925
|
+
project_id: projectId2,
|
|
926
|
+
verification_id: verificationIdSchema
|
|
927
|
+
});
|
|
928
|
+
var readbackCheckSchema = z6.object({
|
|
929
|
+
surface: z6.enum(RECEIPT_SURFACES),
|
|
930
|
+
check: z6.enum(CHECKS),
|
|
931
|
+
hook: z6.enum(HOOK_STATES),
|
|
932
|
+
received_at: iso
|
|
933
|
+
});
|
|
934
|
+
var edgeVerificationResponseSchema = z6.object({
|
|
935
|
+
checks: z6.array(readbackCheckSchema).max(8)
|
|
936
|
+
});
|
|
937
|
+
var readbackResponseSchema = z6.object({
|
|
938
|
+
v: z6.literal(1),
|
|
939
|
+
verification_id: verificationIdSchema,
|
|
940
|
+
node: z6.enum(["connected", "offline"]),
|
|
941
|
+
checks: z6.array(readbackCheckSchema).max(8)
|
|
942
|
+
});
|
|
943
|
+
var ENVIRONMENT_RE = /^[^\u0000-\u001f]{1,64}$/;
|
|
944
|
+
var projectRuntimeSchema = z6.object({
|
|
945
|
+
project_id: projectId2,
|
|
946
|
+
environment: z6.string().max(64),
|
|
947
|
+
surface: z6.enum(SURFACES),
|
|
948
|
+
sdk_name: z6.string().max(80),
|
|
949
|
+
sdk_version: z6.string().max(40),
|
|
950
|
+
latest_release: z6.string().max(200),
|
|
951
|
+
first_seen: iso,
|
|
952
|
+
last_seen: iso,
|
|
953
|
+
events_24h: z6.number().int().nonnegative(),
|
|
954
|
+
check_ins_24h: z6.number().int().nonnegative()
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
// ../src/shared/contracts/vocab/coverage.ts
|
|
958
|
+
var COVERAGE_SURFACES = [
|
|
959
|
+
"browser",
|
|
960
|
+
"server",
|
|
961
|
+
"worker",
|
|
962
|
+
"job",
|
|
963
|
+
"edge_function",
|
|
964
|
+
"database",
|
|
965
|
+
"uptime"
|
|
966
|
+
];
|
|
967
|
+
var COVERAGE_SIGNALS = [
|
|
968
|
+
"errors",
|
|
969
|
+
"traces",
|
|
970
|
+
"logs",
|
|
971
|
+
"metrics",
|
|
972
|
+
"check_ins",
|
|
973
|
+
"web_vitals",
|
|
974
|
+
"probes"
|
|
975
|
+
];
|
|
976
|
+
var COVERAGE_STATUSES = ["verified", "stale", "problem", "unknown"];
|
|
977
|
+
var COVERAGE_SOURCES = ["ui", "code"];
|
|
978
|
+
|
|
979
|
+
// ../src/shared/contracts/coverage.ts
|
|
980
|
+
var SURFACE_SIGNALS = {
|
|
981
|
+
browser: ["errors", "traces", "logs", "web_vitals"],
|
|
982
|
+
server: ["errors", "traces", "logs", "metrics"],
|
|
983
|
+
worker: ["errors", "traces", "logs", "metrics"],
|
|
984
|
+
edge_function: ["errors", "traces", "logs", "metrics"],
|
|
985
|
+
job: ["check_ins", "errors", "traces", "logs"],
|
|
986
|
+
database: ["traces", "metrics"],
|
|
987
|
+
uptime: ["probes"]
|
|
988
|
+
};
|
|
989
|
+
function coveragePairOk(surface, signal) {
|
|
990
|
+
return SURFACE_SIGNALS[surface].includes(signal);
|
|
991
|
+
}
|
|
992
|
+
var COVERAGE_RULES = {
|
|
993
|
+
staleAfterHoursDefault: 168,
|
|
994
|
+
staleAfterHoursMin: 1,
|
|
995
|
+
staleAfterHoursMax: 720,
|
|
996
|
+
noteMax: 200,
|
|
997
|
+
evidenceRowsPerProject: 256,
|
|
998
|
+
undeclaredDays: 30,
|
|
999
|
+
resendMs: 3600000,
|
|
1000
|
+
newKeyFlushMs: 60000,
|
|
1001
|
+
backfillErrorsDays: 30,
|
|
1002
|
+
backfillTelemetryDays: 7,
|
|
1003
|
+
setMaxItems: 1000
|
|
1004
|
+
};
|
|
1005
|
+
var FAAS_CLOUD_PLATFORMS = new Set([
|
|
1006
|
+
"aws_lambda",
|
|
1007
|
+
"azure_functions",
|
|
1008
|
+
"gcp_cloud_functions",
|
|
1009
|
+
"alibaba_cloud_fc",
|
|
1010
|
+
"tencent_cloud_scf"
|
|
1011
|
+
]);
|
|
1012
|
+
var FUNCTION_RUNTIMES = new Set(["cloudflare", "workerd", "vercel-edge", "edge-light"]);
|
|
1013
|
+
var seconds = z7.number().int().positive();
|
|
1014
|
+
var coverageSeenRowSchema = z7.object({
|
|
1015
|
+
environment: z7.string().max(64),
|
|
1016
|
+
surface: z7.enum(COVERAGE_SURFACES),
|
|
1017
|
+
signal: z7.enum(COVERAGE_SIGNALS),
|
|
1018
|
+
last_seen: seconds,
|
|
1019
|
+
last_verified: seconds.nullable()
|
|
1020
|
+
}).strict();
|
|
1021
|
+
var coverageSeenReportSchema = z7.object({
|
|
1022
|
+
project_id: z7.number().int().positive(),
|
|
1023
|
+
rows: z7.array(coverageSeenRowSchema).max(COVERAGE_RULES.evidenceRowsPerProject)
|
|
1024
|
+
}).strict();
|
|
1025
|
+
var environment = z7.string().trim().regex(ENVIRONMENT_RE);
|
|
1026
|
+
var note = z7.string().trim().max(COVERAGE_RULES.noteMax).regex(/^[^\p{Cc}]*$/u);
|
|
1027
|
+
var coverageExpectationInputSchema = z7.object({
|
|
1028
|
+
environment,
|
|
1029
|
+
surface: z7.enum(COVERAGE_SURFACES),
|
|
1030
|
+
signals: z7.array(z7.enum(COVERAGE_SIGNALS)).min(1).max(COVERAGE_SIGNALS.length),
|
|
1031
|
+
staleAfterHours: z7.number().int().min(COVERAGE_RULES.staleAfterHoursMin).max(COVERAGE_RULES.staleAfterHoursMax).default(COVERAGE_RULES.staleAfterHoursDefault),
|
|
1032
|
+
note: note.default("")
|
|
1033
|
+
}).superRefine((e, ctx) => {
|
|
1034
|
+
const seen = new Set;
|
|
1035
|
+
for (const s of e.signals) {
|
|
1036
|
+
if (seen.has(s))
|
|
1037
|
+
ctx.addIssue({ code: "custom", path: ["signals"], message: "duplicate" });
|
|
1038
|
+
seen.add(s);
|
|
1039
|
+
if (!coveragePairOk(e.surface, s))
|
|
1040
|
+
ctx.addIssue({ code: "custom", path: ["signals"], message: `not_for_${e.surface}` });
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
var coverageExpectationListSchema = z7.array(coverageExpectationInputSchema).max(COVERAGE_RULES.setMaxItems).superRefine((list, ctx) => {
|
|
1044
|
+
const keys = new Set;
|
|
1045
|
+
list.forEach((e, i) => {
|
|
1046
|
+
const k = `${e.environment}\x00${e.surface}`;
|
|
1047
|
+
if (keys.has(k))
|
|
1048
|
+
ctx.addIssue({ code: "custom", path: [i, "surface"], message: "duplicate" });
|
|
1049
|
+
keys.add(k);
|
|
1050
|
+
});
|
|
1051
|
+
});
|
|
1052
|
+
var iso2 = z7.string();
|
|
1053
|
+
var count = z7.number().int().nonnegative();
|
|
1054
|
+
var coverageCellSchema = z7.object({
|
|
1055
|
+
expectation_id: z7.string(),
|
|
1056
|
+
project_id: z7.number().int().positive(),
|
|
1057
|
+
environment: z7.string(),
|
|
1058
|
+
surface: z7.enum(COVERAGE_SURFACES),
|
|
1059
|
+
signal: z7.enum(COVERAGE_SIGNALS),
|
|
1060
|
+
status: z7.enum(COVERAGE_STATUSES),
|
|
1061
|
+
source: z7.enum(["receipt", "signal"]).nullable(),
|
|
1062
|
+
last_seen_at: iso2.nullable(),
|
|
1063
|
+
last_verified_at: iso2.nullable(),
|
|
1064
|
+
problem_code: z7.string().nullable()
|
|
1065
|
+
});
|
|
1066
|
+
var coverageExpectationRowSchema = z7.object({
|
|
1067
|
+
expectation_id: z7.string(),
|
|
1068
|
+
project_id: z7.number().int().positive(),
|
|
1069
|
+
environment: z7.string(),
|
|
1070
|
+
surface: z7.enum(COVERAGE_SURFACES),
|
|
1071
|
+
signals: z7.array(z7.enum(COVERAGE_SIGNALS)),
|
|
1072
|
+
stale_after_hours: z7.number().int(),
|
|
1073
|
+
note: z7.string(),
|
|
1074
|
+
config_source: z7.enum(COVERAGE_SOURCES),
|
|
1075
|
+
revision: z7.number().int(),
|
|
1076
|
+
updated_at: iso2
|
|
1077
|
+
});
|
|
1078
|
+
var coverageReportSchema = z7.object({
|
|
1079
|
+
generated_at: iso2,
|
|
1080
|
+
expectations_max: z7.number().int().nonnegative(),
|
|
1081
|
+
summary: z7.object({ total: count, verified: count, stale: count, problem: count, unknown: count }),
|
|
1082
|
+
projects: z7.array(z7.object({
|
|
1083
|
+
project_id: z7.number().int().positive(),
|
|
1084
|
+
slug: z7.string(),
|
|
1085
|
+
name: z7.string(),
|
|
1086
|
+
platform: z7.string(),
|
|
1087
|
+
primary_environment: z7.string(),
|
|
1088
|
+
config_source: z7.enum(COVERAGE_SOURCES).nullable()
|
|
1089
|
+
})),
|
|
1090
|
+
expectations: z7.array(coverageExpectationRowSchema),
|
|
1091
|
+
cells: z7.array(coverageCellSchema),
|
|
1092
|
+
undeclared: z7.array(z7.object({
|
|
1093
|
+
project_id: z7.number().int().positive(),
|
|
1094
|
+
environment: z7.string(),
|
|
1095
|
+
surface: z7.enum(COVERAGE_SURFACES),
|
|
1096
|
+
signal: z7.enum(COVERAGE_SIGNALS),
|
|
1097
|
+
last_seen_at: iso2
|
|
1098
|
+
})),
|
|
1099
|
+
environments: z7.array(z7.string()),
|
|
1100
|
+
node_agent_version: z7.string().nullable()
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
// ../src/shared/contracts/api-ops/coverage.ts
|
|
1104
|
+
var COVERAGE_INPUTS = {
|
|
1105
|
+
get: z8.object({
|
|
1106
|
+
workspaceId: uuid,
|
|
1107
|
+
projectId: projectId.optional(),
|
|
1108
|
+
environment: z8.string().trim().regex(ENVIRONMENT_RE).optional()
|
|
1109
|
+
}),
|
|
1110
|
+
set: z8.object({
|
|
1111
|
+
workspaceId: uuid,
|
|
1112
|
+
projectId,
|
|
1113
|
+
configSource: z8.enum(COVERAGE_SOURCES).default("ui"),
|
|
1114
|
+
expectations: coverageExpectationListSchema
|
|
1115
|
+
})
|
|
1116
|
+
};
|
|
1117
|
+
var C = COVERAGE_INPUTS;
|
|
1118
|
+
var COVERAGE_OPERATIONS = [
|
|
1119
|
+
op({
|
|
1120
|
+
id: "coverage.get",
|
|
1121
|
+
method: "GET",
|
|
1122
|
+
path: "/v1/coverage",
|
|
1123
|
+
scope: "coverage:read",
|
|
1124
|
+
sensitivity: "normal",
|
|
1125
|
+
kind: "read",
|
|
1126
|
+
rpcs: ["api_read_coverage"],
|
|
1127
|
+
input: C.get,
|
|
1128
|
+
workspace: true,
|
|
1129
|
+
idempotency: "none",
|
|
1130
|
+
mcp: "reliability",
|
|
1131
|
+
summary: "What each app is expected to send (surface × signal × environment) against what Belvador saw: `verified`, `stale`, `problem` or `unknown`, the verified rate, and signals seen but not declared. Same numbers as the Coverage page.",
|
|
1132
|
+
ui: []
|
|
1133
|
+
}),
|
|
1134
|
+
op({
|
|
1135
|
+
id: "coverage.set",
|
|
1136
|
+
method: "PUT",
|
|
1137
|
+
path: "/v1/projects/{project_id}/coverage-expectations",
|
|
1138
|
+
scope: "coverage:write",
|
|
1139
|
+
sensitivity: "normal",
|
|
1140
|
+
kind: "write",
|
|
1141
|
+
rpcs: ["set_coverage_expectations"],
|
|
1142
|
+
input: C.set,
|
|
1143
|
+
workspace: true,
|
|
1144
|
+
idempotency: "optional",
|
|
1145
|
+
mcp: "configure",
|
|
1146
|
+
summary: "Replace a project's coverage expectations (one per environment × surface). `config_source: code` locks them in the app; send `ui` once to hand them back. Members and up.",
|
|
1147
|
+
ui: ["coverage#setCoverageExpectations"]
|
|
1148
|
+
})
|
|
1149
|
+
];
|
|
1150
|
+
|
|
1151
|
+
// ../src/shared/contracts/api-ops/incidents.ts
|
|
1152
|
+
import { z as z13 } from "zod";
|
|
1153
|
+
|
|
1154
|
+
// ../src/shared/contracts/notifications.ts
|
|
1155
|
+
import { z as z12 } from "zod";
|
|
1156
|
+
|
|
1157
|
+
// ../src/shared/contracts/maintenance.ts
|
|
1158
|
+
import { z as z9 } from "zod";
|
|
1159
|
+
var MAINTENANCE_SCOPES = ["workspace", "project", "monitor"];
|
|
1160
|
+
var MAINTENANCE_LIMITS = {
|
|
1161
|
+
durationMinutesMin: 5,
|
|
1162
|
+
durationMinutesMax: 1440,
|
|
1163
|
+
reasonMax: 200,
|
|
1164
|
+
idsMax: 50,
|
|
1165
|
+
onceAheadDays: 366,
|
|
1166
|
+
previewStarts: 3
|
|
1167
|
+
};
|
|
1168
|
+
var weekdaySchema = z9.number().int().min(1).max(7);
|
|
1169
|
+
var timeOfDay = z9.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
|
|
1170
|
+
var base = {
|
|
1171
|
+
scope: z9.enum(MAINTENANCE_SCOPES),
|
|
1172
|
+
projectIds: z9.array(z9.number().int().positive()).max(MAINTENANCE_LIMITS.idsMax),
|
|
1173
|
+
monitorIds: z9.array(z9.guid()).max(MAINTENANCE_LIMITS.idsMax),
|
|
1174
|
+
timezone: z9.string().trim().min(1).max(64),
|
|
1175
|
+
durationMinutes: z9.number().int().min(MAINTENANCE_LIMITS.durationMinutesMin).max(MAINTENANCE_LIMITS.durationMinutesMax),
|
|
1176
|
+
reason: z9.string().trim().max(MAINTENANCE_LIMITS.reasonMax).regex(/^[^\p{Cc}]*$/u)
|
|
1177
|
+
};
|
|
1178
|
+
var maintenanceInputSchema = z9.discriminatedUnion("kind", [
|
|
1179
|
+
z9.object({ kind: z9.literal("once"), startsAt: z9.string().datetime({ offset: true }), ...base }),
|
|
1180
|
+
z9.object({
|
|
1181
|
+
kind: z9.literal("weekly"),
|
|
1182
|
+
weekdays: z9.array(weekdaySchema).min(1).max(7),
|
|
1183
|
+
startTime: timeOfDay,
|
|
1184
|
+
...base
|
|
1185
|
+
})
|
|
1186
|
+
]).superRefine((w, ctx) => {
|
|
1187
|
+
const bad = (path) => ctx.addIssue({ code: "custom", path: [path], message: "MAINTENANCE_INVALID" });
|
|
1188
|
+
if (w.scope === "workspace" && (w.projectIds.length || w.monitorIds.length))
|
|
1189
|
+
bad("scope");
|
|
1190
|
+
if (w.scope === "project" && (!w.projectIds.length || w.monitorIds.length))
|
|
1191
|
+
bad("projectIds");
|
|
1192
|
+
if (w.scope === "monitor" && (!w.monitorIds.length || w.projectIds.length))
|
|
1193
|
+
bad("monitorIds");
|
|
1194
|
+
if (new Set(w.projectIds).size !== w.projectIds.length)
|
|
1195
|
+
bad("projectIds");
|
|
1196
|
+
if (new Set(w.monitorIds).size !== w.monitorIds.length)
|
|
1197
|
+
bad("monitorIds");
|
|
1198
|
+
if (w.kind === "weekly" && new Set(w.weekdays).size !== w.weekdays.length)
|
|
1199
|
+
bad("weekdays");
|
|
1200
|
+
if (!validTimeZone(w.timezone))
|
|
1201
|
+
bad("timezone");
|
|
1202
|
+
});
|
|
1203
|
+
function validTimeZone(tz) {
|
|
1204
|
+
try {
|
|
1205
|
+
new Intl.DateTimeFormat("en-US", { timeZone: tz });
|
|
1206
|
+
return true;
|
|
1207
|
+
} catch {
|
|
1208
|
+
return false;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
var fmtCache = new Map;
|
|
1212
|
+
|
|
1213
|
+
// ../src/shared/contracts/signal-monitors.ts
|
|
1214
|
+
import { z as z11 } from "zod";
|
|
1215
|
+
|
|
1216
|
+
// ../src/shared/contracts/monitors.ts
|
|
1217
|
+
import { z as z10 } from "zod";
|
|
1218
|
+
|
|
864
1219
|
// ../src/shared/contracts/vocab/monitors.ts
|
|
865
1220
|
var MONITOR_MODES = ["check_in", "heartbeat"];
|
|
1221
|
+
var MONITOR_TYPES = ["job", "count", "assertion", "deadline", "progress"];
|
|
1222
|
+
var SIGNAL_MONITOR_TYPES = ["count", "assertion", "deadline", "progress"];
|
|
866
1223
|
|
|
867
1224
|
// ../src/shared/contracts/monitors.ts
|
|
868
1225
|
var MONITOR_KINDS = ["crontab", "interval", "on_demand"];
|
|
@@ -872,8 +1229,13 @@ var MONITOR_INCIDENT_CODES = [
|
|
|
872
1229
|
"MONITOR_MISSED",
|
|
873
1230
|
"MONITOR_FAILED",
|
|
874
1231
|
"MONITOR_TIMEOUT",
|
|
875
|
-
"MONITOR_UNKNOWN"
|
|
1232
|
+
"MONITOR_UNKNOWN",
|
|
1233
|
+
"MONITOR_COUNT",
|
|
1234
|
+
"MONITOR_ASSERTION",
|
|
1235
|
+
"MONITOR_DEADLINE_MISSED",
|
|
1236
|
+
"MONITOR_STALLED"
|
|
876
1237
|
];
|
|
1238
|
+
var FAILURE_INCIDENT_CODES = MONITOR_INCIDENT_CODES.filter((c) => c !== "MONITOR_UNKNOWN");
|
|
877
1239
|
var INCIDENT_EVENTS = ["opened", "updated", "resolved"];
|
|
878
1240
|
var UNOBSERVABLE_REASONS = [
|
|
879
1241
|
"node_offline",
|
|
@@ -924,100 +1286,112 @@ function crontabShapeOk(value) {
|
|
|
924
1286
|
const fields = value.trim().split(/\s+/);
|
|
925
1287
|
return value.length <= 120 && fields.length === 5 && fields.every((f) => /^[0-9A-Za-z*,/?#LW-]+$/.test(f));
|
|
926
1288
|
}
|
|
927
|
-
var crontabScheduleSchema =
|
|
928
|
-
type:
|
|
929
|
-
value:
|
|
1289
|
+
var crontabScheduleSchema = z10.object({
|
|
1290
|
+
type: z10.literal("crontab"),
|
|
1291
|
+
value: z10.string().refine(crontabShapeOk, "crontab")
|
|
930
1292
|
});
|
|
931
|
-
var intervalScheduleSchema =
|
|
932
|
-
type:
|
|
933
|
-
value:
|
|
934
|
-
unit:
|
|
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)
|
|
935
1297
|
});
|
|
936
|
-
var scheduleSchema =
|
|
1298
|
+
var scheduleSchema = z10.discriminatedUnion("type", [
|
|
937
1299
|
crontabScheduleSchema,
|
|
938
1300
|
intervalScheduleSchema
|
|
939
1301
|
]);
|
|
940
|
-
var monitorSettingsSchema =
|
|
1302
|
+
var monitorSettingsSchema = z10.object({
|
|
941
1303
|
schedule: scheduleSchema.nullable(),
|
|
942
|
-
timezone:
|
|
943
|
-
checkin_margin:
|
|
944
|
-
max_runtime:
|
|
945
|
-
failure_issue_threshold:
|
|
946
|
-
recovery_threshold:
|
|
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)
|
|
947
1309
|
});
|
|
948
|
-
var
|
|
949
|
-
var
|
|
950
|
-
var envName =
|
|
1310
|
+
var iso3 = z10.string().datetime();
|
|
1311
|
+
var projectId3 = z10.number().int().positive();
|
|
1312
|
+
var envName = z10.string().min(1).max(MONITOR_LIMITS.environmentMax);
|
|
951
1313
|
var monitorDefinitionSchema = monitorSettingsSchema.extend({
|
|
952
|
-
id:
|
|
953
|
-
project_id:
|
|
954
|
-
slug:
|
|
955
|
-
kind:
|
|
956
|
-
expected_environments:
|
|
957
|
-
paused_until:
|
|
958
|
-
created_at:
|
|
959
|
-
config_source:
|
|
960
|
-
config_hash:
|
|
1314
|
+
id: z10.guid(),
|
|
1315
|
+
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),
|
|
1319
|
+
paused_until: iso3.nullable(),
|
|
1320
|
+
created_at: iso3,
|
|
1321
|
+
config_source: z10.enum(CONFIG_SOURCES),
|
|
1322
|
+
config_hash: z10.string().regex(/^[0-9a-f]{64}$/).nullable()
|
|
961
1323
|
});
|
|
962
|
-
var outcomeCounts =
|
|
963
|
-
ok:
|
|
964
|
-
skipped:
|
|
965
|
-
error:
|
|
966
|
-
timeout:
|
|
967
|
-
missed:
|
|
968
|
-
unknown:
|
|
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()
|
|
969
1331
|
});
|
|
970
|
-
var
|
|
971
|
-
|
|
972
|
-
|
|
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(),
|
|
1336
|
+
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()
|
|
1340
|
+
});
|
|
1341
|
+
var monitorStatusSchema = z10.object({
|
|
1342
|
+
monitor_id: z10.guid(),
|
|
1343
|
+
project_id: projectId3,
|
|
973
1344
|
environment: envName,
|
|
974
|
-
open_failure:
|
|
975
|
-
open_unknown:
|
|
976
|
-
unobservable:
|
|
977
|
-
last_outcome:
|
|
978
|
-
last_check_in_at:
|
|
979
|
-
last_healthy_at:
|
|
980
|
-
next_deadline_at:
|
|
981
|
-
next_due_at:
|
|
982
|
-
in_progress:
|
|
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(),
|
|
1349
|
+
last_check_in_at: iso3.nullable(),
|
|
1350
|
+
last_healthy_at: iso3.nullable(),
|
|
1351
|
+
next_deadline_at: iso3.nullable(),
|
|
1352
|
+
next_due_at: iso3.nullable().optional(),
|
|
1353
|
+
in_progress: z10.boolean(),
|
|
983
1354
|
counts_24h: outcomeCounts,
|
|
984
|
-
|
|
1355
|
+
signal: signalStatusSchema.optional(),
|
|
1356
|
+
evaluated_at: iso3
|
|
985
1357
|
});
|
|
986
|
-
var monitorIncidentSchema =
|
|
987
|
-
incident_id:
|
|
988
|
-
monitor_id:
|
|
989
|
-
project_id:
|
|
1358
|
+
var monitorIncidentSchema = z10.object({
|
|
1359
|
+
incident_id: z10.guid(),
|
|
1360
|
+
monitor_id: z10.guid(),
|
|
1361
|
+
project_id: projectId3,
|
|
990
1362
|
environment: envName,
|
|
991
|
-
code:
|
|
992
|
-
event:
|
|
993
|
-
occurred_at:
|
|
994
|
-
detected_late:
|
|
995
|
-
reason:
|
|
996
|
-
duration_ms:
|
|
997
|
-
consecutive:
|
|
998
|
-
reviewed_by:
|
|
1363
|
+
code: z10.enum(MONITOR_INCIDENT_CODES),
|
|
1364
|
+
event: z10.enum(INCIDENT_EVENTS),
|
|
1365
|
+
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()
|
|
999
1373
|
});
|
|
1000
|
-
var monitorDiscoverySchema =
|
|
1001
|
-
project_id:
|
|
1002
|
-
slug:
|
|
1374
|
+
var monitorDiscoverySchema = z10.object({
|
|
1375
|
+
project_id: projectId3,
|
|
1376
|
+
slug: z10.string().regex(SLUG_RE),
|
|
1003
1377
|
settings: monitorSettingsSchema.nullable(),
|
|
1004
|
-
config_hash:
|
|
1005
|
-
check_ins:
|
|
1006
|
-
last_seen_at:
|
|
1378
|
+
config_hash: z10.string().regex(/^[0-9a-f]{64}$/).nullable(),
|
|
1379
|
+
check_ins: z10.number().int().nonnegative(),
|
|
1380
|
+
last_seen_at: iso3
|
|
1007
1381
|
});
|
|
1008
1382
|
var MONITOR_NAME_MAX = MONITOR_LIMITS.nameMax;
|
|
1009
|
-
var environmentName =
|
|
1010
|
-
var monitorInputSchema =
|
|
1011
|
-
name:
|
|
1012
|
-
mode:
|
|
1013
|
-
kind:
|
|
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),
|
|
1014
1388
|
schedule: scheduleSchema.nullable(),
|
|
1015
|
-
timezone:
|
|
1016
|
-
checkinMarginMin:
|
|
1017
|
-
maxRuntimeMin:
|
|
1018
|
-
failureThreshold:
|
|
1019
|
-
recoveryThreshold:
|
|
1020
|
-
expectedEnvironments:
|
|
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)
|
|
1021
1395
|
}).refine((v) => v.kind === "on_demand" ? v.schedule === null : v.schedule?.type === v.kind, {
|
|
1022
1396
|
path: ["schedule"],
|
|
1023
1397
|
message: "schedule"
|
|
@@ -1032,98 +1406,601 @@ var MONITOR_INPUT_DEFAULTS = {
|
|
|
1032
1406
|
recoveryThreshold: MONITOR_LIMITS.recoveryThresholdDefault,
|
|
1033
1407
|
expectedEnvironments: [DEFAULT_CHECK_IN_ENVIRONMENT]
|
|
1034
1408
|
};
|
|
1035
|
-
var runOutcome =
|
|
1036
|
-
var runFlags =
|
|
1037
|
-
var monitorRunSchema =
|
|
1038
|
-
id:
|
|
1039
|
-
kind:
|
|
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"]),
|
|
1040
1414
|
outcome: runOutcome,
|
|
1041
|
-
started_at:
|
|
1042
|
-
ended_at:
|
|
1043
|
-
attempts:
|
|
1044
|
-
duration_ms:
|
|
1045
|
-
reason:
|
|
1046
|
-
check_in_id:
|
|
1047
|
-
trace_id:
|
|
1048
|
-
release:
|
|
1415
|
+
started_at: iso3,
|
|
1416
|
+
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(),
|
|
1049
1423
|
flags: runFlags
|
|
1050
1424
|
});
|
|
1051
|
-
var openAttemptSchema =
|
|
1052
|
-
check_in_id:
|
|
1053
|
-
run_key:
|
|
1054
|
-
attempt:
|
|
1055
|
-
state:
|
|
1056
|
-
started_at:
|
|
1057
|
-
deadline_at:
|
|
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),
|
|
1430
|
+
started_at: iso3,
|
|
1431
|
+
deadline_at: iso3
|
|
1058
1432
|
});
|
|
1059
|
-
var monitorRunsResponseSchema =
|
|
1060
|
-
open:
|
|
1061
|
-
runs:
|
|
1062
|
-
next_cursor:
|
|
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()
|
|
1063
1437
|
});
|
|
1064
|
-
var timelineRunSchema =
|
|
1065
|
-
id:
|
|
1066
|
-
kind:
|
|
1438
|
+
var timelineRunSchema = z10.object({
|
|
1439
|
+
id: z10.number().int().positive(),
|
|
1440
|
+
kind: z10.enum(["run", "missed"]),
|
|
1067
1441
|
outcome: runOutcome,
|
|
1068
|
-
ended_at:
|
|
1442
|
+
ended_at: iso3,
|
|
1069
1443
|
flags: runFlags
|
|
1070
1444
|
});
|
|
1071
|
-
var monitorTimelineResponseSchema =
|
|
1072
|
-
runs:
|
|
1445
|
+
var monitorTimelineResponseSchema = z10.object({
|
|
1446
|
+
runs: z10.array(timelineRunSchema).max(MONITOR_LIMITS.timelineRuns)
|
|
1073
1447
|
});
|
|
1074
|
-
var monitorStripsResponseSchema =
|
|
1075
|
-
strips:
|
|
1076
|
-
monitor_id:
|
|
1448
|
+
var monitorStripsResponseSchema = z10.object({
|
|
1449
|
+
strips: z10.array(z10.object({
|
|
1450
|
+
monitor_id: z10.guid(),
|
|
1077
1451
|
environment: envName,
|
|
1078
|
-
runs:
|
|
1452
|
+
runs: z10.array(timelineRunSchema).max(MONITOR_LIMITS.listStripRuns)
|
|
1079
1453
|
})).max(5000)
|
|
1080
1454
|
});
|
|
1081
|
-
var monitorDiagnosticSchema =
|
|
1082
|
-
id:
|
|
1083
|
-
check_in_id:
|
|
1084
|
-
signal:
|
|
1085
|
-
exit_code:
|
|
1086
|
-
received_at:
|
|
1087
|
-
body:
|
|
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(),
|
|
1460
|
+
received_at: iso3,
|
|
1461
|
+
body: z10.string().max(MONITOR_LIMITS.diagnosticMaxBytes * 2)
|
|
1088
1462
|
});
|
|
1089
|
-
var monitorDiagnosticsResponseSchema =
|
|
1090
|
-
diagnostics:
|
|
1091
|
-
next_cursor:
|
|
1463
|
+
var monitorDiagnosticsResponseSchema = z10.object({
|
|
1464
|
+
diagnostics: z10.array(monitorDiagnosticSchema).max(50),
|
|
1465
|
+
next_cursor: z10.string().regex(/^\d{1,19}$/).nullable()
|
|
1092
1466
|
});
|
|
1093
|
-
var checkInDetailSchema =
|
|
1094
|
-
run_key:
|
|
1095
|
-
attempts:
|
|
1096
|
-
check_in_id:
|
|
1097
|
-
attempt:
|
|
1098
|
-
result:
|
|
1099
|
-
started_at:
|
|
1100
|
-
ended_at:
|
|
1101
|
-
duration_ms:
|
|
1102
|
-
reason:
|
|
1103
|
-
trace_id:
|
|
1104
|
-
release:
|
|
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),
|
|
1473
|
+
started_at: iso3,
|
|
1474
|
+
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()
|
|
1105
1479
|
})).max(1000),
|
|
1106
|
-
errors:
|
|
1107
|
-
event_id:
|
|
1108
|
-
issue_id:
|
|
1109
|
-
title:
|
|
1110
|
-
level:
|
|
1111
|
-
timestamp:
|
|
1112
|
-
same_trace:
|
|
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),
|
|
1485
|
+
timestamp: iso3,
|
|
1486
|
+
same_trace: z10.boolean()
|
|
1113
1487
|
})).max(50),
|
|
1114
|
-
diagnostics:
|
|
1488
|
+
diagnostics: z10.array(monitorDiagnosticSchema).max(20).default([])
|
|
1489
|
+
});
|
|
1490
|
+
var incidentReviewSchema = z10.object({ incident_id: z10.guid() });
|
|
1491
|
+
|
|
1492
|
+
// ../src/shared/contracts/signal-monitors.ts
|
|
1493
|
+
var isSignalMonitorType = (t) => SIGNAL_MONITOR_TYPES.includes(t);
|
|
1494
|
+
var SIGNAL_KINDS = ["event", "check_in", "span", "log"];
|
|
1495
|
+
var SELECTOR_OPS = ["eq", "ne", "lt", "le", "gt", "ge", "in", "exists", "not_exists", "prefix"];
|
|
1496
|
+
var NUMERIC_OPS = new Set(["lt", "le", "gt", "ge"]);
|
|
1497
|
+
var VALUELESS_OPS = new Set(["exists", "not_exists"]);
|
|
1498
|
+
var COMPARATORS = ["lt", "gt", "outside"];
|
|
1499
|
+
var MISSING_DATA_POLICIES = ["alert", "keep", "resolve", "treat_as_zero"];
|
|
1500
|
+
var SEVERITIES = ["critical", "high", "medium", "low"];
|
|
1501
|
+
var OCCURRENCE_STATES = [
|
|
1502
|
+
"pending",
|
|
1503
|
+
"in_progress",
|
|
1504
|
+
"success",
|
|
1505
|
+
"late_success",
|
|
1506
|
+
"missed",
|
|
1507
|
+
"failed",
|
|
1508
|
+
"cancelled"
|
|
1509
|
+
];
|
|
1510
|
+
var OCCURRENCE_OPEN = new Set(["pending", "in_progress"]);
|
|
1511
|
+
var SIGNAL_LIMITS = {
|
|
1512
|
+
matchMax: 5,
|
|
1513
|
+
assertMax: 5,
|
|
1514
|
+
inValuesMax: 20,
|
|
1515
|
+
valueMax: 256,
|
|
1516
|
+
keyMax: 128,
|
|
1517
|
+
environmentsMax: MONITOR_LIMITS.expectedEnvironmentsMax,
|
|
1518
|
+
windowMinutesMin: 1,
|
|
1519
|
+
windowMinutesMax: 1440,
|
|
1520
|
+
thresholdMax: 1e6,
|
|
1521
|
+
graceMinutesMax: 1440,
|
|
1522
|
+
progressMinutesMin: 1,
|
|
1523
|
+
progressMinutesMax: 1440,
|
|
1524
|
+
occurrenceIdMax: 128,
|
|
1525
|
+
occurrenceDueMaxDays: 35,
|
|
1526
|
+
lateSuccessDays: 7,
|
|
1527
|
+
evaluateEverySeconds: 15,
|
|
1528
|
+
settleSeconds: 20,
|
|
1529
|
+
countMaxDelayMinutes: 10,
|
|
1530
|
+
countMinutesPerTick: 60,
|
|
1531
|
+
windowsPerTick: 120,
|
|
1532
|
+
monitorsPerQuery: 50,
|
|
1533
|
+
bucketRowsPerQuery: 9000,
|
|
1534
|
+
backtestDays: 30,
|
|
1535
|
+
bucketRetentionMinutes: 2 * 1440 + 60,
|
|
1536
|
+
occurrencesKeptFinished: 1000,
|
|
1537
|
+
occurrencesPageSize: 50,
|
|
1538
|
+
runIdsPerQuery: 500,
|
|
1539
|
+
dueJudgedPerTick: 5000,
|
|
1540
|
+
queryMaxSeconds: 5
|
|
1541
|
+
};
|
|
1542
|
+
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()
|
|
1548
|
+
}).superRefine((c, ctx) => {
|
|
1549
|
+
const bad = (message) => ctx.addIssue({ code: "custom", path: ["value"], message });
|
|
1550
|
+
if (VALUELESS_OPS.has(c.op)) {
|
|
1551
|
+
if (c.value !== undefined)
|
|
1552
|
+
bad("no_value");
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
if (c.value === undefined)
|
|
1556
|
+
return bad("value");
|
|
1557
|
+
if (c.op === "in") {
|
|
1558
|
+
if (!Array.isArray(c.value))
|
|
1559
|
+
bad("list");
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
if (Array.isArray(c.value))
|
|
1563
|
+
return bad("scalar");
|
|
1564
|
+
if (NUMERIC_OPS.has(c.op) && toNumber(c.value) === null)
|
|
1565
|
+
bad("number");
|
|
1566
|
+
if (c.op === "prefix" && (typeof c.value !== "string" || c.value.length === 0))
|
|
1567
|
+
bad("text");
|
|
1568
|
+
});
|
|
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)
|
|
1573
|
+
});
|
|
1574
|
+
function toNumber(v) {
|
|
1575
|
+
if (typeof v === "number")
|
|
1576
|
+
return Number.isFinite(v) ? v : null;
|
|
1577
|
+
if (typeof v === "string" && v.trim() !== "" && v.length <= 64) {
|
|
1578
|
+
const n = Number(v);
|
|
1579
|
+
return Number.isFinite(n) ? n : null;
|
|
1580
|
+
}
|
|
1581
|
+
return null;
|
|
1582
|
+
}
|
|
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);
|
|
1586
|
+
var common = {
|
|
1587
|
+
environments: environmentListSchema,
|
|
1588
|
+
severity: z11.enum(SEVERITIES),
|
|
1589
|
+
recovery_threshold: recovery
|
|
1590
|
+
};
|
|
1591
|
+
var countSettingsSchema = z11.object({
|
|
1592
|
+
type: z11.literal("count"),
|
|
1593
|
+
selector: selectorSchema,
|
|
1594
|
+
window_minutes: minutes(SIGNAL_LIMITS.windowMinutesMin, SIGNAL_LIMITS.windowMinutesMax),
|
|
1595
|
+
comparator: z11.enum(COMPARATORS),
|
|
1596
|
+
threshold,
|
|
1597
|
+
threshold_high: threshold.nullable(),
|
|
1598
|
+
missing_data: z11.enum(MISSING_DATA_POLICIES),
|
|
1599
|
+
...common
|
|
1600
|
+
}).superRefine((s, ctx) => {
|
|
1601
|
+
if (s.comparator === "outside" && (s.threshold_high === null || s.threshold_high <= s.threshold)) {
|
|
1602
|
+
ctx.addIssue({ code: "custom", path: ["threshold_high"], message: "threshold_high" });
|
|
1603
|
+
}
|
|
1604
|
+
if (s.comparator !== "outside" && s.threshold_high !== null) {
|
|
1605
|
+
ctx.addIssue({ code: "custom", path: ["threshold_high"], message: "threshold_high" });
|
|
1606
|
+
}
|
|
1607
|
+
if (s.comparator === "lt" && s.threshold === 0) {
|
|
1608
|
+
ctx.addIssue({ code: "custom", path: ["threshold"], message: "threshold" });
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
var assertionSettingsSchema = z11.object({
|
|
1612
|
+
type: z11.literal("assertion"),
|
|
1613
|
+
selector: selectorSchema,
|
|
1614
|
+
assert: z11.array(selectorConditionSchema).min(1).max(SIGNAL_LIMITS.assertMax),
|
|
1615
|
+
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),
|
|
1618
|
+
...common
|
|
1115
1619
|
});
|
|
1116
|
-
var
|
|
1620
|
+
var deadlineSettingsSchema = z11.object({
|
|
1621
|
+
type: z11.literal("deadline"),
|
|
1622
|
+
occurrence_grace_minutes: minutes(0, SIGNAL_LIMITS.graceMinutesMax),
|
|
1623
|
+
progress_timeout_minutes: minutes(SIGNAL_LIMITS.progressMinutesMin, SIGNAL_LIMITS.progressMinutesMax).nullable(),
|
|
1624
|
+
...common
|
|
1625
|
+
});
|
|
1626
|
+
var progressSettingsSchema = z11.object({
|
|
1627
|
+
type: z11.literal("progress"),
|
|
1628
|
+
progress_timeout_minutes: minutes(SIGNAL_LIMITS.progressMinutesMin, SIGNAL_LIMITS.progressMinutesMax),
|
|
1629
|
+
...common
|
|
1630
|
+
});
|
|
1631
|
+
var signalSettingsSchema = z11.discriminatedUnion("type", [
|
|
1632
|
+
countSettingsSchema,
|
|
1633
|
+
assertionSettingsSchema,
|
|
1634
|
+
deadlineSettingsSchema,
|
|
1635
|
+
progressSettingsSchema
|
|
1636
|
+
]);
|
|
1637
|
+
function settingsFromRow(row) {
|
|
1638
|
+
if (!isSignalMonitorType(row.type) || !row.signal_settings || typeof row.signal_settings !== "object")
|
|
1639
|
+
return null;
|
|
1640
|
+
const r = signalSettingsSchema.safeParse({
|
|
1641
|
+
...row.signal_settings,
|
|
1642
|
+
type: row.type,
|
|
1643
|
+
environments: [...row.expected_environments],
|
|
1644
|
+
severity: row.severity,
|
|
1645
|
+
recovery_threshold: row.recovery_threshold
|
|
1646
|
+
});
|
|
1647
|
+
return r.success ? r.data : null;
|
|
1648
|
+
}
|
|
1649
|
+
var signalMonitorInputSchema = z11.object({
|
|
1650
|
+
name: z11.string().trim().min(1).max(MONITOR_LIMITS.nameMax),
|
|
1651
|
+
settings: signalSettingsSchema
|
|
1652
|
+
});
|
|
1653
|
+
var signalMonitorDefinitionSchema = z11.object({
|
|
1654
|
+
id: z11.guid(),
|
|
1655
|
+
project_id: z11.number().int().positive(),
|
|
1656
|
+
slug: z11.string().regex(SLUG_RE),
|
|
1657
|
+
settings: signalSettingsSchema,
|
|
1658
|
+
paused_until: z11.string().datetime().nullable(),
|
|
1659
|
+
created_at: z11.string().datetime(),
|
|
1660
|
+
revision: z11.number().int().nonnegative()
|
|
1661
|
+
});
|
|
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)
|
|
1665
|
+
});
|
|
1666
|
+
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()
|
|
1672
|
+
});
|
|
1673
|
+
var occurrenceCancelSchema = occurrenceInputSchema.pick({ monitor_slug: true, occurrence_id: true, environment: true });
|
|
1674
|
+
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()
|
|
1686
|
+
});
|
|
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()
|
|
1693
|
+
});
|
|
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()
|
|
1698
|
+
});
|
|
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()
|
|
1707
|
+
})).max(SIGNAL_LIMITS.occurrencesPageSize)
|
|
1708
|
+
});
|
|
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()
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
// ../src/shared/contracts/notifications.ts
|
|
1722
|
+
var NOTIFY_LIMITS = {
|
|
1723
|
+
policiesMax: 20,
|
|
1724
|
+
nameMax: 80,
|
|
1725
|
+
chainMax: 5,
|
|
1726
|
+
escalateMinutesMin: 5,
|
|
1727
|
+
escalateMinutesMax: 240,
|
|
1728
|
+
digestRowsMax: 50,
|
|
1729
|
+
slotSearchDays: 8
|
|
1730
|
+
};
|
|
1731
|
+
var HOLDABLE_SEVERITIES = ["medium", "low"];
|
|
1732
|
+
var DIGEST_MODES = ["off", "hourly", "daily"];
|
|
1733
|
+
var timeOfDay2 = z12.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
|
|
1734
|
+
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),
|
|
1737
|
+
start: timeOfDay2,
|
|
1738
|
+
end: timeOfDay2
|
|
1739
|
+
}).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),
|
|
1743
|
+
quietHours: quietHoursSchema.nullable(),
|
|
1744
|
+
quietSeverities: z12.array(z12.enum(HOLDABLE_SEVERITIES)).max(2).refine(unique),
|
|
1745
|
+
digest: z12.enum(DIGEST_MODES),
|
|
1746
|
+
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)
|
|
1751
|
+
}).superRefine((p, ctx) => {
|
|
1752
|
+
if (p.digest === "daily" !== (p.digestAt !== null))
|
|
1753
|
+
ctx.addIssue({ code: "custom", path: ["digestAt"], message: "digest_at" });
|
|
1754
|
+
if (p.escalateAfterMinutes !== null !== p.escalation.length > 0)
|
|
1755
|
+
ctx.addIssue({ code: "custom", path: ["escalation"], message: "escalation" });
|
|
1756
|
+
});
|
|
1757
|
+
var MIN = 60000;
|
|
1758
|
+
var HOUR = 60 * MIN;
|
|
1759
|
+
var DAY = 24 * HOUR;
|
|
1760
|
+
|
|
1761
|
+
// ../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]*$/);
|
|
1764
|
+
var INCIDENT_KINDS = ["monitor", "uptime", "slo", "issue"];
|
|
1765
|
+
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)
|
|
1777
|
+
});
|
|
1778
|
+
var INCIDENT_INPUTS = {
|
|
1779
|
+
list: z13.object({
|
|
1780
|
+
workspaceId: uuid,
|
|
1781
|
+
limit: pageLimit,
|
|
1782
|
+
cursor,
|
|
1783
|
+
state: z13.enum(["active", "resolved", "all"]).default("all")
|
|
1784
|
+
}),
|
|
1785
|
+
incidentOnly,
|
|
1786
|
+
resolve: incidentOnly.extend({ note: note2.max(500) }),
|
|
1787
|
+
note: incidentOnly.extend({ note: note2 }),
|
|
1788
|
+
update: incidentOnly.extend({
|
|
1789
|
+
title: z13.string().trim().min(1).max(120).regex(/^[^\p{Cc}]*$/u).optional(),
|
|
1790
|
+
ownerUserId: uuid.nullable().optional()
|
|
1791
|
+
}),
|
|
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({
|
|
1796
|
+
workspaceId: uuid,
|
|
1797
|
+
policyId: uuid.nullable(),
|
|
1798
|
+
isDefault: z13.boolean(),
|
|
1799
|
+
input: policyInputSchema
|
|
1800
|
+
}),
|
|
1801
|
+
policyOnly: z13.object({ workspaceId: uuid, policyId: uuid })
|
|
1802
|
+
};
|
|
1803
|
+
var I = INCIDENT_INPUTS;
|
|
1804
|
+
var w = "incidents:write";
|
|
1805
|
+
var INCIDENT_OPERATIONS = [
|
|
1806
|
+
op({
|
|
1807
|
+
id: "incidents.list",
|
|
1808
|
+
method: "GET",
|
|
1809
|
+
path: "/v1/incidents",
|
|
1810
|
+
scope: "incidents:read",
|
|
1811
|
+
sensitivity: "normal",
|
|
1812
|
+
kind: "read",
|
|
1813
|
+
rpcs: ["api_read_incidents"],
|
|
1814
|
+
input: I.list,
|
|
1815
|
+
workspace: true,
|
|
1816
|
+
idempotency: "none",
|
|
1817
|
+
paged: true,
|
|
1818
|
+
mcp: "reliability",
|
|
1819
|
+
summary: "Incidents (INC-n): state, severity and peak, owner, linked alert count; newest first.",
|
|
1820
|
+
ui: []
|
|
1821
|
+
}),
|
|
1822
|
+
op({
|
|
1823
|
+
id: "incidents.get",
|
|
1824
|
+
method: "GET",
|
|
1825
|
+
path: "/v1/incidents/{incident_id}",
|
|
1826
|
+
scope: "incidents:read",
|
|
1827
|
+
sensitivity: "normal",
|
|
1828
|
+
kind: "read",
|
|
1829
|
+
rpcs: ["api_read_incident"],
|
|
1830
|
+
input: I.incidentOnly,
|
|
1831
|
+
workspace: true,
|
|
1832
|
+
idempotency: "none",
|
|
1833
|
+
mcp: "reliability",
|
|
1834
|
+
summary: "One incident with its linked alerts, timeline (notes included) and message deliveries (`accepted` = the provider took it; only a person acknowledges).",
|
|
1835
|
+
ui: []
|
|
1836
|
+
}),
|
|
1837
|
+
op({
|
|
1838
|
+
id: "incidents.acknowledge",
|
|
1839
|
+
method: "POST",
|
|
1840
|
+
path: "/v1/incidents/{incident_id}/ack",
|
|
1841
|
+
scope: w,
|
|
1842
|
+
sensitivity: "normal",
|
|
1843
|
+
kind: "write",
|
|
1844
|
+
rpcs: ["acknowledge_incident"],
|
|
1845
|
+
input: I.incidentOnly,
|
|
1846
|
+
workspace: true,
|
|
1847
|
+
idempotency: "optional",
|
|
1848
|
+
mcp: "configure",
|
|
1849
|
+
summary: "Take ownership of an open incident; stops its escalation. Members and up.",
|
|
1850
|
+
ui: ["incidents#acknowledgeIncident"]
|
|
1851
|
+
}),
|
|
1852
|
+
op({
|
|
1853
|
+
id: "incidents.resolve",
|
|
1854
|
+
method: "POST",
|
|
1855
|
+
path: "/v1/incidents/{incident_id}/resolve",
|
|
1856
|
+
scope: w,
|
|
1857
|
+
sensitivity: "normal",
|
|
1858
|
+
kind: "write",
|
|
1859
|
+
rpcs: ["resolve_incident"],
|
|
1860
|
+
input: I.resolve,
|
|
1861
|
+
workspace: true,
|
|
1862
|
+
idempotency: "optional",
|
|
1863
|
+
mcp: "configure",
|
|
1864
|
+
summary: 'Close an incident by hand with a reason (1–500 characters); it is labelled "not verified".',
|
|
1865
|
+
ui: ["incidents#resolveIncident"]
|
|
1866
|
+
}),
|
|
1867
|
+
op({
|
|
1868
|
+
id: "incidents.note",
|
|
1869
|
+
method: "POST",
|
|
1870
|
+
path: "/v1/incidents/{incident_id}/notes",
|
|
1871
|
+
scope: w,
|
|
1872
|
+
sensitivity: "normal",
|
|
1873
|
+
kind: "write",
|
|
1874
|
+
rpcs: ["add_incident_note"],
|
|
1875
|
+
input: I.note,
|
|
1876
|
+
workspace: true,
|
|
1877
|
+
idempotency: "optional",
|
|
1878
|
+
mcp: "configure",
|
|
1879
|
+
summary: "Add a note to the incident timeline (plain text, ≤ 2,000 characters).",
|
|
1880
|
+
ui: ["incidents#addIncidentNote"]
|
|
1881
|
+
}),
|
|
1882
|
+
op({
|
|
1883
|
+
id: "incidents.update",
|
|
1884
|
+
method: "PATCH",
|
|
1885
|
+
path: "/v1/incidents/{incident_id}",
|
|
1886
|
+
scope: w,
|
|
1887
|
+
sensitivity: "normal",
|
|
1888
|
+
kind: "write",
|
|
1889
|
+
rpcs: ["update_incident"],
|
|
1890
|
+
input: I.update,
|
|
1891
|
+
workspace: true,
|
|
1892
|
+
idempotency: "none",
|
|
1893
|
+
mcp: "configure",
|
|
1894
|
+
summary: "Rename an incident or assign it to a member (`owner_user_id: null` clears it).",
|
|
1895
|
+
ui: ["incidents#updateIncident"]
|
|
1896
|
+
}),
|
|
1897
|
+
op({
|
|
1898
|
+
id: "incident_rules.list",
|
|
1899
|
+
method: "GET",
|
|
1900
|
+
path: "/v1/incident-rules",
|
|
1901
|
+
scope: "alerts:read",
|
|
1902
|
+
sensitivity: "normal",
|
|
1903
|
+
kind: "read",
|
|
1904
|
+
rpcs: ["api_read_incident_rules"],
|
|
1905
|
+
input: I.workspace,
|
|
1906
|
+
workspace: true,
|
|
1907
|
+
idempotency: "none",
|
|
1908
|
+
mcp: "investigate",
|
|
1909
|
+
summary: "Rules that turn alerts into incidents: match, grouping, window and recovery wait.",
|
|
1910
|
+
ui: []
|
|
1911
|
+
}),
|
|
1912
|
+
op({
|
|
1913
|
+
id: "incident_rules.save",
|
|
1914
|
+
method: "POST",
|
|
1915
|
+
path: "/v1/incident-rules",
|
|
1916
|
+
scope: "alerts:write",
|
|
1917
|
+
sensitivity: "normal",
|
|
1918
|
+
kind: "write",
|
|
1919
|
+
rpcs: ["save_incident_rule"],
|
|
1920
|
+
input: I.saveRule,
|
|
1921
|
+
workspace: true,
|
|
1922
|
+
idempotency: "optional",
|
|
1923
|
+
mcp: "configure",
|
|
1924
|
+
summary: "Create (`rule_id` null) or replace an incident rule. Admins.",
|
|
1925
|
+
ui: ["incidents#saveIncidentRule"]
|
|
1926
|
+
}),
|
|
1927
|
+
op({
|
|
1928
|
+
id: "incident_rules.delete",
|
|
1929
|
+
method: "DELETE",
|
|
1930
|
+
path: "/v1/incident-rules/{rule_id}",
|
|
1931
|
+
scope: "alerts:write",
|
|
1932
|
+
sensitivity: "normal",
|
|
1933
|
+
kind: "write",
|
|
1934
|
+
rpcs: ["delete_incident_rule"],
|
|
1935
|
+
input: I.ruleOnly,
|
|
1936
|
+
workspace: true,
|
|
1937
|
+
idempotency: "none",
|
|
1938
|
+
mcp: "configure",
|
|
1939
|
+
summary: "Delete an incident rule; open incidents stay as they are.",
|
|
1940
|
+
ui: ["incidents#deleteIncidentRule"]
|
|
1941
|
+
}),
|
|
1942
|
+
op({
|
|
1943
|
+
id: "notification_policies.list",
|
|
1944
|
+
method: "GET",
|
|
1945
|
+
path: "/v1/notification-policies",
|
|
1946
|
+
scope: "alerts:read",
|
|
1947
|
+
sensitivity: "normal",
|
|
1948
|
+
kind: "read",
|
|
1949
|
+
rpcs: ["api_read_notification_policies"],
|
|
1950
|
+
input: I.workspace,
|
|
1951
|
+
workspace: true,
|
|
1952
|
+
idempotency: "none",
|
|
1953
|
+
mcp: "investigate",
|
|
1954
|
+
summary: "Notification policies: quiet hours, digest, fallback chain and escalation.",
|
|
1955
|
+
ui: []
|
|
1956
|
+
}),
|
|
1957
|
+
op({
|
|
1958
|
+
id: "notification_policies.save",
|
|
1959
|
+
method: "POST",
|
|
1960
|
+
path: "/v1/notification-policies",
|
|
1961
|
+
scope: "alerts:write",
|
|
1962
|
+
sensitivity: "normal",
|
|
1963
|
+
kind: "write",
|
|
1964
|
+
rpcs: ["save_notification_policy"],
|
|
1965
|
+
input: I.savePolicy,
|
|
1966
|
+
workspace: true,
|
|
1967
|
+
idempotency: "optional",
|
|
1968
|
+
mcp: "configure",
|
|
1969
|
+
summary: "Create (`policy_id` null) or replace a policy. Critical and high are never held; chains use existing destinations only. Admins.",
|
|
1970
|
+
ui: ["incidents#saveNotificationPolicy"]
|
|
1971
|
+
}),
|
|
1972
|
+
op({
|
|
1973
|
+
id: "notification_policies.delete",
|
|
1974
|
+
method: "DELETE",
|
|
1975
|
+
path: "/v1/notification-policies/{policy_id}",
|
|
1976
|
+
scope: "alerts:write",
|
|
1977
|
+
sensitivity: "normal",
|
|
1978
|
+
kind: "write",
|
|
1979
|
+
rpcs: ["delete_notification_policy"],
|
|
1980
|
+
input: I.policyOnly,
|
|
1981
|
+
workspace: true,
|
|
1982
|
+
idempotency: "none",
|
|
1983
|
+
mcp: "configure",
|
|
1984
|
+
summary: "Delete a policy (not the default); its rules fall back to the default policy.",
|
|
1985
|
+
ui: ["incidents#deleteNotificationPolicy"]
|
|
1986
|
+
})
|
|
1987
|
+
];
|
|
1988
|
+
|
|
1989
|
+
// ../src/shared/contracts/api-ops/monitors.ts
|
|
1990
|
+
import { z as z18 } from "zod";
|
|
1991
|
+
|
|
1992
|
+
// ../src/shared/contracts/heartbeat.ts
|
|
1993
|
+
import { z as z15 } from "zod";
|
|
1117
1994
|
|
|
1118
1995
|
// ../src/shared/contracts/signed-message.ts
|
|
1119
|
-
import { z as
|
|
1120
|
-
var nodeIdSchema =
|
|
1121
|
-
var signedEnvelopeSchema =
|
|
1996
|
+
import { z as z14 } from "zod";
|
|
1997
|
+
var nodeIdSchema = z14.guid();
|
|
1998
|
+
var signedEnvelopeSchema = z14.object({
|
|
1122
1999
|
node_id: nodeIdSchema,
|
|
1123
|
-
ts:
|
|
1124
|
-
nonce:
|
|
1125
|
-
payload:
|
|
1126
|
-
sig:
|
|
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}$/)
|
|
1127
2004
|
});
|
|
1128
2005
|
|
|
1129
2006
|
// ../src/shared/contracts/heartbeat.ts
|
|
@@ -1161,78 +2038,78 @@ var HEARTBEAT_LIMITS = {
|
|
|
1161
2038
|
diagnosticsPerRun: 5
|
|
1162
2039
|
};
|
|
1163
2040
|
var PAUSED_FOREVER_MS = Date.parse("9999-12-31T00:00:00.000Z");
|
|
1164
|
-
var uuid2 =
|
|
1165
|
-
var ms =
|
|
1166
|
-
var hex64 =
|
|
1167
|
-
var envName2 =
|
|
1168
|
-
var heartbeatMonitorConfigSchema =
|
|
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({
|
|
1169
2046
|
id: uuid2,
|
|
1170
|
-
project_id:
|
|
1171
|
-
slug:
|
|
2047
|
+
project_id: z15.number().int().positive(),
|
|
2048
|
+
slug: z15.string().regex(SLUG_RE),
|
|
1172
2049
|
environment: envName2,
|
|
1173
2050
|
schedule: scheduleSchema,
|
|
1174
|
-
timezone:
|
|
1175
|
-
grace_min:
|
|
1176
|
-
max_runtime_min:
|
|
1177
|
-
failure_threshold:
|
|
1178
|
-
recovery_threshold:
|
|
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),
|
|
1179
2056
|
paused_until: ms.nullable(),
|
|
1180
2057
|
created_at: ms
|
|
1181
2058
|
});
|
|
1182
|
-
var heartbeatTokenConfigSchema =
|
|
2059
|
+
var heartbeatTokenConfigSchema = z15.object({
|
|
1183
2060
|
id: uuid2,
|
|
1184
2061
|
monitor_id: uuid2,
|
|
1185
2062
|
hash: hex64,
|
|
1186
2063
|
expires_at: ms.nullable()
|
|
1187
2064
|
});
|
|
1188
|
-
var heartbeatSyncSchema =
|
|
1189
|
-
v:
|
|
2065
|
+
var heartbeatSyncSchema = z15.object({
|
|
2066
|
+
v: z15.literal(1),
|
|
1190
2067
|
workspace_id: uuid2,
|
|
1191
|
-
route:
|
|
1192
|
-
revision:
|
|
1193
|
-
workspace_status:
|
|
1194
|
-
ingest_kill:
|
|
1195
|
-
limits:
|
|
1196
|
-
check_in_rate_per_sec:
|
|
1197
|
-
check_in_burst:
|
|
1198
|
-
monthly_check_in_cap:
|
|
1199
|
-
}),
|
|
1200
|
-
projects:
|
|
1201
|
-
monitors:
|
|
1202
|
-
tokens:
|
|
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)
|
|
1203
2080
|
});
|
|
1204
|
-
var signedHeartbeatSyncSchema =
|
|
1205
|
-
body:
|
|
1206
|
-
ts:
|
|
1207
|
-
kid:
|
|
1208
|
-
sig:
|
|
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}$/)
|
|
1209
2086
|
});
|
|
1210
|
-
var heartbeatHourSchema =
|
|
2087
|
+
var heartbeatHourSchema = z15.object({
|
|
1211
2088
|
monitor_id: uuid2,
|
|
1212
|
-
hour:
|
|
1213
|
-
ok:
|
|
1214
|
-
failed:
|
|
1215
|
-
started:
|
|
1216
|
-
missed:
|
|
1217
|
-
logs:
|
|
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()
|
|
1218
2095
|
});
|
|
1219
|
-
var heartbeatReportSchema =
|
|
1220
|
-
v:
|
|
2096
|
+
var heartbeatReportSchema = z15.object({
|
|
2097
|
+
v: z15.literal(1),
|
|
1221
2098
|
workspace_id: uuid2,
|
|
1222
|
-
route:
|
|
1223
|
-
revision:
|
|
1224
|
-
sent_at:
|
|
1225
|
-
incidents:
|
|
1226
|
-
statuses:
|
|
1227
|
-
hours:
|
|
1228
|
-
token_uses:
|
|
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)
|
|
1229
2106
|
});
|
|
1230
2107
|
var ENCODER = new TextEncoder;
|
|
1231
2108
|
var UTF8 = new TextDecoder("utf-8", { fatal: false, ignoreBOM: false });
|
|
1232
2109
|
var TOKEN_IN_TEXT = new RegExp(PING_TOKEN_PATTERN, "g");
|
|
1233
2110
|
|
|
1234
2111
|
// ../src/shared/contracts/slo.ts
|
|
1235
|
-
import { z as
|
|
2112
|
+
import { z as z16 } from "zod";
|
|
1236
2113
|
|
|
1237
2114
|
// ../src/shared/contracts/vocab/slo.ts
|
|
1238
2115
|
var SLO_SOURCES = ["uptime", "monitor", "heartbeat", "spans"];
|
|
@@ -1264,17 +2141,17 @@ var SLO_SOURCE_META = {
|
|
|
1264
2141
|
heartbeat: { provenance: "ping_token", estimated: false, slis: ["availability"], budgeting: "Occurrences" },
|
|
1265
2142
|
spans: { provenance: "ingest_key", estimated: true, slis: ["availability", "latency"], budgeting: "Occurrences" }
|
|
1266
2143
|
};
|
|
1267
|
-
var nodeSloSchema =
|
|
1268
|
-
slo_id:
|
|
1269
|
-
project_id:
|
|
1270
|
-
source:
|
|
1271
|
-
sli:
|
|
1272
|
-
monitor_id:
|
|
1273
|
-
environment:
|
|
1274
|
-
service:
|
|
1275
|
-
operation:
|
|
1276
|
-
latency_threshold_ms:
|
|
1277
|
-
public_sources:
|
|
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()
|
|
1278
2155
|
}).superRefine((v, ctx) => {
|
|
1279
2156
|
if (v.source === "monitor" && (!v.monitor_id || v.sli !== "availability"))
|
|
1280
2157
|
ctx.addIssue({ code: "custom", path: ["monitor_id"], message: "INVALID_INPUT" });
|
|
@@ -1283,27 +2160,27 @@ var nodeSloSchema = z9.object({
|
|
|
1283
2160
|
if (v.sli === "latency" !== (v.latency_threshold_ms !== undefined))
|
|
1284
2161
|
ctx.addIssue({ code: "custom", path: ["latency_threshold_ms"], message: "INVALID_INPUT" });
|
|
1285
2162
|
});
|
|
1286
|
-
var sliCountsSchema =
|
|
1287
|
-
minute:
|
|
1288
|
-
items:
|
|
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)
|
|
1289
2166
|
});
|
|
1290
|
-
var sloInputSchema =
|
|
1291
|
-
name:
|
|
1292
|
-
description:
|
|
1293
|
-
source:
|
|
1294
|
-
sourceRef:
|
|
1295
|
-
id:
|
|
1296
|
-
projectId:
|
|
1297
|
-
service:
|
|
1298
|
-
operation:
|
|
1299
|
-
environment:
|
|
1300
|
-
}),
|
|
1301
|
-
sli:
|
|
1302
|
-
latencyThresholdMs:
|
|
1303
|
-
objective:
|
|
1304
|
-
windowDays:
|
|
1305
|
-
alertPolicy:
|
|
1306
|
-
allowPublicSources:
|
|
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)
|
|
1307
2184
|
}).superRefine((v, ctx) => {
|
|
1308
2185
|
if (!SLO_SOURCE_META[v.source].slis.includes(v.sli))
|
|
1309
2186
|
ctx.addIssue({ code: "custom", path: ["sli"], message: "INVALID_INPUT" });
|
|
@@ -1318,7 +2195,7 @@ var sloInputSchema = z9.object({
|
|
|
1318
2195
|
});
|
|
1319
2196
|
|
|
1320
2197
|
// ../src/shared/contracts/uptime.ts
|
|
1321
|
-
import { z as
|
|
2198
|
+
import { z as z17 } from "zod";
|
|
1322
2199
|
|
|
1323
2200
|
// ../src/shared/contracts/vocab/uptime.ts
|
|
1324
2201
|
var UPTIME_STATUSES = ["up", "degraded", "down", "unknown", "paused", "pending"];
|
|
@@ -1391,51 +2268,51 @@ function isForbiddenHeader(name) {
|
|
|
1391
2268
|
const n = name.trim().toLowerCase();
|
|
1392
2269
|
return UPTIME_FORBIDDEN_HEADERS.includes(n) || n.startsWith("proxy-") || n.startsWith("sec-");
|
|
1393
2270
|
}
|
|
1394
|
-
var text =
|
|
1395
|
-
var statusRange =
|
|
1396
|
-
var assertionSchema =
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
type:
|
|
1402
|
-
pointer:
|
|
1403
|
-
op:
|
|
1404
|
-
value:
|
|
1405
|
-
}),
|
|
1406
|
-
|
|
1407
|
-
type:
|
|
1408
|
-
name:
|
|
1409
|
-
op:
|
|
1410
|
-
value:
|
|
1411
|
-
}),
|
|
1412
|
-
|
|
1413
|
-
|
|
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") })
|
|
1414
2291
|
]);
|
|
1415
|
-
var header =
|
|
1416
|
-
name:
|
|
1417
|
-
value:
|
|
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]*$/)
|
|
1418
2295
|
});
|
|
1419
|
-
var uptimeCheckInputSchema =
|
|
1420
|
-
projectId:
|
|
1421
|
-
name:
|
|
1422
|
-
kind:
|
|
1423
|
-
url:
|
|
1424
|
-
host:
|
|
1425
|
-
port:
|
|
1426
|
-
method:
|
|
1427
|
-
headers:
|
|
1428
|
-
followRedirects:
|
|
1429
|
-
timeoutMs:
|
|
1430
|
-
intervalSeconds:
|
|
1431
|
-
regions:
|
|
1432
|
-
assertions:
|
|
1433
|
-
failureThreshold:
|
|
1434
|
-
recoveryThreshold:
|
|
1435
|
-
certWarningDays:
|
|
1436
|
-
environment:
|
|
1437
|
-
strictMetadata:
|
|
1438
|
-
evidenceOnFailure:
|
|
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)
|
|
1439
2316
|
}).superRefine((v, ctx) => {
|
|
1440
2317
|
if (v.kind === "http" && !v.url)
|
|
1441
2318
|
ctx.addIssue({ code: "custom", path: ["url"], message: "INVALID_INPUT" });
|
|
@@ -1446,237 +2323,243 @@ var uptimeCheckInputSchema = z10.object({
|
|
|
1446
2323
|
if (v.headers.some((h) => isForbiddenHeader(h.name)))
|
|
1447
2324
|
ctx.addIssue({ code: "custom", path: ["headers"], message: "UPTIME_HEADER_FORBIDDEN" });
|
|
1448
2325
|
});
|
|
1449
|
-
var uptimeDefinitionSchema =
|
|
1450
|
-
check_id:
|
|
1451
|
-
workspace_id:
|
|
1452
|
-
project_id:
|
|
1453
|
-
revision:
|
|
1454
|
-
kind:
|
|
1455
|
-
url:
|
|
1456
|
-
host:
|
|
1457
|
-
port:
|
|
1458
|
-
method:
|
|
1459
|
-
headers:
|
|
1460
|
-
follow_redirects:
|
|
1461
|
-
timeout_ms:
|
|
1462
|
-
interval_seconds:
|
|
1463
|
-
regions:
|
|
1464
|
-
assertions:
|
|
1465
|
-
failure_threshold:
|
|
1466
|
-
recovery_threshold:
|
|
1467
|
-
cert_warning_days:
|
|
1468
|
-
strict_metadata:
|
|
1469
|
-
evidence_on_failure:
|
|
1470
|
-
paused_until:
|
|
1471
|
-
muted_until:
|
|
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()
|
|
1472
2349
|
});
|
|
1473
|
-
var timingsSchema =
|
|
1474
|
-
dns_ms:
|
|
1475
|
-
connect_ms:
|
|
1476
|
-
tls_ms:
|
|
1477
|
-
ttfb_ms:
|
|
1478
|
-
download_ms:
|
|
1479
|
-
total_ms:
|
|
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)
|
|
1480
2357
|
});
|
|
1481
|
-
var probeResultSchema =
|
|
1482
|
-
check_id:
|
|
1483
|
-
revision:
|
|
1484
|
-
slot:
|
|
1485
|
-
region:
|
|
1486
|
-
run_now:
|
|
1487
|
-
scheduled_at:
|
|
1488
|
-
started_at:
|
|
1489
|
-
outcome:
|
|
1490
|
-
reason:
|
|
1491
|
-
reason_group:
|
|
1492
|
-
status_code:
|
|
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(),
|
|
1493
2370
|
timings: timingsSchema.nullable(),
|
|
1494
|
-
ip_family:
|
|
1495
|
-
http_version:
|
|
1496
|
-
cert_not_after:
|
|
1497
|
-
cert_issuer:
|
|
1498
|
-
cert_expiring:
|
|
1499
|
-
evidence_sealed:
|
|
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()
|
|
1500
2377
|
});
|
|
1501
|
-
var probeIdSchema =
|
|
1502
|
-
var resultBatchSchema =
|
|
1503
|
-
v:
|
|
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),
|
|
1504
2381
|
probe_id: probeIdSchema,
|
|
1505
|
-
region:
|
|
1506
|
-
version:
|
|
1507
|
-
sent_at:
|
|
1508
|
-
results:
|
|
1509
|
-
stats:
|
|
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() })
|
|
1510
2387
|
});
|
|
1511
2388
|
var assignmentSchema = uptimeDefinitionSchema.omit({ workspace_id: true, paused_until: true, muted_until: true }).extend({
|
|
1512
|
-
seal_public_key:
|
|
2389
|
+
seal_public_key: z17.string().regex(/^[A-Za-z0-9_-]{43}$/).nullable()
|
|
1513
2390
|
});
|
|
1514
|
-
var assignmentsSchema =
|
|
1515
|
-
v:
|
|
1516
|
-
region:
|
|
1517
|
-
revision:
|
|
1518
|
-
issued_at:
|
|
1519
|
-
checks:
|
|
1520
|
-
denied_hosts:
|
|
1521
|
-
run_now:
|
|
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)
|
|
1522
2399
|
});
|
|
1523
|
-
var uuid3 =
|
|
1524
|
-
var b64key =
|
|
1525
|
-
var
|
|
1526
|
-
var uptimeSyncSchema =
|
|
1527
|
-
v:
|
|
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),
|
|
1528
2405
|
workspace_id: uuid3,
|
|
1529
|
-
revision:
|
|
1530
|
-
workspace_status:
|
|
1531
|
-
suspended:
|
|
1532
|
-
checks:
|
|
1533
|
-
projects:
|
|
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)
|
|
1534
2411
|
});
|
|
1535
|
-
var uptimeReconcileSchema =
|
|
1536
|
-
v:
|
|
1537
|
-
as_of:
|
|
1538
|
-
workspace_ids:
|
|
1539
|
-
heartbeat_routes:
|
|
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()
|
|
1540
2417
|
});
|
|
1541
|
-
var probeDirectorySyncSchema =
|
|
1542
|
-
v:
|
|
1543
|
-
revision:
|
|
1544
|
-
probes:
|
|
1545
|
-
denied_hosts:
|
|
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)
|
|
1546
2423
|
});
|
|
1547
|
-
var runNowRequestSchema =
|
|
1548
|
-
var signedAssignmentsSchema =
|
|
1549
|
-
var uptimeRegionStateSchema =
|
|
1550
|
-
region:
|
|
1551
|
-
outcome:
|
|
1552
|
-
reason:
|
|
1553
|
-
status_code:
|
|
1554
|
-
total_ms:
|
|
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(),
|
|
1555
2432
|
timings: timingsSchema.nullable().optional(),
|
|
1556
|
-
at:
|
|
2433
|
+
at: iso4
|
|
1557
2434
|
});
|
|
1558
|
-
var uptimeStatusReportSchema =
|
|
2435
|
+
var uptimeStatusReportSchema = z17.object({
|
|
1559
2436
|
check_id: uuid3,
|
|
1560
|
-
revision:
|
|
1561
|
-
status:
|
|
1562
|
-
last_verdict:
|
|
1563
|
-
last_slot_at:
|
|
2437
|
+
revision: z17.number().int().nonnegative(),
|
|
2438
|
+
status: z17.enum(UPTIME_STATUSES),
|
|
2439
|
+
last_verdict: z17.enum(SLOT_VERDICTS).nullable(),
|
|
2440
|
+
last_slot_at: iso4.nullable(),
|
|
1564
2441
|
incident_id: uuid3.nullable(),
|
|
1565
|
-
down_streak:
|
|
1566
|
-
up_streak:
|
|
1567
|
-
regions:
|
|
1568
|
-
unobserved_regions:
|
|
1569
|
-
cert_not_after:
|
|
1570
|
-
cert_expiring:
|
|
1571
|
-
run_now:
|
|
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),
|
|
2446
|
+
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()
|
|
1572
2449
|
});
|
|
1573
2450
|
var UPTIME_EVENT_KINDS = ["opened", "resolved", "cert_expiring"];
|
|
1574
|
-
var uptimeEventSchema =
|
|
1575
|
-
event_id:
|
|
2451
|
+
var uptimeEventSchema = z17.object({
|
|
2452
|
+
event_id: z17.string().regex(/^[A-Za-z0-9:_-]{8,96}$/),
|
|
1576
2453
|
check_id: uuid3,
|
|
1577
|
-
kind:
|
|
2454
|
+
kind: z17.enum(UPTIME_EVENT_KINDS),
|
|
1578
2455
|
incident_id: uuid3.nullable(),
|
|
1579
|
-
at:
|
|
1580
|
-
reason:
|
|
1581
|
-
regions:
|
|
1582
|
-
cert_days_left:
|
|
2456
|
+
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()
|
|
1583
2460
|
});
|
|
1584
|
-
var uptimeMinuteSchema =
|
|
2461
|
+
var uptimeMinuteSchema = z17.object({
|
|
1585
2462
|
check_id: uuid3,
|
|
1586
|
-
minute:
|
|
1587
|
-
up:
|
|
1588
|
-
degraded:
|
|
1589
|
-
down:
|
|
1590
|
-
unknown:
|
|
1591
|
-
latency:
|
|
2463
|
+
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)
|
|
1592
2469
|
});
|
|
1593
|
-
var uptimeReportSchema =
|
|
1594
|
-
v:
|
|
2470
|
+
var uptimeReportSchema = z17.object({
|
|
2471
|
+
v: z17.literal(1),
|
|
1595
2472
|
workspace_id: uuid3,
|
|
1596
|
-
revision:
|
|
1597
|
-
sent_at:
|
|
1598
|
-
events:
|
|
1599
|
-
statuses:
|
|
1600
|
-
minutes:
|
|
2473
|
+
revision: z17.number().int().nonnegative(),
|
|
2474
|
+
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)
|
|
1601
2478
|
});
|
|
1602
|
-
var probeFleetReportSchema =
|
|
1603
|
-
v:
|
|
1604
|
-
sent_at:
|
|
1605
|
-
probes:
|
|
2479
|
+
var probeFleetReportSchema = z17.object({
|
|
2480
|
+
v: z17.literal(1),
|
|
2481
|
+
sent_at: iso4,
|
|
2482
|
+
probes: z17.array(z17.object({
|
|
1606
2483
|
probe_id: probeIdSchema,
|
|
1607
|
-
region:
|
|
1608
|
-
version:
|
|
1609
|
-
last_seen_at:
|
|
1610
|
-
lag_p99_ms:
|
|
1611
|
-
checks_per_min:
|
|
2484
|
+
region: z17.enum(UPTIME_REGIONS),
|
|
2485
|
+
version: z17.string().max(40).nullable(),
|
|
2486
|
+
last_seen_at: iso4.nullable(),
|
|
2487
|
+
lag_p99_ms: z17.number().nonnegative().nullable(),
|
|
2488
|
+
checks_per_min: z17.number().nonnegative().nullable()
|
|
1612
2489
|
})).max(30),
|
|
1613
|
-
regions_alive:
|
|
2490
|
+
regions_alive: z17.array(z17.enum(UPTIME_REGIONS)).max(3)
|
|
1614
2491
|
});
|
|
1615
|
-
var probeEnrollSchema =
|
|
1616
|
-
v:
|
|
2492
|
+
var probeEnrollSchema = z17.object({
|
|
2493
|
+
v: z17.literal(1),
|
|
1617
2494
|
probe_id: probeIdSchema,
|
|
1618
|
-
public_key:
|
|
1619
|
-
code:
|
|
1620
|
-
ts:
|
|
1621
|
-
sig:
|
|
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}$/)
|
|
1622
2499
|
});
|
|
1623
|
-
var uptimeEvidenceEnvelopeSchema =
|
|
1624
|
-
v:
|
|
1625
|
-
check_id:
|
|
1626
|
-
slot:
|
|
1627
|
-
region:
|
|
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),
|
|
1628
2505
|
probe_id: probeIdSchema,
|
|
1629
|
-
at:
|
|
1630
|
-
sealed:
|
|
2506
|
+
at: z17.number().int().positive(),
|
|
2507
|
+
sealed: z17.string().regex(/^[A-Za-z0-9_-]+$/).max(16384)
|
|
1631
2508
|
}).strict();
|
|
1632
|
-
var uptimeEvidenceSchema =
|
|
1633
|
-
v:
|
|
1634
|
-
check_id:
|
|
1635
|
-
slot:
|
|
1636
|
-
region:
|
|
1637
|
-
at:
|
|
1638
|
-
reason:
|
|
1639
|
-
status_line:
|
|
1640
|
-
headers:
|
|
1641
|
-
body:
|
|
1642
|
-
body_truncated:
|
|
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(),
|
|
1643
2520
|
timings: timingsSchema.nullable(),
|
|
1644
|
-
ip:
|
|
1645
|
-
error:
|
|
2521
|
+
ip: z17.string().max(64).nullable(),
|
|
2522
|
+
error: z17.string().max(300).nullable()
|
|
1646
2523
|
}).strict();
|
|
1647
|
-
var uptimeEvidenceListSchema =
|
|
1648
|
-
items:
|
|
2524
|
+
var uptimeEvidenceListSchema = z17.object({
|
|
2525
|
+
items: z17.array(uptimeEvidenceSchema.extend({ received_at: z17.number().int().positive() })).max(UPTIME_LIMITS.evidenceKeepPerCheck)
|
|
1649
2526
|
});
|
|
1650
2527
|
|
|
1651
2528
|
// ../src/shared/contracts/api-ops/monitors.ts
|
|
2529
|
+
var anyMonitorInputSchema = z18.union([monitorInputSchema, signalMonitorInputSchema]);
|
|
2530
|
+
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 })
|
|
2534
|
+
};
|
|
1652
2535
|
var MONITOR_INPUTS = {
|
|
1653
|
-
create:
|
|
1654
|
-
update:
|
|
1655
|
-
delete:
|
|
1656
|
-
setPause:
|
|
1657
|
-
setMuted:
|
|
1658
|
-
dismissDiscovery:
|
|
1659
|
-
rotatePing:
|
|
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({
|
|
1660
2543
|
monitorId: uuid,
|
|
1661
|
-
graceHours:
|
|
2544
|
+
graceHours: z18.number().int().refine((h) => HEARTBEAT_LIMITS.rotationGraceHoursChoices.includes(h))
|
|
1662
2545
|
}),
|
|
1663
|
-
monitorOnly:
|
|
2546
|
+
monitorOnly: z18.object({ monitorId: uuid })
|
|
1664
2547
|
};
|
|
1665
2548
|
var UPTIME_INPUTS = {
|
|
1666
2549
|
create: uptimeCheckInputSchema,
|
|
1667
|
-
update:
|
|
1668
|
-
checkOnly:
|
|
1669
|
-
setHold:
|
|
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 })
|
|
1670
2553
|
};
|
|
1671
2554
|
var SLO_INPUTS = {
|
|
1672
|
-
create:
|
|
1673
|
-
update:
|
|
1674
|
-
sloOnly:
|
|
1675
|
-
setHold:
|
|
1676
|
-
import:
|
|
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({
|
|
1677
2560
|
workspaceId: uuid,
|
|
1678
|
-
text:
|
|
1679
|
-
dryRun:
|
|
2561
|
+
text: z18.string().max(SLO_LIMITS.openSloMaxBytes * 2),
|
|
2562
|
+
dryRun: z18.boolean()
|
|
1680
2563
|
})
|
|
1681
2564
|
};
|
|
1682
2565
|
var m = "monitors:write";
|
|
@@ -1688,13 +2571,13 @@ var MONITOR_OPERATIONS = [
|
|
|
1688
2571
|
scope: m,
|
|
1689
2572
|
sensitivity: "normal",
|
|
1690
2573
|
kind: "write",
|
|
1691
|
-
rpcs: ["create_monitor", "create_heartbeat_monitor"],
|
|
2574
|
+
rpcs: ["create_monitor", "create_heartbeat_monitor", "create_signal_monitor"],
|
|
1692
2575
|
input: MONITOR_INPUTS.create,
|
|
1693
2576
|
bodyField: "input",
|
|
1694
2577
|
idempotency: "required",
|
|
1695
2578
|
status: 201,
|
|
1696
2579
|
mcp: "configure",
|
|
1697
|
-
summary: "Create a cron or heartbeat monitor. A heartbeat monitor returns its ping token once.",
|
|
2580
|
+
summary: "Create a cron or heartbeat monitor, or a signal monitor (`settings.type`: count, assertion, deadline, progress). A heartbeat monitor returns its ping token once.",
|
|
1698
2581
|
secretOutput: ["ping_token"],
|
|
1699
2582
|
ui: ["monitors#createMonitor"]
|
|
1700
2583
|
}),
|
|
@@ -1705,13 +2588,13 @@ var MONITOR_OPERATIONS = [
|
|
|
1705
2588
|
scope: m,
|
|
1706
2589
|
sensitivity: "normal",
|
|
1707
2590
|
kind: "write",
|
|
1708
|
-
rpcs: ["update_monitor"],
|
|
2591
|
+
rpcs: ["update_monitor", "update_signal_monitor"],
|
|
1709
2592
|
input: MONITOR_INPUTS.update,
|
|
1710
2593
|
bodyField: "input",
|
|
1711
2594
|
ifMatch: true,
|
|
1712
2595
|
idempotency: "none",
|
|
1713
2596
|
mcp: "configure",
|
|
1714
|
-
summary: "Replace a monitor's schedule, margins and thresholds.",
|
|
2597
|
+
summary: "Replace a monitor's schedule, margins and thresholds, or a signal monitor's settings (the type stays).",
|
|
1715
2598
|
ui: ["monitors#updateMonitor"]
|
|
1716
2599
|
}),
|
|
1717
2600
|
op({
|
|
@@ -1966,23 +2849,71 @@ var MONITOR_OPERATIONS = [
|
|
|
1966
2849
|
mcp: "configure",
|
|
1967
2850
|
summary: "Import OpenSLO YAML, all or nothing; `dry_run` returns the plan without applying it.",
|
|
1968
2851
|
ui: ["slos#importOpenSlo"]
|
|
2852
|
+
}),
|
|
2853
|
+
op({
|
|
2854
|
+
id: "maintenance.create",
|
|
2855
|
+
method: "POST",
|
|
2856
|
+
path: "/v1/maintenance-windows",
|
|
2857
|
+
scope: m,
|
|
2858
|
+
sensitivity: "normal",
|
|
2859
|
+
kind: "write",
|
|
2860
|
+
rpcs: ["create_maintenance_window"],
|
|
2861
|
+
input: MAINTENANCE_INPUTS.create,
|
|
2862
|
+
bodyField: "input",
|
|
2863
|
+
workspace: true,
|
|
2864
|
+
idempotency: "required",
|
|
2865
|
+
status: 201,
|
|
2866
|
+
mcp: "configure",
|
|
2867
|
+
summary: "Hold back monitor notifications during a one-off or weekly window (workspace, projects or monitors); monitors keep evaluating and recording.",
|
|
2868
|
+
ui: ["maintenance#createMaintenanceWindow"]
|
|
2869
|
+
}),
|
|
2870
|
+
op({
|
|
2871
|
+
id: "maintenance.update",
|
|
2872
|
+
method: "PATCH",
|
|
2873
|
+
path: "/v1/maintenance-windows/{window_id}",
|
|
2874
|
+
scope: m,
|
|
2875
|
+
sensitivity: "normal",
|
|
2876
|
+
kind: "write",
|
|
2877
|
+
rpcs: ["update_maintenance_window"],
|
|
2878
|
+
input: MAINTENANCE_INPUTS.update,
|
|
2879
|
+
bodyField: "input",
|
|
2880
|
+
workspace: true,
|
|
2881
|
+
idempotency: "none",
|
|
2882
|
+
mcp: "configure",
|
|
2883
|
+
summary: "Replace a maintenance window's scope, times and reason.",
|
|
2884
|
+
ui: ["maintenance#updateMaintenanceWindow"]
|
|
2885
|
+
}),
|
|
2886
|
+
op({
|
|
2887
|
+
id: "maintenance.delete",
|
|
2888
|
+
method: "DELETE",
|
|
2889
|
+
path: "/v1/maintenance-windows/{window_id}",
|
|
2890
|
+
scope: m,
|
|
2891
|
+
sensitivity: "normal",
|
|
2892
|
+
kind: "write",
|
|
2893
|
+
rpcs: ["delete_maintenance_window"],
|
|
2894
|
+
input: MAINTENANCE_INPUTS.delete,
|
|
2895
|
+
workspace: true,
|
|
2896
|
+
idempotency: "none",
|
|
2897
|
+
mcp: "configure",
|
|
2898
|
+
summary: "Delete a maintenance window; notifications resume at once.",
|
|
2899
|
+
ui: ["maintenance#deleteMaintenanceWindow"]
|
|
1969
2900
|
})
|
|
1970
2901
|
];
|
|
1971
2902
|
|
|
1972
2903
|
// ../src/shared/contracts/api-ops/node-data.ts
|
|
1973
|
-
import { z as
|
|
1974
|
-
var issueId =
|
|
1975
|
-
var csv =
|
|
1976
|
-
var name2 =
|
|
1977
|
-
var period =
|
|
1978
|
-
var nodeCursor =
|
|
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();
|
|
1979
2910
|
var windowFields = {
|
|
1980
|
-
start:
|
|
1981
|
-
end:
|
|
2911
|
+
start: z19.string().max(40).optional(),
|
|
2912
|
+
end: z19.string().max(40).optional()
|
|
1982
2913
|
};
|
|
1983
|
-
var traceId =
|
|
1984
|
-
var spanId =
|
|
1985
|
-
var attrs =
|
|
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();
|
|
1986
2917
|
var telemetryCommon = {
|
|
1987
2918
|
...windowFields,
|
|
1988
2919
|
project: csv.optional(),
|
|
@@ -1990,91 +2921,112 @@ var telemetryCommon = {
|
|
|
1990
2921
|
service: csv.optional(),
|
|
1991
2922
|
attrs
|
|
1992
2923
|
};
|
|
1993
|
-
var issueChange =
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
action:
|
|
1999
|
-
mode:
|
|
2000
|
-
events:
|
|
2001
|
-
users:
|
|
2002
|
-
until:
|
|
2003
|
-
}),
|
|
2004
|
-
|
|
2005
|
-
|
|
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"]) })
|
|
2006
2937
|
]);
|
|
2007
2938
|
var NODE_INPUTS = {
|
|
2008
|
-
issuesList:
|
|
2939
|
+
issuesList: z19.object({
|
|
2009
2940
|
project: csv.optional(),
|
|
2010
|
-
status:
|
|
2941
|
+
status: z19.enum(["unresolved", "resolved", "archived", "all"]).optional(),
|
|
2011
2942
|
level: csv.optional(),
|
|
2012
2943
|
priority: csv.optional(),
|
|
2013
2944
|
environment: csv.optional(),
|
|
2014
2945
|
release: csv.optional(),
|
|
2015
|
-
assignee:
|
|
2946
|
+
assignee: z19.string().max(64).optional(),
|
|
2016
2947
|
period: period.optional(),
|
|
2017
|
-
q:
|
|
2018
|
-
sort:
|
|
2948
|
+
q: z19.string().max(200).optional(),
|
|
2949
|
+
sort: z19.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
|
|
2019
2950
|
cursor: nodeCursor,
|
|
2020
|
-
limit:
|
|
2951
|
+
limit: z19.number().int().min(1).max(100).optional()
|
|
2021
2952
|
}),
|
|
2022
|
-
issue:
|
|
2023
|
-
issueStats:
|
|
2024
|
-
issueEvents:
|
|
2025
|
-
issueEvent:
|
|
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({
|
|
2026
2957
|
issueId,
|
|
2027
|
-
eventId:
|
|
2958
|
+
eventId: z19.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
|
|
2028
2959
|
}),
|
|
2029
|
-
issueUpdate:
|
|
2030
|
-
issuesBulk:
|
|
2031
|
-
issueIds:
|
|
2960
|
+
issueUpdate: z19.object({ issueId, change: issueChange }),
|
|
2961
|
+
issuesBulk: z19.object({
|
|
2962
|
+
issueIds: z19.array(issueId).min(1).max(100),
|
|
2032
2963
|
action: issueChange
|
|
2033
2964
|
}),
|
|
2034
|
-
spansList:
|
|
2965
|
+
spansList: z19.object({
|
|
2035
2966
|
...telemetryCommon,
|
|
2036
|
-
operation:
|
|
2037
|
-
status:
|
|
2038
|
-
kind:
|
|
2039
|
-
minDurationMs:
|
|
2040
|
-
maxDurationMs:
|
|
2041
|
-
mode:
|
|
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(),
|
|
2042
2973
|
cursor: nodeCursor
|
|
2043
2974
|
}),
|
|
2044
|
-
spansHistogram:
|
|
2975
|
+
spansHistogram: z19.object({
|
|
2045
2976
|
...telemetryCommon,
|
|
2046
|
-
operation:
|
|
2047
|
-
status:
|
|
2977
|
+
operation: z19.string().min(1).max(1024).optional(),
|
|
2978
|
+
status: z19.enum(["unset", "ok", "error"]).optional()
|
|
2048
2979
|
}),
|
|
2049
|
-
trace:
|
|
2050
|
-
traceSpans:
|
|
2051
|
-
span:
|
|
2052
|
-
logsList:
|
|
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({
|
|
2053
2984
|
...telemetryCommon,
|
|
2054
|
-
severityMin:
|
|
2985
|
+
severityMin: z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
|
|
2055
2986
|
traceId: traceId.optional(),
|
|
2056
2987
|
spanId: spanId.optional(),
|
|
2057
|
-
q:
|
|
2058
|
-
order:
|
|
2988
|
+
q: z19.string().max(500).optional(),
|
|
2989
|
+
order: z19.enum(["asc", "desc"]).optional(),
|
|
2059
2990
|
cursor: nodeCursor
|
|
2060
2991
|
}),
|
|
2061
|
-
logsFacets:
|
|
2992
|
+
logsFacets: z19.object({
|
|
2062
2993
|
...telemetryCommon,
|
|
2063
|
-
severityMin:
|
|
2064
|
-
q:
|
|
2994
|
+
severityMin: z19.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
|
|
2995
|
+
q: z19.string().max(500).optional()
|
|
2065
2996
|
}),
|
|
2066
|
-
logAround:
|
|
2997
|
+
logAround: z19.object({
|
|
2067
2998
|
logId: name2,
|
|
2068
|
-
at:
|
|
2069
|
-
same:
|
|
2070
|
-
before:
|
|
2071
|
-
after:
|
|
2072
|
-
}),
|
|
2073
|
-
telemetryUsage:
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
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(),
|
|
3010
|
+
cursor: nodeCursor
|
|
3011
|
+
}),
|
|
3012
|
+
monitorBacktest: z19.object({ project: z19.number().int().positive(), settings: backtestSettingsSchema }),
|
|
3013
|
+
occurrenceCreate: z19.object({
|
|
3014
|
+
project: z19.number().int().positive(),
|
|
3015
|
+
monitorSlug: occurrenceInputSchema.shape.monitor_slug,
|
|
3016
|
+
occurrenceId: occurrenceInputSchema.shape.occurrence_id,
|
|
3017
|
+
dueAt: occurrenceInputSchema.shape.due_at,
|
|
3018
|
+
environment: occurrenceInputSchema.shape.environment
|
|
3019
|
+
}),
|
|
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()
|
|
2078
3030
|
})
|
|
2079
3031
|
};
|
|
2080
3032
|
var N = NODE_INPUTS;
|
|
@@ -2245,6 +3197,60 @@ var NODE_OPERATIONS = [
|
|
|
2245
3197
|
node: { path: "q/telemetry/usage" },
|
|
2246
3198
|
summary: "Stored spans and logs per day and project on the node."
|
|
2247
3199
|
}),
|
|
3200
|
+
op({
|
|
3201
|
+
...read,
|
|
3202
|
+
id: "monitors.signal",
|
|
3203
|
+
path: "/v1/monitors/{monitor_id}/signal",
|
|
3204
|
+
scope: "monitors:read",
|
|
3205
|
+
input: N.monitorSignal,
|
|
3206
|
+
node: { path: "q/monitors/{monitor_id}/signal" },
|
|
3207
|
+
mcp: "reliability",
|
|
3208
|
+
summary: "A signal monitor's minute counts (count/assertion) for up to 24 h per environment, and its open runs (progress, deadline)."
|
|
3209
|
+
}),
|
|
3210
|
+
op({
|
|
3211
|
+
...read,
|
|
3212
|
+
id: "monitors.occurrences",
|
|
3213
|
+
path: "/v1/monitors/{monitor_id}/occurrences",
|
|
3214
|
+
scope: "monitors:read",
|
|
3215
|
+
input: N.monitorOccurrences,
|
|
3216
|
+
node: { path: "q/monitors/{monitor_id}/occurrences", list: "occurrences" },
|
|
3217
|
+
paged: true,
|
|
3218
|
+
mcp: "reliability",
|
|
3219
|
+
summary: "Occurrences of a deadline monitor (pending, on time, late, missed, failed, cancelled), newest due first."
|
|
3220
|
+
}),
|
|
3221
|
+
op({
|
|
3222
|
+
...read,
|
|
3223
|
+
id: "monitors.backtest",
|
|
3224
|
+
method: "POST",
|
|
3225
|
+
path: "/v1/monitors/backtest",
|
|
3226
|
+
scope: "monitors:read",
|
|
3227
|
+
input: N.monitorBacktest,
|
|
3228
|
+
node: { path: "q/monitors/backtest" },
|
|
3229
|
+
mcp: "reliability",
|
|
3230
|
+
summary: "How often count/assertion settings would have alerted over the last 30 days of stored data (same rule as the live evaluator)."
|
|
3231
|
+
}),
|
|
3232
|
+
op({
|
|
3233
|
+
...read,
|
|
3234
|
+
id: "occurrences.create",
|
|
3235
|
+
method: "POST",
|
|
3236
|
+
path: "/v1/occurrences",
|
|
3237
|
+
scope: "monitors:write",
|
|
3238
|
+
input: N.occurrenceCreate,
|
|
3239
|
+
node: { path: "w/monitors/occurrences", body: "*" },
|
|
3240
|
+
mcp: "configure",
|
|
3241
|
+
summary: "Register one run a deadline monitor expects (`due_at` within 35 days); the same id again moves its due time while it is pending."
|
|
3242
|
+
}),
|
|
3243
|
+
op({
|
|
3244
|
+
...read,
|
|
3245
|
+
id: "occurrences.cancel",
|
|
3246
|
+
method: "DELETE",
|
|
3247
|
+
path: "/v1/occurrences/{monitor_slug}/{occurrence_id}",
|
|
3248
|
+
scope: "monitors:write",
|
|
3249
|
+
input: N.occurrenceCancel,
|
|
3250
|
+
node: { path: "w/monitors/occurrences/cancel", body: "*" },
|
|
3251
|
+
mcp: "configure",
|
|
3252
|
+
summary: "Cancel a pending occurrence (the app moved or dropped the job); a cancelled occurrence never alerts."
|
|
3253
|
+
}),
|
|
2248
3254
|
op({
|
|
2249
3255
|
...read,
|
|
2250
3256
|
id: "issues.update",
|
|
@@ -2281,11 +3287,121 @@ var NODE_OPERATIONS = [
|
|
|
2281
3287
|
})
|
|
2282
3288
|
];
|
|
2283
3289
|
|
|
3290
|
+
// ../src/shared/contracts/api-ops/privacy.ts
|
|
3291
|
+
import { z as z21 } from "zod";
|
|
3292
|
+
|
|
3293
|
+
// ../src/shared/contracts/privacy.ts
|
|
3294
|
+
import { z as z20 } from "zod";
|
|
3295
|
+
|
|
3296
|
+
// ../src/shared/privacy/rules.ts
|
|
3297
|
+
var PRIVACY_SCHEMA = 1;
|
|
3298
|
+
var PRIVACY_LIMITS = {
|
|
3299
|
+
rules: 100,
|
|
3300
|
+
allowlist: 100,
|
|
3301
|
+
selector: 256,
|
|
3302
|
+
pattern: 256,
|
|
3303
|
+
replaceWith: 32,
|
|
3304
|
+
ruleId: 64,
|
|
3305
|
+
stringChars: 16384,
|
|
3306
|
+
quantifierMax: 1000,
|
|
3307
|
+
matches: 500,
|
|
3308
|
+
depth: 32
|
|
3309
|
+
};
|
|
3310
|
+
var PRIVACY_MODES = ["standard", "strict"];
|
|
3311
|
+
var PRIVACY_RULE_TYPES = ["pattern", "anything", "creditcard", "ip", "email", "phone_e164"];
|
|
3312
|
+
var PRIVACY_METHODS = ["remove", "replace", "mask", "hash"];
|
|
3313
|
+
var AUTH_HEADER_KEYS = new Set(["authorization", "proxy-authorization", "x-api-key", "x-auth-token", "x-sentry-auth", "x-amz-security-token"]);
|
|
3314
|
+
var COOKIE_KEYS = new Set(["cookie", "cookies", "set-cookie"]);
|
|
3315
|
+
var BODY_KEYS = new Set(["body", "request_body", "response_body", "raw_body", "message_body", "html_body"]);
|
|
3316
|
+
var CARD_KEYS = new Set(["card_number", "cardnumber", "cc_number", "ccnum", "cvv", "cvc", "pan"]);
|
|
3317
|
+
var OCTET = "(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)";
|
|
3318
|
+
var IPV4_RE = new RegExp(`(^|[^\\d.])(${OCTET}(?:\\.${OCTET}){3})(?![\\d.])`, "g");
|
|
3319
|
+
var H = "[0-9A-Fa-f]{1,4}";
|
|
3320
|
+
var IPV6_RE = new RegExp(`(^|[^0-9A-Fa-f:])((?:${H}:){7}${H}|(?:${H}:){1,6}:(?:${H}(?::${H}){0,5})?|::(?:${H}(?::${H}){0,6})?)(?![0-9A-Fa-f:])`, "g");
|
|
3321
|
+
var REMOVE = Symbol("remove");
|
|
3322
|
+
|
|
3323
|
+
// ../src/shared/contracts/privacy.ts
|
|
3324
|
+
var ruleId = z20.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
|
|
3325
|
+
var privacyRuleInputSchema = z20.object({
|
|
3326
|
+
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()
|
|
3334
|
+
});
|
|
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)
|
|
3339
|
+
});
|
|
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)
|
|
3346
|
+
});
|
|
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)
|
|
3353
|
+
});
|
|
3354
|
+
|
|
3355
|
+
// ../src/shared/contracts/api-ops/privacy.ts
|
|
3356
|
+
var PRIVACY_INPUTS = {
|
|
3357
|
+
get: z21.object({ workspaceId: uuid, projectId }),
|
|
3358
|
+
set: z21.object({
|
|
3359
|
+
workspaceId: uuid,
|
|
3360
|
+
projectId,
|
|
3361
|
+
expectedVersion: z21.number().int().min(0),
|
|
3362
|
+
policy: privacyPolicyInputSchema
|
|
3363
|
+
})
|
|
3364
|
+
};
|
|
3365
|
+
var P = PRIVACY_INPUTS;
|
|
3366
|
+
var PRIVACY_OPERATIONS = [
|
|
3367
|
+
op({
|
|
3368
|
+
id: "privacy.get",
|
|
3369
|
+
method: "GET",
|
|
3370
|
+
path: "/v1/projects/{project_id}/privacy",
|
|
3371
|
+
scope: "projects:read",
|
|
3372
|
+
sensitivity: "normal",
|
|
3373
|
+
kind: "read",
|
|
3374
|
+
rpcs: ["api_read_privacy"],
|
|
3375
|
+
input: P.get,
|
|
3376
|
+
workspace: true,
|
|
3377
|
+
idempotency: "none",
|
|
3378
|
+
mcp: "configure",
|
|
3379
|
+
summary: "A project's privacy policy (mode, rules, strict allowlist, version), the built-in detectors that are off, whether user ids are pseudonymised, the last 20 versions and what the node applies and counted in the last 24 h.",
|
|
3380
|
+
ui: []
|
|
3381
|
+
}),
|
|
3382
|
+
op({
|
|
3383
|
+
id: "privacy.set",
|
|
3384
|
+
method: "PUT",
|
|
3385
|
+
path: "/v1/projects/{project_id}/privacy",
|
|
3386
|
+
scope: "privacy:write",
|
|
3387
|
+
sensitivity: "approval",
|
|
3388
|
+
kind: "write",
|
|
3389
|
+
rpcs: ["set_privacy_policy"],
|
|
3390
|
+
input: P.set,
|
|
3391
|
+
bodyField: "policy",
|
|
3392
|
+
workspace: true,
|
|
3393
|
+
idempotency: "optional",
|
|
3394
|
+
mcp: "configure",
|
|
3395
|
+
summary: "Replace a project's privacy policy (rules are applied in order on the node before anything is stored). Always needs an admin's approval; loosening (a rule removed or changed, strict off, allowlist grown) also needs their fresh authenticator code and emails owners.",
|
|
3396
|
+
ui: ["privacy#setPrivacyPolicy"]
|
|
3397
|
+
})
|
|
3398
|
+
];
|
|
3399
|
+
|
|
2284
3400
|
// ../src/shared/contracts/api-ops/projects.ts
|
|
2285
|
-
import { z as
|
|
3401
|
+
import { z as z25 } from "zod";
|
|
2286
3402
|
|
|
2287
3403
|
// ../src/shared/contracts/ingest-keys.ts
|
|
2288
|
-
import { z as
|
|
3404
|
+
import { z as z22 } from "zod";
|
|
2289
3405
|
var INGEST_KEY_SCOPES = ["traces", "logs", "errors", "monitors"];
|
|
2290
3406
|
var INGEST_KEY_STATES = ["active", "revoked"];
|
|
2291
3407
|
var INGEST_KEY_LIMITS = {
|
|
@@ -2295,174 +3411,91 @@ var INGEST_KEY_LIMITS = {
|
|
|
2295
3411
|
edgeCacheSeconds: 60
|
|
2296
3412
|
};
|
|
2297
3413
|
var CHECKIN_AUTH_MODES = ["public_or_key", "key_only"];
|
|
2298
|
-
var ingestKeyConfigSchema =
|
|
2299
|
-
v:
|
|
2300
|
-
key_id:
|
|
2301
|
-
project_public_id:
|
|
2302
|
-
project_id:
|
|
2303
|
-
workspace_id:
|
|
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(),
|
|
2304
3420
|
node_id: nodeIdSchema,
|
|
2305
|
-
scopes:
|
|
2306
|
-
environments:
|
|
2307
|
-
expires_at:
|
|
2308
|
-
state:
|
|
2309
|
-
workspace_status:
|
|
2310
|
-
ingest_kill:
|
|
2311
|
-
telemetry_kill:
|
|
2312
|
-
telemetry_rate_bytes_per_sec:
|
|
2313
|
-
telemetry_burst_bytes:
|
|
2314
|
-
traces_monthly_bytes:
|
|
2315
|
-
logs_monthly_bytes:
|
|
2316
|
-
telemetry_buffer_minutes:
|
|
2317
|
-
revision:
|
|
2318
|
-
});
|
|
2319
|
-
var createIngestKeyInputSchema = z13.object({
|
|
2320
|
-
projectId: z13.number().int().positive(),
|
|
2321
|
-
name: z13.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
|
|
2322
|
-
scopes: z13.array(z13.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
|
|
2323
|
-
environments: z13.array(z13.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
|
|
2324
|
-
expiresAt: z13.string().datetime({ offset: true }).nullable()
|
|
2325
|
-
});
|
|
2326
|
-
var ingestKeyRowSchema = z13.object({
|
|
2327
|
-
id: z13.guid(),
|
|
2328
|
-
project_id: z13.number().int().positive(),
|
|
2329
|
-
name: z13.string(),
|
|
2330
|
-
prefix: z13.string(),
|
|
2331
|
-
scopes: z13.array(z13.enum(INGEST_KEY_SCOPES)),
|
|
2332
|
-
environments: z13.array(z13.string()),
|
|
2333
|
-
expires_at: z13.string().nullable(),
|
|
2334
|
-
state: z13.enum(INGEST_KEY_STATES),
|
|
2335
|
-
created_by: z13.guid().nullable(),
|
|
2336
|
-
created_at: z13.string(),
|
|
2337
|
-
revoked_at: z13.string().nullable(),
|
|
2338
|
-
last_used_at: z13.string().nullable()
|
|
2339
|
-
});
|
|
2340
|
-
|
|
2341
|
-
// ../src/shared/contracts/integration-health.ts
|
|
2342
|
-
import { z as z14 } from "zod";
|
|
2343
|
-
|
|
2344
|
-
// ../src/shared/contracts/platforms.ts
|
|
2345
|
-
var PLATFORMS = [
|
|
2346
|
-
"javascript-browser",
|
|
2347
|
-
"react",
|
|
2348
|
-
"node",
|
|
2349
|
-
"python",
|
|
2350
|
-
"tanstack-start",
|
|
2351
|
-
"other"
|
|
2352
|
-
];
|
|
2353
|
-
|
|
2354
|
-
// ../src/shared/contracts/integration-health.ts
|
|
2355
|
-
var VERIFICATION_ID_RE = /^bv1_[0-9a-f]{32}$/;
|
|
2356
|
-
var verificationIdSchema = z14.string().regex(VERIFICATION_ID_RE);
|
|
2357
|
-
var SURFACES = ["browser", "server"];
|
|
2358
|
-
var RECEIPT_SURFACES = ["browser", "server", "belvador"];
|
|
2359
|
-
var CHECKS = ["delivery", "uncaught", "pipeline"];
|
|
2360
|
-
var HOOK_STATES = ["ok", "missing", "unknown"];
|
|
2361
|
-
var verificationContextSchema = z14.object({
|
|
2362
|
-
v: z14.literal(1),
|
|
2363
|
-
surface: z14.enum(RECEIPT_SURFACES),
|
|
2364
|
-
check: z14.enum(CHECKS),
|
|
2365
|
-
hook: z14.enum(HOOK_STATES).optional(),
|
|
2366
|
-
uncaught_expected: z14.boolean().optional()
|
|
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()
|
|
2367
3434
|
});
|
|
2368
|
-
var
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
check: z14.enum(CHECKS),
|
|
2375
|
-
hook: z14.enum(HOOK_STATES),
|
|
2376
|
-
uncaught_expected: z14.boolean(),
|
|
2377
|
-
sdk_name: z14.string().max(80),
|
|
2378
|
-
sdk_version: z14.string().max(40),
|
|
2379
|
-
environment: z14.string().max(64),
|
|
2380
|
-
release: z14.string().max(200),
|
|
2381
|
-
source_host: z14.string().max(253),
|
|
2382
|
-
received_at: iso3
|
|
2383
|
-
});
|
|
2384
|
-
var SDK_DELIVERY_DROP_REASONS = ["network_error", "queue_overflow", "send_error"];
|
|
2385
|
-
var clientDiscardSchema = z14.object({
|
|
2386
|
-
hour: iso3,
|
|
2387
|
-
reason: z14.enum(SDK_DELIVERY_DROP_REASONS),
|
|
2388
|
-
n: z14.number().int().nonnegative()
|
|
2389
|
-
});
|
|
2390
|
-
var edgeVerificationRequestSchema = z14.object({
|
|
2391
|
-
v: z14.literal(1),
|
|
2392
|
-
project_id: projectId3,
|
|
2393
|
-
verification_id: verificationIdSchema
|
|
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()
|
|
2394
3441
|
});
|
|
2395
|
-
var
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
checks: z14.array(readbackCheckSchema).max(8)
|
|
2409
|
-
});
|
|
2410
|
-
var ENVIRONMENT_RE = /^[^\u0000-\u001f]{1,64}$/;
|
|
2411
|
-
var projectRuntimeSchema = z14.object({
|
|
2412
|
-
project_id: projectId3,
|
|
2413
|
-
environment: z14.string().max(64),
|
|
2414
|
-
surface: z14.enum(SURFACES),
|
|
2415
|
-
sdk_name: z14.string().max(80),
|
|
2416
|
-
sdk_version: z14.string().max(40),
|
|
2417
|
-
latest_release: z14.string().max(200),
|
|
2418
|
-
first_seen: iso3,
|
|
2419
|
-
last_seen: iso3,
|
|
2420
|
-
events_24h: z14.number().int().nonnegative(),
|
|
2421
|
-
check_ins_24h: z14.number().int().nonnegative()
|
|
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()
|
|
2422
3455
|
});
|
|
2423
3456
|
|
|
2424
3457
|
// ../src/shared/contracts/node-config.ts
|
|
2425
|
-
import { z as
|
|
3458
|
+
import { z as z24 } from "zod";
|
|
2426
3459
|
|
|
2427
3460
|
// ../src/shared/contracts/backup.ts
|
|
2428
|
-
import { z as
|
|
3461
|
+
import { z as z23 } from "zod";
|
|
2429
3462
|
var BACKUP_KINDS = ["daily", "weekly", "manual", "pre_upgrade"];
|
|
2430
|
-
var ageRecipient =
|
|
2431
|
-
var backupIdSchema =
|
|
2432
|
-
var nodeBackupConfigSchema =
|
|
2433
|
-
enabled:
|
|
2434
|
-
hour_utc:
|
|
2435
|
-
weekly_day:
|
|
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),
|
|
2436
3469
|
workspace_recipient: ageRecipient
|
|
2437
3470
|
});
|
|
2438
|
-
var backupCredentialsRequestSchema =
|
|
2439
|
-
mode:
|
|
3471
|
+
var backupCredentialsRequestSchema = z23.object({
|
|
3472
|
+
mode: z23.enum(["upload", "download"]),
|
|
2440
3473
|
backup_id: backupIdSchema,
|
|
2441
|
-
source_node_id:
|
|
3474
|
+
source_node_id: z23.guid().optional()
|
|
2442
3475
|
});
|
|
2443
|
-
var backupCredentialsSchema =
|
|
2444
|
-
endpoint:
|
|
2445
|
-
bucket:
|
|
2446
|
-
prefix:
|
|
2447
|
-
access_key_id:
|
|
2448
|
-
secret_access_key:
|
|
2449
|
-
session_token:
|
|
2450
|
-
expires_at:
|
|
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()
|
|
2451
3484
|
});
|
|
2452
|
-
var rowCountsSchema =
|
|
2453
|
-
var backupManifestSchema =
|
|
2454
|
-
v:
|
|
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),
|
|
2455
3488
|
backup_id: backupIdSchema,
|
|
2456
|
-
node_id:
|
|
2457
|
-
kind:
|
|
2458
|
-
created_at:
|
|
2459
|
-
object_key:
|
|
2460
|
-
size_bytes:
|
|
2461
|
-
sha256:
|
|
2462
|
-
clickhouse_version:
|
|
2463
|
-
schema_version:
|
|
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(),
|
|
2464
3497
|
row_counts: rowCountsSchema,
|
|
2465
|
-
recipients:
|
|
3498
|
+
recipients: z23.array(z23.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
|
|
2466
3499
|
});
|
|
2467
3500
|
var BACKUP_ERROR_CODES = [
|
|
2468
3501
|
"CLICKHOUSE_BACKUP_FAILED",
|
|
@@ -2476,48 +3509,48 @@ var BACKUP_ERROR_CODES = [
|
|
|
2476
3509
|
"RESTORE_FAILED",
|
|
2477
3510
|
"ROW_COUNT_MISMATCH"
|
|
2478
3511
|
];
|
|
2479
|
-
var backupReportSchema =
|
|
3512
|
+
var backupReportSchema = z23.object({
|
|
2480
3513
|
backup_id: backupIdSchema,
|
|
2481
|
-
kind:
|
|
2482
|
-
status:
|
|
2483
|
-
started_at:
|
|
2484
|
-
finished_at:
|
|
3514
|
+
kind: z23.enum(BACKUP_KINDS),
|
|
3515
|
+
status: z23.enum(["succeeded", "failed"]),
|
|
3516
|
+
started_at: z23.string().datetime(),
|
|
3517
|
+
finished_at: z23.string().datetime(),
|
|
2485
3518
|
manifest: backupManifestSchema.nullable(),
|
|
2486
|
-
error_code:
|
|
3519
|
+
error_code: z23.enum(BACKUP_ERROR_CODES).nullable()
|
|
2487
3520
|
});
|
|
2488
|
-
var drillReportSchema =
|
|
3521
|
+
var drillReportSchema = z23.object({
|
|
2489
3522
|
backup_id: backupIdSchema,
|
|
2490
|
-
kind:
|
|
2491
|
-
status:
|
|
2492
|
-
finished_at:
|
|
2493
|
-
detail:
|
|
2494
|
-
error_code:
|
|
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()
|
|
2495
3528
|
});
|
|
2496
|
-
var nodeIdentityEscrowSchema =
|
|
2497
|
-
v:
|
|
2498
|
-
node_id:
|
|
2499
|
-
seal:
|
|
2500
|
-
publicKey:
|
|
2501
|
-
privateKey:
|
|
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}$/)
|
|
2502
3535
|
}),
|
|
2503
|
-
created_at:
|
|
3536
|
+
created_at: z23.string().datetime()
|
|
2504
3537
|
});
|
|
2505
|
-
var restoreArgsSchema =
|
|
2506
|
-
job_id:
|
|
2507
|
-
workspace_id:
|
|
2508
|
-
source_node_id:
|
|
3538
|
+
var restoreArgsSchema = z23.object({
|
|
3539
|
+
job_id: z23.guid(),
|
|
3540
|
+
workspace_id: z23.guid(),
|
|
3541
|
+
source_node_id: z23.guid(),
|
|
2509
3542
|
manifest: backupManifestSchema,
|
|
2510
|
-
sealed_identity:
|
|
2511
|
-
mode:
|
|
3543
|
+
sealed_identity: z23.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
|
|
3544
|
+
mode: z23.enum(["rebuild", "drill"])
|
|
2512
3545
|
});
|
|
2513
|
-
var restoreReportSchema =
|
|
2514
|
-
job_id:
|
|
3546
|
+
var restoreReportSchema = z23.object({
|
|
3547
|
+
job_id: z23.guid(),
|
|
2515
3548
|
backup_id: backupIdSchema,
|
|
2516
|
-
mode:
|
|
2517
|
-
status:
|
|
2518
|
-
finished_at:
|
|
2519
|
-
detail:
|
|
2520
|
-
error_code:
|
|
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()
|
|
2521
3554
|
});
|
|
2522
3555
|
|
|
2523
3556
|
// ../src/shared/contracts/node-config.ts
|
|
@@ -2531,81 +3564,84 @@ var SCRUB_GROUPS = [
|
|
|
2531
3564
|
"headers"
|
|
2532
3565
|
];
|
|
2533
3566
|
var MAX_NODE_MONITORS = 5000;
|
|
2534
|
-
var kid =
|
|
2535
|
-
var publicKey =
|
|
2536
|
-
var nodeConfigSchema =
|
|
2537
|
-
v:
|
|
2538
|
-
config_version:
|
|
2539
|
-
node_id:
|
|
2540
|
-
workspace_id:
|
|
2541
|
-
workspace_status:
|
|
2542
|
-
issued_at:
|
|
2543
|
-
retention_days:
|
|
2544
|
-
channel:
|
|
2545
|
-
projects:
|
|
2546
|
-
project_id:
|
|
2547
|
-
slug:
|
|
2548
|
-
short_prefix:
|
|
2549
|
-
user_id_salt:
|
|
2550
|
-
scrub_disabled:
|
|
2551
|
-
upload_tokens:
|
|
2552
|
-
hash:
|
|
2553
|
-
expires_at:
|
|
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()
|
|
2554
3587
|
})).max(10).optional()
|
|
2555
3588
|
})).max(1000),
|
|
2556
|
-
ticket_keys:
|
|
2557
|
-
control_ops_keys:
|
|
2558
|
-
kill_switches:
|
|
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() }),
|
|
2559
3592
|
backup: nodeBackupConfigSchema.optional(),
|
|
2560
|
-
purged_projects:
|
|
2561
|
-
monitors:
|
|
2562
|
-
purged_monitors:
|
|
2563
|
-
telemetry:
|
|
2564
|
-
traces_retention_days:
|
|
2565
|
-
logs_retention_days:
|
|
2566
|
-
traces_disk_share:
|
|
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)
|
|
2567
3600
|
}).optional(),
|
|
2568
|
-
slos:
|
|
3601
|
+
slos: z24.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
|
|
3602
|
+
signal_monitors: z24.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
|
|
3603
|
+
signal_limits: signalLimitsConfigSchema.optional(),
|
|
3604
|
+
privacy: nodePrivacyBlockSchema.optional()
|
|
2569
3605
|
});
|
|
2570
|
-
var signedNodeConfigSchema =
|
|
3606
|
+
var signedNodeConfigSchema = z24.object({ config: nodeConfigSchema, kid, sig: z24.string() });
|
|
2571
3607
|
|
|
2572
3608
|
// ../src/shared/contracts/api-ops/projects.ts
|
|
2573
|
-
var slug =
|
|
2574
|
-
var name3 =
|
|
2575
|
-
var label =
|
|
2576
|
-
var platform =
|
|
2577
|
-
var origin =
|
|
2578
|
-
var keyId =
|
|
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();
|
|
2579
3615
|
var PROJECT_INPUTS = {
|
|
2580
|
-
create:
|
|
2581
|
-
update:
|
|
2582
|
-
updateIntake:
|
|
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({
|
|
2583
3619
|
projectId,
|
|
2584
|
-
rateLimit:
|
|
2585
|
-
burst:
|
|
2586
|
-
allowedOrigins:
|
|
3620
|
+
rateLimit: z25.number().int().positive().nullable(),
|
|
3621
|
+
burst: z25.number().int().positive().nullable(),
|
|
3622
|
+
allowedOrigins: z25.array(origin).max(50)
|
|
2587
3623
|
}),
|
|
2588
|
-
updateObservability:
|
|
3624
|
+
updateObservability: z25.object({
|
|
2589
3625
|
projectId,
|
|
2590
|
-
primaryEnvironment:
|
|
2591
|
-
allowCodeMonitors:
|
|
3626
|
+
primaryEnvironment: z25.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
|
|
3627
|
+
allowCodeMonitors: z25.boolean()
|
|
2592
3628
|
}),
|
|
2593
|
-
setScrub:
|
|
2594
|
-
setCheckinAuth:
|
|
2595
|
-
setEnvironmentHidden:
|
|
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({
|
|
2596
3632
|
projectId,
|
|
2597
|
-
name:
|
|
2598
|
-
hidden:
|
|
2599
|
-
}),
|
|
2600
|
-
scheduleDeletion:
|
|
2601
|
-
projectOnly:
|
|
2602
|
-
labelled:
|
|
2603
|
-
keyOnly:
|
|
2604
|
-
tokenOnly:
|
|
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 }),
|
|
2605
3641
|
createIngestKey: createIngestKeyInputSchema,
|
|
2606
|
-
ingestKeyOnly:
|
|
3642
|
+
ingestKeyOnly: z25.object({ keyId: uuid })
|
|
2607
3643
|
};
|
|
2608
|
-
var
|
|
3644
|
+
var P2 = PROJECT_INPUTS;
|
|
2609
3645
|
var PROJECT_OPERATIONS = [
|
|
2610
3646
|
op({
|
|
2611
3647
|
id: "projects.create",
|
|
@@ -2615,7 +3651,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2615
3651
|
sensitivity: "normal",
|
|
2616
3652
|
kind: "write",
|
|
2617
3653
|
rpcs: ["create_project"],
|
|
2618
|
-
input:
|
|
3654
|
+
input: P2.create,
|
|
2619
3655
|
workspace: true,
|
|
2620
3656
|
idempotency: "required",
|
|
2621
3657
|
status: 201,
|
|
@@ -2631,7 +3667,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2631
3667
|
sensitivity: "normal",
|
|
2632
3668
|
kind: "write",
|
|
2633
3669
|
rpcs: ["update_project"],
|
|
2634
|
-
input:
|
|
3670
|
+
input: P2.update,
|
|
2635
3671
|
ifMatch: true,
|
|
2636
3672
|
idempotency: "none",
|
|
2637
3673
|
mcp: "configure",
|
|
@@ -2646,7 +3682,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2646
3682
|
sensitivity: "normal",
|
|
2647
3683
|
kind: "write",
|
|
2648
3684
|
rpcs: ["update_project_intake"],
|
|
2649
|
-
input:
|
|
3685
|
+
input: P2.updateIntake,
|
|
2650
3686
|
ifMatch: true,
|
|
2651
3687
|
idempotency: "none",
|
|
2652
3688
|
mcp: "configure",
|
|
@@ -2661,7 +3697,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2661
3697
|
sensitivity: "normal",
|
|
2662
3698
|
kind: "write",
|
|
2663
3699
|
rpcs: ["update_project_observability"],
|
|
2664
|
-
input:
|
|
3700
|
+
input: P2.updateObservability,
|
|
2665
3701
|
ifMatch: true,
|
|
2666
3702
|
idempotency: "none",
|
|
2667
3703
|
mcp: "configure",
|
|
@@ -2673,10 +3709,10 @@ var PROJECT_OPERATIONS = [
|
|
|
2673
3709
|
method: "PUT",
|
|
2674
3710
|
path: "/v1/projects/{project_id}/scrub/{group}",
|
|
2675
3711
|
scope: "privacy:write",
|
|
2676
|
-
sensitivity: "
|
|
3712
|
+
sensitivity: "approval",
|
|
2677
3713
|
kind: "write",
|
|
2678
3714
|
rpcs: ["set_project_scrub"],
|
|
2679
|
-
input:
|
|
3715
|
+
input: P2.setScrub,
|
|
2680
3716
|
idempotency: "none",
|
|
2681
3717
|
mcp: "configure",
|
|
2682
3718
|
summary: "Turn one built-in scrubbing group on or off.",
|
|
@@ -2690,7 +3726,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2690
3726
|
sensitivity: "approval",
|
|
2691
3727
|
kind: "write",
|
|
2692
3728
|
rpcs: ["set_project_checkin_auth"],
|
|
2693
|
-
input:
|
|
3729
|
+
input: P2.setCheckinAuth,
|
|
2694
3730
|
idempotency: "none",
|
|
2695
3731
|
mcp: "configure",
|
|
2696
3732
|
summary: "Choose which credentials may send check-ins.",
|
|
@@ -2704,7 +3740,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2704
3740
|
sensitivity: "normal",
|
|
2705
3741
|
kind: "write",
|
|
2706
3742
|
rpcs: ["set_environment_hidden"],
|
|
2707
|
-
input:
|
|
3743
|
+
input: P2.setEnvironmentHidden,
|
|
2708
3744
|
idempotency: "none",
|
|
2709
3745
|
mcp: "configure",
|
|
2710
3746
|
summary: "Hide or show an environment in lists.",
|
|
@@ -2718,7 +3754,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2718
3754
|
sensitivity: "approval",
|
|
2719
3755
|
kind: "write",
|
|
2720
3756
|
rpcs: ["schedule_project_deletion"],
|
|
2721
|
-
input:
|
|
3757
|
+
input: P2.scheduleDeletion,
|
|
2722
3758
|
idempotency: "none",
|
|
2723
3759
|
mcp: "configure",
|
|
2724
3760
|
summary: "Schedule the project's deletion; `confirm_slug` must repeat its slug.",
|
|
@@ -2732,7 +3768,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2732
3768
|
sensitivity: "normal",
|
|
2733
3769
|
kind: "write",
|
|
2734
3770
|
rpcs: ["cancel_project_deletion"],
|
|
2735
|
-
input:
|
|
3771
|
+
input: P2.projectOnly,
|
|
2736
3772
|
idempotency: "optional",
|
|
2737
3773
|
mcp: "configure",
|
|
2738
3774
|
summary: "Cancel a scheduled project deletion.",
|
|
@@ -2746,7 +3782,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2746
3782
|
sensitivity: "normal",
|
|
2747
3783
|
kind: "write",
|
|
2748
3784
|
rpcs: ["request_test_event"],
|
|
2749
|
-
input:
|
|
3785
|
+
input: P2.projectOnly,
|
|
2750
3786
|
idempotency: "optional",
|
|
2751
3787
|
mcp: "reliability",
|
|
2752
3788
|
summary: "Ask the node to send one test event through the public intake.",
|
|
@@ -2760,7 +3796,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2760
3796
|
sensitivity: "approval",
|
|
2761
3797
|
kind: "write",
|
|
2762
3798
|
rpcs: ["create_project_key"],
|
|
2763
|
-
input:
|
|
3799
|
+
input: P2.labelled,
|
|
2764
3800
|
idempotency: "required",
|
|
2765
3801
|
status: 201,
|
|
2766
3802
|
mcp: "configure",
|
|
@@ -2775,7 +3811,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2775
3811
|
sensitivity: "approval",
|
|
2776
3812
|
kind: "write",
|
|
2777
3813
|
rpcs: ["rotate_project_key"],
|
|
2778
|
-
input:
|
|
3814
|
+
input: P2.keyOnly,
|
|
2779
3815
|
idempotency: "optional",
|
|
2780
3816
|
mcp: "configure",
|
|
2781
3817
|
summary: "Replace a DSN key.",
|
|
@@ -2789,7 +3825,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2789
3825
|
sensitivity: "approval",
|
|
2790
3826
|
kind: "write",
|
|
2791
3827
|
rpcs: ["revoke_project_key"],
|
|
2792
|
-
input:
|
|
3828
|
+
input: P2.keyOnly,
|
|
2793
3829
|
idempotency: "none",
|
|
2794
3830
|
mcp: "configure",
|
|
2795
3831
|
summary: "Revoke a DSN key.",
|
|
@@ -2803,7 +3839,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2803
3839
|
sensitivity: "approval",
|
|
2804
3840
|
kind: "write",
|
|
2805
3841
|
rpcs: ["create_upload_token"],
|
|
2806
|
-
input:
|
|
3842
|
+
input: P2.labelled,
|
|
2807
3843
|
idempotency: "required",
|
|
2808
3844
|
status: 201,
|
|
2809
3845
|
mcp: "configure",
|
|
@@ -2819,7 +3855,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2819
3855
|
sensitivity: "approval",
|
|
2820
3856
|
kind: "write",
|
|
2821
3857
|
rpcs: ["revoke_upload_token"],
|
|
2822
|
-
input:
|
|
3858
|
+
input: P2.tokenOnly,
|
|
2823
3859
|
idempotency: "none",
|
|
2824
3860
|
mcp: "configure",
|
|
2825
3861
|
summary: "Revoke a source map upload token.",
|
|
@@ -2833,7 +3869,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2833
3869
|
sensitivity: "approval",
|
|
2834
3870
|
kind: "write",
|
|
2835
3871
|
rpcs: ["create_ingest_key"],
|
|
2836
|
-
input:
|
|
3872
|
+
input: P2.createIngestKey,
|
|
2837
3873
|
idempotency: "required",
|
|
2838
3874
|
status: 201,
|
|
2839
3875
|
mcp: "configure",
|
|
@@ -2849,7 +3885,7 @@ var PROJECT_OPERATIONS = [
|
|
|
2849
3885
|
sensitivity: "approval",
|
|
2850
3886
|
kind: "write",
|
|
2851
3887
|
rpcs: ["revoke_ingest_key"],
|
|
2852
|
-
input:
|
|
3888
|
+
input: P2.ingestKeyOnly,
|
|
2853
3889
|
idempotency: "none",
|
|
2854
3890
|
mcp: "configure",
|
|
2855
3891
|
summary: "Revoke an OTLP ingest key.",
|
|
@@ -2858,24 +3894,28 @@ var PROJECT_OPERATIONS = [
|
|
|
2858
3894
|
];
|
|
2859
3895
|
|
|
2860
3896
|
// ../src/shared/contracts/api-ops/reads.ts
|
|
2861
|
-
import { z as
|
|
2862
|
-
var list =
|
|
3897
|
+
import { z as z26 } from "zod";
|
|
3898
|
+
var list = z26.object({ workspaceId: uuid, limit: pageLimit, cursor });
|
|
2863
3899
|
var READ_INPUTS = {
|
|
2864
|
-
workspace:
|
|
3900
|
+
workspace: z26.object({ workspaceId: uuid }),
|
|
2865
3901
|
list,
|
|
2866
|
-
projectsGet:
|
|
3902
|
+
projectsGet: z26.object({ workspaceId: uuid, projectId }),
|
|
2867
3903
|
monitorsList: list.extend({ projectId: projectId.optional() }),
|
|
2868
|
-
monitorsGet:
|
|
2869
|
-
uptimeGet:
|
|
2870
|
-
slosGet:
|
|
3904
|
+
monitorsGet: z26.object({ workspaceId: uuid, monitorId: uuid }),
|
|
3905
|
+
uptimeGet: z26.object({ workspaceId: uuid, checkId: uuid }),
|
|
3906
|
+
slosGet: z26.object({ workspaceId: uuid, sloId: uuid }),
|
|
2871
3907
|
alertsList: list.extend({
|
|
2872
|
-
state:
|
|
3908
|
+
state: z26.enum(["open", "resolved", "all"]).default("all"),
|
|
2873
3909
|
monitorId: uuid.optional()
|
|
2874
3910
|
}),
|
|
2875
|
-
approvalsGet:
|
|
3911
|
+
approvalsGet: z26.object({ workspaceId: uuid, approvalId: uuid }),
|
|
3912
|
+
monitorsListTyped: list.extend({
|
|
3913
|
+
projectId: projectId.optional(),
|
|
3914
|
+
type: z26.enum(MONITOR_TYPES).optional()
|
|
3915
|
+
})
|
|
2876
3916
|
};
|
|
2877
3917
|
var R = READ_INPUTS;
|
|
2878
|
-
var
|
|
3918
|
+
var base2 = {
|
|
2879
3919
|
sensitivity: "normal",
|
|
2880
3920
|
kind: "read",
|
|
2881
3921
|
method: "GET",
|
|
@@ -2885,7 +3925,7 @@ var base = {
|
|
|
2885
3925
|
};
|
|
2886
3926
|
var READ_OPERATIONS = [
|
|
2887
3927
|
op({
|
|
2888
|
-
...
|
|
3928
|
+
...base2,
|
|
2889
3929
|
id: "workspace.get",
|
|
2890
3930
|
path: "/v1/workspace",
|
|
2891
3931
|
scope: "org:read",
|
|
@@ -2895,7 +3935,7 @@ var READ_OPERATIONS = [
|
|
|
2895
3935
|
summary: "The token's workspace, plan and the caller's role."
|
|
2896
3936
|
}),
|
|
2897
3937
|
op({
|
|
2898
|
-
...
|
|
3938
|
+
...base2,
|
|
2899
3939
|
id: "members.list",
|
|
2900
3940
|
path: "/v1/members",
|
|
2901
3941
|
scope: "members:read",
|
|
@@ -2906,7 +3946,7 @@ var READ_OPERATIONS = [
|
|
|
2906
3946
|
summary: "Workspace members and their roles."
|
|
2907
3947
|
}),
|
|
2908
3948
|
op({
|
|
2909
|
-
...
|
|
3949
|
+
...base2,
|
|
2910
3950
|
id: "projects.list",
|
|
2911
3951
|
path: "/v1/projects",
|
|
2912
3952
|
scope: "projects:read",
|
|
@@ -2917,7 +3957,7 @@ var READ_OPERATIONS = [
|
|
|
2917
3957
|
summary: "Projects the token can see."
|
|
2918
3958
|
}),
|
|
2919
3959
|
op({
|
|
2920
|
-
...
|
|
3960
|
+
...base2,
|
|
2921
3961
|
id: "projects.get",
|
|
2922
3962
|
path: "/v1/projects/{project_id}",
|
|
2923
3963
|
scope: "projects:read",
|
|
@@ -2927,18 +3967,18 @@ var READ_OPERATIONS = [
|
|
|
2927
3967
|
summary: "One project."
|
|
2928
3968
|
}),
|
|
2929
3969
|
op({
|
|
2930
|
-
...
|
|
3970
|
+
...base2,
|
|
2931
3971
|
id: "monitors.list",
|
|
2932
3972
|
path: "/v1/monitors",
|
|
2933
3973
|
scope: "monitors:read",
|
|
2934
3974
|
rpcs: ["api_read_monitors"],
|
|
2935
|
-
input: R.
|
|
3975
|
+
input: R.monitorsListTyped,
|
|
2936
3976
|
paged: true,
|
|
2937
3977
|
mcp: "investigate",
|
|
2938
|
-
summary: "
|
|
3978
|
+
summary: "Monitors of every type (cron, heartbeat, count, assertion, deadline, progress); `type` narrows the list."
|
|
2939
3979
|
}),
|
|
2940
3980
|
op({
|
|
2941
|
-
...
|
|
3981
|
+
...base2,
|
|
2942
3982
|
id: "monitors.get",
|
|
2943
3983
|
path: "/v1/monitors/{monitor_id}",
|
|
2944
3984
|
scope: "monitors:read",
|
|
@@ -2948,7 +3988,7 @@ var READ_OPERATIONS = [
|
|
|
2948
3988
|
summary: "One monitor with its ETag."
|
|
2949
3989
|
}),
|
|
2950
3990
|
op({
|
|
2951
|
-
...
|
|
3991
|
+
...base2,
|
|
2952
3992
|
id: "uptime.list",
|
|
2953
3993
|
path: "/v1/uptime-checks",
|
|
2954
3994
|
scope: "monitors:read",
|
|
@@ -2959,7 +3999,7 @@ var READ_OPERATIONS = [
|
|
|
2959
3999
|
summary: "Uptime checks (header values are never returned)."
|
|
2960
4000
|
}),
|
|
2961
4001
|
op({
|
|
2962
|
-
...
|
|
4002
|
+
...base2,
|
|
2963
4003
|
id: "uptime.get",
|
|
2964
4004
|
path: "/v1/uptime-checks/{check_id}",
|
|
2965
4005
|
scope: "monitors:read",
|
|
@@ -2969,7 +4009,7 @@ var READ_OPERATIONS = [
|
|
|
2969
4009
|
summary: "One uptime check."
|
|
2970
4010
|
}),
|
|
2971
4011
|
op({
|
|
2972
|
-
...
|
|
4012
|
+
...base2,
|
|
2973
4013
|
id: "slos.list",
|
|
2974
4014
|
path: "/v1/slos",
|
|
2975
4015
|
scope: "monitors:read",
|
|
@@ -2980,7 +4020,7 @@ var READ_OPERATIONS = [
|
|
|
2980
4020
|
summary: "SLO definitions."
|
|
2981
4021
|
}),
|
|
2982
4022
|
op({
|
|
2983
|
-
...
|
|
4023
|
+
...base2,
|
|
2984
4024
|
id: "slos.get",
|
|
2985
4025
|
path: "/v1/slos/{slo_id}",
|
|
2986
4026
|
scope: "monitors:read",
|
|
@@ -2990,7 +4030,7 @@ var READ_OPERATIONS = [
|
|
|
2990
4030
|
summary: "One SLO definition."
|
|
2991
4031
|
}),
|
|
2992
4032
|
op({
|
|
2993
|
-
...
|
|
4033
|
+
...base2,
|
|
2994
4034
|
id: "alert_rules.list",
|
|
2995
4035
|
path: "/v1/alert-rules",
|
|
2996
4036
|
scope: "alerts:read",
|
|
@@ -3001,7 +4041,7 @@ var READ_OPERATIONS = [
|
|
|
3001
4041
|
summary: "Alert rules."
|
|
3002
4042
|
}),
|
|
3003
4043
|
op({
|
|
3004
|
-
...
|
|
4044
|
+
...base2,
|
|
3005
4045
|
id: "destinations.list",
|
|
3006
4046
|
path: "/v1/destinations",
|
|
3007
4047
|
scope: "alerts:read",
|
|
@@ -3012,7 +4052,7 @@ var READ_OPERATIONS = [
|
|
|
3012
4052
|
summary: "Alert destinations with a masked hint; secrets never leave the server."
|
|
3013
4053
|
}),
|
|
3014
4054
|
op({
|
|
3015
|
-
...
|
|
4055
|
+
...base2,
|
|
3016
4056
|
id: "alerts.list",
|
|
3017
4057
|
path: "/v1/alerts",
|
|
3018
4058
|
scope: "alerts:read",
|
|
@@ -3023,7 +4063,18 @@ var READ_OPERATIONS = [
|
|
|
3023
4063
|
summary: "Alerts: one row per violation episode of a monitor, open or resolved."
|
|
3024
4064
|
}),
|
|
3025
4065
|
op({
|
|
3026
|
-
...
|
|
4066
|
+
...base2,
|
|
4067
|
+
id: "maintenance.list",
|
|
4068
|
+
path: "/v1/maintenance-windows",
|
|
4069
|
+
scope: "monitors:read",
|
|
4070
|
+
rpcs: ["api_read_maintenance_windows"],
|
|
4071
|
+
input: R.list,
|
|
4072
|
+
paged: true,
|
|
4073
|
+
mcp: "reliability",
|
|
4074
|
+
summary: "Maintenance windows and whether each is active now."
|
|
4075
|
+
}),
|
|
4076
|
+
op({
|
|
4077
|
+
...base2,
|
|
3027
4078
|
id: "node.get",
|
|
3028
4079
|
path: "/v1/node",
|
|
3029
4080
|
scope: "org:read",
|
|
@@ -3033,7 +4084,7 @@ var READ_OPERATIONS = [
|
|
|
3033
4084
|
summary: "The node's state, versions and last heartbeat (null before provisioning)."
|
|
3034
4085
|
}),
|
|
3035
4086
|
op({
|
|
3036
|
-
...
|
|
4087
|
+
...base2,
|
|
3037
4088
|
id: "usage.get",
|
|
3038
4089
|
path: "/v1/usage",
|
|
3039
4090
|
scope: "usage:read",
|
|
@@ -3043,7 +4094,7 @@ var READ_OPERATIONS = [
|
|
|
3043
4094
|
summary: "The workspace's plan and limits."
|
|
3044
4095
|
}),
|
|
3045
4096
|
op({
|
|
3046
|
-
...
|
|
4097
|
+
...base2,
|
|
3047
4098
|
id: "audit.list",
|
|
3048
4099
|
path: "/v1/audit-log",
|
|
3049
4100
|
scope: "audit:read",
|
|
@@ -3054,7 +4105,7 @@ var READ_OPERATIONS = [
|
|
|
3054
4105
|
summary: "Audit log, newest first (admins)."
|
|
3055
4106
|
}),
|
|
3056
4107
|
op({
|
|
3057
|
-
...
|
|
4108
|
+
...base2,
|
|
3058
4109
|
id: "approvals.get",
|
|
3059
4110
|
path: "/v1/approvals/{approval_id}",
|
|
3060
4111
|
scope: "org:read",
|
|
@@ -3071,6 +4122,9 @@ var API_OPERATIONS = [
|
|
|
3071
4122
|
...PROJECT_OPERATIONS,
|
|
3072
4123
|
...MONITOR_OPERATIONS,
|
|
3073
4124
|
...ALERT_OPERATIONS,
|
|
4125
|
+
...INCIDENT_OPERATIONS,
|
|
4126
|
+
...COVERAGE_OPERATIONS,
|
|
4127
|
+
...PRIVACY_OPERATIONS,
|
|
3074
4128
|
...ACCESS_OPERATIONS,
|
|
3075
4129
|
...NODE_OPERATIONS
|
|
3076
4130
|
];
|
|
@@ -3095,6 +4149,8 @@ var APPROVAL_LIMITS = {
|
|
|
3095
4149
|
var APPROVAL_APPROVER = {
|
|
3096
4150
|
"projects.set_checkin_auth": "admin",
|
|
3097
4151
|
"projects.schedule_deletion": "admin",
|
|
4152
|
+
"projects.set_scrub": "admin",
|
|
4153
|
+
"privacy.set": "admin",
|
|
3098
4154
|
"project_keys.create": "member",
|
|
3099
4155
|
"project_keys.rotate": "member",
|
|
3100
4156
|
"project_keys.revoke": "member",
|
|
@@ -3139,14 +4195,14 @@ function approvalRequestSchema(operationId, input) {
|
|
|
3139
4195
|
}
|
|
3140
4196
|
|
|
3141
4197
|
// ../src/shared/contracts/api-ops/wire.ts
|
|
3142
|
-
import { z as
|
|
4198
|
+
import { z as z27 } from "zod";
|
|
3143
4199
|
var toSnake = (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
3144
4200
|
var toCamel = (s) => s.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
3145
4201
|
var schemaCache = new WeakMap;
|
|
3146
4202
|
function inputJsonSchema(op) {
|
|
3147
4203
|
let js = schemaCache.get(op.input);
|
|
3148
4204
|
if (!js) {
|
|
3149
|
-
js =
|
|
4205
|
+
js = z27.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
|
|
3150
4206
|
schemaCache.set(op.input, js);
|
|
3151
4207
|
}
|
|
3152
4208
|
return js;
|
|
@@ -3271,6 +4327,18 @@ function wirePointer(op, path) {
|
|
|
3271
4327
|
segs.shift();
|
|
3272
4328
|
return `/${segs.map((s) => s.replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
|
|
3273
4329
|
}
|
|
4330
|
+
var WIRE_ERRORS_MAX = 20;
|
|
4331
|
+
function wireErrors(op, error) {
|
|
4332
|
+
const flat = (issues, prefix) => issues.flatMap((i) => {
|
|
4333
|
+
if (i.code === "invalid_union" && i.errors && i.errors.length > 0) {
|
|
4334
|
+
const best = i.errors.reduce((a, b) => b.length < a.length ? b : a);
|
|
4335
|
+
if (best.length > 0)
|
|
4336
|
+
return flat(best, [...prefix, ...i.path]);
|
|
4337
|
+
}
|
|
4338
|
+
return [{ ...i, path: [...prefix, ...i.path] }];
|
|
4339
|
+
});
|
|
4340
|
+
return flat(error.issues, []).slice(0, WIRE_ERRORS_MAX).map((i) => ({ pointer: wirePointer(op, i.path), code: i.code }));
|
|
4341
|
+
}
|
|
3274
4342
|
|
|
3275
4343
|
// ../src/shared/contracts/api-ops/openapi.ts
|
|
3276
4344
|
function clean(js) {
|
|
@@ -3348,7 +4416,7 @@ function wireInput(operationId, opts = {}) {
|
|
|
3348
4416
|
for (const [k, v] of Object.entries(op.input.shape))
|
|
3349
4417
|
if (!omit.has(k))
|
|
3350
4418
|
shape[toSnake(k)] = v;
|
|
3351
|
-
return
|
|
4419
|
+
return z28.object(shape);
|
|
3352
4420
|
}
|
|
3353
4421
|
var BUDGETS = [
|
|
3354
4422
|
{ stringBytes: MCP_LIMITS.untrustedStringMaxBytes, listMax: MCP_LIMITS.listMax },
|
|
@@ -3438,40 +4506,40 @@ function errorResult(o) {
|
|
|
3438
4506
|
}
|
|
3439
4507
|
};
|
|
3440
4508
|
}
|
|
3441
|
-
var TOOL_OUTPUT_SCHEMA =
|
|
3442
|
-
untrusted:
|
|
3443
|
-
data:
|
|
3444
|
-
provenance:
|
|
3445
|
-
source:
|
|
3446
|
-
operations:
|
|
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())
|
|
3447
4515
|
})
|
|
3448
4516
|
}).optional(),
|
|
3449
|
-
doc:
|
|
3450
|
-
results:
|
|
3451
|
-
next_cursor:
|
|
3452
|
-
complete:
|
|
3453
|
-
omitted:
|
|
3454
|
-
truncated:
|
|
3455
|
-
suspicious_unicode:
|
|
3456
|
-
error:
|
|
3457
|
-
code:
|
|
3458
|
-
status:
|
|
3459
|
-
detail:
|
|
3460
|
-
scope:
|
|
3461
|
-
retry_after:
|
|
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()
|
|
3462
4530
|
}).optional(),
|
|
3463
|
-
operations:
|
|
3464
|
-
operation:
|
|
3465
|
-
plan:
|
|
3466
|
-
status:
|
|
3467
|
-
approval:
|
|
3468
|
-
approval_id:
|
|
3469
|
-
approval_url:
|
|
3470
|
-
expires_at:
|
|
3471
|
-
state:
|
|
3472
|
-
result_code:
|
|
3473
|
-
result:
|
|
3474
|
-
next:
|
|
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()
|
|
3475
4543
|
}).optional()
|
|
3476
4544
|
});
|
|
3477
4545
|
var spec = (name) => {
|
|
@@ -3517,10 +4585,10 @@ var has = (rt, operationId) => {
|
|
|
3517
4585
|
return !!op && rt.scopes.includes(op.scope);
|
|
3518
4586
|
};
|
|
3519
4587
|
var isoWindow = {
|
|
3520
|
-
start:
|
|
3521
|
-
end:
|
|
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.")
|
|
3522
4590
|
};
|
|
3523
|
-
var traceIdSchema =
|
|
4591
|
+
var traceIdSchema = z28.string().regex(/^[0-9a-fA-F]{32}$/);
|
|
3524
4592
|
var MONITOR_KINDS2 = {
|
|
3525
4593
|
cron: { list: "monitors.list", get: "monitors.get", idField: "monitor_id" },
|
|
3526
4594
|
uptime: { list: "uptime.list", get: "uptime.get", idField: "check_id" },
|
|
@@ -3569,7 +4637,7 @@ function validateConfigure(op, params) {
|
|
|
3569
4637
|
return { ok: true };
|
|
3570
4638
|
return {
|
|
3571
4639
|
ok: false,
|
|
3572
|
-
errors:
|
|
4640
|
+
errors: wireErrors(op, r.error)
|
|
3573
4641
|
};
|
|
3574
4642
|
}
|
|
3575
4643
|
function describe(op, scopes) {
|
|
@@ -3584,8 +4652,8 @@ function describe(op, scopes) {
|
|
|
3584
4652
|
destructive: isDestructiveOperation(op)
|
|
3585
4653
|
};
|
|
3586
4654
|
}
|
|
3587
|
-
var params =
|
|
3588
|
-
var operationIdArg =
|
|
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`.");
|
|
3589
4657
|
function approvalBlock(t, next) {
|
|
3590
4658
|
return {
|
|
3591
4659
|
approval_id: t.approval_id,
|
|
@@ -3605,7 +4673,7 @@ var MCP_TOOL_DEFS = [
|
|
|
3605
4673
|
title: "Workspace and node",
|
|
3606
4674
|
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.",
|
|
3607
4675
|
operations: ["workspace.get", "node.get"],
|
|
3608
|
-
input:
|
|
4676
|
+
input: z28.object({}),
|
|
3609
4677
|
async run(_args, rt) {
|
|
3610
4678
|
const [ws, node] = await Promise.all([rt.call("workspace.get", {}), rt.call("node.get", {})]);
|
|
3611
4679
|
if (!ws.ok)
|
|
@@ -3623,9 +4691,9 @@ var MCP_TOOL_DEFS = [
|
|
|
3623
4691
|
title: "Get an issue",
|
|
3624
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).",
|
|
3625
4693
|
operations: ["issues.get", "events.get"],
|
|
3626
|
-
input:
|
|
3627
|
-
issue_id:
|
|
3628
|
-
include_latest_event:
|
|
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)
|
|
3629
4697
|
}),
|
|
3630
4698
|
async run(args, rt) {
|
|
3631
4699
|
const omitted = [];
|
|
@@ -3653,9 +4721,9 @@ var MCP_TOOL_DEFS = [
|
|
|
3653
4721
|
title: "Get a trace",
|
|
3654
4722
|
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).",
|
|
3655
4723
|
operations: ["traces.get", "traces.spans"],
|
|
3656
|
-
input:
|
|
4724
|
+
input: z28.object({
|
|
3657
4725
|
trace_id: traceIdSchema.describe("W3C trace id, 32 hex characters."),
|
|
3658
|
-
spans:
|
|
4726
|
+
spans: z28.enum(["none", "errors", "all"]).default("none")
|
|
3659
4727
|
}),
|
|
3660
4728
|
async run(args, rt) {
|
|
3661
4729
|
const sum = await rt.call("traces.get", { trace_id: args["trace_id"] });
|
|
@@ -3683,11 +4751,11 @@ var MCP_TOOL_DEFS = [
|
|
|
3683
4751
|
title: "Correlate by trace or run",
|
|
3684
4752
|
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.",
|
|
3685
4753
|
operations: ["traces.get", "traces.spans", "spans.list", "logs.list"],
|
|
3686
|
-
input:
|
|
4754
|
+
input: z28.object({
|
|
3687
4755
|
trace_id: traceIdSchema.optional(),
|
|
3688
|
-
run_id:
|
|
4756
|
+
run_id: z28.string().min(1).max(128).optional(),
|
|
3689
4757
|
...isoWindow,
|
|
3690
|
-
project:
|
|
4758
|
+
project: z28.string().max(2000).optional().describe("Comma-separated project ids.")
|
|
3691
4759
|
}),
|
|
3692
4760
|
async run(args, rt) {
|
|
3693
4761
|
const trace = args["trace_id"];
|
|
@@ -3730,12 +4798,12 @@ var MCP_TOOL_DEFS = [
|
|
|
3730
4798
|
{
|
|
3731
4799
|
...spec("list_monitors"),
|
|
3732
4800
|
title: "List monitors",
|
|
3733
|
-
description: "
|
|
4801
|
+
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).",
|
|
3734
4802
|
operations: ["monitors.list", "uptime.list", "slos.list"],
|
|
3735
|
-
input:
|
|
3736
|
-
kind:
|
|
3737
|
-
project_id:
|
|
3738
|
-
limit:
|
|
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)
|
|
3739
4807
|
}),
|
|
3740
4808
|
async run(args, rt) {
|
|
3741
4809
|
const kinds = args["kind"] && args["kind"] !== "all" ? [args["kind"]] : ["cron", "uptime", "slo"];
|
|
@@ -3761,26 +4829,70 @@ var MCP_TOOL_DEFS = [
|
|
|
3761
4829
|
{
|
|
3762
4830
|
...spec("get_monitor_status"),
|
|
3763
4831
|
title: "Get a monitor",
|
|
3764
|
-
description: "One
|
|
3765
|
-
operations: ["monitors.get", "uptime.get", "slos.get"],
|
|
3766
|
-
input:
|
|
4832
|
+
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)
|
|
4838
|
+
}),
|
|
3767
4839
|
async run(args, rt) {
|
|
3768
4840
|
const k = MONITOR_KINDS2[args["kind"]];
|
|
3769
4841
|
const r = await rt.call(k.get, { [k.idField]: args["id"] });
|
|
3770
4842
|
if (!r.ok)
|
|
3771
4843
|
return errorResult(r);
|
|
3772
|
-
|
|
4844
|
+
const row = r.body ?? {};
|
|
4845
|
+
const type = typeof row["type"] === "string" ? row["type"] : "job";
|
|
4846
|
+
if (k.get !== "monitors.get" || !isSignalMonitorType(type)) {
|
|
4847
|
+
return wrapResult({ data: r.body, operations: [k.get], source: "control_plane" });
|
|
4848
|
+
}
|
|
4849
|
+
const ops = [k.get, "monitors.signal"];
|
|
4850
|
+
const calls = [
|
|
4851
|
+
rt.call("monitors.signal", { monitor_id: args["id"], hours: 24 })
|
|
4852
|
+
];
|
|
4853
|
+
const parts = ["signal"];
|
|
4854
|
+
if (type === "deadline") {
|
|
4855
|
+
ops.push("monitors.occurrences");
|
|
4856
|
+
parts.push("occurrences");
|
|
4857
|
+
calls.push(rt.call("monitors.occurrences", { monitor_id: args["id"], state: "all" }));
|
|
4858
|
+
}
|
|
4859
|
+
const settings = args["backtest"] === true && (type === "count" || type === "assertion") ? settingsFromRow({
|
|
4860
|
+
type,
|
|
4861
|
+
signal_settings: row["signal_settings"],
|
|
4862
|
+
expected_environments: Array.isArray(row["expected_environments"]) ? row["expected_environments"] : [],
|
|
4863
|
+
severity: String(row["severity"] ?? "medium"),
|
|
4864
|
+
recovery_threshold: Number(row["recovery_threshold"] ?? 1)
|
|
4865
|
+
}) : null;
|
|
4866
|
+
if (settings) {
|
|
4867
|
+
ops.push("monitors.backtest");
|
|
4868
|
+
parts.push("backtest");
|
|
4869
|
+
calls.push(rt.call("monitors.backtest", { project: row["project_id"], settings }));
|
|
4870
|
+
}
|
|
4871
|
+
const answers = await Promise.all(calls);
|
|
4872
|
+
const data = { monitor: r.body };
|
|
4873
|
+
const omitted = [];
|
|
4874
|
+
for (const [i, part] of parts.entries()) {
|
|
4875
|
+
const a = answers[i];
|
|
4876
|
+
if (a.ok)
|
|
4877
|
+
data[part] = part === "occurrences" ? withoutPaging(a.body) : a.body;
|
|
4878
|
+
else
|
|
4879
|
+
omitted.push({ part, reason: a.code });
|
|
4880
|
+
}
|
|
4881
|
+
return wrapResult({ data, operations: ops, source: omitted.length === parts.length ? "control_plane" : "node" }, { omitted });
|
|
3773
4882
|
}
|
|
3774
4883
|
},
|
|
3775
4884
|
single("list_alerts", "alerts.list", "List alerts", "Alerts Belvador raised (open, resolved or all), newest first, optionally for one monitor."),
|
|
4885
|
+
single("list_incidents", "incidents.list", "List incidents", "Incidents (INC-n): related alerts grouped into one piece of work. State (open, acknowledged, monitoring, resolved), severity and peak, owner, linked and still-firing alert counts; newest first. `state` = active, resolved or all. Returns ids for get_incident."),
|
|
4886
|
+
single("get_incident", "incidents.get", "Get an incident", "One incident by id: its linked alerts (monitor, uptime, SLO, issue) with ids for get_monitor_status or get_issue, the timeline (opened, joined, acknowledged, notes, escalation, resolution) and each message's delivery state. `accepted` means the service took the message; only `acknowledged: true` means a person took the incident."),
|
|
4887
|
+
single("get_coverage", "coverage.get", "Get coverage", "What each app is expected to send (part of the app × signal × environment) against what Belvador really received: `verified` (fresh evidence or verification receipt), `stale`, `problem` (open connection problem) or `unknown` (never seen). Same numbers as the Coverage page. `undeclared` lists signals seen without an expectation; they do not count. Optional `project_id` and `environment` narrow it."),
|
|
3776
4888
|
{
|
|
3777
4889
|
...spec("verify_integration"),
|
|
3778
4890
|
title: "Send a test event",
|
|
3779
4891
|
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).",
|
|
3780
4892
|
operations: ["projects.send_test_event"],
|
|
3781
|
-
input:
|
|
3782
|
-
project_id:
|
|
3783
|
-
idempotency_key:
|
|
4893
|
+
input: z28.object({
|
|
4894
|
+
project_id: z28.number().int().positive(),
|
|
4895
|
+
idempotency_key: z28.string().min(8).max(255).optional()
|
|
3784
4896
|
}),
|
|
3785
4897
|
async run(args, rt) {
|
|
3786
4898
|
const r = await rt.call("projects.send_test_event", { project_id: args["project_id"] }, { idempotencyKey: args["idempotency_key"] ?? rt.newKey() });
|
|
@@ -3792,11 +4904,11 @@ var MCP_TOOL_DEFS = [
|
|
|
3792
4904
|
{
|
|
3793
4905
|
...spec("search_operations"),
|
|
3794
4906
|
title: "Find a configuration change",
|
|
3795
|
-
description: "Searches what this token can change in its Belvador workspace: projects, keys and tokens, monitors, 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.",
|
|
4907
|
+
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.",
|
|
3796
4908
|
operations: [],
|
|
3797
|
-
input:
|
|
3798
|
-
query:
|
|
3799
|
-
limit:
|
|
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)
|
|
3800
4912
|
}),
|
|
3801
4913
|
async run(args, rt) {
|
|
3802
4914
|
const q = words(String(args["query"]));
|
|
@@ -3824,7 +4936,7 @@ var MCP_TOOL_DEFS = [
|
|
|
3824
4936
|
title: "Describe a configuration change",
|
|
3825
4937
|
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.",
|
|
3826
4938
|
operations: [],
|
|
3827
|
-
input:
|
|
4939
|
+
input: z28.object({ operation_id: operationIdArg }),
|
|
3828
4940
|
async run(args, rt) {
|
|
3829
4941
|
const op = configureOp(args["operation_id"]);
|
|
3830
4942
|
if (!op || op.method === "GET")
|
|
@@ -3853,7 +4965,7 @@ var MCP_TOOL_DEFS = [
|
|
|
3853
4965
|
title: "Check a change before applying it",
|
|
3854
4966
|
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.",
|
|
3855
4967
|
operations: [],
|
|
3856
|
-
input:
|
|
4968
|
+
input: z28.object({ operation_id: operationIdArg, params }),
|
|
3857
4969
|
async run(args, rt) {
|
|
3858
4970
|
const op = configureOp(args["operation_id"]);
|
|
3859
4971
|
if (!op || op.method === "GET")
|
|
@@ -3902,11 +5014,11 @@ var MCP_TOOL_DEFS = [
|
|
|
3902
5014
|
title: "Apply a configuration change",
|
|
3903
5015
|
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.",
|
|
3904
5016
|
operations: [],
|
|
3905
|
-
input:
|
|
5017
|
+
input: z28.object({
|
|
3906
5018
|
operation_id: operationIdArg,
|
|
3907
5019
|
params,
|
|
3908
|
-
idempotency_key:
|
|
3909
|
-
if_match:
|
|
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.")
|
|
3910
5022
|
}),
|
|
3911
5023
|
async run(args, rt) {
|
|
3912
5024
|
const op = configureOp(args["operation_id"]);
|
|
@@ -3957,7 +5069,7 @@ var MCP_TOOL_DEFS = [
|
|
|
3957
5069
|
title: "Follow an approval",
|
|
3958
5070
|
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).",
|
|
3959
5071
|
operations: ["approvals.get"],
|
|
3960
|
-
input:
|
|
5072
|
+
input: z28.object({ approval_id: z28.guid().describe("approval_id from apply_change.") }),
|
|
3961
5073
|
async run(args, rt) {
|
|
3962
5074
|
const r = await rt.call("approvals.get", { approval_id: args["approval_id"] });
|
|
3963
5075
|
if (!r.ok)
|
|
@@ -3977,10 +5089,10 @@ var MCP_TOOL_DEFS = [
|
|
|
3977
5089
|
title: "Search Belvador docs",
|
|
3978
5090
|
description: "Searches the public Belvador documentation (titles and summaries) and returns the best pages with their slugs for get_doc.",
|
|
3979
5091
|
operations: [],
|
|
3980
|
-
input:
|
|
3981
|
-
query:
|
|
3982
|
-
locale:
|
|
3983
|
-
limit:
|
|
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)
|
|
3984
5096
|
}),
|
|
3985
5097
|
async run(args, rt) {
|
|
3986
5098
|
const locale = args["locale"] ?? "en";
|
|
@@ -3996,9 +5108,9 @@ var MCP_TOOL_DEFS = [
|
|
|
3996
5108
|
title: "Read a docs page",
|
|
3997
5109
|
description: "The Markdown of one public Belvador docs page by slug (e.g. `quickstart`, `sdk/react`, `reference/api`).",
|
|
3998
5110
|
operations: [],
|
|
3999
|
-
input:
|
|
4000
|
-
slug:
|
|
4001
|
-
locale:
|
|
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")
|
|
4002
5114
|
}),
|
|
4003
5115
|
async run(args, rt) {
|
|
4004
5116
|
const locale = args["locale"] ?? "en";
|
|
@@ -4180,7 +5292,7 @@ function findToken(env = process.env, keychain = keychainToken) {
|
|
|
4180
5292
|
}
|
|
4181
5293
|
|
|
4182
5294
|
// packages/mcp/src/cli.ts
|
|
4183
|
-
var PACKAGE_VERSION = "0.
|
|
5295
|
+
var PACKAGE_VERSION = "0.4.0";
|
|
4184
5296
|
var HELP = `belvador-mcp ${PACKAGE_VERSION} — Belvador MCP server (stdio)
|
|
4185
5297
|
|
|
4186
5298
|
Usage: npx -y @belvador/mcp [--toolsets=${MCP_DEFAULT_TOOLSETS.join(",")}]
|