@debugbundle/mcp 0.1.7 → 0.1.9
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/README.md +2 -0
- package/dist/main.cjs +2382 -155
- package/package.json +3 -3
package/dist/main.cjs
CHANGED
|
@@ -14776,8 +14776,9 @@ var GitHubDispatchDeliverySchema = external_exports.object({
|
|
|
14776
14776
|
delivery_id: external_exports.string(),
|
|
14777
14777
|
rule_id: external_exports.string(),
|
|
14778
14778
|
rule_name: external_exports.string(),
|
|
14779
|
-
incident_id: external_exports.string(),
|
|
14780
|
-
|
|
14779
|
+
incident_id: external_exports.string().nullable(),
|
|
14780
|
+
improvement_id: external_exports.string().nullable(),
|
|
14781
|
+
target_title: external_exports.string(),
|
|
14781
14782
|
status: external_exports.enum(["pending", "retrying", "delivered", "failed", "skipped"]),
|
|
14782
14783
|
attempt_count: external_exports.number().int(),
|
|
14783
14784
|
last_attempt_at: external_exports.string().nullable(),
|
|
@@ -15259,6 +15260,7 @@ var ImprovementSchema = external_exports.object({
|
|
|
15259
15260
|
summary: external_exports.string(),
|
|
15260
15261
|
occurrence_count: external_exports.number().int(),
|
|
15261
15262
|
evidence: external_exports.record(external_exports.unknown()),
|
|
15263
|
+
related_incident_ids: external_exports.array(external_exports.string()),
|
|
15262
15264
|
first_detected_at: external_exports.string(),
|
|
15263
15265
|
last_detected_at: external_exports.string(),
|
|
15264
15266
|
resolved_at: external_exports.string().nullable(),
|
|
@@ -15791,6 +15793,7 @@ var ProjectTokenSchema = external_exports.object({
|
|
|
15791
15793
|
token_id: external_exports.string(),
|
|
15792
15794
|
project_id: external_exports.string(),
|
|
15793
15795
|
label: external_exports.string(),
|
|
15796
|
+
allowed_origins: external_exports.array(external_exports.string()).default([]),
|
|
15794
15797
|
created_at: external_exports.string(),
|
|
15795
15798
|
last_used_at: external_exports.string().nullable(),
|
|
15796
15799
|
revoked_at: external_exports.string().nullable(),
|
|
@@ -15875,7 +15878,8 @@ function createTokenManagementApi(client) {
|
|
|
15875
15878
|
path: `/v1/projects/${input.projectId}/tokens`,
|
|
15876
15879
|
bearerToken: input.bearerToken,
|
|
15877
15880
|
body: {
|
|
15878
|
-
label: input.label
|
|
15881
|
+
label: input.label,
|
|
15882
|
+
...input.allowedOrigins === void 0 ? {} : { allowed_origins: input.allowedOrigins }
|
|
15879
15883
|
}
|
|
15880
15884
|
})
|
|
15881
15885
|
);
|
|
@@ -16548,6 +16552,406 @@ function getRequestAnomalyThreshold(input) {
|
|
|
16548
16552
|
return null;
|
|
16549
16553
|
}
|
|
16550
16554
|
|
|
16555
|
+
// ../../packages/shared-types/src/capture-rules.ts
|
|
16556
|
+
var CAPTURE_RULE_EVENT_TYPES = [
|
|
16557
|
+
"backend_exception",
|
|
16558
|
+
"request_event",
|
|
16559
|
+
"log_event",
|
|
16560
|
+
"frontend_breadcrumb",
|
|
16561
|
+
"frontend_exception",
|
|
16562
|
+
"deploy_metadata",
|
|
16563
|
+
"error_suppressed",
|
|
16564
|
+
"probe_event"
|
|
16565
|
+
];
|
|
16566
|
+
var CAPTURE_RULE_RUNTIME_VALUES = [
|
|
16567
|
+
"browser",
|
|
16568
|
+
"node",
|
|
16569
|
+
"python",
|
|
16570
|
+
"php",
|
|
16571
|
+
"java",
|
|
16572
|
+
"go",
|
|
16573
|
+
"ruby",
|
|
16574
|
+
"unknown"
|
|
16575
|
+
];
|
|
16576
|
+
var CaptureRuleActionValues = ["demote", "sample", "drop"];
|
|
16577
|
+
var CaptureRuleActionSchema = external_exports.enum(CaptureRuleActionValues);
|
|
16578
|
+
var CaptureRuleSampleEventClassValues = ["preserve", "context"];
|
|
16579
|
+
var CaptureRuleSampleEventClassSchema = external_exports.enum(CaptureRuleSampleEventClassValues);
|
|
16580
|
+
var CaptureRuleRuntimeSchema = external_exports.enum(CAPTURE_RULE_RUNTIME_VALUES);
|
|
16581
|
+
var CaptureRuleEventTypeSchema = external_exports.enum(CAPTURE_RULE_EVENT_TYPES);
|
|
16582
|
+
var BrowserEventKindSchema = external_exports.enum(["window_error", "resource_error"]);
|
|
16583
|
+
function normalizeOptionalTrimmedString(value) {
|
|
16584
|
+
const trimmed = value?.trim();
|
|
16585
|
+
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
16586
|
+
}
|
|
16587
|
+
function normalizeOptionalLowercaseHost(value) {
|
|
16588
|
+
const trimmed = normalizeOptionalTrimmedString(value);
|
|
16589
|
+
return trimmed?.toLowerCase();
|
|
16590
|
+
}
|
|
16591
|
+
function normalizeOptionalPath(value) {
|
|
16592
|
+
const trimmed = normalizeOptionalTrimmedString(value);
|
|
16593
|
+
if (trimmed === void 0) {
|
|
16594
|
+
return void 0;
|
|
16595
|
+
}
|
|
16596
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
16597
|
+
}
|
|
16598
|
+
function hasValue(value) {
|
|
16599
|
+
return value !== void 0 && value !== null;
|
|
16600
|
+
}
|
|
16601
|
+
var UrlMatcherSchema = external_exports.object({
|
|
16602
|
+
host: external_exports.string().min(1).max(255).optional(),
|
|
16603
|
+
host_suffix: external_exports.string().min(1).max(255).optional(),
|
|
16604
|
+
path_prefix: external_exports.string().min(1).max(1024).optional(),
|
|
16605
|
+
path_equals: external_exports.string().min(1).max(1024).optional()
|
|
16606
|
+
}).transform((value) => {
|
|
16607
|
+
const normalized = {};
|
|
16608
|
+
const host = normalizeOptionalLowercaseHost(value.host);
|
|
16609
|
+
const hostSuffix = normalizeOptionalLowercaseHost(value.host_suffix);
|
|
16610
|
+
const pathPrefix = normalizeOptionalPath(value.path_prefix);
|
|
16611
|
+
const pathEquals = normalizeOptionalPath(value.path_equals);
|
|
16612
|
+
if (host !== void 0) {
|
|
16613
|
+
normalized.host = host;
|
|
16614
|
+
}
|
|
16615
|
+
if (hostSuffix !== void 0) {
|
|
16616
|
+
normalized.host_suffix = hostSuffix;
|
|
16617
|
+
}
|
|
16618
|
+
if (pathPrefix !== void 0) {
|
|
16619
|
+
normalized.path_prefix = pathPrefix;
|
|
16620
|
+
}
|
|
16621
|
+
if (pathEquals !== void 0) {
|
|
16622
|
+
normalized.path_equals = pathEquals;
|
|
16623
|
+
}
|
|
16624
|
+
return normalized;
|
|
16625
|
+
}).refine((value) => hasValue(value.host) || hasValue(value.host_suffix) || hasValue(value.path_prefix) || hasValue(value.path_equals), {
|
|
16626
|
+
message: "URL matchers must include at least one host or path constraint."
|
|
16627
|
+
});
|
|
16628
|
+
var StatusRangeSchema = external_exports.object({
|
|
16629
|
+
start: external_exports.number().int().min(100).max(599),
|
|
16630
|
+
end: external_exports.number().int().min(100).max(599)
|
|
16631
|
+
}).refine((value) => value.start <= value.end, {
|
|
16632
|
+
message: "Status range start must be less than or equal to end."
|
|
16633
|
+
});
|
|
16634
|
+
var CaptureRuleFingerprintSchema = external_exports.object({
|
|
16635
|
+
version: external_exports.string().min(1).max(32),
|
|
16636
|
+
value: external_exports.string().min(1).max(256)
|
|
16637
|
+
});
|
|
16638
|
+
function normalizeStringArray(values) {
|
|
16639
|
+
if (values === void 0) {
|
|
16640
|
+
return void 0;
|
|
16641
|
+
}
|
|
16642
|
+
return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
|
|
16643
|
+
}
|
|
16644
|
+
function normalizeNumberArray(values) {
|
|
16645
|
+
if (values === void 0) {
|
|
16646
|
+
return void 0;
|
|
16647
|
+
}
|
|
16648
|
+
return Array.from(new Set(values)).sort((left, right) => left - right);
|
|
16649
|
+
}
|
|
16650
|
+
var CaptureRuleMatcherSchema = external_exports.object({
|
|
16651
|
+
event_types: external_exports.array(CaptureRuleEventTypeSchema).min(1).optional(),
|
|
16652
|
+
services: external_exports.array(external_exports.string().min(1).max(120)).min(1).optional(),
|
|
16653
|
+
environments: external_exports.array(external_exports.string().min(1).max(120)).min(1).optional(),
|
|
16654
|
+
runtime: external_exports.array(CaptureRuleRuntimeSchema).min(1).optional(),
|
|
16655
|
+
first_party: external_exports.boolean().optional(),
|
|
16656
|
+
error_name: external_exports.string().min(1).max(120).optional(),
|
|
16657
|
+
message_contains: external_exports.string().min(1).max(500).optional(),
|
|
16658
|
+
message_equals: external_exports.string().min(1).max(500).optional(),
|
|
16659
|
+
browser_event_kind: BrowserEventKindSchema.optional(),
|
|
16660
|
+
resource_url: UrlMatcherSchema.optional(),
|
|
16661
|
+
request_url: UrlMatcherSchema.optional(),
|
|
16662
|
+
status_codes: external_exports.array(external_exports.number().int().min(100).max(599)).min(1).optional(),
|
|
16663
|
+
status_ranges: external_exports.array(StatusRangeSchema).min(1).optional(),
|
|
16664
|
+
fingerprint: CaptureRuleFingerprintSchema.optional()
|
|
16665
|
+
}).transform((value) => {
|
|
16666
|
+
const normalized = {};
|
|
16667
|
+
const eventTypes = normalizeStringArray(value.event_types);
|
|
16668
|
+
const services = normalizeStringArray(value.services);
|
|
16669
|
+
const environments = normalizeStringArray(value.environments);
|
|
16670
|
+
const runtime = normalizeStringArray(value.runtime);
|
|
16671
|
+
const errorName = normalizeOptionalTrimmedString(value.error_name);
|
|
16672
|
+
const messageContains = normalizeOptionalTrimmedString(value.message_contains);
|
|
16673
|
+
const messageEquals = normalizeOptionalTrimmedString(value.message_equals);
|
|
16674
|
+
const statusCodes = normalizeNumberArray(value.status_codes);
|
|
16675
|
+
if (eventTypes !== void 0) {
|
|
16676
|
+
normalized.event_types = eventTypes;
|
|
16677
|
+
}
|
|
16678
|
+
if (services !== void 0) {
|
|
16679
|
+
normalized.services = services;
|
|
16680
|
+
}
|
|
16681
|
+
if (environments !== void 0) {
|
|
16682
|
+
normalized.environments = environments;
|
|
16683
|
+
}
|
|
16684
|
+
if (runtime !== void 0) {
|
|
16685
|
+
normalized.runtime = runtime;
|
|
16686
|
+
}
|
|
16687
|
+
if (value.first_party !== void 0) {
|
|
16688
|
+
normalized.first_party = value.first_party;
|
|
16689
|
+
}
|
|
16690
|
+
if (errorName !== void 0) {
|
|
16691
|
+
normalized.error_name = errorName;
|
|
16692
|
+
}
|
|
16693
|
+
if (messageContains !== void 0) {
|
|
16694
|
+
normalized.message_contains = messageContains;
|
|
16695
|
+
}
|
|
16696
|
+
if (messageEquals !== void 0) {
|
|
16697
|
+
normalized.message_equals = messageEquals;
|
|
16698
|
+
}
|
|
16699
|
+
if (value.browser_event_kind !== void 0) {
|
|
16700
|
+
normalized.browser_event_kind = value.browser_event_kind;
|
|
16701
|
+
}
|
|
16702
|
+
if (value.resource_url !== void 0) {
|
|
16703
|
+
normalized.resource_url = value.resource_url;
|
|
16704
|
+
}
|
|
16705
|
+
if (value.request_url !== void 0) {
|
|
16706
|
+
normalized.request_url = value.request_url;
|
|
16707
|
+
}
|
|
16708
|
+
if (statusCodes !== void 0) {
|
|
16709
|
+
normalized.status_codes = statusCodes;
|
|
16710
|
+
}
|
|
16711
|
+
if (value.status_ranges !== void 0) {
|
|
16712
|
+
normalized.status_ranges = value.status_ranges;
|
|
16713
|
+
}
|
|
16714
|
+
if (value.fingerprint !== void 0) {
|
|
16715
|
+
normalized.fingerprint = value.fingerprint;
|
|
16716
|
+
}
|
|
16717
|
+
return normalized;
|
|
16718
|
+
}).superRefine((value, context) => {
|
|
16719
|
+
const narrowingKeys = [
|
|
16720
|
+
"services",
|
|
16721
|
+
"environments",
|
|
16722
|
+
"runtime",
|
|
16723
|
+
"first_party",
|
|
16724
|
+
"error_name",
|
|
16725
|
+
"message_contains",
|
|
16726
|
+
"message_equals",
|
|
16727
|
+
"browser_event_kind",
|
|
16728
|
+
"resource_url",
|
|
16729
|
+
"request_url",
|
|
16730
|
+
"status_codes",
|
|
16731
|
+
"status_ranges",
|
|
16732
|
+
"fingerprint"
|
|
16733
|
+
];
|
|
16734
|
+
if (!narrowingKeys.some((key) => hasValue(value[key]))) {
|
|
16735
|
+
context.addIssue({
|
|
16736
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16737
|
+
message: "Capture rules must include at least one narrowing field beyond event_types."
|
|
16738
|
+
});
|
|
16739
|
+
}
|
|
16740
|
+
if (value.browser_event_kind === "resource_error") {
|
|
16741
|
+
const hasResourceConstraint = hasValue(value.resource_url) || hasValue(value.fingerprint);
|
|
16742
|
+
if (!hasResourceConstraint) {
|
|
16743
|
+
context.addIssue({
|
|
16744
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16745
|
+
message: "Resource-error rules require a resource URL constraint or an exact fingerprint."
|
|
16746
|
+
});
|
|
16747
|
+
}
|
|
16748
|
+
}
|
|
16749
|
+
});
|
|
16750
|
+
var CaptureRuleCoreObjectSchema = external_exports.object({
|
|
16751
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
16752
|
+
description: external_exports.string().trim().max(500).nullable(),
|
|
16753
|
+
enabled: external_exports.boolean(),
|
|
16754
|
+
action: CaptureRuleActionSchema,
|
|
16755
|
+
matcher: CaptureRuleMatcherSchema,
|
|
16756
|
+
sample_rate: external_exports.number().min(0).max(1).nullable(),
|
|
16757
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable(),
|
|
16758
|
+
created_by_user_id: external_exports.string().min(1).max(120).nullable(),
|
|
16759
|
+
created_from_incident_id: external_exports.string().min(1).max(120).nullable(),
|
|
16760
|
+
created_from_event_id: external_exports.string().min(1).max(120).nullable(),
|
|
16761
|
+
expires_at: external_exports.string().datetime().nullable()
|
|
16762
|
+
});
|
|
16763
|
+
function addCaptureRuleActionValidation(schema) {
|
|
16764
|
+
return schema.superRefine((value, context) => {
|
|
16765
|
+
if (value["action"] === "sample") {
|
|
16766
|
+
if (value["sample_rate"] === null) {
|
|
16767
|
+
context.addIssue({
|
|
16768
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16769
|
+
path: ["sample_rate"],
|
|
16770
|
+
message: "Sample rules require sample_rate."
|
|
16771
|
+
});
|
|
16772
|
+
}
|
|
16773
|
+
if (value["sample_event_class"] === null) {
|
|
16774
|
+
context.addIssue({
|
|
16775
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16776
|
+
path: ["sample_event_class"],
|
|
16777
|
+
message: "Sample rules require sample_event_class."
|
|
16778
|
+
});
|
|
16779
|
+
}
|
|
16780
|
+
return;
|
|
16781
|
+
}
|
|
16782
|
+
if (value["sample_rate"] !== null) {
|
|
16783
|
+
context.addIssue({
|
|
16784
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16785
|
+
path: ["sample_rate"],
|
|
16786
|
+
message: "Only sample rules can set sample_rate."
|
|
16787
|
+
});
|
|
16788
|
+
}
|
|
16789
|
+
if (value["sample_event_class"] !== null) {
|
|
16790
|
+
context.addIssue({
|
|
16791
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16792
|
+
path: ["sample_event_class"],
|
|
16793
|
+
message: "Only sample rules can set sample_event_class."
|
|
16794
|
+
});
|
|
16795
|
+
}
|
|
16796
|
+
});
|
|
16797
|
+
}
|
|
16798
|
+
var CaptureRuleSchema = addCaptureRuleActionValidation(
|
|
16799
|
+
CaptureRuleCoreObjectSchema.extend({
|
|
16800
|
+
id: external_exports.string().uuid(),
|
|
16801
|
+
project_id: external_exports.string().min(1).max(120),
|
|
16802
|
+
hit_count: external_exports.number().int().nonnegative(),
|
|
16803
|
+
last_matched_at: external_exports.string().datetime().nullable(),
|
|
16804
|
+
created_at: external_exports.string().datetime(),
|
|
16805
|
+
updated_at: external_exports.string().datetime()
|
|
16806
|
+
})
|
|
16807
|
+
);
|
|
16808
|
+
var CaptureRuleCreateSchema = external_exports.object({
|
|
16809
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
16810
|
+
description: external_exports.string().trim().max(500).nullable().default(null),
|
|
16811
|
+
enabled: external_exports.boolean().default(true),
|
|
16812
|
+
action: CaptureRuleActionSchema,
|
|
16813
|
+
matcher: CaptureRuleMatcherSchema,
|
|
16814
|
+
sample_rate: external_exports.number().min(0).max(1).nullable().optional(),
|
|
16815
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable().optional(),
|
|
16816
|
+
created_by_user_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16817
|
+
created_from_incident_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16818
|
+
created_from_event_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16819
|
+
expires_at: external_exports.string().datetime().nullable().default(null)
|
|
16820
|
+
}).superRefine((value, context) => {
|
|
16821
|
+
if (value.action === "sample") {
|
|
16822
|
+
if (value.sample_rate === void 0 || value.sample_rate === null) {
|
|
16823
|
+
context.addIssue({
|
|
16824
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16825
|
+
path: ["sample_rate"],
|
|
16826
|
+
message: "Sample rules require sample_rate."
|
|
16827
|
+
});
|
|
16828
|
+
}
|
|
16829
|
+
return;
|
|
16830
|
+
}
|
|
16831
|
+
if (value.sample_rate !== void 0 && value.sample_rate !== null) {
|
|
16832
|
+
context.addIssue({
|
|
16833
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16834
|
+
path: ["sample_rate"],
|
|
16835
|
+
message: "Only sample rules can set sample_rate."
|
|
16836
|
+
});
|
|
16837
|
+
}
|
|
16838
|
+
if (value.sample_event_class !== void 0 && value.sample_event_class !== null) {
|
|
16839
|
+
context.addIssue({
|
|
16840
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16841
|
+
path: ["sample_event_class"],
|
|
16842
|
+
message: "Only sample rules can set sample_event_class."
|
|
16843
|
+
});
|
|
16844
|
+
}
|
|
16845
|
+
}).transform((value) => ({
|
|
16846
|
+
...value,
|
|
16847
|
+
sample_rate: value.action === "sample" ? value.sample_rate : null,
|
|
16848
|
+
sample_event_class: value.action === "sample" ? value.sample_event_class ?? "preserve" : null
|
|
16849
|
+
}));
|
|
16850
|
+
var CaptureRuleUpdateSchema = external_exports.object({
|
|
16851
|
+
name: external_exports.string().trim().min(1).max(120).optional(),
|
|
16852
|
+
description: external_exports.string().trim().max(500).nullable().optional(),
|
|
16853
|
+
enabled: external_exports.boolean().optional(),
|
|
16854
|
+
action: CaptureRuleActionSchema.optional(),
|
|
16855
|
+
matcher: CaptureRuleMatcherSchema.optional(),
|
|
16856
|
+
sample_rate: external_exports.number().min(0).max(1).nullable().optional(),
|
|
16857
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable().optional(),
|
|
16858
|
+
expires_at: external_exports.string().datetime().nullable().optional()
|
|
16859
|
+
}).superRefine((value, context) => {
|
|
16860
|
+
if (Object.keys(value).length === 0) {
|
|
16861
|
+
context.addIssue({
|
|
16862
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16863
|
+
message: "At least one capture rule field must be provided."
|
|
16864
|
+
});
|
|
16865
|
+
}
|
|
16866
|
+
const resolvedAction = value.action;
|
|
16867
|
+
if (resolvedAction === "sample") {
|
|
16868
|
+
if (!("sample_rate" in value)) {
|
|
16869
|
+
context.addIssue({
|
|
16870
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16871
|
+
path: ["sample_rate"],
|
|
16872
|
+
message: "Sample rule updates must include sample_rate when changing action to sample."
|
|
16873
|
+
});
|
|
16874
|
+
}
|
|
16875
|
+
if (!("sample_event_class" in value)) {
|
|
16876
|
+
context.addIssue({
|
|
16877
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16878
|
+
path: ["sample_event_class"],
|
|
16879
|
+
message: "Sample rule updates must include sample_event_class when changing action to sample."
|
|
16880
|
+
});
|
|
16881
|
+
}
|
|
16882
|
+
return;
|
|
16883
|
+
}
|
|
16884
|
+
if ("sample_rate" in value) {
|
|
16885
|
+
context.addIssue({
|
|
16886
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16887
|
+
path: ["sample_rate"],
|
|
16888
|
+
message: "Sample rule fields can only be updated while setting action to sample."
|
|
16889
|
+
});
|
|
16890
|
+
}
|
|
16891
|
+
if ("sample_event_class" in value) {
|
|
16892
|
+
context.addIssue({
|
|
16893
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16894
|
+
path: ["sample_event_class"],
|
|
16895
|
+
message: "Sample rule fields can only be updated while setting action to sample."
|
|
16896
|
+
});
|
|
16897
|
+
}
|
|
16898
|
+
});
|
|
16899
|
+
var CaptureRuleResponseSchema = external_exports.object({
|
|
16900
|
+
rule: CaptureRuleSchema
|
|
16901
|
+
});
|
|
16902
|
+
var CaptureRulesResponseSchema = external_exports.object({
|
|
16903
|
+
access_mode: external_exports.enum(["manage", "preview"]),
|
|
16904
|
+
rules: external_exports.array(CaptureRuleSchema)
|
|
16905
|
+
});
|
|
16906
|
+
var CaptureRulesFileSchema = external_exports.object({
|
|
16907
|
+
version: external_exports.literal(1),
|
|
16908
|
+
rules: external_exports.array(CaptureRuleSchema)
|
|
16909
|
+
});
|
|
16910
|
+
var CaptureRuleEvaluationUrlSchema = external_exports.object({
|
|
16911
|
+
host: external_exports.string().min(1).transform((value) => value.toLowerCase()).optional(),
|
|
16912
|
+
path: external_exports.string().min(1).transform((value) => value.startsWith("/") ? value : `/${value}`)
|
|
16913
|
+
});
|
|
16914
|
+
var CaptureRuleEvaluationContextSchema = external_exports.object({
|
|
16915
|
+
project_id: external_exports.string().min(1).max(120),
|
|
16916
|
+
event_id: external_exports.string().uuid(),
|
|
16917
|
+
event_type: CaptureRuleEventTypeSchema,
|
|
16918
|
+
service: external_exports.string().min(1).optional(),
|
|
16919
|
+
environment: external_exports.string().min(1).optional(),
|
|
16920
|
+
runtime: CaptureRuleRuntimeSchema,
|
|
16921
|
+
first_party: external_exports.boolean().optional(),
|
|
16922
|
+
error_name: external_exports.string().min(1).optional(),
|
|
16923
|
+
message: external_exports.string().min(1).optional(),
|
|
16924
|
+
browser_event_kind: BrowserEventKindSchema.optional(),
|
|
16925
|
+
resource_url: CaptureRuleEvaluationUrlSchema.optional(),
|
|
16926
|
+
request_url: CaptureRuleEvaluationUrlSchema.optional(),
|
|
16927
|
+
status_code: external_exports.number().int().min(0).max(599).optional(),
|
|
16928
|
+
fingerprint: CaptureRuleFingerprintSchema.optional()
|
|
16929
|
+
});
|
|
16930
|
+
|
|
16931
|
+
// ../../packages/shared-types/src/capture-rule-suggestions.ts
|
|
16932
|
+
var CaptureRuleSuggestionConfidenceSchema = external_exports.enum(["high", "medium", "low"]);
|
|
16933
|
+
var CaptureRuleSuggestionSchema = external_exports.object({
|
|
16934
|
+
suggestion_id: external_exports.string().min(1).max(120),
|
|
16935
|
+
label: external_exports.string().min(1).max(200),
|
|
16936
|
+
recommended_action: CaptureRuleActionSchema,
|
|
16937
|
+
confidence: CaptureRuleSuggestionConfidenceSchema,
|
|
16938
|
+
reason: external_exports.string().min(1).max(500),
|
|
16939
|
+
requires_confirmation: external_exports.boolean(),
|
|
16940
|
+
rule: CaptureRuleCreateSchema
|
|
16941
|
+
});
|
|
16942
|
+
var CaptureRuleSuggestionsResponseSchema = external_exports.object({
|
|
16943
|
+
suggestions: external_exports.array(CaptureRuleSuggestionSchema),
|
|
16944
|
+
bundle_status: external_exports.enum(["ready", "pending", "failed"]).optional(),
|
|
16945
|
+
bundle_reason: external_exports.string().nullable().optional()
|
|
16946
|
+
});
|
|
16947
|
+
var CreateCaptureRuleFromSuggestionSchema = external_exports.object({
|
|
16948
|
+
suggestion_id: external_exports.string().min(1).max(120),
|
|
16949
|
+
name: external_exports.string().trim().min(1).max(120).optional(),
|
|
16950
|
+
description: external_exports.string().trim().max(500).nullable().optional(),
|
|
16951
|
+
enabled: external_exports.boolean().optional(),
|
|
16952
|
+
expires_at: external_exports.string().datetime().nullable().optional()
|
|
16953
|
+
});
|
|
16954
|
+
|
|
16551
16955
|
// ../../packages/shared-types/src/improvement-settings.ts
|
|
16552
16956
|
var ImprovementBundleSensitivityValues = [
|
|
16553
16957
|
"high_confidence",
|
|
@@ -16704,6 +17108,18 @@ var DeviceInfoSchema = external_exports.object({
|
|
|
16704
17108
|
connection_type: external_exports.string().nullable(),
|
|
16705
17109
|
color_scheme_preference: external_exports.enum(["light", "dark", "no-preference"]).nullable()
|
|
16706
17110
|
}).strict();
|
|
17111
|
+
var BrowserExceptionEventSchema = external_exports.object({
|
|
17112
|
+
kind: external_exports.enum(["window_error", "resource_error"]),
|
|
17113
|
+
message: external_exports.string().nullable(),
|
|
17114
|
+
file_name: external_exports.string().nullable(),
|
|
17115
|
+
line_number: external_exports.number().int().nonnegative().nullable(),
|
|
17116
|
+
column_number: external_exports.number().int().nonnegative().nullable(),
|
|
17117
|
+
target: external_exports.object({
|
|
17118
|
+
tag_name: external_exports.string().nullable(),
|
|
17119
|
+
source_url: external_exports.string().nullable()
|
|
17120
|
+
}).nullable(),
|
|
17121
|
+
opaque: external_exports.boolean()
|
|
17122
|
+
}).strict();
|
|
16707
17123
|
var FrontendExceptionPayloadSchema = external_exports.object({
|
|
16708
17124
|
name: external_exports.string().min(1),
|
|
16709
17125
|
message: external_exports.string().min(1),
|
|
@@ -16715,6 +17131,7 @@ var FrontendExceptionPayloadSchema = external_exports.object({
|
|
|
16715
17131
|
}),
|
|
16716
17132
|
breadcrumbs: external_exports.array(FrontendExceptionBreadcrumbSchema).optional(),
|
|
16717
17133
|
device: DeviceInfoSchema.nullable().optional(),
|
|
17134
|
+
browser_event: BrowserExceptionEventSchema.optional(),
|
|
16718
17135
|
dom_context: external_exports.object({
|
|
16719
17136
|
mode: external_exports.literal("lightweight"),
|
|
16720
17137
|
html_excerpt: external_exports.string().min(1)
|
|
@@ -17123,6 +17540,25 @@ function buildSkill() {
|
|
|
17123
17540
|
"",
|
|
17124
17541
|
"Use DebugBundle before starting a fresh bug investigation.",
|
|
17125
17542
|
"",
|
|
17543
|
+
"## Investigation Quickstart",
|
|
17544
|
+
"",
|
|
17545
|
+
"When the user reports a bug, runtime failure, production incident, regression, broken deploy, or unknown error, start here before reading arbitrary source files.",
|
|
17546
|
+
"",
|
|
17547
|
+
"1. Run `debugbundle doctor --json` to learn whether the project is local-only or connected and whether the local scaffold is healthy.",
|
|
17548
|
+
"2. List actionable failures with `debugbundle incidents --source local --status open --json` for local data, or `debugbundle incidents --source cloud --status open --json` when the issue came from a hosted environment.",
|
|
17549
|
+
"3. Inspect the chosen incident with `debugbundle inspect <incident-id> --source <local|cloud> --json` and `debugbundle explain <incident-id> --source <local|cloud> --json`.",
|
|
17550
|
+
"4. Fetch evidence before editing code: `debugbundle bundle <incident-id> --source <local|cloud> --json` and `debugbundle reproduce <incident-id> --source <local|cloud> --json`.",
|
|
17551
|
+
"5. If local SDK or relay events have landed but no bundle exists yet, run `debugbundle process --preset <minimal|balanced|investigative> --json` and then list incidents again.",
|
|
17552
|
+
"",
|
|
17553
|
+
"Key local paths:",
|
|
17554
|
+
"- `.debugbundle/profile.json` \u2014 project map, service paths, and validation state",
|
|
17555
|
+
"- `.debugbundle/local/connection.json` \u2014 local-only vs connected mode and environment delivery policy",
|
|
17556
|
+
"- `.debugbundle/local/events/` \u2014 raw local SDK, relay, ingest, and watch event batches",
|
|
17557
|
+
"- `.debugbundle/local/state.json` \u2014 local incident index, lifecycle state, and bundle paths",
|
|
17558
|
+
"- `.debugbundle/bundles/local/` \u2014 locally generated bundle artifacts",
|
|
17559
|
+
"- `.debugbundle/bundles/local/reproductions/` \u2014 local reproduction artifacts",
|
|
17560
|
+
"- `.debugbundle/bundles/cloud/` \u2014 explicitly fetched cloud artifact cache",
|
|
17561
|
+
"",
|
|
17126
17562
|
"## Core Workflow",
|
|
17127
17563
|
"",
|
|
17128
17564
|
"1. Check DebugBundle incidents first to avoid re-investigating a known failure.",
|
|
@@ -17152,6 +17588,18 @@ function buildSkill() {
|
|
|
17152
17588
|
"- Run `debugbundle validate --fix` to restore missing generated setup files without overwriting the profile.",
|
|
17153
17589
|
"- Run `debugbundle process` after local events land in `.debugbundle/local/events/`.",
|
|
17154
17590
|
"",
|
|
17591
|
+
"## Browser Capture and Relay Setup",
|
|
17592
|
+
"",
|
|
17593
|
+
"When the repository has a browser frontend, verify capture end to end instead of stopping at backend SDK setup.",
|
|
17594
|
+
"",
|
|
17595
|
+
"1. Add `@debugbundle/sdk-browser` to each browser app that should capture console, error, navigation, or request context.",
|
|
17596
|
+
"2. Initialize the browser SDK from the app entrypoint with the active environment and a browser relay endpoint.",
|
|
17597
|
+
"3. Add a backend relay endpoint at `/debugbundle/browser` using the server SDK relay helper when available.",
|
|
17598
|
+
"4. For same-origin apps, keep the browser endpoint as `/debugbundle/browser`.",
|
|
17599
|
+
"5. For split frontend/backend hosts, configure the browser endpoint to the API host relay URL and require explicit frontend origin allowlisting on the backend.",
|
|
17600
|
+
"6. Ensure auth and CSRF middleware allow the relay path while the relay still enforces origin, content type, body size, schema validation, and rate limits.",
|
|
17601
|
+
"7. Trigger a local browser smoke event, then run `debugbundle process --json` and confirm the incident or context event appears before marking setup complete.",
|
|
17602
|
+
"",
|
|
17155
17603
|
"## References",
|
|
17156
17604
|
"",
|
|
17157
17605
|
"- CLI reference: `references/cli.md`",
|
|
@@ -17173,23 +17621,35 @@ function buildCliReference() {
|
|
|
17173
17621
|
"## Setup",
|
|
17174
17622
|
"",
|
|
17175
17623
|
"- `debugbundle setup [--non-interactive] [--json]`",
|
|
17176
|
-
"- `debugbundle doctor [--json]`",
|
|
17624
|
+
"- `debugbundle doctor [--check-relay] [--json]`",
|
|
17177
17625
|
"- `debugbundle validate [--fix] [--json]`",
|
|
17178
17626
|
"- `debugbundle ingest <file> --format <format> [--json]`",
|
|
17179
17627
|
"- `debugbundle watch --log <file> --format <format> [--json]`",
|
|
17180
17628
|
"- `debugbundle watch --cloud --log <file> --format <format> [--json]`",
|
|
17181
17629
|
"- `debugbundle process [--preset <minimal|balanced|investigative>] [--json]`",
|
|
17630
|
+
"- `debugbundle clean [--events] [--bundles] [--all] [--older-than <Nd>] [--json]`",
|
|
17182
17631
|
"",
|
|
17183
17632
|
"## Investigation",
|
|
17184
17633
|
"",
|
|
17185
|
-
"- `debugbundle incidents`",
|
|
17186
|
-
"- `debugbundle inspect <incident-id
|
|
17187
|
-
"- `debugbundle
|
|
17188
|
-
"- `debugbundle
|
|
17189
|
-
"- `debugbundle
|
|
17190
|
-
"- `debugbundle
|
|
17634
|
+
"- `debugbundle incidents [--source <local|cloud>] [--project-id <id>] [--environment <name>] [--service <name>] [--status <status>] [--severity <severity>] [--cursor <cursor>] [--limit <n>] [--json]`",
|
|
17635
|
+
"- `debugbundle inspect <incident-id> [--source <local|cloud>] [--json]`",
|
|
17636
|
+
"- `debugbundle explain <incident-id> [--source <local|cloud>] [--json]`",
|
|
17637
|
+
"- `debugbundle bundle <incident-id> [--source <local|cloud>] [--json]`",
|
|
17638
|
+
"- `debugbundle reproduce <incident-id> [--source <local|cloud>] [--json]`",
|
|
17639
|
+
"- `debugbundle resolve <incident-id> [--source <local|cloud>] [--json]`",
|
|
17640
|
+
"- `debugbundle reopen <incident-id> [--source <local|cloud>] [--json]`",
|
|
17191
17641
|
"- `debugbundle analyze --type improvement --local`",
|
|
17192
17642
|
"",
|
|
17643
|
+
"## Operational Paths",
|
|
17644
|
+
"",
|
|
17645
|
+
"- `.debugbundle/profile.json` \u2014 committed project map and agent validation state",
|
|
17646
|
+
"- `.debugbundle/local/connection.json` \u2014 committed delivery policy and cloud connection metadata",
|
|
17647
|
+
"- `.debugbundle/local/events/` \u2014 gitignored raw local event batches",
|
|
17648
|
+
"- `.debugbundle/local/state.json` \u2014 gitignored local incident index and lifecycle state",
|
|
17649
|
+
"- `.debugbundle/bundles/local/` \u2014 gitignored local bundle artifacts",
|
|
17650
|
+
"- `.debugbundle/bundles/local/reproductions/` \u2014 gitignored local reproduction artifacts",
|
|
17651
|
+
"- `.debugbundle/bundles/cloud/` \u2014 gitignored cache for explicitly fetched cloud artifacts",
|
|
17652
|
+
"",
|
|
17193
17653
|
"## Incident Hygiene",
|
|
17194
17654
|
"",
|
|
17195
17655
|
"Resolve incidents after a fix is verified or after an intentional smoke, dogfood, or verification incident has served its purpose.",
|
|
@@ -17221,6 +17681,17 @@ function buildMcpReference() {
|
|
|
17221
17681
|
"",
|
|
17222
17682
|
"Use the same incident-first workflow through MCP when an agent is operating in connected mode.",
|
|
17223
17683
|
"",
|
|
17684
|
+
"## Investigation Tools",
|
|
17685
|
+
"",
|
|
17686
|
+
"- `doctor` \u2014 validate local profile, connection config, auth state, and setup health.",
|
|
17687
|
+
"- `list_incidents` \u2014 list local, cloud, or connected combined incidents; pass `source`, `status`, `environment`, `service`, `severity`, `cursor`, and `limit` when needed.",
|
|
17688
|
+
"- `get_incident` \u2014 fetch incident metadata by incident id.",
|
|
17689
|
+
"- `get_incident_context` \u2014 fetch deterministic explanation context for triage.",
|
|
17690
|
+
"- `get_bundle` \u2014 fetch the full debug bundle before proposing a fix.",
|
|
17691
|
+
"- `get_reproduction` \u2014 fetch reproduction guidance before editing code.",
|
|
17692
|
+
"- `resolve_incident` / `reopen_incident` \u2014 update lifecycle state after validation.",
|
|
17693
|
+
"- `analyze` \u2014 run local agent-oriented analysis from local bundles and skill schemas.",
|
|
17694
|
+
"",
|
|
17224
17695
|
"- Prefer bundle retrieval tools before reading raw repository files.",
|
|
17225
17696
|
"- Use MCP bundle access when the current issue originated in production.",
|
|
17226
17697
|
"- Resolve fixed or intentionally generated incidents with `resolve_incident` so open incidents stay actionable.",
|
|
@@ -17244,8 +17715,12 @@ function buildBundleSchemaReference() {
|
|
|
17244
17715
|
"Focus on:",
|
|
17245
17716
|
"- `summary` for the failure synopsis and recommended action",
|
|
17246
17717
|
"- `service` and `environment` for routing to the right code path",
|
|
17718
|
+
"- `context.error`, `context.request`, `context.response`, `context.logs`, `context.frontend`, `context.runtime`, `context.git`, `context.dependencies`, and `context.probe_data` for supporting evidence",
|
|
17719
|
+
"- `reproduction` for confidence, commands, and manual steps",
|
|
17247
17720
|
"- `links.reproduction` for the generated reproduction artifact",
|
|
17248
17721
|
"- `metadata.source` for whether the bundle came from local or cloud data",
|
|
17722
|
+
"",
|
|
17723
|
+
"Treat the bundle as the source of truth for the failure report. Use repository reads to confirm and patch the implicated code paths, not to rediscover incident context from scratch.",
|
|
17249
17724
|
""
|
|
17250
17725
|
].join("\n");
|
|
17251
17726
|
}
|
|
@@ -17256,10 +17731,14 @@ function buildProfileEnrichmentReference() {
|
|
|
17256
17731
|
"The setup profile is generated from static analysis and must be reviewed before agents rely on it for architecture decisions.",
|
|
17257
17732
|
"",
|
|
17258
17733
|
"Checklist:",
|
|
17259
|
-
"- verify
|
|
17260
|
-
"-
|
|
17261
|
-
"-
|
|
17262
|
-
"-
|
|
17734
|
+
"- verify `project.primary_languages`, `project.package_managers`, and `project.deployment_targets`",
|
|
17735
|
+
"- verify each service `kind`, `runtime`, `framework`, `paths`, `owns_routes`, and `depends_on` value against the repository",
|
|
17736
|
+
"- add critical paths for ingestion, processing, retrieval, SDK capture, auth, billing, and any project-specific high-risk workflows",
|
|
17737
|
+
"- confirm `repo.generated_paths` and `repo.do_not_edit_paths` match the local scaffold",
|
|
17738
|
+
"- confirm build, test, lint, and install workflows in `developer_workflows`",
|
|
17739
|
+
"- for browser frontends, confirm `@debugbundle/sdk-browser` is initialized and a backend `/debugbundle/browser` relay is reachable",
|
|
17740
|
+
"- for split frontend/backend hosts, confirm the browser SDK uses the API relay URL and the backend allowlists the frontend origin",
|
|
17741
|
+
"- update `debugbundle.last_reviewed_at` and set `debugbundle.validation_status` to `agent-validated` when complete",
|
|
17263
17742
|
""
|
|
17264
17743
|
].join("\n");
|
|
17265
17744
|
}
|
|
@@ -17341,6 +17820,22 @@ function buildSkillEvals() {
|
|
|
17341
17820
|
"Resolve verified or intentionally generated incidents after the workflow is complete.",
|
|
17342
17821
|
"Leave unresolved incidents open when the failure is still live or unverified."
|
|
17343
17822
|
]
|
|
17823
|
+
},
|
|
17824
|
+
{
|
|
17825
|
+
name: "artifact_path_discovery",
|
|
17826
|
+
prompt: "The user reports an unknown local runtime error. Confirm the skill tells the agent which DebugBundle paths and commands to inspect first.",
|
|
17827
|
+
expected_behavior: [
|
|
17828
|
+
"Run doctor and list local open incidents before broad source exploration.",
|
|
17829
|
+
"Use .debugbundle/local/state.json, .debugbundle/bundles/local/, and reproduction artifact paths as the local evidence map."
|
|
17830
|
+
]
|
|
17831
|
+
},
|
|
17832
|
+
{
|
|
17833
|
+
name: "connected_incident_fetch",
|
|
17834
|
+
prompt: "The user says a production incident fired in the hosted DebugBundle project. Confirm the skill points the agent to the cloud retrieval path.",
|
|
17835
|
+
expected_behavior: [
|
|
17836
|
+
"List cloud open incidents or use MCP list_incidents with source cloud.",
|
|
17837
|
+
"Fetch inspect, context, bundle, and reproduction artifacts before editing code."
|
|
17838
|
+
]
|
|
17344
17839
|
}
|
|
17345
17840
|
]
|
|
17346
17841
|
},
|
|
@@ -17436,10 +17931,37 @@ async function pathExists(path, stat) {
|
|
|
17436
17931
|
}
|
|
17437
17932
|
}
|
|
17438
17933
|
function formatZodErrors(error) {
|
|
17439
|
-
return error.issues.map((issue) =>
|
|
17440
|
-
path
|
|
17441
|
-
|
|
17442
|
-
|
|
17934
|
+
return error.issues.map((issue) => {
|
|
17935
|
+
const path = issue.path.join(".");
|
|
17936
|
+
if (path === "services" || path.startsWith("services.")) {
|
|
17937
|
+
return {
|
|
17938
|
+
path,
|
|
17939
|
+
message: issue.message,
|
|
17940
|
+
suggestion: "Add service entries with name, kind, runtime, framework, paths, owns_routes, and depends_on.",
|
|
17941
|
+
example: '[{"name":"api","kind":"backend","runtime":"Node.js","framework":"Fastify","paths":["apps/api"],"owns_routes":["POST /checkout"],"depends_on":["worker"]}]'
|
|
17942
|
+
};
|
|
17943
|
+
}
|
|
17944
|
+
if (path === "critical_paths" || path.startsWith("critical_paths.")) {
|
|
17945
|
+
return {
|
|
17946
|
+
path,
|
|
17947
|
+
message: issue.message,
|
|
17948
|
+
suggestion: "Use object entries so each critical path records its owner_service and review notes.",
|
|
17949
|
+
example: '[{"name":"checkout","owner_service":"api","notes":"Creates the order, charges the card, and enqueues fulfillment."}]'
|
|
17950
|
+
};
|
|
17951
|
+
}
|
|
17952
|
+
if (path === "developer_workflows" || path.startsWith("developer_workflows.")) {
|
|
17953
|
+
return {
|
|
17954
|
+
path,
|
|
17955
|
+
message: issue.message,
|
|
17956
|
+
suggestion: "Provide install, build, test, and lint as command strings so agents can run the standard repo workflows.",
|
|
17957
|
+
example: '{"install":"pnpm install","build":"pnpm build","test":"pnpm test","lint":"pnpm lint"}'
|
|
17958
|
+
};
|
|
17959
|
+
}
|
|
17960
|
+
return {
|
|
17961
|
+
path,
|
|
17962
|
+
message: issue.message
|
|
17963
|
+
};
|
|
17964
|
+
});
|
|
17443
17965
|
}
|
|
17444
17966
|
async function validateProfile(rootDirectory, dependencies = {}) {
|
|
17445
17967
|
const readFile = dependencies.readFile ?? ((filePath) => (0, import_promises.readFile)(filePath, "utf8"));
|
|
@@ -17786,6 +18308,118 @@ function createCliHttpClient(input, dependencies) {
|
|
|
17786
18308
|
};
|
|
17787
18309
|
}
|
|
17788
18310
|
|
|
18311
|
+
// ../cli/src/capture-rule-commands.ts
|
|
18312
|
+
var CaptureRuleApiError = class extends Error {
|
|
18313
|
+
status;
|
|
18314
|
+
constructor(status, message) {
|
|
18315
|
+
super(message);
|
|
18316
|
+
this.name = "CaptureRuleApiError";
|
|
18317
|
+
this.status = status;
|
|
18318
|
+
}
|
|
18319
|
+
};
|
|
18320
|
+
function toApiError(status, body, fallback) {
|
|
18321
|
+
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
18322
|
+
return new CaptureRuleApiError(status, body.error);
|
|
18323
|
+
}
|
|
18324
|
+
return new CaptureRuleApiError(status, fallback);
|
|
18325
|
+
}
|
|
18326
|
+
function createCaptureRuleApi(httpClient) {
|
|
18327
|
+
return {
|
|
18328
|
+
async listCaptureRules(input) {
|
|
18329
|
+
const response = await httpClient.request({
|
|
18330
|
+
method: "GET",
|
|
18331
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules`,
|
|
18332
|
+
bearerToken: input.bearerToken
|
|
18333
|
+
});
|
|
18334
|
+
if (response.status !== 200) {
|
|
18335
|
+
throw toApiError(response.status, response.body, "Failed to list capture rules.");
|
|
18336
|
+
}
|
|
18337
|
+
const parsed = CaptureRulesResponseSchema.safeParse(response.body);
|
|
18338
|
+
if (!parsed.success) {
|
|
18339
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule list response.");
|
|
18340
|
+
}
|
|
18341
|
+
return parsed.data;
|
|
18342
|
+
},
|
|
18343
|
+
async createCaptureRule(input) {
|
|
18344
|
+
const response = await httpClient.request({
|
|
18345
|
+
method: "POST",
|
|
18346
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules`,
|
|
18347
|
+
bearerToken: input.bearerToken,
|
|
18348
|
+
body: input.create
|
|
18349
|
+
});
|
|
18350
|
+
if (response.status !== 201) {
|
|
18351
|
+
throw toApiError(response.status, response.body, "Failed to create capture rule.");
|
|
18352
|
+
}
|
|
18353
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18354
|
+
if (!parsed.success) {
|
|
18355
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule create response.");
|
|
18356
|
+
}
|
|
18357
|
+
return parsed.data;
|
|
18358
|
+
},
|
|
18359
|
+
async suggestCaptureRulesFromIncident(input) {
|
|
18360
|
+
const response = await httpClient.request({
|
|
18361
|
+
method: "POST",
|
|
18362
|
+
path: `/v1/incidents/${encodeURIComponent(input.incidentId)}/capture-rule-suggestion`,
|
|
18363
|
+
bearerToken: input.bearerToken
|
|
18364
|
+
});
|
|
18365
|
+
if (response.status !== 200) {
|
|
18366
|
+
throw toApiError(response.status, response.body, "Failed to suggest capture rules.");
|
|
18367
|
+
}
|
|
18368
|
+
const parsed = CaptureRuleSuggestionsResponseSchema.safeParse(response.body);
|
|
18369
|
+
if (!parsed.success) {
|
|
18370
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule suggestion response.");
|
|
18371
|
+
}
|
|
18372
|
+
return parsed.data;
|
|
18373
|
+
},
|
|
18374
|
+
async createCaptureRuleFromIncidentSuggestion(input) {
|
|
18375
|
+
const response = await httpClient.request({
|
|
18376
|
+
method: "POST",
|
|
18377
|
+
path: `/v1/incidents/${encodeURIComponent(input.incidentId)}/capture-rules`,
|
|
18378
|
+
bearerToken: input.bearerToken,
|
|
18379
|
+
body: input.create
|
|
18380
|
+
});
|
|
18381
|
+
if (response.status !== 201) {
|
|
18382
|
+
throw toApiError(response.status, response.body, "Failed to create capture rule from suggestion.");
|
|
18383
|
+
}
|
|
18384
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18385
|
+
if (!parsed.success) {
|
|
18386
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule create-from-suggestion response.");
|
|
18387
|
+
}
|
|
18388
|
+
return parsed.data;
|
|
18389
|
+
},
|
|
18390
|
+
async updateCaptureRule(input) {
|
|
18391
|
+
const response = await httpClient.request({
|
|
18392
|
+
method: "PATCH",
|
|
18393
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules/${encodeURIComponent(input.ruleId)}`,
|
|
18394
|
+
bearerToken: input.bearerToken,
|
|
18395
|
+
body: input.update
|
|
18396
|
+
});
|
|
18397
|
+
if (response.status !== 200) {
|
|
18398
|
+
throw toApiError(response.status, response.body, "Failed to update capture rule.");
|
|
18399
|
+
}
|
|
18400
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18401
|
+
if (!parsed.success) {
|
|
18402
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule update response.");
|
|
18403
|
+
}
|
|
18404
|
+
return parsed.data;
|
|
18405
|
+
},
|
|
18406
|
+
async deleteCaptureRule(input) {
|
|
18407
|
+
const response = await httpClient.request({
|
|
18408
|
+
method: "DELETE",
|
|
18409
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules/${encodeURIComponent(input.ruleId)}`,
|
|
18410
|
+
bearerToken: input.bearerToken
|
|
18411
|
+
});
|
|
18412
|
+
if (response.status !== 200) {
|
|
18413
|
+
throw toApiError(response.status, response.body, "Failed to delete capture rule.");
|
|
18414
|
+
}
|
|
18415
|
+
if (typeof response.body !== "object" || response.body === null || !("success" in response.body) || response.body.success !== true) {
|
|
18416
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule delete response.");
|
|
18417
|
+
}
|
|
18418
|
+
return { success: true };
|
|
18419
|
+
}
|
|
18420
|
+
};
|
|
18421
|
+
}
|
|
18422
|
+
|
|
17789
18423
|
// ../cli/src/capture-policy-commands.ts
|
|
17790
18424
|
var CapturePolicyApiError = class extends Error {
|
|
17791
18425
|
status;
|
|
@@ -17795,7 +18429,7 @@ var CapturePolicyApiError = class extends Error {
|
|
|
17795
18429
|
this.status = status;
|
|
17796
18430
|
}
|
|
17797
18431
|
};
|
|
17798
|
-
function
|
|
18432
|
+
function toApiError2(status, body, fallback) {
|
|
17799
18433
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17800
18434
|
return new CapturePolicyApiError(status, body.error);
|
|
17801
18435
|
}
|
|
@@ -17810,7 +18444,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17810
18444
|
bearerToken: input.bearerToken
|
|
17811
18445
|
});
|
|
17812
18446
|
if (response.status !== 200) {
|
|
17813
|
-
throw
|
|
18447
|
+
throw toApiError2(response.status, response.body, "Failed to get capture policy.");
|
|
17814
18448
|
}
|
|
17815
18449
|
const parsed = CapturePolicyResponseSchema.safeParse(response.body);
|
|
17816
18450
|
if (!parsed.success) {
|
|
@@ -17826,7 +18460,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17826
18460
|
body: input.update
|
|
17827
18461
|
});
|
|
17828
18462
|
if (response.status !== 200) {
|
|
17829
|
-
throw
|
|
18463
|
+
throw toApiError2(response.status, response.body, "Failed to update capture policy.");
|
|
17830
18464
|
}
|
|
17831
18465
|
const parsed = CapturePolicyResponseSchema.safeParse(response.body);
|
|
17832
18466
|
if (!parsed.success) {
|
|
@@ -17846,7 +18480,7 @@ var ImprovementSettingsApiError = class extends Error {
|
|
|
17846
18480
|
this.status = status;
|
|
17847
18481
|
}
|
|
17848
18482
|
};
|
|
17849
|
-
function
|
|
18483
|
+
function toApiError3(status, body, fallback) {
|
|
17850
18484
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17851
18485
|
return new ImprovementSettingsApiError(status, body.error);
|
|
17852
18486
|
}
|
|
@@ -17861,7 +18495,7 @@ function createImprovementSettingsApi(httpClient) {
|
|
|
17861
18495
|
bearerToken: input.bearerToken
|
|
17862
18496
|
});
|
|
17863
18497
|
if (response.status !== 200) {
|
|
17864
|
-
throw
|
|
18498
|
+
throw toApiError3(response.status, response.body, "Failed to get improvement settings.");
|
|
17865
18499
|
}
|
|
17866
18500
|
const parsed = ImprovementSettingsResponseSchema.safeParse(response.body);
|
|
17867
18501
|
if (!parsed.success) {
|
|
@@ -17877,7 +18511,7 @@ function createImprovementSettingsApi(httpClient) {
|
|
|
17877
18511
|
body: input.update
|
|
17878
18512
|
});
|
|
17879
18513
|
if (response.status !== 200) {
|
|
17880
|
-
throw
|
|
18514
|
+
throw toApiError3(response.status, response.body, "Failed to update improvement settings.");
|
|
17881
18515
|
}
|
|
17882
18516
|
const parsed = ImprovementSettingsResponseSchema.safeParse(response.body);
|
|
17883
18517
|
if (!parsed.success) {
|
|
@@ -17899,7 +18533,7 @@ var MemberApiError = class extends Error {
|
|
|
17899
18533
|
this.code = code;
|
|
17900
18534
|
}
|
|
17901
18535
|
};
|
|
17902
|
-
function
|
|
18536
|
+
function toApiError4(status, body) {
|
|
17903
18537
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17904
18538
|
return new MemberApiError(status, body.error);
|
|
17905
18539
|
}
|
|
@@ -17914,7 +18548,7 @@ function createMemberApi(httpClient) {
|
|
|
17914
18548
|
bearerToken: input.bearerToken
|
|
17915
18549
|
});
|
|
17916
18550
|
if (response.status !== 200) {
|
|
17917
|
-
throw
|
|
18551
|
+
throw toApiError4(response.status, response.body);
|
|
17918
18552
|
}
|
|
17919
18553
|
return response.body;
|
|
17920
18554
|
},
|
|
@@ -17925,7 +18559,7 @@ function createMemberApi(httpClient) {
|
|
|
17925
18559
|
bearerToken: input.bearerToken
|
|
17926
18560
|
});
|
|
17927
18561
|
if (response.status !== 200) {
|
|
17928
|
-
throw
|
|
18562
|
+
throw toApiError4(response.status, response.body);
|
|
17929
18563
|
}
|
|
17930
18564
|
return response.body;
|
|
17931
18565
|
},
|
|
@@ -17937,7 +18571,7 @@ function createMemberApi(httpClient) {
|
|
|
17937
18571
|
body: { email: input.email, role: input.role }
|
|
17938
18572
|
});
|
|
17939
18573
|
if (response.status !== 201) {
|
|
17940
|
-
throw
|
|
18574
|
+
throw toApiError4(response.status, response.body);
|
|
17941
18575
|
}
|
|
17942
18576
|
return response.body;
|
|
17943
18577
|
},
|
|
@@ -17948,7 +18582,7 @@ function createMemberApi(httpClient) {
|
|
|
17948
18582
|
bearerToken: input.bearerToken
|
|
17949
18583
|
});
|
|
17950
18584
|
if (response.status !== 200) {
|
|
17951
|
-
throw
|
|
18585
|
+
throw toApiError4(response.status, response.body);
|
|
17952
18586
|
}
|
|
17953
18587
|
return response.body;
|
|
17954
18588
|
},
|
|
@@ -17960,7 +18594,7 @@ function createMemberApi(httpClient) {
|
|
|
17960
18594
|
body: { role: input.role }
|
|
17961
18595
|
});
|
|
17962
18596
|
if (response.status !== 200) {
|
|
17963
|
-
throw
|
|
18597
|
+
throw toApiError4(response.status, response.body);
|
|
17964
18598
|
}
|
|
17965
18599
|
return response.body;
|
|
17966
18600
|
},
|
|
@@ -17971,7 +18605,7 @@ function createMemberApi(httpClient) {
|
|
|
17971
18605
|
bearerToken: input.bearerToken
|
|
17972
18606
|
});
|
|
17973
18607
|
if (response.status !== 200) {
|
|
17974
|
-
throw
|
|
18608
|
+
throw toApiError4(response.status, response.body);
|
|
17975
18609
|
}
|
|
17976
18610
|
return response.body;
|
|
17977
18611
|
}
|
|
@@ -17989,7 +18623,7 @@ var ProbeApiError = class extends Error {
|
|
|
17989
18623
|
this.code = code;
|
|
17990
18624
|
}
|
|
17991
18625
|
};
|
|
17992
|
-
function
|
|
18626
|
+
function toApiError5(status, body) {
|
|
17993
18627
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17994
18628
|
return new ProbeApiError(status, body.error);
|
|
17995
18629
|
}
|
|
@@ -18020,7 +18654,7 @@ function createProbeApi(httpClient) {
|
|
|
18020
18654
|
body
|
|
18021
18655
|
});
|
|
18022
18656
|
if (response.status !== 201) {
|
|
18023
|
-
throw
|
|
18657
|
+
throw toApiError5(response.status, response.body);
|
|
18024
18658
|
}
|
|
18025
18659
|
return response.body;
|
|
18026
18660
|
},
|
|
@@ -18031,7 +18665,7 @@ function createProbeApi(httpClient) {
|
|
|
18031
18665
|
bearerToken: input.bearerToken
|
|
18032
18666
|
});
|
|
18033
18667
|
if (response.status !== 200) {
|
|
18034
|
-
throw
|
|
18668
|
+
throw toApiError5(response.status, response.body);
|
|
18035
18669
|
}
|
|
18036
18670
|
return response.body;
|
|
18037
18671
|
},
|
|
@@ -18043,7 +18677,7 @@ function createProbeApi(httpClient) {
|
|
|
18043
18677
|
body: { activation_id: input.activationId }
|
|
18044
18678
|
});
|
|
18045
18679
|
if (response.status !== 200) {
|
|
18046
|
-
throw
|
|
18680
|
+
throw toApiError5(response.status, response.body);
|
|
18047
18681
|
}
|
|
18048
18682
|
return response.body;
|
|
18049
18683
|
}
|
|
@@ -18166,6 +18800,15 @@ function inferMatchedFields(event) {
|
|
|
18166
18800
|
if (event.top_frames.length > 0) {
|
|
18167
18801
|
matchedFields.push("top_frames");
|
|
18168
18802
|
}
|
|
18803
|
+
if (event.browser_event_kind != null) {
|
|
18804
|
+
matchedFields.push("browser_event_kind");
|
|
18805
|
+
}
|
|
18806
|
+
if (event.resource_host != null) {
|
|
18807
|
+
matchedFields.push("resource_host");
|
|
18808
|
+
}
|
|
18809
|
+
if (event.resource_path != null) {
|
|
18810
|
+
matchedFields.push("resource_path");
|
|
18811
|
+
}
|
|
18169
18812
|
if (event.http_method !== null) {
|
|
18170
18813
|
matchedFields.push("http_method");
|
|
18171
18814
|
}
|
|
@@ -18226,6 +18869,39 @@ function selectTopFrames(stack, limit = 5) {
|
|
|
18226
18869
|
const frames = normalizedStack.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("at ")).filter((line) => FRAME_NOISE_PATTERNS.every((pattern) => !line.includes(pattern))).slice(0, limit);
|
|
18227
18870
|
return frames;
|
|
18228
18871
|
}
|
|
18872
|
+
function normalizeResourceIdentity(value) {
|
|
18873
|
+
if (value === null) {
|
|
18874
|
+
return { host: null, path: null };
|
|
18875
|
+
}
|
|
18876
|
+
const trimmed = value.trim();
|
|
18877
|
+
if (trimmed.length === 0) {
|
|
18878
|
+
return { host: null, path: null };
|
|
18879
|
+
}
|
|
18880
|
+
if (trimmed.startsWith("/")) {
|
|
18881
|
+
return {
|
|
18882
|
+
host: null,
|
|
18883
|
+
path: normalizeRoute(trimmed)
|
|
18884
|
+
};
|
|
18885
|
+
}
|
|
18886
|
+
try {
|
|
18887
|
+
const parsed = new URL(trimmed);
|
|
18888
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:") {
|
|
18889
|
+
return {
|
|
18890
|
+
host: parsed.hostname.length > 0 ? parsed.hostname.toLowerCase() : null,
|
|
18891
|
+
path: normalizeRoute(parsed.pathname)
|
|
18892
|
+
};
|
|
18893
|
+
}
|
|
18894
|
+
return {
|
|
18895
|
+
host: null,
|
|
18896
|
+
path: parsed.protocol.replace(/:$/, "")
|
|
18897
|
+
};
|
|
18898
|
+
} catch {
|
|
18899
|
+
return {
|
|
18900
|
+
host: null,
|
|
18901
|
+
path: normalizeRoute(trimmed) ?? trimmed
|
|
18902
|
+
};
|
|
18903
|
+
}
|
|
18904
|
+
}
|
|
18229
18905
|
function stableJson(value) {
|
|
18230
18906
|
if (value === null || typeof value !== "object") {
|
|
18231
18907
|
return JSON.stringify(value);
|
|
@@ -18253,6 +18929,9 @@ function normalizeEvent(event) {
|
|
|
18253
18929
|
http_method: event.payload.request.method,
|
|
18254
18930
|
http_status: event.payload.response.status_code,
|
|
18255
18931
|
top_frames: selectTopFrames(event.payload.stack),
|
|
18932
|
+
browser_event_kind: null,
|
|
18933
|
+
resource_host: null,
|
|
18934
|
+
resource_path: null,
|
|
18256
18935
|
payload: redactedPayload
|
|
18257
18936
|
};
|
|
18258
18937
|
}
|
|
@@ -18266,6 +18945,9 @@ function normalizeEvent(event) {
|
|
|
18266
18945
|
http_method: event.payload.method,
|
|
18267
18946
|
http_status: event.payload.response_status,
|
|
18268
18947
|
top_frames: [],
|
|
18948
|
+
browser_event_kind: null,
|
|
18949
|
+
resource_host: null,
|
|
18950
|
+
resource_path: null,
|
|
18269
18951
|
payload: redactedPayload
|
|
18270
18952
|
};
|
|
18271
18953
|
}
|
|
@@ -18279,6 +18961,28 @@ function normalizeEvent(event) {
|
|
|
18279
18961
|
http_method: null,
|
|
18280
18962
|
http_status: null,
|
|
18281
18963
|
top_frames: [],
|
|
18964
|
+
browser_event_kind: null,
|
|
18965
|
+
resource_host: null,
|
|
18966
|
+
resource_path: null,
|
|
18967
|
+
payload: redactedPayload
|
|
18968
|
+
};
|
|
18969
|
+
}
|
|
18970
|
+
if (event.event_type === "frontend_exception") {
|
|
18971
|
+
const browserEvent = event.payload.browser_event;
|
|
18972
|
+
const resourceIdentity = browserEvent?.kind === "resource_error" ? normalizeResourceIdentity(browserEvent.target?.source_url ?? browserEvent.file_name) : { host: null, path: null };
|
|
18973
|
+
const topFrames = browserEvent?.opaque === true ? [] : selectTopFrames(event.payload.stack);
|
|
18974
|
+
return {
|
|
18975
|
+
event_type: event.event_type,
|
|
18976
|
+
environment: event.service.environment,
|
|
18977
|
+
error_type: event.payload.name,
|
|
18978
|
+
normalized_message: normalizeMessage(event.payload.message),
|
|
18979
|
+
route_template: normalizeRoute(event.payload.route ?? null),
|
|
18980
|
+
http_method: null,
|
|
18981
|
+
http_status: null,
|
|
18982
|
+
top_frames: topFrames,
|
|
18983
|
+
browser_event_kind: browserEvent?.kind ?? null,
|
|
18984
|
+
resource_host: resourceIdentity.host,
|
|
18985
|
+
resource_path: resourceIdentity.path,
|
|
18282
18986
|
payload: redactedPayload
|
|
18283
18987
|
};
|
|
18284
18988
|
}
|
|
@@ -18291,6 +18995,9 @@ function normalizeEvent(event) {
|
|
|
18291
18995
|
http_method: null,
|
|
18292
18996
|
http_status: null,
|
|
18293
18997
|
top_frames: [],
|
|
18998
|
+
browser_event_kind: null,
|
|
18999
|
+
resource_host: null,
|
|
19000
|
+
resource_path: null,
|
|
18294
19001
|
payload: redactedPayload
|
|
18295
19002
|
};
|
|
18296
19003
|
}
|
|
@@ -18300,6 +19007,9 @@ function fingerprint(event) {
|
|
|
18300
19007
|
normalized_message: event.normalized_message,
|
|
18301
19008
|
top_frames: event.top_frames,
|
|
18302
19009
|
route_template: event.route_template,
|
|
19010
|
+
browser_event_kind: event.browser_event_kind,
|
|
19011
|
+
resource_host: event.resource_host,
|
|
19012
|
+
resource_path: event.resource_path,
|
|
18303
19013
|
http_method: event.http_method,
|
|
18304
19014
|
http_status: event.http_status,
|
|
18305
19015
|
environment: event.environment
|
|
@@ -18354,18 +19064,18 @@ var ConnectionConfigSchema = external_exports.object({
|
|
|
18354
19064
|
}).strict();
|
|
18355
19065
|
|
|
18356
19066
|
// ../cli/src/doctor-command.ts
|
|
18357
|
-
var ProfileSchema2 = external_exports.object({
|
|
18358
|
-
debugbundle: external_exports.object({
|
|
18359
|
-
last_reviewed_at: external_exports.string(),
|
|
18360
|
-
validation_status: external_exports.enum(["static-analysis-only", "agent-validated"])
|
|
18361
|
-
})
|
|
18362
|
-
});
|
|
18363
19067
|
var HealthResponseSchema = external_exports.object({
|
|
18364
19068
|
status: external_exports.literal("ok")
|
|
18365
19069
|
});
|
|
18366
19070
|
var IncidentsProbeResponseSchema = external_exports.object({
|
|
18367
19071
|
incidents: external_exports.array(external_exports.unknown())
|
|
18368
19072
|
});
|
|
19073
|
+
var DoctorProfileSchema = external_exports.object({
|
|
19074
|
+
debugbundle: external_exports.object({
|
|
19075
|
+
last_reviewed_at: external_exports.string(),
|
|
19076
|
+
validation_status: external_exports.enum(["static-analysis-only", "agent-validated"])
|
|
19077
|
+
})
|
|
19078
|
+
});
|
|
18369
19079
|
var PROFILE_STALENESS_THRESHOLD_DAYS = 30;
|
|
18370
19080
|
var LOCAL_RELAY_SPOOL_DIRECTORY_PATH = ".debugbundle/local/browser-relay-spool";
|
|
18371
19081
|
var RELAY_SPOOL_DELIVERED_MARKER_SUFFIX = ".delivered";
|
|
@@ -18508,6 +19218,12 @@ async function buildFileCheck(rootDirectory, name, filePath, stat) {
|
|
|
18508
19218
|
message: exists ? `Found ${filePath}` : `Missing ${filePath}`
|
|
18509
19219
|
};
|
|
18510
19220
|
}
|
|
19221
|
+
function formatZodErrors2(error) {
|
|
19222
|
+
return error.issues.map((issue) => ({
|
|
19223
|
+
path: issue.path.join("."),
|
|
19224
|
+
message: issue.message
|
|
19225
|
+
}));
|
|
19226
|
+
}
|
|
18511
19227
|
async function loadProfile(rootDirectory, dependencies) {
|
|
18512
19228
|
const profilePath = (0, import_node_path4.join)(rootDirectory, PROFILE_FILE_PATH);
|
|
18513
19229
|
if (!await pathExists3(profilePath, dependencies.stat)) {
|
|
@@ -18517,29 +19233,46 @@ async function loadProfile(rootDirectory, dependencies) {
|
|
|
18517
19233
|
status: "missing",
|
|
18518
19234
|
message: `Missing ${PROFILE_FILE_PATH}`
|
|
18519
19235
|
},
|
|
18520
|
-
profile: null
|
|
19236
|
+
profile: null,
|
|
19237
|
+
validationErrors: []
|
|
18521
19238
|
};
|
|
18522
19239
|
}
|
|
19240
|
+
let parsedJson;
|
|
18523
19241
|
try {
|
|
18524
|
-
|
|
19242
|
+
parsedJson = JSON.parse(await dependencies.readFile(profilePath));
|
|
19243
|
+
} catch {
|
|
18525
19244
|
return {
|
|
18526
19245
|
check: {
|
|
18527
19246
|
name: "profile",
|
|
18528
|
-
status: "
|
|
18529
|
-
message: `
|
|
19247
|
+
status: "error",
|
|
19248
|
+
message: `Invalid ${PROFILE_FILE_PATH}`
|
|
18530
19249
|
},
|
|
18531
|
-
profile:
|
|
19250
|
+
profile: null,
|
|
19251
|
+
validationErrors: []
|
|
18532
19252
|
};
|
|
18533
|
-
}
|
|
19253
|
+
}
|
|
19254
|
+
const parsedDoctorProfile = DoctorProfileSchema.safeParse(parsedJson);
|
|
19255
|
+
if (!parsedDoctorProfile.success) {
|
|
18534
19256
|
return {
|
|
18535
19257
|
check: {
|
|
18536
19258
|
name: "profile",
|
|
18537
19259
|
status: "error",
|
|
18538
19260
|
message: `Invalid ${PROFILE_FILE_PATH}`
|
|
18539
19261
|
},
|
|
18540
|
-
profile: null
|
|
19262
|
+
profile: null,
|
|
19263
|
+
validationErrors: formatZodErrors2(parsedDoctorProfile.error)
|
|
18541
19264
|
};
|
|
18542
19265
|
}
|
|
19266
|
+
const parsedFullProfile = ProfileSchema.safeParse(parsedJson);
|
|
19267
|
+
return {
|
|
19268
|
+
check: {
|
|
19269
|
+
name: "profile",
|
|
19270
|
+
status: "ok",
|
|
19271
|
+
message: `Found ${PROFILE_FILE_PATH}`
|
|
19272
|
+
},
|
|
19273
|
+
profile: parsedDoctorProfile.data,
|
|
19274
|
+
validationErrors: parsedFullProfile.success ? [] : formatZodErrors2(parsedFullProfile.error)
|
|
19275
|
+
};
|
|
18543
19276
|
}
|
|
18544
19277
|
async function loadConnection(rootDirectory, dependencies) {
|
|
18545
19278
|
const connectionPath = (0, import_node_path4.join)(rootDirectory, CONNECTION_FILE_PATH);
|
|
@@ -18591,7 +19324,20 @@ function buildProjectModeCheck(connection) {
|
|
|
18591
19324
|
message: `Project mode is ${connection.mode}.`
|
|
18592
19325
|
};
|
|
18593
19326
|
}
|
|
18594
|
-
function
|
|
19327
|
+
function formatProfileValidationError(errors) {
|
|
19328
|
+
const firstError = errors[0];
|
|
19329
|
+
const path = firstError.path.length === 0 ? PROFILE_FILE_PATH : firstError.path;
|
|
19330
|
+
const totalErrors = errors.length === 1 ? "" : ` (${errors.length} total errors)`;
|
|
19331
|
+
return `Profile schema validation failed at ${path}: ${firstError.message}${totalErrors}.`;
|
|
19332
|
+
}
|
|
19333
|
+
function buildProfileValidationCheck(profile, validationErrors) {
|
|
19334
|
+
if (validationErrors.length > 0) {
|
|
19335
|
+
return {
|
|
19336
|
+
name: "profile-validation",
|
|
19337
|
+
status: "error",
|
|
19338
|
+
message: formatProfileValidationError(validationErrors)
|
|
19339
|
+
};
|
|
19340
|
+
}
|
|
18595
19341
|
if (profile === null) {
|
|
18596
19342
|
return {
|
|
18597
19343
|
name: "profile-validation",
|
|
@@ -18840,7 +19586,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18840
19586
|
const stat = dependencies.stat ?? import_promises4.stat;
|
|
18841
19587
|
const rootDirectory = cwd();
|
|
18842
19588
|
const currentTime = now();
|
|
18843
|
-
const { check: profileCheck, profile } = await loadProfile(rootDirectory, { readFile, stat });
|
|
19589
|
+
const { check: profileCheck, profile, validationErrors } = await loadProfile(rootDirectory, { readFile, stat });
|
|
18844
19590
|
const { check: connectionCheck, connection } = await loadConnection(rootDirectory, { readFile, stat });
|
|
18845
19591
|
const { check: authCheck, authState } = await buildAuthCheck(input, readAuthStateImpl);
|
|
18846
19592
|
const connectedApiCheck = await buildConnectedApiCheck({
|
|
@@ -18855,7 +19601,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18855
19601
|
authCheck,
|
|
18856
19602
|
buildProjectModeCheck(connection),
|
|
18857
19603
|
...connectedApiCheck === null ? [] : [connectedApiCheck],
|
|
18858
|
-
buildProfileValidationCheck(profile),
|
|
19604
|
+
buildProfileValidationCheck(profile, validationErrors),
|
|
18859
19605
|
buildProfileFreshnessCheck(profile, currentTime),
|
|
18860
19606
|
...input.checkRelay === true ? [await buildRelaySpoolCheck(rootDirectory, currentTime, { readdir, stat })] : []
|
|
18861
19607
|
];
|
|
@@ -18867,6 +19613,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18867
19613
|
}
|
|
18868
19614
|
|
|
18869
19615
|
// ../cli/src/verify-command.ts
|
|
19616
|
+
var import_node_crypto6 = require("node:crypto");
|
|
18870
19617
|
var import_promises7 = require("node:fs/promises");
|
|
18871
19618
|
var import_node_path9 = require("node:path");
|
|
18872
19619
|
|
|
@@ -19167,6 +19914,868 @@ var import_ioredis4 = __toESM(require_built3(), 1);
|
|
|
19167
19914
|
|
|
19168
19915
|
// ../../packages/storage/src/schema-migrations.ts
|
|
19169
19916
|
var import_node_crypto3 = require("node:crypto");
|
|
19917
|
+
|
|
19918
|
+
// ../../packages/storage/src/migrations.ts
|
|
19919
|
+
var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
19920
|
+
`
|
|
19921
|
+
CREATE TABLE users (
|
|
19922
|
+
id uuid PRIMARY KEY,
|
|
19923
|
+
email text NOT NULL UNIQUE,
|
|
19924
|
+
accepted_terms_at timestamptz,
|
|
19925
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19926
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19927
|
+
email_verified_at timestamptz,
|
|
19928
|
+
avatar_source text,
|
|
19929
|
+
avatar_object_key text,
|
|
19930
|
+
avatar_content_type text,
|
|
19931
|
+
avatar_updated_at timestamptz
|
|
19932
|
+
)
|
|
19933
|
+
`,
|
|
19934
|
+
`
|
|
19935
|
+
CREATE TABLE organizations (
|
|
19936
|
+
id uuid PRIMARY KEY,
|
|
19937
|
+
name text NOT NULL,
|
|
19938
|
+
slug text NOT NULL UNIQUE,
|
|
19939
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19940
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19941
|
+
suspended_at timestamptz,
|
|
19942
|
+
plan text NOT NULL DEFAULT 'free',
|
|
19943
|
+
stripe_customer_id text,
|
|
19944
|
+
additional_capacity_units integer NOT NULL DEFAULT 0,
|
|
19945
|
+
stripe_subscription_id text,
|
|
19946
|
+
billing_state text,
|
|
19947
|
+
billing_period_ends_at timestamptz,
|
|
19948
|
+
last_billing_sync_at timestamptz,
|
|
19949
|
+
last_billing_event_id text,
|
|
19950
|
+
billing_period_starts_at timestamptz
|
|
19951
|
+
)
|
|
19952
|
+
`,
|
|
19953
|
+
`
|
|
19954
|
+
CREATE UNIQUE INDEX organizations_stripe_customer_id_key
|
|
19955
|
+
ON organizations (stripe_customer_id)
|
|
19956
|
+
WHERE stripe_customer_id IS NOT NULL
|
|
19957
|
+
`,
|
|
19958
|
+
`
|
|
19959
|
+
CREATE TABLE projects (
|
|
19960
|
+
id uuid PRIMARY KEY,
|
|
19961
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
19962
|
+
owner_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
19963
|
+
name text NOT NULL,
|
|
19964
|
+
slug text NOT NULL,
|
|
19965
|
+
environment_default text NOT NULL DEFAULT 'production',
|
|
19966
|
+
automated_improvement_bundles_enabled boolean NOT NULL DEFAULT true,
|
|
19967
|
+
improvement_bundle_sensitivity text NOT NULL DEFAULT 'high_confidence'
|
|
19968
|
+
CHECK (improvement_bundle_sensitivity IN ('high_confidence', 'balanced', 'verbose')),
|
|
19969
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19970
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19971
|
+
plan text NOT NULL DEFAULT 'free'
|
|
19972
|
+
)
|
|
19973
|
+
`,
|
|
19974
|
+
`
|
|
19975
|
+
CREATE UNIQUE INDEX projects_organization_id_slug_key
|
|
19976
|
+
ON projects (organization_id, slug)
|
|
19977
|
+
`,
|
|
19978
|
+
`
|
|
19979
|
+
CREATE TABLE services (
|
|
19980
|
+
id uuid PRIMARY KEY,
|
|
19981
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
19982
|
+
name text NOT NULL,
|
|
19983
|
+
runtime text,
|
|
19984
|
+
framework text,
|
|
19985
|
+
environment text NOT NULL DEFAULT 'production',
|
|
19986
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19987
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19988
|
+
UNIQUE (project_id, name, environment)
|
|
19989
|
+
)
|
|
19990
|
+
`,
|
|
19991
|
+
`
|
|
19992
|
+
CREATE TABLE project_tokens (
|
|
19993
|
+
id uuid PRIMARY KEY,
|
|
19994
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
19995
|
+
token_hash text UNIQUE NOT NULL,
|
|
19996
|
+
label text NOT NULL,
|
|
19997
|
+
allowed_origins jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
19998
|
+
last_used_at timestamptz,
|
|
19999
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20000
|
+
revoked_at timestamptz,
|
|
20001
|
+
expires_at timestamptz
|
|
20002
|
+
)
|
|
20003
|
+
`,
|
|
20004
|
+
`
|
|
20005
|
+
CREATE TABLE member_tokens (
|
|
20006
|
+
id uuid PRIMARY KEY,
|
|
20007
|
+
user_id uuid NOT NULL,
|
|
20008
|
+
organization_id uuid NOT NULL,
|
|
20009
|
+
token_hash text UNIQUE NOT NULL,
|
|
20010
|
+
label text NOT NULL,
|
|
20011
|
+
last_used_at timestamptz,
|
|
20012
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20013
|
+
revoked_at timestamptz,
|
|
20014
|
+
expires_at timestamptz
|
|
20015
|
+
)
|
|
20016
|
+
`,
|
|
20017
|
+
`
|
|
20018
|
+
CREATE INDEX member_tokens_org_idx
|
|
20019
|
+
ON member_tokens (organization_id)
|
|
20020
|
+
`,
|
|
20021
|
+
`
|
|
20022
|
+
CREATE TABLE audit_logs (
|
|
20023
|
+
id uuid PRIMARY KEY,
|
|
20024
|
+
organization_id uuid,
|
|
20025
|
+
actor_user_id uuid,
|
|
20026
|
+
actor_type text NOT NULL,
|
|
20027
|
+
action text NOT NULL,
|
|
20028
|
+
target_type text NOT NULL,
|
|
20029
|
+
target_id text,
|
|
20030
|
+
status text NOT NULL,
|
|
20031
|
+
ip_address text,
|
|
20032
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20033
|
+
occurred_at timestamptz NOT NULL,
|
|
20034
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20035
|
+
)
|
|
20036
|
+
`,
|
|
20037
|
+
`
|
|
20038
|
+
CREATE INDEX audit_logs_organization_occurred_at_idx
|
|
20039
|
+
ON audit_logs (organization_id, occurred_at DESC, created_at DESC)
|
|
20040
|
+
`,
|
|
20041
|
+
`
|
|
20042
|
+
CREATE INDEX audit_logs_action_occurred_at_idx
|
|
20043
|
+
ON audit_logs (action, occurred_at DESC, created_at DESC)
|
|
20044
|
+
`,
|
|
20045
|
+
`
|
|
20046
|
+
CREATE TABLE organization_members (
|
|
20047
|
+
id uuid PRIMARY KEY,
|
|
20048
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20049
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20050
|
+
role text NOT NULL DEFAULT 'member',
|
|
20051
|
+
suspended_at timestamptz,
|
|
20052
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20053
|
+
UNIQUE (organization_id, user_id)
|
|
20054
|
+
)
|
|
20055
|
+
`,
|
|
20056
|
+
`
|
|
20057
|
+
CREATE INDEX organization_members_org_idx
|
|
20058
|
+
ON organization_members (organization_id)
|
|
20059
|
+
`,
|
|
20060
|
+
`
|
|
20061
|
+
CREATE INDEX organization_members_user_idx
|
|
20062
|
+
ON organization_members (user_id)
|
|
20063
|
+
`,
|
|
20064
|
+
`
|
|
20065
|
+
CREATE TABLE sessions (
|
|
20066
|
+
id uuid PRIMARY KEY,
|
|
20067
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20068
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20069
|
+
session_token_hash text UNIQUE NOT NULL,
|
|
20070
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20071
|
+
expires_at timestamptz NOT NULL,
|
|
20072
|
+
revoked_at timestamptz
|
|
20073
|
+
)
|
|
20074
|
+
`,
|
|
20075
|
+
`
|
|
20076
|
+
CREATE INDEX sessions_token_hash_idx
|
|
20077
|
+
ON sessions (session_token_hash)
|
|
20078
|
+
`,
|
|
20079
|
+
`
|
|
20080
|
+
CREATE INDEX sessions_user_org_idx
|
|
20081
|
+
ON sessions (user_id, organization_id)
|
|
20082
|
+
`,
|
|
20083
|
+
`
|
|
20084
|
+
CREATE TABLE email_auth_challenges (
|
|
20085
|
+
id uuid PRIMARY KEY,
|
|
20086
|
+
email text NOT NULL,
|
|
20087
|
+
code_hash text NOT NULL,
|
|
20088
|
+
accepted_terms_at timestamptz,
|
|
20089
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20090
|
+
expires_at timestamptz NOT NULL,
|
|
20091
|
+
used_at timestamptz
|
|
20092
|
+
)
|
|
20093
|
+
`,
|
|
20094
|
+
`
|
|
20095
|
+
CREATE INDEX email_auth_challenges_email_idx
|
|
20096
|
+
ON email_auth_challenges (lower(email), created_at DESC)
|
|
20097
|
+
`,
|
|
20098
|
+
`
|
|
20099
|
+
CREATE INDEX email_auth_challenges_code_hash_idx
|
|
20100
|
+
ON email_auth_challenges (code_hash)
|
|
20101
|
+
`,
|
|
20102
|
+
`
|
|
20103
|
+
CREATE TABLE github_device_authorizations (
|
|
20104
|
+
id uuid PRIMARY KEY,
|
|
20105
|
+
device_code text NOT NULL UNIQUE,
|
|
20106
|
+
user_code text NOT NULL,
|
|
20107
|
+
verification_uri text NOT NULL,
|
|
20108
|
+
interval_seconds integer NOT NULL,
|
|
20109
|
+
expires_at timestamptz NOT NULL,
|
|
20110
|
+
accepted_terms_at timestamptz,
|
|
20111
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20112
|
+
completed_at timestamptz,
|
|
20113
|
+
claimed_at timestamptz,
|
|
20114
|
+
terminal_error text,
|
|
20115
|
+
user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20116
|
+
organization_id uuid REFERENCES organizations(id) ON DELETE SET NULL
|
|
20117
|
+
)
|
|
20118
|
+
`,
|
|
20119
|
+
`
|
|
20120
|
+
CREATE INDEX github_device_authorizations_user_code_idx
|
|
20121
|
+
ON github_device_authorizations (user_code, created_at DESC)
|
|
20122
|
+
`,
|
|
20123
|
+
`
|
|
20124
|
+
CREATE INDEX github_device_authorizations_expires_at_idx
|
|
20125
|
+
ON github_device_authorizations (expires_at)
|
|
20126
|
+
`,
|
|
20127
|
+
`
|
|
20128
|
+
CREATE TABLE project_members (
|
|
20129
|
+
id uuid PRIMARY KEY,
|
|
20130
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20131
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20132
|
+
role text NOT NULL,
|
|
20133
|
+
invited_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20134
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20135
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20136
|
+
UNIQUE (project_id, user_id)
|
|
20137
|
+
)
|
|
20138
|
+
`,
|
|
20139
|
+
`
|
|
20140
|
+
CREATE INDEX project_members_project_id_idx
|
|
20141
|
+
ON project_members (project_id, created_at DESC)
|
|
20142
|
+
`,
|
|
20143
|
+
`
|
|
20144
|
+
CREATE INDEX project_members_user_id_idx
|
|
20145
|
+
ON project_members (user_id, created_at DESC)
|
|
20146
|
+
`,
|
|
20147
|
+
`
|
|
20148
|
+
CREATE TABLE project_invites (
|
|
20149
|
+
id uuid PRIMARY KEY,
|
|
20150
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20151
|
+
email text NOT NULL,
|
|
20152
|
+
role text NOT NULL,
|
|
20153
|
+
invited_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20154
|
+
invite_token_hash text NOT NULL,
|
|
20155
|
+
accepted_at timestamptz,
|
|
20156
|
+
canceled_at timestamptz,
|
|
20157
|
+
expires_at timestamptz NOT NULL,
|
|
20158
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20159
|
+
)
|
|
20160
|
+
`,
|
|
20161
|
+
`
|
|
20162
|
+
CREATE INDEX project_invites_project_id_idx
|
|
20163
|
+
ON project_invites (project_id, created_at DESC)
|
|
20164
|
+
`,
|
|
20165
|
+
`
|
|
20166
|
+
CREATE UNIQUE INDEX project_invites_pending_project_email_key
|
|
20167
|
+
ON project_invites (project_id, lower(email))
|
|
20168
|
+
WHERE accepted_at IS NULL AND canceled_at IS NULL
|
|
20169
|
+
`,
|
|
20170
|
+
`
|
|
20171
|
+
CREATE UNIQUE INDEX project_invites_invite_token_hash_key
|
|
20172
|
+
ON project_invites (invite_token_hash)
|
|
20173
|
+
`,
|
|
20174
|
+
`
|
|
20175
|
+
CREATE TABLE oauth_identities (
|
|
20176
|
+
id uuid PRIMARY KEY,
|
|
20177
|
+
provider text NOT NULL,
|
|
20178
|
+
provider_user_id text NOT NULL,
|
|
20179
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20180
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20181
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20182
|
+
UNIQUE (provider, provider_user_id)
|
|
20183
|
+
)
|
|
20184
|
+
`,
|
|
20185
|
+
`
|
|
20186
|
+
CREATE INDEX oauth_identities_user_id_idx
|
|
20187
|
+
ON oauth_identities (user_id, provider)
|
|
20188
|
+
`,
|
|
20189
|
+
`
|
|
20190
|
+
CREATE TABLE probe_activations (
|
|
20191
|
+
id uuid PRIMARY KEY,
|
|
20192
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20193
|
+
created_by_member_id uuid NOT NULL,
|
|
20194
|
+
label_pattern text NOT NULL,
|
|
20195
|
+
service text NOT NULL DEFAULT '*',
|
|
20196
|
+
environment text NOT NULL DEFAULT '*',
|
|
20197
|
+
trigger_expires_at timestamptz NOT NULL,
|
|
20198
|
+
expires_at timestamptz NOT NULL,
|
|
20199
|
+
deactivated_at timestamptz,
|
|
20200
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20201
|
+
)
|
|
20202
|
+
`,
|
|
20203
|
+
`
|
|
20204
|
+
CREATE INDEX probe_activations_project_active_idx
|
|
20205
|
+
ON probe_activations (project_id, expires_at DESC)
|
|
20206
|
+
WHERE deactivated_at IS NULL
|
|
20207
|
+
`,
|
|
20208
|
+
`
|
|
20209
|
+
CREATE TABLE capture_policies (
|
|
20210
|
+
project_id uuid PRIMARY KEY REFERENCES projects(id) ON DELETE CASCADE,
|
|
20211
|
+
preset text NOT NULL DEFAULT 'minimal',
|
|
20212
|
+
capture_logs text,
|
|
20213
|
+
capture_request_events text,
|
|
20214
|
+
capture_breadcrumbs text,
|
|
20215
|
+
capture_probe_events text,
|
|
20216
|
+
immediate_client_error_statuses jsonb,
|
|
20217
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20218
|
+
)
|
|
20219
|
+
`,
|
|
20220
|
+
`
|
|
20221
|
+
CREATE TABLE capture_rules (
|
|
20222
|
+
id uuid PRIMARY KEY,
|
|
20223
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20224
|
+
name text NOT NULL,
|
|
20225
|
+
description text,
|
|
20226
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
20227
|
+
action text NOT NULL,
|
|
20228
|
+
matcher jsonb NOT NULL,
|
|
20229
|
+
sample_rate double precision,
|
|
20230
|
+
sample_event_class text,
|
|
20231
|
+
created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20232
|
+
created_from_incident_id text,
|
|
20233
|
+
created_from_event_id text,
|
|
20234
|
+
expires_at timestamptz,
|
|
20235
|
+
hit_count bigint NOT NULL DEFAULT 0,
|
|
20236
|
+
last_matched_at timestamptz,
|
|
20237
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20238
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20239
|
+
)
|
|
20240
|
+
`,
|
|
20241
|
+
`
|
|
20242
|
+
CREATE INDEX capture_rules_project_enabled_idx
|
|
20243
|
+
ON capture_rules (project_id, enabled)
|
|
20244
|
+
`,
|
|
20245
|
+
`
|
|
20246
|
+
CREATE INDEX capture_rules_project_updated_idx
|
|
20247
|
+
ON capture_rules (project_id, updated_at DESC)
|
|
20248
|
+
`,
|
|
20249
|
+
`
|
|
20250
|
+
CREATE TABLE deployments (
|
|
20251
|
+
id uuid PRIMARY KEY,
|
|
20252
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20253
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20254
|
+
environment text NOT NULL,
|
|
20255
|
+
source_event_id uuid UNIQUE NOT NULL,
|
|
20256
|
+
commit_sha text,
|
|
20257
|
+
version text,
|
|
20258
|
+
branch text,
|
|
20259
|
+
deployed_at timestamptz NOT NULL,
|
|
20260
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20261
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20262
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20263
|
+
)
|
|
20264
|
+
`,
|
|
20265
|
+
`
|
|
20266
|
+
CREATE INDEX deployments_project_service_env_deployed_idx
|
|
20267
|
+
ON deployments (project_id, service_id, environment, deployed_at DESC)
|
|
20268
|
+
`,
|
|
20269
|
+
`
|
|
20270
|
+
CREATE TABLE incidents (
|
|
20271
|
+
id uuid PRIMARY KEY,
|
|
20272
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20273
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20274
|
+
environment text NOT NULL DEFAULT 'production',
|
|
20275
|
+
fingerprint text NOT NULL,
|
|
20276
|
+
fingerprint_version text NOT NULL DEFAULT 'v1',
|
|
20277
|
+
title text NOT NULL,
|
|
20278
|
+
severity text NOT NULL,
|
|
20279
|
+
status text NOT NULL DEFAULT 'open',
|
|
20280
|
+
first_seen_at timestamptz NOT NULL,
|
|
20281
|
+
last_seen_at timestamptz NOT NULL,
|
|
20282
|
+
occurrence_count integer NOT NULL DEFAULT 1,
|
|
20283
|
+
matched_fields text[],
|
|
20284
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20285
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20286
|
+
regressed_at timestamptz,
|
|
20287
|
+
spike_detected_at timestamptz,
|
|
20288
|
+
frequency_occurrences_1m integer,
|
|
20289
|
+
frequency_occurrences_5m integer,
|
|
20290
|
+
frequency_occurrences_1h integer,
|
|
20291
|
+
frequency_occurrences_24h integer,
|
|
20292
|
+
frequency_baseline_1h_per_5m double precision,
|
|
20293
|
+
frequency_spike_ratio_5m_to_1h double precision,
|
|
20294
|
+
frequency_has_sufficient_baseline boolean,
|
|
20295
|
+
frequency_is_spiking boolean,
|
|
20296
|
+
frequency_snapshot_at timestamptz,
|
|
20297
|
+
latest_deployment_id uuid REFERENCES deployments(id) ON DELETE SET NULL,
|
|
20298
|
+
bundle_generation_number integer NOT NULL DEFAULT 0,
|
|
20299
|
+
bundle_created_at timestamptz,
|
|
20300
|
+
bundle_updated_at timestamptz,
|
|
20301
|
+
bundle_source_event_id uuid,
|
|
20302
|
+
bundle_source_occurred_at timestamptz,
|
|
20303
|
+
bundle_trigger text,
|
|
20304
|
+
bundle_failure_reason text,
|
|
20305
|
+
resolved_at timestamptz,
|
|
20306
|
+
resolved_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20307
|
+
UNIQUE (project_id, environment, service_id, fingerprint)
|
|
20308
|
+
)
|
|
20309
|
+
`,
|
|
20310
|
+
`
|
|
20311
|
+
CREATE TABLE processed_events (
|
|
20312
|
+
event_id uuid PRIMARY KEY,
|
|
20313
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20314
|
+
event_type text NOT NULL,
|
|
20315
|
+
fingerprint text NOT NULL,
|
|
20316
|
+
normalized_message text NOT NULL,
|
|
20317
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20318
|
+
)
|
|
20319
|
+
`,
|
|
20320
|
+
`
|
|
20321
|
+
CREATE TABLE improvement_opportunities (
|
|
20322
|
+
id uuid PRIMARY KEY,
|
|
20323
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20324
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20325
|
+
service_name text NOT NULL,
|
|
20326
|
+
environment text NOT NULL DEFAULT 'production',
|
|
20327
|
+
kind text NOT NULL,
|
|
20328
|
+
status text NOT NULL DEFAULT 'open',
|
|
20329
|
+
severity text NOT NULL,
|
|
20330
|
+
confidence numeric NOT NULL,
|
|
20331
|
+
fingerprint text NOT NULL,
|
|
20332
|
+
title text NOT NULL,
|
|
20333
|
+
summary text NOT NULL,
|
|
20334
|
+
occurrence_count integer NOT NULL DEFAULT 1,
|
|
20335
|
+
evidence jsonb NOT NULL,
|
|
20336
|
+
first_detected_at timestamptz NOT NULL,
|
|
20337
|
+
last_detected_at timestamptz NOT NULL,
|
|
20338
|
+
last_source_event_id uuid,
|
|
20339
|
+
related_incident_ids uuid[] NOT NULL DEFAULT '{}',
|
|
20340
|
+
bundle_generation_number integer NOT NULL DEFAULT 0,
|
|
20341
|
+
bundle_created_at timestamptz,
|
|
20342
|
+
bundle_updated_at timestamptz,
|
|
20343
|
+
bundle_source_event_id uuid,
|
|
20344
|
+
bundle_failure_reason text,
|
|
20345
|
+
resolved_at timestamptz,
|
|
20346
|
+
resolved_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20347
|
+
snoozed_until timestamptz,
|
|
20348
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20349
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20350
|
+
UNIQUE (project_id, fingerprint)
|
|
20351
|
+
)
|
|
20352
|
+
`,
|
|
20353
|
+
`
|
|
20354
|
+
CREATE INDEX improvement_opportunities_project_status_detected_idx
|
|
20355
|
+
ON improvement_opportunities (project_id, status, last_detected_at DESC)
|
|
20356
|
+
`,
|
|
20357
|
+
`
|
|
20358
|
+
CREATE INDEX improvement_opportunities_project_kind_detected_idx
|
|
20359
|
+
ON improvement_opportunities (project_id, kind, last_detected_at DESC)
|
|
20360
|
+
`,
|
|
20361
|
+
`
|
|
20362
|
+
CREATE INDEX improvement_opportunities_project_service_env_idx
|
|
20363
|
+
ON improvement_opportunities (project_id, service_id, environment)
|
|
20364
|
+
`,
|
|
20365
|
+
`
|
|
20366
|
+
CREATE TABLE improvement_opportunity_events (
|
|
20367
|
+
improvement_opportunity_id uuid NOT NULL REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20368
|
+
event_id uuid NOT NULL,
|
|
20369
|
+
event_type text NOT NULL,
|
|
20370
|
+
occurred_at timestamptz NOT NULL,
|
|
20371
|
+
PRIMARY KEY (improvement_opportunity_id, event_id)
|
|
20372
|
+
)
|
|
20373
|
+
`,
|
|
20374
|
+
`
|
|
20375
|
+
CREATE INDEX improvement_opportunity_events_detected_idx
|
|
20376
|
+
ON improvement_opportunity_events (improvement_opportunity_id, occurred_at DESC, event_id DESC)
|
|
20377
|
+
`,
|
|
20378
|
+
`
|
|
20379
|
+
CREATE TABLE bundle_generations (
|
|
20380
|
+
id uuid PRIMARY KEY,
|
|
20381
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20382
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20383
|
+
improvement_opportunity_id uuid REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20384
|
+
bundle_type text NOT NULL,
|
|
20385
|
+
generation_number integer NOT NULL,
|
|
20386
|
+
source_event_id uuid NOT NULL,
|
|
20387
|
+
source_occurred_at timestamptz NOT NULL,
|
|
20388
|
+
trigger text NOT NULL,
|
|
20389
|
+
created_at timestamptz NOT NULL,
|
|
20390
|
+
updated_at timestamptz NOT NULL,
|
|
20391
|
+
CHECK (
|
|
20392
|
+
(incident_id IS NOT NULL AND improvement_opportunity_id IS NULL AND bundle_type = 'failure')
|
|
20393
|
+
OR (incident_id IS NULL AND improvement_opportunity_id IS NOT NULL AND bundle_type = 'improvement')
|
|
20394
|
+
)
|
|
20395
|
+
)
|
|
20396
|
+
`,
|
|
20397
|
+
`
|
|
20398
|
+
CREATE UNIQUE INDEX bundle_generations_incident_source_idx
|
|
20399
|
+
ON bundle_generations (incident_id, source_event_id)
|
|
20400
|
+
WHERE incident_id IS NOT NULL
|
|
20401
|
+
`,
|
|
20402
|
+
`
|
|
20403
|
+
CREATE UNIQUE INDEX bundle_generations_improvement_source_idx
|
|
20404
|
+
ON bundle_generations (improvement_opportunity_id, source_event_id)
|
|
20405
|
+
WHERE improvement_opportunity_id IS NOT NULL
|
|
20406
|
+
`,
|
|
20407
|
+
`
|
|
20408
|
+
CREATE INDEX bundle_generations_project_created_idx
|
|
20409
|
+
ON bundle_generations (project_id, created_at DESC, bundle_type)
|
|
20410
|
+
`,
|
|
20411
|
+
`
|
|
20412
|
+
CREATE INDEX bundle_generations_incident_generation_idx
|
|
20413
|
+
ON bundle_generations (incident_id, generation_number DESC)
|
|
20414
|
+
`,
|
|
20415
|
+
`
|
|
20416
|
+
CREATE INDEX bundle_generations_improvement_generation_idx
|
|
20417
|
+
ON bundle_generations (improvement_opportunity_id, generation_number DESC)
|
|
20418
|
+
WHERE improvement_opportunity_id IS NOT NULL
|
|
20419
|
+
`,
|
|
20420
|
+
`
|
|
20421
|
+
CREATE TABLE incident_events (
|
|
20422
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20423
|
+
event_id uuid NOT NULL,
|
|
20424
|
+
event_type text NOT NULL,
|
|
20425
|
+
event_class text NOT NULL DEFAULT 'context_signal',
|
|
20426
|
+
occurred_at timestamptz NOT NULL,
|
|
20427
|
+
is_sampled boolean NOT NULL DEFAULT false,
|
|
20428
|
+
level text,
|
|
20429
|
+
retain_first boolean NOT NULL DEFAULT false,
|
|
20430
|
+
retain_latest boolean NOT NULL DEFAULT false,
|
|
20431
|
+
retain_after_deploy boolean NOT NULL DEFAULT false,
|
|
20432
|
+
retain_highest_severity boolean NOT NULL DEFAULT false,
|
|
20433
|
+
retain_deploy_metadata boolean NOT NULL DEFAULT false,
|
|
20434
|
+
severity_rank integer NOT NULL DEFAULT 0,
|
|
20435
|
+
PRIMARY KEY (incident_id, event_id)
|
|
20436
|
+
)
|
|
20437
|
+
`,
|
|
20438
|
+
`
|
|
20439
|
+
CREATE INDEX incident_events_incident_occurred_event_idx
|
|
20440
|
+
ON incident_events (incident_id, occurred_at DESC, event_id DESC)
|
|
20441
|
+
`,
|
|
20442
|
+
`
|
|
20443
|
+
CREATE INDEX incident_events_incident_level_occurred_event_idx
|
|
20444
|
+
ON incident_events (incident_id, level, occurred_at DESC, event_id DESC)
|
|
20445
|
+
`,
|
|
20446
|
+
`
|
|
20447
|
+
CREATE INDEX incident_events_incident_sampled_idx
|
|
20448
|
+
ON incident_events (incident_id, is_sampled, occurred_at ASC, event_id ASC)
|
|
20449
|
+
`,
|
|
20450
|
+
`
|
|
20451
|
+
CREATE TABLE weekly_report_channels (
|
|
20452
|
+
id uuid PRIMARY KEY,
|
|
20453
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20454
|
+
channel text NOT NULL,
|
|
20455
|
+
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20456
|
+
schedule_day_of_week text NOT NULL,
|
|
20457
|
+
schedule_hour_of_day integer NOT NULL,
|
|
20458
|
+
schedule_timezone text NOT NULL,
|
|
20459
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20460
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20461
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20462
|
+
)
|
|
20463
|
+
`,
|
|
20464
|
+
`
|
|
20465
|
+
CREATE INDEX weekly_report_channels_project_created_idx
|
|
20466
|
+
ON weekly_report_channels (project_id, created_at ASC)
|
|
20467
|
+
`,
|
|
20468
|
+
`
|
|
20469
|
+
CREATE UNIQUE INDEX weekly_report_channels_project_email_unique_idx
|
|
20470
|
+
ON weekly_report_channels (project_id)
|
|
20471
|
+
WHERE channel = 'email'
|
|
20472
|
+
`,
|
|
20473
|
+
`
|
|
20474
|
+
CREATE TABLE weekly_report_deliveries (
|
|
20475
|
+
id uuid PRIMARY KEY,
|
|
20476
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20477
|
+
weekly_report_channel_id uuid REFERENCES weekly_report_channels(id) ON DELETE CASCADE,
|
|
20478
|
+
window_start timestamptz NOT NULL,
|
|
20479
|
+
window_end timestamptz NOT NULL,
|
|
20480
|
+
channel text NOT NULL,
|
|
20481
|
+
status text NOT NULL,
|
|
20482
|
+
last_error text,
|
|
20483
|
+
delivered_at timestamptz,
|
|
20484
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20485
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20486
|
+
)
|
|
20487
|
+
`,
|
|
20488
|
+
`
|
|
20489
|
+
CREATE INDEX weekly_report_deliveries_project_window_idx
|
|
20490
|
+
ON weekly_report_deliveries (project_id, window_end DESC, channel)
|
|
20491
|
+
`,
|
|
20492
|
+
`
|
|
20493
|
+
CREATE UNIQUE INDEX weekly_report_deliveries_channel_window_idx
|
|
20494
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_start, window_end)
|
|
20495
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
20496
|
+
`,
|
|
20497
|
+
`
|
|
20498
|
+
CREATE INDEX weekly_report_deliveries_channel_idx
|
|
20499
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_end DESC)
|
|
20500
|
+
`,
|
|
20501
|
+
`
|
|
20502
|
+
CREATE TABLE alert_rules (
|
|
20503
|
+
id uuid PRIMARY KEY,
|
|
20504
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20505
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20506
|
+
service_id uuid REFERENCES services(id) ON DELETE CASCADE,
|
|
20507
|
+
channel text NOT NULL,
|
|
20508
|
+
condition_type text NOT NULL,
|
|
20509
|
+
severity_min text,
|
|
20510
|
+
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20511
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20512
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20513
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20514
|
+
)
|
|
20515
|
+
`,
|
|
20516
|
+
`
|
|
20517
|
+
CREATE INDEX alert_rules_project_enabled_idx
|
|
20518
|
+
ON alert_rules (project_id, is_enabled)
|
|
20519
|
+
`,
|
|
20520
|
+
`
|
|
20521
|
+
CREATE TABLE slack_destinations (
|
|
20522
|
+
id uuid PRIMARY KEY,
|
|
20523
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20524
|
+
slack_team_id text NOT NULL,
|
|
20525
|
+
slack_team_name text,
|
|
20526
|
+
slack_channel_id text NOT NULL,
|
|
20527
|
+
slack_channel_name text,
|
|
20528
|
+
webhook_url_ciphertext text NOT NULL,
|
|
20529
|
+
installed_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20530
|
+
is_active boolean NOT NULL DEFAULT true,
|
|
20531
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20532
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20533
|
+
UNIQUE (organization_id, slack_team_id, slack_channel_id)
|
|
20534
|
+
)
|
|
20535
|
+
`,
|
|
20536
|
+
`
|
|
20537
|
+
CREATE INDEX slack_destinations_org_active_idx
|
|
20538
|
+
ON slack_destinations (organization_id, is_active, created_at)
|
|
20539
|
+
`,
|
|
20540
|
+
`
|
|
20541
|
+
CREATE TABLE alert_deliveries (
|
|
20542
|
+
id uuid PRIMARY KEY,
|
|
20543
|
+
alert_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE,
|
|
20544
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20545
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20546
|
+
condition_type text NOT NULL,
|
|
20547
|
+
dedupe_key text NOT NULL,
|
|
20548
|
+
channel text NOT NULL,
|
|
20549
|
+
status text NOT NULL,
|
|
20550
|
+
payload jsonb NOT NULL,
|
|
20551
|
+
last_error text,
|
|
20552
|
+
delivered_at timestamptz,
|
|
20553
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20554
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20555
|
+
UNIQUE (alert_id, incident_id, dedupe_key)
|
|
20556
|
+
)
|
|
20557
|
+
`,
|
|
20558
|
+
`
|
|
20559
|
+
CREATE INDEX alert_deliveries_project_status_idx
|
|
20560
|
+
ON alert_deliveries (project_id, status, created_at DESC)
|
|
20561
|
+
`,
|
|
20562
|
+
`
|
|
20563
|
+
CREATE TABLE alert_email_digests (
|
|
20564
|
+
id uuid PRIMARY KEY,
|
|
20565
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20566
|
+
recipient text NOT NULL,
|
|
20567
|
+
status text NOT NULL,
|
|
20568
|
+
next_attempt_at timestamptz,
|
|
20569
|
+
claimed_at timestamptz,
|
|
20570
|
+
last_error text,
|
|
20571
|
+
delivered_at timestamptz,
|
|
20572
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20573
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20574
|
+
)
|
|
20575
|
+
`,
|
|
20576
|
+
`
|
|
20577
|
+
CREATE UNIQUE INDEX alert_email_digests_project_recipient_pending_idx
|
|
20578
|
+
ON alert_email_digests (project_id, recipient)
|
|
20579
|
+
WHERE status = 'pending' AND claimed_at IS NULL
|
|
20580
|
+
`,
|
|
20581
|
+
`
|
|
20582
|
+
CREATE INDEX alert_email_digests_status_next_attempt_idx
|
|
20583
|
+
ON alert_email_digests (status, next_attempt_at)
|
|
20584
|
+
`,
|
|
20585
|
+
`
|
|
20586
|
+
CREATE TABLE alert_email_digest_items (
|
|
20587
|
+
id uuid PRIMARY KEY,
|
|
20588
|
+
digest_id uuid NOT NULL REFERENCES alert_email_digests(id) ON DELETE CASCADE,
|
|
20589
|
+
alert_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE,
|
|
20590
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20591
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20592
|
+
condition_type text NOT NULL,
|
|
20593
|
+
dedupe_key text NOT NULL,
|
|
20594
|
+
payload jsonb NOT NULL,
|
|
20595
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20596
|
+
UNIQUE (alert_id, incident_id, dedupe_key)
|
|
20597
|
+
)
|
|
20598
|
+
`,
|
|
20599
|
+
`
|
|
20600
|
+
CREATE INDEX alert_email_digest_items_digest_created_idx
|
|
20601
|
+
ON alert_email_digest_items (digest_id, created_at ASC)
|
|
20602
|
+
`,
|
|
20603
|
+
`
|
|
20604
|
+
CREATE TABLE agent_webhooks (
|
|
20605
|
+
id uuid PRIMARY KEY,
|
|
20606
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20607
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20608
|
+
url text NOT NULL,
|
|
20609
|
+
secret_hash text NOT NULL,
|
|
20610
|
+
events text[] NOT NULL,
|
|
20611
|
+
filters jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20612
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20613
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20614
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20615
|
+
)
|
|
20616
|
+
`,
|
|
20617
|
+
`
|
|
20618
|
+
CREATE INDEX agent_webhooks_project_enabled_idx
|
|
20619
|
+
ON agent_webhooks (project_id, is_enabled)
|
|
20620
|
+
`,
|
|
20621
|
+
`
|
|
20622
|
+
CREATE TABLE webhook_deliveries (
|
|
20623
|
+
id uuid PRIMARY KEY,
|
|
20624
|
+
webhook_id uuid REFERENCES agent_webhooks(id) ON DELETE CASCADE,
|
|
20625
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20626
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20627
|
+
event_type text NOT NULL,
|
|
20628
|
+
target_url text NOT NULL,
|
|
20629
|
+
signing_secret text NOT NULL,
|
|
20630
|
+
status text NOT NULL DEFAULT 'pending',
|
|
20631
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20632
|
+
occurred_at timestamptz NOT NULL,
|
|
20633
|
+
next_attempt_at timestamptz,
|
|
20634
|
+
last_response_code integer,
|
|
20635
|
+
last_attempted_at timestamptz,
|
|
20636
|
+
last_error text,
|
|
20637
|
+
payload jsonb NOT NULL,
|
|
20638
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20639
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20640
|
+
)
|
|
20641
|
+
`,
|
|
20642
|
+
`
|
|
20643
|
+
CREATE INDEX webhook_deliveries_status_next_attempt_idx
|
|
20644
|
+
ON webhook_deliveries (status, next_attempt_at)
|
|
20645
|
+
`,
|
|
20646
|
+
`
|
|
20647
|
+
CREATE TABLE processed_billing_events (
|
|
20648
|
+
event_id text PRIMARY KEY,
|
|
20649
|
+
event_type text NOT NULL,
|
|
20650
|
+
organization_id uuid,
|
|
20651
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20652
|
+
)
|
|
20653
|
+
`,
|
|
20654
|
+
`
|
|
20655
|
+
CREATE TABLE github_installations (
|
|
20656
|
+
id uuid PRIMARY KEY,
|
|
20657
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20658
|
+
installation_id bigint NOT NULL UNIQUE,
|
|
20659
|
+
account_login text NOT NULL,
|
|
20660
|
+
account_type text NOT NULL CHECK (account_type IN ('Organization', 'User')),
|
|
20661
|
+
status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'removed')),
|
|
20662
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20663
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20664
|
+
UNIQUE (organization_id)
|
|
20665
|
+
)
|
|
20666
|
+
`,
|
|
20667
|
+
`
|
|
20668
|
+
CREATE INDEX github_installations_status_idx
|
|
20669
|
+
ON github_installations (status)
|
|
20670
|
+
`,
|
|
20671
|
+
`
|
|
20672
|
+
CREATE TABLE project_github_repos (
|
|
20673
|
+
id uuid PRIMARY KEY,
|
|
20674
|
+
project_id uuid NOT NULL UNIQUE REFERENCES projects(id) ON DELETE CASCADE,
|
|
20675
|
+
installation_id uuid NOT NULL REFERENCES github_installations(id) ON DELETE CASCADE,
|
|
20676
|
+
repo_owner text NOT NULL,
|
|
20677
|
+
repo_name text NOT NULL,
|
|
20678
|
+
default_branch text NOT NULL DEFAULT 'main',
|
|
20679
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20680
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20681
|
+
)
|
|
20682
|
+
`,
|
|
20683
|
+
`
|
|
20684
|
+
CREATE TABLE github_dispatch_rules (
|
|
20685
|
+
id uuid PRIMARY KEY,
|
|
20686
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20687
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20688
|
+
name text NOT NULL,
|
|
20689
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
20690
|
+
event_types text[] NOT NULL,
|
|
20691
|
+
environments text[],
|
|
20692
|
+
services text[],
|
|
20693
|
+
severity_min text CHECK (severity_min IN ('low', 'medium', 'high', 'critical')),
|
|
20694
|
+
bundle_type text CHECK (bundle_type IN ('failure', 'improvement')),
|
|
20695
|
+
incident_status text NOT NULL DEFAULT 'new_or_reopened'
|
|
20696
|
+
CHECK (incident_status IN ('new_only', 'reopened_only', 'new_or_reopened')),
|
|
20697
|
+
cooldown_seconds integer NOT NULL DEFAULT 300,
|
|
20698
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20699
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20700
|
+
)
|
|
20701
|
+
`,
|
|
20702
|
+
`
|
|
20703
|
+
CREATE INDEX github_dispatch_rules_project_enabled_idx
|
|
20704
|
+
ON github_dispatch_rules (project_id, enabled)
|
|
20705
|
+
`,
|
|
20706
|
+
`
|
|
20707
|
+
CREATE TABLE github_dispatch_deliveries (
|
|
20708
|
+
id uuid PRIMARY KEY,
|
|
20709
|
+
rule_id uuid NOT NULL REFERENCES github_dispatch_rules(id) ON DELETE CASCADE,
|
|
20710
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20711
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20712
|
+
improvement_opportunity_id uuid REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20713
|
+
target_fingerprint text NOT NULL,
|
|
20714
|
+
installation_id bigint NOT NULL,
|
|
20715
|
+
repo_owner text NOT NULL,
|
|
20716
|
+
repo_name text NOT NULL,
|
|
20717
|
+
status text NOT NULL DEFAULT 'pending'
|
|
20718
|
+
CHECK (status IN ('pending', 'retrying', 'delivered', 'failed', 'skipped')),
|
|
20719
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20720
|
+
next_attempt_at timestamptz,
|
|
20721
|
+
last_attempt_at timestamptz,
|
|
20722
|
+
last_error text,
|
|
20723
|
+
github_status_code integer,
|
|
20724
|
+
dispatch_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20725
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20726
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20727
|
+
dedupe_key text NOT NULL,
|
|
20728
|
+
CHECK (
|
|
20729
|
+
(incident_id IS NOT NULL AND improvement_opportunity_id IS NULL)
|
|
20730
|
+
OR (incident_id IS NULL AND improvement_opportunity_id IS NOT NULL)
|
|
20731
|
+
)
|
|
20732
|
+
)
|
|
20733
|
+
`,
|
|
20734
|
+
`
|
|
20735
|
+
CREATE INDEX github_dispatch_deliveries_status_next_attempt_idx
|
|
20736
|
+
ON github_dispatch_deliveries (status, next_attempt_at)
|
|
20737
|
+
`,
|
|
20738
|
+
`
|
|
20739
|
+
CREATE UNIQUE INDEX github_dispatch_deliveries_rule_dedupe_key_idx
|
|
20740
|
+
ON github_dispatch_deliveries (rule_id, target_fingerprint, dedupe_key)
|
|
20741
|
+
`,
|
|
20742
|
+
`
|
|
20743
|
+
CREATE TABLE org_usage_counters (
|
|
20744
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20745
|
+
period_starts_at timestamptz NOT NULL,
|
|
20746
|
+
raw_ingested_events integer NOT NULL DEFAULT 0,
|
|
20747
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20748
|
+
PRIMARY KEY (organization_id, period_starts_at)
|
|
20749
|
+
)
|
|
20750
|
+
`,
|
|
20751
|
+
`
|
|
20752
|
+
CREATE TABLE operational_email_deliveries (
|
|
20753
|
+
id uuid PRIMARY KEY,
|
|
20754
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20755
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20756
|
+
kind text NOT NULL
|
|
20757
|
+
CHECK (kind IN ('webhook_auto_disabled', 'allowance_warning_80', 'allowance_limit_reached', 'retention_rotation_notice')),
|
|
20758
|
+
dedupe_key text NOT NULL,
|
|
20759
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20760
|
+
status text NOT NULL DEFAULT 'pending'
|
|
20761
|
+
CHECK (status IN ('pending', 'retrying', 'delivered', 'failed')),
|
|
20762
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20763
|
+
next_attempt_at timestamptz,
|
|
20764
|
+
last_error text,
|
|
20765
|
+
delivered_at timestamptz,
|
|
20766
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20767
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20768
|
+
UNIQUE (organization_id, kind, dedupe_key)
|
|
20769
|
+
)
|
|
20770
|
+
`,
|
|
20771
|
+
`
|
|
20772
|
+
CREATE INDEX operational_email_deliveries_status_next_attempt_idx
|
|
20773
|
+
ON operational_email_deliveries (status, next_attempt_at, created_at)
|
|
20774
|
+
`
|
|
20775
|
+
];
|
|
20776
|
+
var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS.join(";\n\n");
|
|
20777
|
+
|
|
20778
|
+
// ../../packages/storage/src/schema-migrations.ts
|
|
19170
20779
|
function computeMigrationChecksum(input) {
|
|
19171
20780
|
return (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(input)).digest("hex");
|
|
19172
20781
|
}
|
|
@@ -19430,6 +21039,234 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
19430
21039
|
)
|
|
19431
21040
|
`
|
|
19432
21041
|
]
|
|
21042
|
+
}),
|
|
21043
|
+
defineStorageSchemaMigration({
|
|
21044
|
+
id: "202605180004_add_operational_email_deliveries",
|
|
21045
|
+
description: "Add durable operational email delivery queue with retries and dedupe.",
|
|
21046
|
+
statements: [
|
|
21047
|
+
`
|
|
21048
|
+
CREATE TABLE IF NOT EXISTS operational_email_deliveries (
|
|
21049
|
+
id uuid PRIMARY KEY,
|
|
21050
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
21051
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
21052
|
+
kind text NOT NULL,
|
|
21053
|
+
dedupe_key text NOT NULL,
|
|
21054
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
21055
|
+
status text NOT NULL DEFAULT 'pending',
|
|
21056
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
21057
|
+
next_attempt_at timestamptz,
|
|
21058
|
+
last_error text,
|
|
21059
|
+
delivered_at timestamptz,
|
|
21060
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
21061
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
21062
|
+
UNIQUE (organization_id, kind, dedupe_key)
|
|
21063
|
+
)
|
|
21064
|
+
`,
|
|
21065
|
+
`
|
|
21066
|
+
ALTER TABLE operational_email_deliveries
|
|
21067
|
+
DROP CONSTRAINT IF EXISTS operational_email_deliveries_kind_check
|
|
21068
|
+
`,
|
|
21069
|
+
`
|
|
21070
|
+
ALTER TABLE operational_email_deliveries
|
|
21071
|
+
ADD CONSTRAINT operational_email_deliveries_kind_check
|
|
21072
|
+
CHECK (kind IN ('webhook_auto_disabled', 'allowance_warning_80', 'allowance_limit_reached', 'retention_rotation_notice'))
|
|
21073
|
+
`,
|
|
21074
|
+
`
|
|
21075
|
+
ALTER TABLE operational_email_deliveries
|
|
21076
|
+
DROP CONSTRAINT IF EXISTS operational_email_deliveries_status_check
|
|
21077
|
+
`,
|
|
21078
|
+
`
|
|
21079
|
+
ALTER TABLE operational_email_deliveries
|
|
21080
|
+
ADD CONSTRAINT operational_email_deliveries_status_check
|
|
21081
|
+
CHECK (status IN ('pending', 'retrying', 'delivered', 'failed'))
|
|
21082
|
+
`,
|
|
21083
|
+
`
|
|
21084
|
+
CREATE INDEX IF NOT EXISTS operational_email_deliveries_status_next_attempt_idx
|
|
21085
|
+
ON operational_email_deliveries (status, next_attempt_at, created_at)
|
|
21086
|
+
`
|
|
21087
|
+
]
|
|
21088
|
+
}),
|
|
21089
|
+
defineStorageSchemaMigration({
|
|
21090
|
+
id: "202605180005_add_github_improvement_dispatch_targets",
|
|
21091
|
+
description: "Allow GitHub dispatch deliveries to target either incidents or hosted improvements.",
|
|
21092
|
+
statements: [
|
|
21093
|
+
"ALTER TABLE github_dispatch_deliveries ALTER COLUMN incident_id DROP NOT NULL",
|
|
21094
|
+
"ALTER TABLE github_dispatch_deliveries RENAME COLUMN incident_fingerprint TO target_fingerprint",
|
|
21095
|
+
"ALTER TABLE github_dispatch_deliveries ADD COLUMN IF NOT EXISTS improvement_opportunity_id uuid REFERENCES improvement_opportunities(id) ON DELETE CASCADE",
|
|
21096
|
+
"DROP INDEX IF EXISTS github_dispatch_deliveries_rule_dedupe_key_idx",
|
|
21097
|
+
`
|
|
21098
|
+
CREATE UNIQUE INDEX IF NOT EXISTS github_dispatch_deliveries_rule_dedupe_key_idx
|
|
21099
|
+
ON github_dispatch_deliveries (rule_id, target_fingerprint, dedupe_key)
|
|
21100
|
+
`,
|
|
21101
|
+
"ALTER TABLE github_dispatch_deliveries DROP CONSTRAINT IF EXISTS github_dispatch_deliveries_check",
|
|
21102
|
+
`
|
|
21103
|
+
ALTER TABLE github_dispatch_deliveries
|
|
21104
|
+
ADD CONSTRAINT github_dispatch_deliveries_check CHECK (
|
|
21105
|
+
(incident_id IS NOT NULL AND improvement_opportunity_id IS NULL)
|
|
21106
|
+
OR (incident_id IS NULL AND improvement_opportunity_id IS NOT NULL)
|
|
21107
|
+
)
|
|
21108
|
+
`
|
|
21109
|
+
]
|
|
21110
|
+
}),
|
|
21111
|
+
defineStorageSchemaMigration({
|
|
21112
|
+
id: "202605180006_add_missing_bundle_and_creator_columns",
|
|
21113
|
+
description: "Backfill creator ownership columns and incident bundle tracking columns that existed only in bootstrap schema.",
|
|
21114
|
+
statements: [
|
|
21115
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_generation_number integer NOT NULL DEFAULT 0",
|
|
21116
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_created_at timestamptz",
|
|
21117
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_updated_at timestamptz",
|
|
21118
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_source_event_id uuid",
|
|
21119
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_source_occurred_at timestamptz",
|
|
21120
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_trigger text",
|
|
21121
|
+
"ALTER TABLE incidents ADD COLUMN IF NOT EXISTS bundle_failure_reason text",
|
|
21122
|
+
"ALTER TABLE alert_rules ADD COLUMN IF NOT EXISTS created_by_user_id uuid",
|
|
21123
|
+
`
|
|
21124
|
+
UPDATE alert_rules ar
|
|
21125
|
+
SET created_by_user_id = p.owner_user_id
|
|
21126
|
+
FROM projects p
|
|
21127
|
+
WHERE ar.project_id = p.id
|
|
21128
|
+
AND ar.created_by_user_id IS NULL
|
|
21129
|
+
`,
|
|
21130
|
+
"ALTER TABLE alert_rules DROP CONSTRAINT IF EXISTS alert_rules_created_by_user_id_fkey",
|
|
21131
|
+
`
|
|
21132
|
+
ALTER TABLE alert_rules
|
|
21133
|
+
ADD CONSTRAINT alert_rules_created_by_user_id_fkey
|
|
21134
|
+
FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
21135
|
+
`,
|
|
21136
|
+
"ALTER TABLE alert_rules ALTER COLUMN created_by_user_id SET NOT NULL",
|
|
21137
|
+
"ALTER TABLE agent_webhooks ADD COLUMN IF NOT EXISTS created_by_user_id uuid",
|
|
21138
|
+
`
|
|
21139
|
+
UPDATE agent_webhooks aw
|
|
21140
|
+
SET created_by_user_id = p.owner_user_id
|
|
21141
|
+
FROM projects p
|
|
21142
|
+
WHERE aw.project_id = p.id
|
|
21143
|
+
AND aw.created_by_user_id IS NULL
|
|
21144
|
+
`,
|
|
21145
|
+
"ALTER TABLE agent_webhooks DROP CONSTRAINT IF EXISTS agent_webhooks_created_by_user_id_fkey",
|
|
21146
|
+
`
|
|
21147
|
+
ALTER TABLE agent_webhooks
|
|
21148
|
+
ADD CONSTRAINT agent_webhooks_created_by_user_id_fkey
|
|
21149
|
+
FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
21150
|
+
`,
|
|
21151
|
+
"ALTER TABLE agent_webhooks ALTER COLUMN created_by_user_id SET NOT NULL",
|
|
21152
|
+
"ALTER TABLE github_dispatch_rules ADD COLUMN IF NOT EXISTS created_by_user_id uuid",
|
|
21153
|
+
`
|
|
21154
|
+
UPDATE github_dispatch_rules gdr
|
|
21155
|
+
SET created_by_user_id = p.owner_user_id
|
|
21156
|
+
FROM projects p
|
|
21157
|
+
WHERE gdr.project_id = p.id
|
|
21158
|
+
AND gdr.created_by_user_id IS NULL
|
|
21159
|
+
`,
|
|
21160
|
+
"ALTER TABLE github_dispatch_rules DROP CONSTRAINT IF EXISTS github_dispatch_rules_created_by_user_id_fkey",
|
|
21161
|
+
`
|
|
21162
|
+
ALTER TABLE github_dispatch_rules
|
|
21163
|
+
ADD CONSTRAINT github_dispatch_rules_created_by_user_id_fkey
|
|
21164
|
+
FOREIGN KEY (created_by_user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
21165
|
+
`,
|
|
21166
|
+
"ALTER TABLE github_dispatch_rules ALTER COLUMN created_by_user_id SET NOT NULL"
|
|
21167
|
+
]
|
|
21168
|
+
}),
|
|
21169
|
+
defineStorageSchemaMigration({
|
|
21170
|
+
id: "202605200001_limit_weekly_report_email_channel_per_project",
|
|
21171
|
+
description: "Keep weekly email reports singular per project.",
|
|
21172
|
+
statements: [
|
|
21173
|
+
`
|
|
21174
|
+
DELETE FROM weekly_report_channels
|
|
21175
|
+
WHERE id IN (
|
|
21176
|
+
SELECT id
|
|
21177
|
+
FROM (
|
|
21178
|
+
SELECT
|
|
21179
|
+
id,
|
|
21180
|
+
row_number() OVER (PARTITION BY project_id ORDER BY created_at ASC, id ASC) AS row_number
|
|
21181
|
+
FROM weekly_report_channels
|
|
21182
|
+
WHERE channel = 'email'
|
|
21183
|
+
) ranked
|
|
21184
|
+
WHERE ranked.row_number > 1
|
|
21185
|
+
)
|
|
21186
|
+
`,
|
|
21187
|
+
`
|
|
21188
|
+
CREATE UNIQUE INDEX IF NOT EXISTS weekly_report_channels_project_email_unique_idx
|
|
21189
|
+
ON weekly_report_channels (project_id)
|
|
21190
|
+
WHERE channel = 'email'
|
|
21191
|
+
`
|
|
21192
|
+
]
|
|
21193
|
+
}),
|
|
21194
|
+
defineStorageSchemaMigration({
|
|
21195
|
+
id: "202605220001_add_project_token_allowed_origins",
|
|
21196
|
+
description: "Add optional browser-origin allowlists to project ingestion tokens.",
|
|
21197
|
+
statements: [
|
|
21198
|
+
"ALTER TABLE project_tokens ADD COLUMN IF NOT EXISTS allowed_origins jsonb NOT NULL DEFAULT '[]'::jsonb"
|
|
21199
|
+
]
|
|
21200
|
+
}),
|
|
21201
|
+
defineStorageSchemaMigration({
|
|
21202
|
+
id: "202605260001_fix_weekly_report_delivery_conflict_index",
|
|
21203
|
+
description: "Ensure weekly report delivery dedupe rows and partial unique index exist for conflict claims.",
|
|
21204
|
+
statements: [
|
|
21205
|
+
`
|
|
21206
|
+
DELETE FROM weekly_report_deliveries
|
|
21207
|
+
WHERE id IN (
|
|
21208
|
+
SELECT id
|
|
21209
|
+
FROM (
|
|
21210
|
+
SELECT
|
|
21211
|
+
id,
|
|
21212
|
+
row_number() OVER (
|
|
21213
|
+
PARTITION BY weekly_report_channel_id, window_start, window_end
|
|
21214
|
+
ORDER BY created_at ASC, id ASC
|
|
21215
|
+
) AS row_number
|
|
21216
|
+
FROM weekly_report_deliveries
|
|
21217
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
21218
|
+
) ranked
|
|
21219
|
+
WHERE ranked.row_number > 1
|
|
21220
|
+
)
|
|
21221
|
+
`,
|
|
21222
|
+
`
|
|
21223
|
+
CREATE UNIQUE INDEX IF NOT EXISTS weekly_report_deliveries_channel_window_idx
|
|
21224
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_start, window_end)
|
|
21225
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
21226
|
+
`
|
|
21227
|
+
]
|
|
21228
|
+
}),
|
|
21229
|
+
defineStorageSchemaMigration({
|
|
21230
|
+
id: "202605260001_set_high_confidence_as_project_improvement_default",
|
|
21231
|
+
description: "Make high-confidence the default hosted improvement sensitivity for new projects.",
|
|
21232
|
+
statements: [
|
|
21233
|
+
"ALTER TABLE projects ALTER COLUMN improvement_bundle_sensitivity SET DEFAULT 'high_confidence'"
|
|
21234
|
+
]
|
|
21235
|
+
}),
|
|
21236
|
+
defineStorageSchemaMigration({
|
|
21237
|
+
id: "202605260002_add_capture_rules",
|
|
21238
|
+
description: "Add persisted project capture rules for dynamic demote/sample/drop handling.",
|
|
21239
|
+
statements: [
|
|
21240
|
+
`
|
|
21241
|
+
CREATE TABLE IF NOT EXISTS capture_rules (
|
|
21242
|
+
id uuid PRIMARY KEY,
|
|
21243
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
21244
|
+
name text NOT NULL,
|
|
21245
|
+
description text,
|
|
21246
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
21247
|
+
action text NOT NULL,
|
|
21248
|
+
matcher jsonb NOT NULL,
|
|
21249
|
+
sample_rate double precision,
|
|
21250
|
+
sample_event_class text,
|
|
21251
|
+
created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
21252
|
+
created_from_incident_id text,
|
|
21253
|
+
created_from_event_id text,
|
|
21254
|
+
expires_at timestamptz,
|
|
21255
|
+
hit_count bigint NOT NULL DEFAULT 0,
|
|
21256
|
+
last_matched_at timestamptz,
|
|
21257
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
21258
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
21259
|
+
)
|
|
21260
|
+
`,
|
|
21261
|
+
`
|
|
21262
|
+
CREATE INDEX IF NOT EXISTS capture_rules_project_enabled_idx
|
|
21263
|
+
ON capture_rules (project_id, enabled)
|
|
21264
|
+
`,
|
|
21265
|
+
`
|
|
21266
|
+
CREATE INDEX IF NOT EXISTS capture_rules_project_updated_idx
|
|
21267
|
+
ON capture_rules (project_id, updated_at DESC)
|
|
21268
|
+
`
|
|
21269
|
+
]
|
|
19433
21270
|
})
|
|
19434
21271
|
];
|
|
19435
21272
|
|
|
@@ -19552,11 +21389,17 @@ function normalizeRouteTemplate(path) {
|
|
|
19552
21389
|
const normalizedSegments = pathWithoutQueryOrFragment.split("/").filter((segment) => segment.length > 0).map((segment) => isDynamicRouteSegment2(segment) ? "{param}" : segment);
|
|
19553
21390
|
return normalizedSegments.length === 0 ? "/" : `/${normalizedSegments.join("/")}`;
|
|
19554
21391
|
}
|
|
21392
|
+
function isBrowserSdkFallbackFrame(frame) {
|
|
21393
|
+
return frame.includes("debugbundle-browser-sdk") && frame.includes("onError");
|
|
21394
|
+
}
|
|
19555
21395
|
function deriveFirstApplicationFrame(errorContext) {
|
|
19556
21396
|
const firstFrame = errorContext?.top_frames[0];
|
|
19557
21397
|
if (firstFrame === void 0) {
|
|
19558
21398
|
return null;
|
|
19559
21399
|
}
|
|
21400
|
+
if (isBrowserSdkFallbackFrame(firstFrame)) {
|
|
21401
|
+
return null;
|
|
21402
|
+
}
|
|
19560
21403
|
const match = /at\s+(.*?)\s+\((.*?):(\d+):(\d+)\)$/.exec(firstFrame) ?? /at\s+(.*?):(\d+):(\d+)$/.exec(firstFrame);
|
|
19561
21404
|
if (match === null) {
|
|
19562
21405
|
return {
|
|
@@ -19578,6 +21421,20 @@ function deriveFirstApplicationFrame(errorContext) {
|
|
|
19578
21421
|
line: Number(match[2])
|
|
19579
21422
|
};
|
|
19580
21423
|
}
|
|
21424
|
+
function getPrimaryBrowserExceptionEvent(envelopes, primarySignalEnvelope) {
|
|
21425
|
+
if (primarySignalEnvelope !== null && isFrontendExceptionEnvelope(primarySignalEnvelope)) {
|
|
21426
|
+
return primarySignalEnvelope.payload.browser_event ?? null;
|
|
21427
|
+
}
|
|
21428
|
+
const envelope = selectLatestEnvelopeByType(envelopes, isFrontendExceptionEnvelope);
|
|
21429
|
+
return envelope?.payload.browser_event ?? null;
|
|
21430
|
+
}
|
|
21431
|
+
function isOpaqueBrowserError(errorContext, browserEvent) {
|
|
21432
|
+
if (browserEvent?.opaque === true) {
|
|
21433
|
+
return true;
|
|
21434
|
+
}
|
|
21435
|
+
const firstFrame = errorContext?.top_frames[0];
|
|
21436
|
+
return errorContext?.message === "Window error" && firstFrame !== void 0 && isBrowserSdkFallbackFrame(firstFrame);
|
|
21437
|
+
}
|
|
19581
21438
|
function buildErrorContext(envelopes, incident, primarySignalEnvelope) {
|
|
19582
21439
|
if (primarySignalEnvelope !== null && isBackendExceptionEnvelope(primarySignalEnvelope)) {
|
|
19583
21440
|
return {
|
|
@@ -19700,6 +21557,20 @@ function buildSummaryGuidance(input) {
|
|
|
19700
21557
|
recommended_action: null
|
|
19701
21558
|
};
|
|
19702
21559
|
}
|
|
21560
|
+
if (input.opaqueBrowserError) {
|
|
21561
|
+
if (input.browserEvent?.kind === "resource_error") {
|
|
21562
|
+
return {
|
|
21563
|
+
likely_cause: "The browser reported a resource load error without a usable application stack.",
|
|
21564
|
+
confidence: 0.35,
|
|
21565
|
+
recommended_action: "Inspect the captured resource target, browser network failures, CSP rules, and cross-origin asset configuration."
|
|
21566
|
+
};
|
|
21567
|
+
}
|
|
21568
|
+
return {
|
|
21569
|
+
likely_cause: "The browser reported an opaque window error without a usable application stack.",
|
|
21570
|
+
confidence: 0.35,
|
|
21571
|
+
recommended_action: "Inspect browser console output, resource loading, cross-origin script settings, and framework-level error boundaries for the affected route."
|
|
21572
|
+
};
|
|
21573
|
+
}
|
|
19703
21574
|
const route = input.requestContext?.route_template ?? input.requestContext?.path ?? null;
|
|
19704
21575
|
const requestDescription = input.requestContext !== null ? `${input.requestContext.method} ${route ?? input.requestContext.path}` : null;
|
|
19705
21576
|
const firstDependency = input.dependenciesContext?.items[0] ?? null;
|
|
@@ -19886,7 +21757,8 @@ function buildFrontendContext(envelopes) {
|
|
|
19886
21757
|
message: envelope.payload.message,
|
|
19887
21758
|
route: envelope.payload.route ?? null,
|
|
19888
21759
|
browser: envelope.payload.browser,
|
|
19889
|
-
ts: toIsoTimestamp(envelope.occurred_at)
|
|
21760
|
+
ts: toIsoTimestamp(envelope.occurred_at),
|
|
21761
|
+
...envelope.payload.browser_event !== void 0 ? { browser_event: envelope.payload.browser_event } : {}
|
|
19890
21762
|
});
|
|
19891
21763
|
}
|
|
19892
21764
|
}
|
|
@@ -20029,6 +21901,8 @@ function buildBundle(input) {
|
|
|
20029
21901
|
const gitContext = buildGitContext(sourceEnvelopes, input.configuredDeploy);
|
|
20030
21902
|
const deviceContext = buildDeviceContext(sourceEnvelopes);
|
|
20031
21903
|
const dependenciesContext = buildDependenciesContext(input.incident, errorContext, requestContext);
|
|
21904
|
+
const browserEvent = getPrimaryBrowserExceptionEvent(sourceEnvelopes, primarySignalEnvelope);
|
|
21905
|
+
const opaqueBrowserError = isOpaqueBrowserError(errorContext, browserEvent);
|
|
20032
21906
|
const primarySignalType = primarySignalEnvelope !== null ? mapSignalType(primarySignalEnvelope.event_type) : inferSignalTypeFromSourceEventTypes(sourceEventTypes);
|
|
20033
21907
|
const primarySourceEvent = errorContext?.name ?? sourceEventTypes[0] ?? "backend_exception";
|
|
20034
21908
|
const firstSeenAt = new Date(input.incident.first_seen_at).toISOString();
|
|
@@ -20043,7 +21917,9 @@ function buildBundle(input) {
|
|
|
20043
21917
|
requestContext,
|
|
20044
21918
|
responseContext,
|
|
20045
21919
|
dependenciesContext,
|
|
20046
|
-
firstApplicationFrame
|
|
21920
|
+
firstApplicationFrame,
|
|
21921
|
+
browserEvent,
|
|
21922
|
+
opaqueBrowserError
|
|
20047
21923
|
});
|
|
20048
21924
|
const candidate = {
|
|
20049
21925
|
bundle_version: 1,
|
|
@@ -21181,7 +23057,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
21181
23057
|
|
|
21182
23058
|
// ../cli/src/ingest-command.ts
|
|
21183
23059
|
var LOCAL_EVENTS_DIRECTORY_PATH2 = ".debugbundle/local/events";
|
|
21184
|
-
var
|
|
23060
|
+
var ProfileSchema2 = external_exports.object({
|
|
21185
23061
|
project: external_exports.object({
|
|
21186
23062
|
name: external_exports.string().min(1),
|
|
21187
23063
|
repo_url: external_exports.string()
|
|
@@ -21206,7 +23082,7 @@ function buildEventFileName(events, filePath) {
|
|
|
21206
23082
|
return `${lastOccurredAt}-${digest}-${slugify(events[0]?.service.name ?? (0, import_node_path7.basename)(filePath))}.events.json`;
|
|
21207
23083
|
}
|
|
21208
23084
|
async function readProfile(rootDirectory, readFile) {
|
|
21209
|
-
const parsedProfile =
|
|
23085
|
+
const parsedProfile = ProfileSchema2.safeParse(JSON.parse(await readFile((0, import_node_path7.join)(rootDirectory, PROFILE_FILE_PATH))));
|
|
21210
23086
|
if (!parsedProfile.success) {
|
|
21211
23087
|
throw new Error(`Invalid ${PROFILE_FILE_PATH}`);
|
|
21212
23088
|
}
|
|
@@ -21526,19 +23402,32 @@ function formatResult(input, exitCode, checks, errors, incidentId) {
|
|
|
21526
23402
|
output: input.json ? buildJsonOutput(checks, errors, incidentId) : formatHumanOutput(checks, incidentId)
|
|
21527
23403
|
};
|
|
21528
23404
|
}
|
|
21529
|
-
function buildCloudSuggestedActions(status, incidentId,
|
|
23405
|
+
function buildCloudSuggestedActions(status, incidentId, verification) {
|
|
23406
|
+
const mode = verification?.mode ?? "passive_recent_incident";
|
|
21530
23407
|
if (status === "healthy" && incidentId !== void 0 && (mode === "active_5xx" || mode === "active_4xx")) {
|
|
21531
23408
|
return [
|
|
21532
23409
|
`Run debugbundle inspect ${incidentId} --source cloud to inspect why the incident fired.`,
|
|
21533
23410
|
`Run debugbundle bundle ${incidentId} --source cloud to fetch the generated debug bundle.`
|
|
21534
23411
|
];
|
|
21535
23412
|
}
|
|
23413
|
+
if (status === "healthy" && incidentId !== void 0 && mode === "app_event") {
|
|
23414
|
+
return [
|
|
23415
|
+
`Run debugbundle inspect ${incidentId} --source cloud to inspect the captured app event.`,
|
|
23416
|
+
"Re-run debugbundle verify cloud --expect-app-event after instrumentation or deploy changes, using the same service, environment, and correlation hints when available."
|
|
23417
|
+
];
|
|
23418
|
+
}
|
|
21536
23419
|
if (status === "healthy" && incidentId !== void 0) {
|
|
21537
23420
|
return [
|
|
21538
23421
|
`Review incident ${incidentId} if you want to inspect the latest production bundle.`,
|
|
21539
23422
|
"Re-run debugbundle verify cloud after a fresh deploy or instrumentation change."
|
|
21540
23423
|
];
|
|
21541
23424
|
}
|
|
23425
|
+
if (mode === "app_event") {
|
|
23426
|
+
return [
|
|
23427
|
+
"Trigger a real SDK event from the target app, then re-run debugbundle verify cloud --expect-app-event with the same service and environment filters.",
|
|
23428
|
+
"Add --trace-id or --request-id when you have a correlation hint so the verification can match the hosted bundle deterministically."
|
|
23429
|
+
];
|
|
23430
|
+
}
|
|
21542
23431
|
return [
|
|
21543
23432
|
"Run debugbundle login to choose an auth flow, or use debugbundle login --github, debugbundle login --github-device, or debugbundle login <dbundle_mem_...> to create ~/.debugbundle/auth.json before verifying cloud traffic.",
|
|
21544
23433
|
"Generate a live cloud request, then re-run debugbundle verify cloud with the correct project and service filters."
|
|
@@ -21551,7 +23440,7 @@ function buildCloudJsonOutput(checks, errors, incidentId, verification) {
|
|
|
21551
23440
|
checks,
|
|
21552
23441
|
warnings: collectWarnings(checks),
|
|
21553
23442
|
errors,
|
|
21554
|
-
suggested_actions: buildCloudSuggestedActions(status, incidentId, verification
|
|
23443
|
+
suggested_actions: buildCloudSuggestedActions(status, incidentId, verification),
|
|
21555
23444
|
auto_fix_available: false
|
|
21556
23445
|
};
|
|
21557
23446
|
if (verification !== void 0) {
|
|
@@ -21566,7 +23455,7 @@ function formatCloudHumanOutput(checks, incidentId, verification) {
|
|
|
21566
23455
|
"Checks:",
|
|
21567
23456
|
...checks.map((check) => `- ${check.name}: ${check.status} - ${check.message}`),
|
|
21568
23457
|
"Suggested actions:",
|
|
21569
|
-
...buildCloudSuggestedActions(status, incidentId, verification
|
|
23458
|
+
...buildCloudSuggestedActions(status, incidentId, verification).map((action) => `- ${action}`)
|
|
21570
23459
|
].join("\n");
|
|
21571
23460
|
}
|
|
21572
23461
|
function formatCloudResult(input, exitCode, checks, errors, incidentId, verification) {
|
|
@@ -21597,6 +23486,19 @@ function localFailureStepName(checks) {
|
|
|
21597
23486
|
function cloudVerificationRunId(now) {
|
|
21598
23487
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
21599
23488
|
}
|
|
23489
|
+
function defaultCloudVerificationSuffix() {
|
|
23490
|
+
return (0, import_node_crypto6.randomUUID)().replace(/-/g, "").slice(0, 12);
|
|
23491
|
+
}
|
|
23492
|
+
function normalizeCloudVerificationSuffix(suffix) {
|
|
23493
|
+
const normalized = suffix.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 12);
|
|
23494
|
+
if (normalized.length > 0) {
|
|
23495
|
+
return normalized;
|
|
23496
|
+
}
|
|
23497
|
+
return defaultCloudVerificationSuffix();
|
|
23498
|
+
}
|
|
23499
|
+
function buildCloudVerificationRunId(now, suffix) {
|
|
23500
|
+
return `${cloudVerificationRunId(now)}-${normalizeCloudVerificationSuffix(suffix)}`;
|
|
23501
|
+
}
|
|
21600
23502
|
function requestFailureReason(responseStatus) {
|
|
21601
23503
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
21602
23504
|
event_type: "request_event",
|
|
@@ -21609,7 +23511,6 @@ function requestFailureReason(responseStatus) {
|
|
|
21609
23511
|
return incidentReason;
|
|
21610
23512
|
}
|
|
21611
23513
|
function buildCloudVerificationEvent(input) {
|
|
21612
|
-
const runId = cloudVerificationRunId(input.now);
|
|
21613
23514
|
const is5xxVerification = input.responseStatus >= 500;
|
|
21614
23515
|
const routeTemplate = is5xxVerification ? "/debugbundle/verify/cloud" : `/debugbundle/verify/cloud/client-error/${input.responseStatus}`;
|
|
21615
23516
|
const verificationLabel = is5xxVerification ? "true" : `client-error-${input.responseStatus}`;
|
|
@@ -21630,7 +23531,7 @@ function buildCloudVerificationEvent(input) {
|
|
|
21630
23531
|
route_template: routeTemplate,
|
|
21631
23532
|
query: {
|
|
21632
23533
|
debugbundle_verification: true,
|
|
21633
|
-
run_id: runId,
|
|
23534
|
+
run_id: input.runId,
|
|
21634
23535
|
synthetic_status: input.responseStatus
|
|
21635
23536
|
},
|
|
21636
23537
|
headers: {
|
|
@@ -21644,7 +23545,7 @@ function buildCloudVerificationEvent(input) {
|
|
|
21644
23545
|
response_body: {
|
|
21645
23546
|
error: is5xxVerification ? "debugbundle_cloud_verification" : "debugbundle_cloud_client_error_verification",
|
|
21646
23547
|
synthetic: true,
|
|
21647
|
-
run_id: runId,
|
|
23548
|
+
run_id: input.runId,
|
|
21648
23549
|
response_status: input.responseStatus
|
|
21649
23550
|
}
|
|
21650
23551
|
}
|
|
@@ -21659,6 +23560,45 @@ function validateActiveCloudVerificationInput(input) {
|
|
|
21659
23560
|
}
|
|
21660
23561
|
return null;
|
|
21661
23562
|
}
|
|
23563
|
+
function validateCloudVerificationInput(input) {
|
|
23564
|
+
const activeInputError = validateActiveCloudVerificationInput(input);
|
|
23565
|
+
if (activeInputError !== null) {
|
|
23566
|
+
return activeInputError;
|
|
23567
|
+
}
|
|
23568
|
+
const appEventVerificationEnabled = input.expectAppEvent === true || input.traceId !== void 0 || input.requestId !== void 0;
|
|
23569
|
+
if (appEventVerificationEnabled && (input.trigger5xx === true || input.trigger4xxStatus !== void 0)) {
|
|
23570
|
+
return "Choose either a synthetic trigger run or --expect-app-event, not both.";
|
|
23571
|
+
}
|
|
23572
|
+
if (appEventVerificationEnabled && input.service === void 0 && input.traceId === void 0 && input.requestId === void 0) {
|
|
23573
|
+
return "App-event verification requires --service, --trace-id, or --request-id so the check stays scoped.";
|
|
23574
|
+
}
|
|
23575
|
+
return null;
|
|
23576
|
+
}
|
|
23577
|
+
function buildCorrelationHints(input) {
|
|
23578
|
+
return {
|
|
23579
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23580
|
+
environment: input.environment,
|
|
23581
|
+
...input.traceId === void 0 ? {} : { trace_id: input.traceId },
|
|
23582
|
+
...input.requestId === void 0 ? {} : { request_id: input.requestId }
|
|
23583
|
+
};
|
|
23584
|
+
}
|
|
23585
|
+
function collectBundleHintMatches(bundle, input) {
|
|
23586
|
+
const serializedBundle = JSON.stringify(bundle);
|
|
23587
|
+
const matches = [];
|
|
23588
|
+
if (input.traceId !== void 0 && serializedBundle.includes(input.traceId)) {
|
|
23589
|
+
matches.push("trace_id");
|
|
23590
|
+
}
|
|
23591
|
+
if (input.requestId !== void 0 && serializedBundle.includes(input.requestId)) {
|
|
23592
|
+
matches.push("request_id");
|
|
23593
|
+
}
|
|
23594
|
+
return matches;
|
|
23595
|
+
}
|
|
23596
|
+
function requestedBundleHints(input) {
|
|
23597
|
+
return [
|
|
23598
|
+
...input.traceId === void 0 ? [] : ["trace_id"],
|
|
23599
|
+
...input.requestId === void 0 ? [] : ["request_id"]
|
|
23600
|
+
];
|
|
23601
|
+
}
|
|
21662
23602
|
async function sendEventsToApi(input, dependencies = {}) {
|
|
21663
23603
|
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
21664
23604
|
const baseUrl = input.baseUrl.endsWith("/") ? input.baseUrl.slice(0, -1) : input.baseUrl;
|
|
@@ -21850,7 +23790,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21850
23790
|
const checks = [];
|
|
21851
23791
|
const environment = input.environment ?? "production";
|
|
21852
23792
|
const maxAgeMinutes = input.maxAgeMinutes ?? 15;
|
|
21853
|
-
const activeInputError =
|
|
23793
|
+
const activeInputError = validateCloudVerificationInput(input);
|
|
21854
23794
|
if (activeInputError !== null) {
|
|
21855
23795
|
checks.push({
|
|
21856
23796
|
name: "trigger-input",
|
|
@@ -21891,9 +23831,124 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21891
23831
|
requestInput,
|
|
21892
23832
|
dependencies.fetchImpl === void 0 ? {} : { fetchImpl: dependencies.fetchImpl }
|
|
21893
23833
|
));
|
|
23834
|
+
const appEventVerificationEnabled = input.expectAppEvent === true || input.traceId !== void 0 || input.requestId !== void 0;
|
|
23835
|
+
if (appEventVerificationEnabled) {
|
|
23836
|
+
const verificationStartedAt = now();
|
|
23837
|
+
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
23838
|
+
const pollIntervalMs = dependencies.pollIntervalMs ?? 2e3;
|
|
23839
|
+
const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
23840
|
+
const requestedHints = requestedBundleHints(input);
|
|
23841
|
+
const verification = {
|
|
23842
|
+
mode: "app_event",
|
|
23843
|
+
bundle_status: "unknown",
|
|
23844
|
+
correlation_hints: buildCorrelationHints({
|
|
23845
|
+
environment,
|
|
23846
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23847
|
+
...input.traceId === void 0 ? {} : { traceId: input.traceId },
|
|
23848
|
+
...input.requestId === void 0 ? {} : { requestId: input.requestId }
|
|
23849
|
+
})
|
|
23850
|
+
};
|
|
23851
|
+
const oldestAcceptedIncidentTimestamp = verificationStartedAt.getTime() - maxAgeMinutes * 6e4;
|
|
23852
|
+
let incidentId;
|
|
23853
|
+
let exitCode = 0;
|
|
23854
|
+
let activeStep = "app-event-visibility";
|
|
23855
|
+
const errors = [];
|
|
23856
|
+
try {
|
|
23857
|
+
for (let attempt = 1; attempt <= pollAttempts; attempt += 1) {
|
|
23858
|
+
const result = await listIncidents({
|
|
23859
|
+
bearerToken: authState.bearer_token,
|
|
23860
|
+
projectId: input.projectId,
|
|
23861
|
+
environment,
|
|
23862
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23863
|
+
limit: 5
|
|
23864
|
+
});
|
|
23865
|
+
const recentIncidents = result.incidents.filter((candidate) => {
|
|
23866
|
+
const lastSeenAt = new Date(candidate.last_seen_at);
|
|
23867
|
+
return !Number.isNaN(lastSeenAt.getTime()) && lastSeenAt.getTime() >= oldestAcceptedIncidentTimestamp;
|
|
23868
|
+
});
|
|
23869
|
+
for (const candidate of recentIncidents) {
|
|
23870
|
+
const lastSeenAt = new Date(candidate.last_seen_at);
|
|
23871
|
+
if (requestedHints.length === 0 && lastSeenAt.getTime() < verificationStartedAt.getTime()) {
|
|
23872
|
+
continue;
|
|
23873
|
+
}
|
|
23874
|
+
if (requestedHints.length === 0) {
|
|
23875
|
+
incidentId = candidate.incident_id;
|
|
23876
|
+
verification.incident_id = candidate.incident_id;
|
|
23877
|
+
break;
|
|
23878
|
+
}
|
|
23879
|
+
activeStep = "bundle-status";
|
|
23880
|
+
const bundle = await getBundle({
|
|
23881
|
+
bearerToken: authState.bearer_token,
|
|
23882
|
+
incidentId: candidate.incident_id
|
|
23883
|
+
});
|
|
23884
|
+
verification.bundle_status = "status" in bundle && bundle.status === "pending" ? "pending" : "ready";
|
|
23885
|
+
if (verification.bundle_status !== "ready") {
|
|
23886
|
+
continue;
|
|
23887
|
+
}
|
|
23888
|
+
const matchedHints = collectBundleHintMatches(bundle, input);
|
|
23889
|
+
verification.matched_hints = matchedHints;
|
|
23890
|
+
if (requestedHints.every((hint) => matchedHints.includes(hint))) {
|
|
23891
|
+
incidentId = candidate.incident_id;
|
|
23892
|
+
verification.incident_id = candidate.incident_id;
|
|
23893
|
+
verification.suggested_next_command = `debugbundle inspect ${candidate.incident_id} --source cloud`;
|
|
23894
|
+
break;
|
|
23895
|
+
}
|
|
23896
|
+
}
|
|
23897
|
+
if (incidentId !== void 0) {
|
|
23898
|
+
break;
|
|
23899
|
+
}
|
|
23900
|
+
if (attempt < pollAttempts) {
|
|
23901
|
+
await sleep(pollIntervalMs);
|
|
23902
|
+
}
|
|
23903
|
+
}
|
|
23904
|
+
if (incidentId === void 0) {
|
|
23905
|
+
if (requestedHints.length > 0) {
|
|
23906
|
+
throw new Error(`No recent cloud incident matched the requested ${requestedHints.join(" and ")} hints within the ${maxAgeMinutes} minute verification window.`);
|
|
23907
|
+
}
|
|
23908
|
+
throw new Error(`No new ${environment} app event was visible within the ${maxAgeMinutes} minute verification window.`);
|
|
23909
|
+
}
|
|
23910
|
+
checks.push({
|
|
23911
|
+
name: "app-event-visibility",
|
|
23912
|
+
status: "ok",
|
|
23913
|
+
message: `Observed cloud incident ${incidentId} for the requested app-driven verification window.`
|
|
23914
|
+
});
|
|
23915
|
+
if (requestedHints.length > 0) {
|
|
23916
|
+
checks.push({
|
|
23917
|
+
name: "bundle-hint-match",
|
|
23918
|
+
status: "ok",
|
|
23919
|
+
message: `Matched ${verification.matched_hints?.join(" and ")} in bundle ${incidentId}.`
|
|
23920
|
+
});
|
|
23921
|
+
} else {
|
|
23922
|
+
const bundle = await getBundle({
|
|
23923
|
+
bearerToken: authState.bearer_token,
|
|
23924
|
+
incidentId
|
|
23925
|
+
});
|
|
23926
|
+
verification.bundle_status = "status" in bundle && bundle.status === "pending" ? "pending" : "ready";
|
|
23927
|
+
verification.suggested_next_command = `debugbundle inspect ${incidentId} --source cloud`;
|
|
23928
|
+
checks.push({
|
|
23929
|
+
name: "bundle-status",
|
|
23930
|
+
status: verification.bundle_status === "ready" ? "ok" : "warning",
|
|
23931
|
+
message: verification.bundle_status === "ready" ? `Bundle for incident ${incidentId} is ready.` : `Bundle for incident ${incidentId} is still pending.`
|
|
23932
|
+
});
|
|
23933
|
+
}
|
|
23934
|
+
} catch (error) {
|
|
23935
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
23936
|
+
checks.push({
|
|
23937
|
+
name: activeStep,
|
|
23938
|
+
status: "error",
|
|
23939
|
+
message
|
|
23940
|
+
});
|
|
23941
|
+
errors.push(message);
|
|
23942
|
+
exitCode = 1;
|
|
23943
|
+
}
|
|
23944
|
+
return formatCloudResult(input, exitCode, checks, errors, incidentId, verification);
|
|
23945
|
+
}
|
|
21894
23946
|
if (input.trigger5xx === true || input.trigger4xxStatus !== void 0) {
|
|
21895
23947
|
const verificationStartedAt = now();
|
|
21896
|
-
const runId =
|
|
23948
|
+
const runId = buildCloudVerificationRunId(
|
|
23949
|
+
verificationStartedAt,
|
|
23950
|
+
(dependencies.randomId ?? defaultCloudVerificationSuffix)()
|
|
23951
|
+
);
|
|
21897
23952
|
const serviceName = input.service ?? `debugbundle-verify-cloud-${runId}`;
|
|
21898
23953
|
const tokenLabel = `debugbundle verify cloud ${runId}`;
|
|
21899
23954
|
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
@@ -21925,6 +23980,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21925
23980
|
}
|
|
21926
23981
|
const event = buildCloudVerificationEvent({
|
|
21927
23982
|
now: verificationStartedAt,
|
|
23983
|
+
runId,
|
|
21928
23984
|
serviceName,
|
|
21929
23985
|
environment,
|
|
21930
23986
|
responseStatus
|
|
@@ -22231,53 +24287,62 @@ var import_node_path10 = require("node:path");
|
|
|
22231
24287
|
var SUGGESTED_ACTIONS2 = [
|
|
22232
24288
|
"Run debugbundle setup if .debugbundle/profile.json is missing.",
|
|
22233
24289
|
"Run debugbundle profile validate for field-level profile errors.",
|
|
22234
|
-
"Run debugbundle validate --fix to recreate missing local DebugBundle stubs when safe."
|
|
24290
|
+
"Run debugbundle validate --fix to recreate missing or stale local DebugBundle stubs when safe."
|
|
22235
24291
|
];
|
|
22236
24292
|
var FIXABLE_FILES = [
|
|
22237
24293
|
{
|
|
22238
24294
|
name: "connection-config",
|
|
22239
24295
|
filePath: CONNECTION_FILE_PATH,
|
|
22240
|
-
buildContent: buildConnectionConfig
|
|
24296
|
+
buildContent: buildConnectionConfig,
|
|
24297
|
+
checkContent: false
|
|
22241
24298
|
},
|
|
22242
24299
|
{
|
|
22243
24300
|
name: "agent-skill",
|
|
22244
24301
|
filePath: SKILL_FILE_PATH,
|
|
22245
|
-
buildContent: buildSkill
|
|
24302
|
+
buildContent: buildSkill,
|
|
24303
|
+
checkContent: true
|
|
22246
24304
|
},
|
|
22247
24305
|
{
|
|
22248
24306
|
name: "cli-reference",
|
|
22249
24307
|
filePath: CLI_REFERENCE_FILE_PATH,
|
|
22250
|
-
buildContent: buildCliReference
|
|
24308
|
+
buildContent: buildCliReference,
|
|
24309
|
+
checkContent: true
|
|
22251
24310
|
},
|
|
22252
24311
|
{
|
|
22253
24312
|
name: "mcp-reference",
|
|
22254
24313
|
filePath: MCP_REFERENCE_FILE_PATH,
|
|
22255
|
-
buildContent: buildMcpReference
|
|
24314
|
+
buildContent: buildMcpReference,
|
|
24315
|
+
checkContent: true
|
|
22256
24316
|
},
|
|
22257
24317
|
{
|
|
22258
24318
|
name: "bundle-schema-reference",
|
|
22259
24319
|
filePath: BUNDLE_SCHEMA_REFERENCE_FILE_PATH,
|
|
22260
|
-
buildContent: buildBundleSchemaReference
|
|
24320
|
+
buildContent: buildBundleSchemaReference,
|
|
24321
|
+
checkContent: true
|
|
22261
24322
|
},
|
|
22262
24323
|
{
|
|
22263
24324
|
name: "profile-enrichment-reference",
|
|
22264
24325
|
filePath: PROFILE_ENRICHMENT_REFERENCE_FILE_PATH,
|
|
22265
|
-
buildContent: buildProfileEnrichmentReference
|
|
24326
|
+
buildContent: buildProfileEnrichmentReference,
|
|
24327
|
+
checkContent: true
|
|
22266
24328
|
},
|
|
22267
24329
|
{
|
|
22268
24330
|
name: "improvement-analysis-recipe",
|
|
22269
24331
|
filePath: IMPROVEMENT_ANALYSIS_RECIPE_FILE_PATH,
|
|
22270
|
-
buildContent: buildImprovementAnalysisRecipe
|
|
24332
|
+
buildContent: buildImprovementAnalysisRecipe,
|
|
24333
|
+
checkContent: true
|
|
22271
24334
|
},
|
|
22272
24335
|
{
|
|
22273
24336
|
name: "performance-analysis-recipe",
|
|
22274
24337
|
filePath: PERFORMANCE_ANALYSIS_RECIPE_FILE_PATH,
|
|
22275
|
-
buildContent: buildPerformanceAnalysisRecipe
|
|
24338
|
+
buildContent: buildPerformanceAnalysisRecipe,
|
|
24339
|
+
checkContent: true
|
|
22276
24340
|
},
|
|
22277
24341
|
{
|
|
22278
24342
|
name: "skill-evals",
|
|
22279
24343
|
filePath: EVALS_FILE_PATH,
|
|
22280
|
-
buildContent: buildSkillEvals
|
|
24344
|
+
buildContent: buildSkillEvals,
|
|
24345
|
+
checkContent: true
|
|
22281
24346
|
}
|
|
22282
24347
|
];
|
|
22283
24348
|
async function pathExists5(path, stat) {
|
|
@@ -22391,6 +24456,28 @@ async function validateCommand(input, dependencies = {}) {
|
|
|
22391
24456
|
for (const fixableFile of FIXABLE_FILES) {
|
|
22392
24457
|
const absoluteFilePath = (0, import_node_path10.join)(rootDirectory, fixableFile.filePath);
|
|
22393
24458
|
if (await pathExists5(absoluteFilePath, stat)) {
|
|
24459
|
+
if (fixableFile.checkContent) {
|
|
24460
|
+
const currentContents = await readFile(absoluteFilePath);
|
|
24461
|
+
const expectedContents = fixableFile.buildContent();
|
|
24462
|
+
if (currentContents !== expectedContents) {
|
|
24463
|
+
if (input.fix === true) {
|
|
24464
|
+
await writeFile(absoluteFilePath, expectedContents);
|
|
24465
|
+
checks.push({
|
|
24466
|
+
name: fixableFile.name,
|
|
24467
|
+
status: "ok",
|
|
24468
|
+
message: `Updated stale ${fixableFile.filePath}`
|
|
24469
|
+
});
|
|
24470
|
+
continue;
|
|
24471
|
+
}
|
|
24472
|
+
autoFixAvailable = true;
|
|
24473
|
+
checks.push({
|
|
24474
|
+
name: fixableFile.name,
|
|
24475
|
+
status: "warning",
|
|
24476
|
+
message: `Stale ${fixableFile.filePath}; run debugbundle validate --fix to refresh it.`
|
|
24477
|
+
});
|
|
24478
|
+
continue;
|
|
24479
|
+
}
|
|
24480
|
+
}
|
|
22394
24481
|
checks.push({
|
|
22395
24482
|
name: fixableFile.name,
|
|
22396
24483
|
status: "ok",
|
|
@@ -22613,8 +24700,85 @@ function createBillingMcpTools(api) {
|
|
|
22613
24700
|
};
|
|
22614
24701
|
}
|
|
22615
24702
|
|
|
22616
|
-
// src/capture-
|
|
24703
|
+
// src/capture-rule-tools.ts
|
|
22617
24704
|
function mapMcpError4(error) {
|
|
24705
|
+
if (error instanceof CaptureRuleApiError) {
|
|
24706
|
+
throw new Error(`mcp_tool_error:${error.message}`);
|
|
24707
|
+
}
|
|
24708
|
+
throw new Error("mcp_tool_error:unknown_error");
|
|
24709
|
+
}
|
|
24710
|
+
function createCaptureRuleMcpTools(api) {
|
|
24711
|
+
return {
|
|
24712
|
+
async list_capture_rules(input) {
|
|
24713
|
+
try {
|
|
24714
|
+
return await api.listCaptureRules({
|
|
24715
|
+
bearerToken: String(input["bearerToken"]),
|
|
24716
|
+
projectId: String(input["projectId"])
|
|
24717
|
+
});
|
|
24718
|
+
} catch (error) {
|
|
24719
|
+
mapMcpError4(error);
|
|
24720
|
+
}
|
|
24721
|
+
},
|
|
24722
|
+
async create_capture_rule(input) {
|
|
24723
|
+
try {
|
|
24724
|
+
return await api.createCaptureRule({
|
|
24725
|
+
bearerToken: String(input["bearerToken"]),
|
|
24726
|
+
projectId: String(input["projectId"]),
|
|
24727
|
+
create: typeof input["create"] === "object" && input["create"] !== null ? input["create"] : {}
|
|
24728
|
+
});
|
|
24729
|
+
} catch (error) {
|
|
24730
|
+
mapMcpError4(error);
|
|
24731
|
+
}
|
|
24732
|
+
},
|
|
24733
|
+
async update_capture_rule(input) {
|
|
24734
|
+
try {
|
|
24735
|
+
return await api.updateCaptureRule({
|
|
24736
|
+
bearerToken: String(input["bearerToken"]),
|
|
24737
|
+
projectId: String(input["projectId"]),
|
|
24738
|
+
ruleId: String(input["ruleId"]),
|
|
24739
|
+
update: typeof input["update"] === "object" && input["update"] !== null ? input["update"] : {}
|
|
24740
|
+
});
|
|
24741
|
+
} catch (error) {
|
|
24742
|
+
mapMcpError4(error);
|
|
24743
|
+
}
|
|
24744
|
+
},
|
|
24745
|
+
async delete_capture_rule(input) {
|
|
24746
|
+
try {
|
|
24747
|
+
return await api.deleteCaptureRule({
|
|
24748
|
+
bearerToken: String(input["bearerToken"]),
|
|
24749
|
+
projectId: String(input["projectId"]),
|
|
24750
|
+
ruleId: String(input["ruleId"])
|
|
24751
|
+
});
|
|
24752
|
+
} catch (error) {
|
|
24753
|
+
mapMcpError4(error);
|
|
24754
|
+
}
|
|
24755
|
+
},
|
|
24756
|
+
async suggest_capture_rules_from_incident(input) {
|
|
24757
|
+
try {
|
|
24758
|
+
return await api.suggestCaptureRulesFromIncident({
|
|
24759
|
+
bearerToken: String(input["bearerToken"]),
|
|
24760
|
+
incidentId: String(input["incidentId"])
|
|
24761
|
+
});
|
|
24762
|
+
} catch (error) {
|
|
24763
|
+
mapMcpError4(error);
|
|
24764
|
+
}
|
|
24765
|
+
},
|
|
24766
|
+
async create_capture_rule_from_incident_suggestion(input) {
|
|
24767
|
+
try {
|
|
24768
|
+
return await api.createCaptureRuleFromIncidentSuggestion({
|
|
24769
|
+
bearerToken: String(input["bearerToken"]),
|
|
24770
|
+
incidentId: String(input["incidentId"]),
|
|
24771
|
+
create: typeof input["create"] === "object" && input["create"] !== null ? input["create"] : {}
|
|
24772
|
+
});
|
|
24773
|
+
} catch (error) {
|
|
24774
|
+
mapMcpError4(error);
|
|
24775
|
+
}
|
|
24776
|
+
}
|
|
24777
|
+
};
|
|
24778
|
+
}
|
|
24779
|
+
|
|
24780
|
+
// src/capture-policy-tools.ts
|
|
24781
|
+
function mapMcpError5(error) {
|
|
22618
24782
|
if (error instanceof CapturePolicyApiError) {
|
|
22619
24783
|
throw new Error(`mcp_tool_error:${error.message}`);
|
|
22620
24784
|
}
|
|
@@ -22629,7 +24793,7 @@ function createCapturePolicyMcpTools(api) {
|
|
|
22629
24793
|
projectId: String(input["projectId"])
|
|
22630
24794
|
});
|
|
22631
24795
|
} catch (error) {
|
|
22632
|
-
|
|
24796
|
+
mapMcpError5(error);
|
|
22633
24797
|
}
|
|
22634
24798
|
},
|
|
22635
24799
|
async update_capture_policy(input) {
|
|
@@ -22641,14 +24805,14 @@ function createCapturePolicyMcpTools(api) {
|
|
|
22641
24805
|
update
|
|
22642
24806
|
});
|
|
22643
24807
|
} catch (error) {
|
|
22644
|
-
|
|
24808
|
+
mapMcpError5(error);
|
|
22645
24809
|
}
|
|
22646
24810
|
}
|
|
22647
24811
|
};
|
|
22648
24812
|
}
|
|
22649
24813
|
|
|
22650
24814
|
// src/github-tools.ts
|
|
22651
|
-
function
|
|
24815
|
+
function mapMcpError6(error) {
|
|
22652
24816
|
if (error instanceof GitHubManagementApiError) {
|
|
22653
24817
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22654
24818
|
}
|
|
@@ -22667,7 +24831,7 @@ function createGitHubMcpTools(api) {
|
|
|
22667
24831
|
const repo = projectId === void 0 || api.getProjectRepo === void 0 ? void 0 : await api.getProjectRepo({ bearerToken, projectId });
|
|
22668
24832
|
return repo === void 0 ? { installation } : { installation, repo };
|
|
22669
24833
|
} catch (error) {
|
|
22670
|
-
|
|
24834
|
+
mapMcpError6(error);
|
|
22671
24835
|
}
|
|
22672
24836
|
},
|
|
22673
24837
|
async list_github_repositories(input) {
|
|
@@ -22679,7 +24843,7 @@ function createGitHubMcpTools(api) {
|
|
|
22679
24843
|
})
|
|
22680
24844
|
};
|
|
22681
24845
|
} catch (error) {
|
|
22682
|
-
|
|
24846
|
+
mapMcpError6(error);
|
|
22683
24847
|
}
|
|
22684
24848
|
},
|
|
22685
24849
|
async list_github_dispatch_rules(input) {
|
|
@@ -22691,7 +24855,7 @@ function createGitHubMcpTools(api) {
|
|
|
22691
24855
|
})
|
|
22692
24856
|
};
|
|
22693
24857
|
} catch (error) {
|
|
22694
|
-
|
|
24858
|
+
mapMcpError6(error);
|
|
22695
24859
|
}
|
|
22696
24860
|
},
|
|
22697
24861
|
async create_github_dispatch_rule(input) {
|
|
@@ -22712,7 +24876,7 @@ function createGitHubMcpTools(api) {
|
|
|
22712
24876
|
})
|
|
22713
24877
|
};
|
|
22714
24878
|
} catch (error) {
|
|
22715
|
-
|
|
24879
|
+
mapMcpError6(error);
|
|
22716
24880
|
}
|
|
22717
24881
|
},
|
|
22718
24882
|
async update_github_dispatch_rule(input) {
|
|
@@ -22734,7 +24898,7 @@ function createGitHubMcpTools(api) {
|
|
|
22734
24898
|
})
|
|
22735
24899
|
};
|
|
22736
24900
|
} catch (error) {
|
|
22737
|
-
|
|
24901
|
+
mapMcpError6(error);
|
|
22738
24902
|
}
|
|
22739
24903
|
},
|
|
22740
24904
|
async delete_github_dispatch_rule(input) {
|
|
@@ -22750,7 +24914,7 @@ function createGitHubMcpTools(api) {
|
|
|
22750
24914
|
rule_id: String(input["ruleId"])
|
|
22751
24915
|
};
|
|
22752
24916
|
} catch (error) {
|
|
22753
|
-
|
|
24917
|
+
mapMcpError6(error);
|
|
22754
24918
|
}
|
|
22755
24919
|
},
|
|
22756
24920
|
async list_github_deliveries(input) {
|
|
@@ -22764,7 +24928,7 @@ function createGitHubMcpTools(api) {
|
|
|
22764
24928
|
})
|
|
22765
24929
|
};
|
|
22766
24930
|
} catch (error) {
|
|
22767
|
-
|
|
24931
|
+
mapMcpError6(error);
|
|
22768
24932
|
}
|
|
22769
24933
|
},
|
|
22770
24934
|
async retry_github_delivery(input) {
|
|
@@ -22777,7 +24941,7 @@ function createGitHubMcpTools(api) {
|
|
|
22777
24941
|
})
|
|
22778
24942
|
};
|
|
22779
24943
|
} catch (error) {
|
|
22780
|
-
|
|
24944
|
+
mapMcpError6(error);
|
|
22781
24945
|
}
|
|
22782
24946
|
},
|
|
22783
24947
|
async set_project_github_repo(input) {
|
|
@@ -22791,7 +24955,7 @@ function createGitHubMcpTools(api) {
|
|
|
22791
24955
|
})
|
|
22792
24956
|
};
|
|
22793
24957
|
} catch (error) {
|
|
22794
|
-
|
|
24958
|
+
mapMcpError6(error);
|
|
22795
24959
|
}
|
|
22796
24960
|
},
|
|
22797
24961
|
async remove_project_github_repo(input) {
|
|
@@ -22805,14 +24969,14 @@ function createGitHubMcpTools(api) {
|
|
|
22805
24969
|
project_id: String(input["projectId"])
|
|
22806
24970
|
};
|
|
22807
24971
|
} catch (error) {
|
|
22808
|
-
|
|
24972
|
+
mapMcpError6(error);
|
|
22809
24973
|
}
|
|
22810
24974
|
}
|
|
22811
24975
|
};
|
|
22812
24976
|
}
|
|
22813
24977
|
|
|
22814
24978
|
// src/improvement-tools.ts
|
|
22815
|
-
function
|
|
24979
|
+
function mapMcpError7(error) {
|
|
22816
24980
|
if (error instanceof RetrievalApiError) {
|
|
22817
24981
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22818
24982
|
}
|
|
@@ -22845,7 +25009,7 @@ function createImprovementMcpTools(api) {
|
|
|
22845
25009
|
...typeof input["limit"] === "number" ? { limit: input["limit"] } : {}
|
|
22846
25010
|
});
|
|
22847
25011
|
} catch (error) {
|
|
22848
|
-
|
|
25012
|
+
mapMcpError7(error);
|
|
22849
25013
|
}
|
|
22850
25014
|
},
|
|
22851
25015
|
async get_improvement(input) {
|
|
@@ -22855,7 +25019,7 @@ function createImprovementMcpTools(api) {
|
|
|
22855
25019
|
improvementId: readString2(input, "improvementId")
|
|
22856
25020
|
});
|
|
22857
25021
|
} catch (error) {
|
|
22858
|
-
|
|
25022
|
+
mapMcpError7(error);
|
|
22859
25023
|
}
|
|
22860
25024
|
},
|
|
22861
25025
|
async get_improvement_bundle(input) {
|
|
@@ -22866,7 +25030,7 @@ function createImprovementMcpTools(api) {
|
|
|
22866
25030
|
improvementId: readString2(input, "improvementId")
|
|
22867
25031
|
});
|
|
22868
25032
|
} catch (error) {
|
|
22869
|
-
|
|
25033
|
+
mapMcpError7(error);
|
|
22870
25034
|
}
|
|
22871
25035
|
},
|
|
22872
25036
|
async resolve_improvement(input) {
|
|
@@ -22876,7 +25040,7 @@ function createImprovementMcpTools(api) {
|
|
|
22876
25040
|
improvementId: readString2(input, "improvementId")
|
|
22877
25041
|
});
|
|
22878
25042
|
} catch (error) {
|
|
22879
|
-
|
|
25043
|
+
mapMcpError7(error);
|
|
22880
25044
|
}
|
|
22881
25045
|
},
|
|
22882
25046
|
async reopen_improvement(input) {
|
|
@@ -22886,7 +25050,7 @@ function createImprovementMcpTools(api) {
|
|
|
22886
25050
|
improvementId: readString2(input, "improvementId")
|
|
22887
25051
|
});
|
|
22888
25052
|
} catch (error) {
|
|
22889
|
-
|
|
25053
|
+
mapMcpError7(error);
|
|
22890
25054
|
}
|
|
22891
25055
|
},
|
|
22892
25056
|
async snooze_improvement(input) {
|
|
@@ -22897,14 +25061,14 @@ function createImprovementMcpTools(api) {
|
|
|
22897
25061
|
snoozedUntil: readString2(input, "snoozedUntil")
|
|
22898
25062
|
});
|
|
22899
25063
|
} catch (error) {
|
|
22900
|
-
|
|
25064
|
+
mapMcpError7(error);
|
|
22901
25065
|
}
|
|
22902
25066
|
}
|
|
22903
25067
|
};
|
|
22904
25068
|
}
|
|
22905
25069
|
|
|
22906
25070
|
// src/improvement-settings-tools.ts
|
|
22907
|
-
function
|
|
25071
|
+
function mapMcpError8(error) {
|
|
22908
25072
|
if (error instanceof ImprovementSettingsApiError) {
|
|
22909
25073
|
throw new Error(`mcp_tool_error:${error.message}`);
|
|
22910
25074
|
}
|
|
@@ -22919,7 +25083,7 @@ function createImprovementSettingsMcpTools(api) {
|
|
|
22919
25083
|
projectId: String(input["projectId"])
|
|
22920
25084
|
});
|
|
22921
25085
|
} catch (error) {
|
|
22922
|
-
|
|
25086
|
+
mapMcpError8(error);
|
|
22923
25087
|
}
|
|
22924
25088
|
},
|
|
22925
25089
|
async update_improvement_settings(input) {
|
|
@@ -22931,14 +25095,14 @@ function createImprovementSettingsMcpTools(api) {
|
|
|
22931
25095
|
update
|
|
22932
25096
|
});
|
|
22933
25097
|
} catch (error) {
|
|
22934
|
-
|
|
25098
|
+
mapMcpError8(error);
|
|
22935
25099
|
}
|
|
22936
25100
|
}
|
|
22937
25101
|
};
|
|
22938
25102
|
}
|
|
22939
25103
|
|
|
22940
25104
|
// src/member-tools.ts
|
|
22941
|
-
function
|
|
25105
|
+
function mapMcpError9(error) {
|
|
22942
25106
|
if (error instanceof MemberApiError) {
|
|
22943
25107
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22944
25108
|
}
|
|
@@ -22953,7 +25117,7 @@ function createMemberMcpTools(api) {
|
|
|
22953
25117
|
projectId: String(input["projectId"])
|
|
22954
25118
|
});
|
|
22955
25119
|
} catch (error) {
|
|
22956
|
-
|
|
25120
|
+
mapMcpError9(error);
|
|
22957
25121
|
}
|
|
22958
25122
|
},
|
|
22959
25123
|
async list_project_member_invites(input) {
|
|
@@ -22963,7 +25127,7 @@ function createMemberMcpTools(api) {
|
|
|
22963
25127
|
projectId: String(input["projectId"])
|
|
22964
25128
|
});
|
|
22965
25129
|
} catch (error) {
|
|
22966
|
-
|
|
25130
|
+
mapMcpError9(error);
|
|
22967
25131
|
}
|
|
22968
25132
|
},
|
|
22969
25133
|
async invite_project_member(input) {
|
|
@@ -22975,7 +25139,7 @@ function createMemberMcpTools(api) {
|
|
|
22975
25139
|
role: String(input["role"])
|
|
22976
25140
|
});
|
|
22977
25141
|
} catch (error) {
|
|
22978
|
-
|
|
25142
|
+
mapMcpError9(error);
|
|
22979
25143
|
}
|
|
22980
25144
|
},
|
|
22981
25145
|
async cancel_project_member_invite(input) {
|
|
@@ -22986,7 +25150,7 @@ function createMemberMcpTools(api) {
|
|
|
22986
25150
|
inviteId: String(input["inviteId"])
|
|
22987
25151
|
});
|
|
22988
25152
|
} catch (error) {
|
|
22989
|
-
|
|
25153
|
+
mapMcpError9(error);
|
|
22990
25154
|
}
|
|
22991
25155
|
},
|
|
22992
25156
|
async update_project_member_role(input) {
|
|
@@ -22998,7 +25162,7 @@ function createMemberMcpTools(api) {
|
|
|
22998
25162
|
role: String(input["role"])
|
|
22999
25163
|
});
|
|
23000
25164
|
} catch (error) {
|
|
23001
|
-
|
|
25165
|
+
mapMcpError9(error);
|
|
23002
25166
|
}
|
|
23003
25167
|
},
|
|
23004
25168
|
async remove_project_member(input) {
|
|
@@ -23009,14 +25173,14 @@ function createMemberMcpTools(api) {
|
|
|
23009
25173
|
userId: String(input["userId"])
|
|
23010
25174
|
});
|
|
23011
25175
|
} catch (error) {
|
|
23012
|
-
|
|
25176
|
+
mapMcpError9(error);
|
|
23013
25177
|
}
|
|
23014
25178
|
}
|
|
23015
25179
|
};
|
|
23016
25180
|
}
|
|
23017
25181
|
|
|
23018
25182
|
// src/probe-tools.ts
|
|
23019
|
-
function
|
|
25183
|
+
function mapMcpError10(error) {
|
|
23020
25184
|
if (error instanceof ProbeApiError) {
|
|
23021
25185
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23022
25186
|
}
|
|
@@ -23045,7 +25209,7 @@ function createProbeMcpTools(api) {
|
|
|
23045
25209
|
}
|
|
23046
25210
|
return await api.activateProbe(requestInput);
|
|
23047
25211
|
} catch (error) {
|
|
23048
|
-
|
|
25212
|
+
mapMcpError10(error);
|
|
23049
25213
|
}
|
|
23050
25214
|
},
|
|
23051
25215
|
async list_active_probes(input) {
|
|
@@ -23055,7 +25219,7 @@ function createProbeMcpTools(api) {
|
|
|
23055
25219
|
projectId: String(input["projectId"])
|
|
23056
25220
|
});
|
|
23057
25221
|
} catch (error) {
|
|
23058
|
-
|
|
25222
|
+
mapMcpError10(error);
|
|
23059
25223
|
}
|
|
23060
25224
|
},
|
|
23061
25225
|
async deactivate_probe(input) {
|
|
@@ -23066,14 +25230,14 @@ function createProbeMcpTools(api) {
|
|
|
23066
25230
|
activationId: String(input["activationId"])
|
|
23067
25231
|
});
|
|
23068
25232
|
} catch (error) {
|
|
23069
|
-
|
|
25233
|
+
mapMcpError10(error);
|
|
23070
25234
|
}
|
|
23071
25235
|
}
|
|
23072
25236
|
};
|
|
23073
25237
|
}
|
|
23074
25238
|
|
|
23075
25239
|
// src/project-tools.ts
|
|
23076
|
-
function
|
|
25240
|
+
function mapMcpError11(error) {
|
|
23077
25241
|
if (error instanceof ProjectManagementApiError) {
|
|
23078
25242
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23079
25243
|
}
|
|
@@ -23091,7 +25255,7 @@ function createProjectMcpTools(api) {
|
|
|
23091
25255
|
}
|
|
23092
25256
|
return { projects: await api.listProjects(requestInput) };
|
|
23093
25257
|
} catch (error) {
|
|
23094
|
-
|
|
25258
|
+
mapMcpError11(error);
|
|
23095
25259
|
}
|
|
23096
25260
|
},
|
|
23097
25261
|
async create_project(input) {
|
|
@@ -23106,7 +25270,7 @@ function createProjectMcpTools(api) {
|
|
|
23106
25270
|
}
|
|
23107
25271
|
return { project: await api.createProject(requestInput) };
|
|
23108
25272
|
} catch (error) {
|
|
23109
|
-
|
|
25273
|
+
mapMcpError11(error);
|
|
23110
25274
|
}
|
|
23111
25275
|
},
|
|
23112
25276
|
async update_project(input) {
|
|
@@ -23126,7 +25290,7 @@ function createProjectMcpTools(api) {
|
|
|
23126
25290
|
}
|
|
23127
25291
|
return { project: await api.updateProject(requestInput) };
|
|
23128
25292
|
} catch (error) {
|
|
23129
|
-
|
|
25293
|
+
mapMcpError11(error);
|
|
23130
25294
|
}
|
|
23131
25295
|
},
|
|
23132
25296
|
async delete_project(input) {
|
|
@@ -23138,7 +25302,7 @@ function createProjectMcpTools(api) {
|
|
|
23138
25302
|
})
|
|
23139
25303
|
};
|
|
23140
25304
|
} catch (error) {
|
|
23141
|
-
|
|
25305
|
+
mapMcpError11(error);
|
|
23142
25306
|
}
|
|
23143
25307
|
}
|
|
23144
25308
|
};
|
|
@@ -23345,7 +25509,7 @@ async function persistCloudArtifact(directoryPath, fileName, payload, dependenci
|
|
|
23345
25509
|
}
|
|
23346
25510
|
|
|
23347
25511
|
// src/retrieval-tools.ts
|
|
23348
|
-
function
|
|
25512
|
+
function mapMcpError12(error) {
|
|
23349
25513
|
if (error instanceof RetrievalApiError) {
|
|
23350
25514
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23351
25515
|
}
|
|
@@ -23527,7 +25691,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23527
25691
|
incidents: incidents.incidents.map((incident) => attachSourceToRecord(incident, "cloud"))
|
|
23528
25692
|
};
|
|
23529
25693
|
} catch (error) {
|
|
23530
|
-
|
|
25694
|
+
mapMcpError12(error);
|
|
23531
25695
|
}
|
|
23532
25696
|
},
|
|
23533
25697
|
async get_incident(input) {
|
|
@@ -23562,7 +25726,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23562
25726
|
)
|
|
23563
25727
|
};
|
|
23564
25728
|
} catch (error) {
|
|
23565
|
-
|
|
25729
|
+
mapMcpError12(error);
|
|
23566
25730
|
}
|
|
23567
25731
|
},
|
|
23568
25732
|
async get_incident_context(input) {
|
|
@@ -23591,7 +25755,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23591
25755
|
"cloud"
|
|
23592
25756
|
);
|
|
23593
25757
|
} catch (error) {
|
|
23594
|
-
|
|
25758
|
+
mapMcpError12(error);
|
|
23595
25759
|
}
|
|
23596
25760
|
},
|
|
23597
25761
|
async resolve_incident(input) {
|
|
@@ -23636,7 +25800,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23636
25800
|
})()
|
|
23637
25801
|
};
|
|
23638
25802
|
} catch (error) {
|
|
23639
|
-
|
|
25803
|
+
mapMcpError12(error);
|
|
23640
25804
|
}
|
|
23641
25805
|
},
|
|
23642
25806
|
async reopen_incident(input) {
|
|
@@ -23681,7 +25845,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23681
25845
|
})()
|
|
23682
25846
|
};
|
|
23683
25847
|
} catch (error) {
|
|
23684
|
-
|
|
25848
|
+
mapMcpError12(error);
|
|
23685
25849
|
}
|
|
23686
25850
|
},
|
|
23687
25851
|
async get_bundle(input) {
|
|
@@ -23712,7 +25876,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23712
25876
|
}
|
|
23713
25877
|
);
|
|
23714
25878
|
} catch (error) {
|
|
23715
|
-
|
|
25879
|
+
mapMcpError12(error);
|
|
23716
25880
|
}
|
|
23717
25881
|
},
|
|
23718
25882
|
async get_logs(input) {
|
|
@@ -23732,7 +25896,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23732
25896
|
}
|
|
23733
25897
|
return await api.getLogs(requestInput);
|
|
23734
25898
|
} catch (error) {
|
|
23735
|
-
|
|
25899
|
+
mapMcpError12(error);
|
|
23736
25900
|
}
|
|
23737
25901
|
},
|
|
23738
25902
|
async get_reproduction(input) {
|
|
@@ -23763,14 +25927,14 @@ function createRetrievalMcpTools(api) {
|
|
|
23763
25927
|
}
|
|
23764
25928
|
);
|
|
23765
25929
|
} catch (error) {
|
|
23766
|
-
|
|
25930
|
+
mapMcpError12(error);
|
|
23767
25931
|
}
|
|
23768
25932
|
}
|
|
23769
25933
|
};
|
|
23770
25934
|
}
|
|
23771
25935
|
|
|
23772
25936
|
// src/services-tools.ts
|
|
23773
|
-
function
|
|
25937
|
+
function mapMcpError13(error) {
|
|
23774
25938
|
if (error instanceof RetrievalApiError) {
|
|
23775
25939
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23776
25940
|
}
|
|
@@ -23791,14 +25955,14 @@ function createServicesMcpTools(api) {
|
|
|
23791
25955
|
services: await api.listServices(requestInput)
|
|
23792
25956
|
};
|
|
23793
25957
|
} catch (error) {
|
|
23794
|
-
|
|
25958
|
+
mapMcpError13(error);
|
|
23795
25959
|
}
|
|
23796
25960
|
}
|
|
23797
25961
|
};
|
|
23798
25962
|
}
|
|
23799
25963
|
|
|
23800
25964
|
// src/setup-tools.ts
|
|
23801
|
-
function
|
|
25965
|
+
function mapMcpError14() {
|
|
23802
25966
|
throw new Error("mcp_tool_error:unknown_error");
|
|
23803
25967
|
}
|
|
23804
25968
|
function parseJsonOutput2(output) {
|
|
@@ -23813,7 +25977,7 @@ async function runJsonCommand2(command) {
|
|
|
23813
25977
|
const result = await command();
|
|
23814
25978
|
return parseJsonOutput2(result.output);
|
|
23815
25979
|
} catch {
|
|
23816
|
-
|
|
25980
|
+
mapMcpError14();
|
|
23817
25981
|
}
|
|
23818
25982
|
}
|
|
23819
25983
|
function createSetupMcpTools(commands) {
|
|
@@ -23872,7 +26036,7 @@ function createSetupMcpTools(commands) {
|
|
|
23872
26036
|
}
|
|
23873
26037
|
|
|
23874
26038
|
// src/slack-tools.ts
|
|
23875
|
-
function
|
|
26039
|
+
function mapMcpError15(error) {
|
|
23876
26040
|
if (error instanceof SlackApiError) {
|
|
23877
26041
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23878
26042
|
}
|
|
@@ -23889,7 +26053,7 @@ function createSlackMcpTools(api) {
|
|
|
23889
26053
|
})
|
|
23890
26054
|
};
|
|
23891
26055
|
} catch (error) {
|
|
23892
|
-
|
|
26056
|
+
mapMcpError15(error);
|
|
23893
26057
|
}
|
|
23894
26058
|
},
|
|
23895
26059
|
async get_slack_connect_url(input) {
|
|
@@ -23902,7 +26066,7 @@ function createSlackMcpTools(api) {
|
|
|
23902
26066
|
})
|
|
23903
26067
|
};
|
|
23904
26068
|
} catch (error) {
|
|
23905
|
-
|
|
26069
|
+
mapMcpError15(error);
|
|
23906
26070
|
}
|
|
23907
26071
|
},
|
|
23908
26072
|
async test_slack_destination(input) {
|
|
@@ -23915,7 +26079,7 @@ function createSlackMcpTools(api) {
|
|
|
23915
26079
|
})
|
|
23916
26080
|
};
|
|
23917
26081
|
} catch (error) {
|
|
23918
|
-
|
|
26082
|
+
mapMcpError15(error);
|
|
23919
26083
|
}
|
|
23920
26084
|
},
|
|
23921
26085
|
async delete_slack_destination(input) {
|
|
@@ -23928,14 +26092,14 @@ function createSlackMcpTools(api) {
|
|
|
23928
26092
|
})
|
|
23929
26093
|
};
|
|
23930
26094
|
} catch (error) {
|
|
23931
|
-
|
|
26095
|
+
mapMcpError15(error);
|
|
23932
26096
|
}
|
|
23933
26097
|
}
|
|
23934
26098
|
};
|
|
23935
26099
|
}
|
|
23936
26100
|
|
|
23937
26101
|
// src/token-tools.ts
|
|
23938
|
-
function
|
|
26102
|
+
function mapMcpError16(error) {
|
|
23939
26103
|
if (error instanceof TokenManagementApiError) {
|
|
23940
26104
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23941
26105
|
}
|
|
@@ -23956,20 +26120,22 @@ function createTokenMcpTools(api) {
|
|
|
23956
26120
|
tokens: await api.listProjectTokens(requestInput)
|
|
23957
26121
|
};
|
|
23958
26122
|
} catch (error) {
|
|
23959
|
-
|
|
26123
|
+
mapMcpError16(error);
|
|
23960
26124
|
}
|
|
23961
26125
|
},
|
|
23962
26126
|
async create_project_token(input) {
|
|
23963
26127
|
try {
|
|
26128
|
+
const allowedOrigins = Array.isArray(input["allowedOrigins"]) ? input["allowedOrigins"].map((value) => String(value)) : void 0;
|
|
23964
26129
|
return {
|
|
23965
26130
|
token: await api.createProjectToken({
|
|
23966
26131
|
bearerToken: String(input["bearerToken"]),
|
|
23967
26132
|
projectId: String(input["projectId"]),
|
|
23968
|
-
label: String(input["label"])
|
|
26133
|
+
label: String(input["label"]),
|
|
26134
|
+
...allowedOrigins === void 0 ? {} : { allowedOrigins }
|
|
23969
26135
|
})
|
|
23970
26136
|
};
|
|
23971
26137
|
} catch (error) {
|
|
23972
|
-
|
|
26138
|
+
mapMcpError16(error);
|
|
23973
26139
|
}
|
|
23974
26140
|
},
|
|
23975
26141
|
async revoke_project_token(input) {
|
|
@@ -23982,7 +26148,7 @@ function createTokenMcpTools(api) {
|
|
|
23982
26148
|
})
|
|
23983
26149
|
};
|
|
23984
26150
|
} catch (error) {
|
|
23985
|
-
|
|
26151
|
+
mapMcpError16(error);
|
|
23986
26152
|
}
|
|
23987
26153
|
},
|
|
23988
26154
|
async list_member_tokens(input) {
|
|
@@ -23997,7 +26163,7 @@ function createTokenMcpTools(api) {
|
|
|
23997
26163
|
tokens: await api.listMemberTokens(requestInput)
|
|
23998
26164
|
};
|
|
23999
26165
|
} catch (error) {
|
|
24000
|
-
|
|
26166
|
+
mapMcpError16(error);
|
|
24001
26167
|
}
|
|
24002
26168
|
},
|
|
24003
26169
|
async create_member_token(input) {
|
|
@@ -24009,7 +26175,7 @@ function createTokenMcpTools(api) {
|
|
|
24009
26175
|
})
|
|
24010
26176
|
};
|
|
24011
26177
|
} catch (error) {
|
|
24012
|
-
|
|
26178
|
+
mapMcpError16(error);
|
|
24013
26179
|
}
|
|
24014
26180
|
},
|
|
24015
26181
|
async revoke_member_token(input) {
|
|
@@ -24021,14 +26187,14 @@ function createTokenMcpTools(api) {
|
|
|
24021
26187
|
})
|
|
24022
26188
|
};
|
|
24023
26189
|
} catch (error) {
|
|
24024
|
-
|
|
26190
|
+
mapMcpError16(error);
|
|
24025
26191
|
}
|
|
24026
26192
|
}
|
|
24027
26193
|
};
|
|
24028
26194
|
}
|
|
24029
26195
|
|
|
24030
26196
|
// src/webhook-tools.ts
|
|
24031
|
-
function
|
|
26197
|
+
function mapMcpError17(error) {
|
|
24032
26198
|
if (error instanceof WebhookApiError) {
|
|
24033
26199
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24034
26200
|
}
|
|
@@ -24049,7 +26215,7 @@ function createWebhookMcpTools(api) {
|
|
|
24049
26215
|
webhooks: await api.listWebhooks(requestInput)
|
|
24050
26216
|
};
|
|
24051
26217
|
} catch (error) {
|
|
24052
|
-
|
|
26218
|
+
mapMcpError17(error);
|
|
24053
26219
|
}
|
|
24054
26220
|
},
|
|
24055
26221
|
async create_webhook(input) {
|
|
@@ -24070,7 +26236,7 @@ function createWebhookMcpTools(api) {
|
|
|
24070
26236
|
webhook: await api.createWebhook(requestInput)
|
|
24071
26237
|
};
|
|
24072
26238
|
} catch (error) {
|
|
24073
|
-
|
|
26239
|
+
mapMcpError17(error);
|
|
24074
26240
|
}
|
|
24075
26241
|
},
|
|
24076
26242
|
async update_webhook(input) {
|
|
@@ -24096,7 +26262,7 @@ function createWebhookMcpTools(api) {
|
|
|
24096
26262
|
webhook: await api.updateWebhook(requestInput)
|
|
24097
26263
|
};
|
|
24098
26264
|
} catch (error) {
|
|
24099
|
-
|
|
26265
|
+
mapMcpError17(error);
|
|
24100
26266
|
}
|
|
24101
26267
|
},
|
|
24102
26268
|
async delete_webhook(input) {
|
|
@@ -24109,7 +26275,7 @@ function createWebhookMcpTools(api) {
|
|
|
24109
26275
|
})
|
|
24110
26276
|
};
|
|
24111
26277
|
} catch (error) {
|
|
24112
|
-
|
|
26278
|
+
mapMcpError17(error);
|
|
24113
26279
|
}
|
|
24114
26280
|
},
|
|
24115
26281
|
async test_webhook(input) {
|
|
@@ -24126,7 +26292,7 @@ function createWebhookMcpTools(api) {
|
|
|
24126
26292
|
delivery: await api.testWebhook(requestInput)
|
|
24127
26293
|
};
|
|
24128
26294
|
} catch (error) {
|
|
24129
|
-
|
|
26295
|
+
mapMcpError17(error);
|
|
24130
26296
|
}
|
|
24131
26297
|
},
|
|
24132
26298
|
async list_webhook_deliveries(input) {
|
|
@@ -24143,7 +26309,7 @@ function createWebhookMcpTools(api) {
|
|
|
24143
26309
|
deliveries: await api.listWebhookDeliveries(requestInput)
|
|
24144
26310
|
};
|
|
24145
26311
|
} catch (error) {
|
|
24146
|
-
|
|
26312
|
+
mapMcpError17(error);
|
|
24147
26313
|
}
|
|
24148
26314
|
},
|
|
24149
26315
|
async retry_webhook_delivery(input) {
|
|
@@ -24155,14 +26321,14 @@ function createWebhookMcpTools(api) {
|
|
|
24155
26321
|
deliveryId: String(input["deliveryId"])
|
|
24156
26322
|
});
|
|
24157
26323
|
} catch (error) {
|
|
24158
|
-
|
|
26324
|
+
mapMcpError17(error);
|
|
24159
26325
|
}
|
|
24160
26326
|
}
|
|
24161
26327
|
};
|
|
24162
26328
|
}
|
|
24163
26329
|
|
|
24164
26330
|
// src/weekly-report-tools.ts
|
|
24165
|
-
function
|
|
26331
|
+
function mapMcpError18(error) {
|
|
24166
26332
|
if (error instanceof WeeklyReportApiError) {
|
|
24167
26333
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24168
26334
|
}
|
|
@@ -24180,7 +26346,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24180
26346
|
})
|
|
24181
26347
|
};
|
|
24182
26348
|
} catch (error) {
|
|
24183
|
-
|
|
26349
|
+
mapMcpError18(error);
|
|
24184
26350
|
}
|
|
24185
26351
|
},
|
|
24186
26352
|
async create_weekly_report_channel(input) {
|
|
@@ -24196,7 +26362,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24196
26362
|
})
|
|
24197
26363
|
};
|
|
24198
26364
|
} catch (error) {
|
|
24199
|
-
|
|
26365
|
+
mapMcpError18(error);
|
|
24200
26366
|
}
|
|
24201
26367
|
},
|
|
24202
26368
|
async update_weekly_report_channel(input) {
|
|
@@ -24211,7 +26377,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24211
26377
|
})
|
|
24212
26378
|
};
|
|
24213
26379
|
} catch (error) {
|
|
24214
|
-
|
|
26380
|
+
mapMcpError18(error);
|
|
24215
26381
|
}
|
|
24216
26382
|
},
|
|
24217
26383
|
async delete_weekly_report_channel(input) {
|
|
@@ -24223,7 +26389,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24223
26389
|
})
|
|
24224
26390
|
};
|
|
24225
26391
|
} catch (error) {
|
|
24226
|
-
|
|
26392
|
+
mapMcpError18(error);
|
|
24227
26393
|
}
|
|
24228
26394
|
}
|
|
24229
26395
|
};
|
|
@@ -24279,6 +26445,7 @@ async function createDefaultMcpTools(input = {}) {
|
|
|
24279
26445
|
...createWeeklyReportMcpTools(createWeeklyReportApi(httpClient)),
|
|
24280
26446
|
...createAlertMcpTools(createAlertApi(httpClient)),
|
|
24281
26447
|
...createProjectMcpTools(createProjectManagementApi(httpClient)),
|
|
26448
|
+
...createCaptureRuleMcpTools(createCaptureRuleApi(httpClient)),
|
|
24282
26449
|
...createCapturePolicyMcpTools(createCapturePolicyApi(httpClient)),
|
|
24283
26450
|
...createImprovementSettingsMcpTools(createImprovementSettingsApi(httpClient)),
|
|
24284
26451
|
...createProbeMcpTools(createProbeApi(httpClient)),
|
|
@@ -25906,7 +28073,8 @@ var MCP_TOOL_CATALOG = [
|
|
|
25906
28073
|
inputSchema: external_exports.object({
|
|
25907
28074
|
bearerToken: external_exports.string(),
|
|
25908
28075
|
projectId: external_exports.string(),
|
|
25909
|
-
label: external_exports.string()
|
|
28076
|
+
label: external_exports.string(),
|
|
28077
|
+
allowedOrigins: external_exports.array(external_exports.string()).optional()
|
|
25910
28078
|
})
|
|
25911
28079
|
},
|
|
25912
28080
|
{
|
|
@@ -26078,7 +28246,7 @@ var MCP_TOOL_CATALOG = [
|
|
|
26078
28246
|
{
|
|
26079
28247
|
name: "create_weekly_report_channel",
|
|
26080
28248
|
group: "weekly_reports",
|
|
26081
|
-
description: "Create a weekly report delivery channel.",
|
|
28249
|
+
description: "Create a weekly report delivery channel. Email channel config supports up to 3 recipients in config.to.",
|
|
26082
28250
|
inputSchema: external_exports.object({
|
|
26083
28251
|
bearerToken: external_exports.string(),
|
|
26084
28252
|
projectId: external_exports.string(),
|
|
@@ -26091,7 +28259,7 @@ var MCP_TOOL_CATALOG = [
|
|
|
26091
28259
|
{
|
|
26092
28260
|
name: "update_weekly_report_channel",
|
|
26093
28261
|
group: "weekly_reports",
|
|
26094
|
-
description: "Update a weekly report delivery channel.",
|
|
28262
|
+
description: "Update a weekly report delivery channel. Email channel config supports up to 3 recipients in config.to.",
|
|
26095
28263
|
inputSchema: external_exports.object({
|
|
26096
28264
|
bearerToken: external_exports.string(),
|
|
26097
28265
|
channelId: external_exports.string(),
|
|
@@ -26201,6 +28369,65 @@ var MCP_TOOL_CATALOG = [
|
|
|
26201
28369
|
projectId: external_exports.string()
|
|
26202
28370
|
})
|
|
26203
28371
|
},
|
|
28372
|
+
{
|
|
28373
|
+
name: "list_capture_rules",
|
|
28374
|
+
group: "capture_rules",
|
|
28375
|
+
description: "List project capture rules.",
|
|
28376
|
+
inputSchema: external_exports.object({
|
|
28377
|
+
bearerToken: external_exports.string(),
|
|
28378
|
+
projectId: external_exports.string()
|
|
28379
|
+
})
|
|
28380
|
+
},
|
|
28381
|
+
{
|
|
28382
|
+
name: "create_capture_rule",
|
|
28383
|
+
group: "capture_rules",
|
|
28384
|
+
description: "Create a project capture rule.",
|
|
28385
|
+
inputSchema: external_exports.object({
|
|
28386
|
+
bearerToken: external_exports.string(),
|
|
28387
|
+
projectId: external_exports.string(),
|
|
28388
|
+
create: jsonObjectSchema
|
|
28389
|
+
})
|
|
28390
|
+
},
|
|
28391
|
+
{
|
|
28392
|
+
name: "update_capture_rule",
|
|
28393
|
+
group: "capture_rules",
|
|
28394
|
+
description: "Update a project capture rule.",
|
|
28395
|
+
inputSchema: external_exports.object({
|
|
28396
|
+
bearerToken: external_exports.string(),
|
|
28397
|
+
projectId: external_exports.string(),
|
|
28398
|
+
ruleId: external_exports.string(),
|
|
28399
|
+
update: jsonObjectSchema
|
|
28400
|
+
})
|
|
28401
|
+
},
|
|
28402
|
+
{
|
|
28403
|
+
name: "delete_capture_rule",
|
|
28404
|
+
group: "capture_rules",
|
|
28405
|
+
description: "Delete a project capture rule.",
|
|
28406
|
+
inputSchema: external_exports.object({
|
|
28407
|
+
bearerToken: external_exports.string(),
|
|
28408
|
+
projectId: external_exports.string(),
|
|
28409
|
+
ruleId: external_exports.string()
|
|
28410
|
+
})
|
|
28411
|
+
},
|
|
28412
|
+
{
|
|
28413
|
+
name: "suggest_capture_rules_from_incident",
|
|
28414
|
+
group: "capture_rules",
|
|
28415
|
+
description: "Generate deterministic capture rule suggestions from an incident bundle.",
|
|
28416
|
+
inputSchema: external_exports.object({
|
|
28417
|
+
bearerToken: external_exports.string(),
|
|
28418
|
+
incidentId: external_exports.string()
|
|
28419
|
+
})
|
|
28420
|
+
},
|
|
28421
|
+
{
|
|
28422
|
+
name: "create_capture_rule_from_incident_suggestion",
|
|
28423
|
+
group: "capture_rules",
|
|
28424
|
+
description: "Create a capture rule from an incident-derived suggestion.",
|
|
28425
|
+
inputSchema: external_exports.object({
|
|
28426
|
+
bearerToken: external_exports.string(),
|
|
28427
|
+
incidentId: external_exports.string(),
|
|
28428
|
+
create: jsonObjectSchema
|
|
28429
|
+
})
|
|
28430
|
+
},
|
|
26204
28431
|
{
|
|
26205
28432
|
name: "get_capture_policy",
|
|
26206
28433
|
group: "capture_policy",
|