@debugbundle/mcp 0.1.8 → 0.1.10
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 +3 -1
- package/dist/main.cjs +2150 -131
- package/package.json +5 -4
- package/server.json +39 -0
package/dist/main.cjs
CHANGED
|
@@ -15665,7 +15665,8 @@ function createRetrievalApi(client) {
|
|
|
15665
15665
|
BundleSchema,
|
|
15666
15666
|
external_exports.object({
|
|
15667
15667
|
status: external_exports.literal("failed"),
|
|
15668
|
-
reason: external_exports.string()
|
|
15668
|
+
reason: external_exports.string(),
|
|
15669
|
+
related_incident_ids: external_exports.array(external_exports.string()).optional()
|
|
15669
15670
|
}).strict()
|
|
15670
15671
|
])
|
|
15671
15672
|
);
|
|
@@ -16552,6 +16553,406 @@ function getRequestAnomalyThreshold(input) {
|
|
|
16552
16553
|
return null;
|
|
16553
16554
|
}
|
|
16554
16555
|
|
|
16556
|
+
// ../../packages/shared-types/src/capture-rules.ts
|
|
16557
|
+
var CAPTURE_RULE_EVENT_TYPES = [
|
|
16558
|
+
"backend_exception",
|
|
16559
|
+
"request_event",
|
|
16560
|
+
"log_event",
|
|
16561
|
+
"frontend_breadcrumb",
|
|
16562
|
+
"frontend_exception",
|
|
16563
|
+
"deploy_metadata",
|
|
16564
|
+
"error_suppressed",
|
|
16565
|
+
"probe_event"
|
|
16566
|
+
];
|
|
16567
|
+
var CAPTURE_RULE_RUNTIME_VALUES = [
|
|
16568
|
+
"browser",
|
|
16569
|
+
"node",
|
|
16570
|
+
"python",
|
|
16571
|
+
"php",
|
|
16572
|
+
"java",
|
|
16573
|
+
"go",
|
|
16574
|
+
"ruby",
|
|
16575
|
+
"unknown"
|
|
16576
|
+
];
|
|
16577
|
+
var CaptureRuleActionValues = ["demote", "sample", "drop"];
|
|
16578
|
+
var CaptureRuleActionSchema = external_exports.enum(CaptureRuleActionValues);
|
|
16579
|
+
var CaptureRuleSampleEventClassValues = ["preserve", "context"];
|
|
16580
|
+
var CaptureRuleSampleEventClassSchema = external_exports.enum(CaptureRuleSampleEventClassValues);
|
|
16581
|
+
var CaptureRuleRuntimeSchema = external_exports.enum(CAPTURE_RULE_RUNTIME_VALUES);
|
|
16582
|
+
var CaptureRuleEventTypeSchema = external_exports.enum(CAPTURE_RULE_EVENT_TYPES);
|
|
16583
|
+
var BrowserEventKindSchema = external_exports.enum(["window_error", "resource_error"]);
|
|
16584
|
+
function normalizeOptionalTrimmedString(value) {
|
|
16585
|
+
const trimmed = value?.trim();
|
|
16586
|
+
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
16587
|
+
}
|
|
16588
|
+
function normalizeOptionalLowercaseHost(value) {
|
|
16589
|
+
const trimmed = normalizeOptionalTrimmedString(value);
|
|
16590
|
+
return trimmed?.toLowerCase();
|
|
16591
|
+
}
|
|
16592
|
+
function normalizeOptionalPath(value) {
|
|
16593
|
+
const trimmed = normalizeOptionalTrimmedString(value);
|
|
16594
|
+
if (trimmed === void 0) {
|
|
16595
|
+
return void 0;
|
|
16596
|
+
}
|
|
16597
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
16598
|
+
}
|
|
16599
|
+
function hasValue(value) {
|
|
16600
|
+
return value !== void 0 && value !== null;
|
|
16601
|
+
}
|
|
16602
|
+
var UrlMatcherSchema = external_exports.object({
|
|
16603
|
+
host: external_exports.string().min(1).max(255).optional(),
|
|
16604
|
+
host_suffix: external_exports.string().min(1).max(255).optional(),
|
|
16605
|
+
path_prefix: external_exports.string().min(1).max(1024).optional(),
|
|
16606
|
+
path_equals: external_exports.string().min(1).max(1024).optional()
|
|
16607
|
+
}).transform((value) => {
|
|
16608
|
+
const normalized = {};
|
|
16609
|
+
const host = normalizeOptionalLowercaseHost(value.host);
|
|
16610
|
+
const hostSuffix = normalizeOptionalLowercaseHost(value.host_suffix);
|
|
16611
|
+
const pathPrefix = normalizeOptionalPath(value.path_prefix);
|
|
16612
|
+
const pathEquals = normalizeOptionalPath(value.path_equals);
|
|
16613
|
+
if (host !== void 0) {
|
|
16614
|
+
normalized.host = host;
|
|
16615
|
+
}
|
|
16616
|
+
if (hostSuffix !== void 0) {
|
|
16617
|
+
normalized.host_suffix = hostSuffix;
|
|
16618
|
+
}
|
|
16619
|
+
if (pathPrefix !== void 0) {
|
|
16620
|
+
normalized.path_prefix = pathPrefix;
|
|
16621
|
+
}
|
|
16622
|
+
if (pathEquals !== void 0) {
|
|
16623
|
+
normalized.path_equals = pathEquals;
|
|
16624
|
+
}
|
|
16625
|
+
return normalized;
|
|
16626
|
+
}).refine((value) => hasValue(value.host) || hasValue(value.host_suffix) || hasValue(value.path_prefix) || hasValue(value.path_equals), {
|
|
16627
|
+
message: "URL matchers must include at least one host or path constraint."
|
|
16628
|
+
});
|
|
16629
|
+
var StatusRangeSchema = external_exports.object({
|
|
16630
|
+
start: external_exports.number().int().min(100).max(599),
|
|
16631
|
+
end: external_exports.number().int().min(100).max(599)
|
|
16632
|
+
}).refine((value) => value.start <= value.end, {
|
|
16633
|
+
message: "Status range start must be less than or equal to end."
|
|
16634
|
+
});
|
|
16635
|
+
var CaptureRuleFingerprintSchema = external_exports.object({
|
|
16636
|
+
version: external_exports.string().min(1).max(32),
|
|
16637
|
+
value: external_exports.string().min(1).max(256)
|
|
16638
|
+
});
|
|
16639
|
+
function normalizeStringArray(values) {
|
|
16640
|
+
if (values === void 0) {
|
|
16641
|
+
return void 0;
|
|
16642
|
+
}
|
|
16643
|
+
return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
|
|
16644
|
+
}
|
|
16645
|
+
function normalizeNumberArray(values) {
|
|
16646
|
+
if (values === void 0) {
|
|
16647
|
+
return void 0;
|
|
16648
|
+
}
|
|
16649
|
+
return Array.from(new Set(values)).sort((left, right) => left - right);
|
|
16650
|
+
}
|
|
16651
|
+
var CaptureRuleMatcherSchema = external_exports.object({
|
|
16652
|
+
event_types: external_exports.array(CaptureRuleEventTypeSchema).min(1).optional(),
|
|
16653
|
+
services: external_exports.array(external_exports.string().min(1).max(120)).min(1).optional(),
|
|
16654
|
+
environments: external_exports.array(external_exports.string().min(1).max(120)).min(1).optional(),
|
|
16655
|
+
runtime: external_exports.array(CaptureRuleRuntimeSchema).min(1).optional(),
|
|
16656
|
+
first_party: external_exports.boolean().optional(),
|
|
16657
|
+
error_name: external_exports.string().min(1).max(120).optional(),
|
|
16658
|
+
message_contains: external_exports.string().min(1).max(500).optional(),
|
|
16659
|
+
message_equals: external_exports.string().min(1).max(500).optional(),
|
|
16660
|
+
browser_event_kind: BrowserEventKindSchema.optional(),
|
|
16661
|
+
resource_url: UrlMatcherSchema.optional(),
|
|
16662
|
+
request_url: UrlMatcherSchema.optional(),
|
|
16663
|
+
status_codes: external_exports.array(external_exports.number().int().min(100).max(599)).min(1).optional(),
|
|
16664
|
+
status_ranges: external_exports.array(StatusRangeSchema).min(1).optional(),
|
|
16665
|
+
fingerprint: CaptureRuleFingerprintSchema.optional()
|
|
16666
|
+
}).transform((value) => {
|
|
16667
|
+
const normalized = {};
|
|
16668
|
+
const eventTypes = normalizeStringArray(value.event_types);
|
|
16669
|
+
const services = normalizeStringArray(value.services);
|
|
16670
|
+
const environments = normalizeStringArray(value.environments);
|
|
16671
|
+
const runtime = normalizeStringArray(value.runtime);
|
|
16672
|
+
const errorName = normalizeOptionalTrimmedString(value.error_name);
|
|
16673
|
+
const messageContains = normalizeOptionalTrimmedString(value.message_contains);
|
|
16674
|
+
const messageEquals = normalizeOptionalTrimmedString(value.message_equals);
|
|
16675
|
+
const statusCodes = normalizeNumberArray(value.status_codes);
|
|
16676
|
+
if (eventTypes !== void 0) {
|
|
16677
|
+
normalized.event_types = eventTypes;
|
|
16678
|
+
}
|
|
16679
|
+
if (services !== void 0) {
|
|
16680
|
+
normalized.services = services;
|
|
16681
|
+
}
|
|
16682
|
+
if (environments !== void 0) {
|
|
16683
|
+
normalized.environments = environments;
|
|
16684
|
+
}
|
|
16685
|
+
if (runtime !== void 0) {
|
|
16686
|
+
normalized.runtime = runtime;
|
|
16687
|
+
}
|
|
16688
|
+
if (value.first_party !== void 0) {
|
|
16689
|
+
normalized.first_party = value.first_party;
|
|
16690
|
+
}
|
|
16691
|
+
if (errorName !== void 0) {
|
|
16692
|
+
normalized.error_name = errorName;
|
|
16693
|
+
}
|
|
16694
|
+
if (messageContains !== void 0) {
|
|
16695
|
+
normalized.message_contains = messageContains;
|
|
16696
|
+
}
|
|
16697
|
+
if (messageEquals !== void 0) {
|
|
16698
|
+
normalized.message_equals = messageEquals;
|
|
16699
|
+
}
|
|
16700
|
+
if (value.browser_event_kind !== void 0) {
|
|
16701
|
+
normalized.browser_event_kind = value.browser_event_kind;
|
|
16702
|
+
}
|
|
16703
|
+
if (value.resource_url !== void 0) {
|
|
16704
|
+
normalized.resource_url = value.resource_url;
|
|
16705
|
+
}
|
|
16706
|
+
if (value.request_url !== void 0) {
|
|
16707
|
+
normalized.request_url = value.request_url;
|
|
16708
|
+
}
|
|
16709
|
+
if (statusCodes !== void 0) {
|
|
16710
|
+
normalized.status_codes = statusCodes;
|
|
16711
|
+
}
|
|
16712
|
+
if (value.status_ranges !== void 0) {
|
|
16713
|
+
normalized.status_ranges = value.status_ranges;
|
|
16714
|
+
}
|
|
16715
|
+
if (value.fingerprint !== void 0) {
|
|
16716
|
+
normalized.fingerprint = value.fingerprint;
|
|
16717
|
+
}
|
|
16718
|
+
return normalized;
|
|
16719
|
+
}).superRefine((value, context) => {
|
|
16720
|
+
const narrowingKeys = [
|
|
16721
|
+
"services",
|
|
16722
|
+
"environments",
|
|
16723
|
+
"runtime",
|
|
16724
|
+
"first_party",
|
|
16725
|
+
"error_name",
|
|
16726
|
+
"message_contains",
|
|
16727
|
+
"message_equals",
|
|
16728
|
+
"browser_event_kind",
|
|
16729
|
+
"resource_url",
|
|
16730
|
+
"request_url",
|
|
16731
|
+
"status_codes",
|
|
16732
|
+
"status_ranges",
|
|
16733
|
+
"fingerprint"
|
|
16734
|
+
];
|
|
16735
|
+
if (!narrowingKeys.some((key) => hasValue(value[key]))) {
|
|
16736
|
+
context.addIssue({
|
|
16737
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16738
|
+
message: "Capture rules must include at least one narrowing field beyond event_types."
|
|
16739
|
+
});
|
|
16740
|
+
}
|
|
16741
|
+
if (value.browser_event_kind === "resource_error") {
|
|
16742
|
+
const hasResourceConstraint = hasValue(value.resource_url) || hasValue(value.fingerprint);
|
|
16743
|
+
if (!hasResourceConstraint) {
|
|
16744
|
+
context.addIssue({
|
|
16745
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16746
|
+
message: "Resource-error rules require a resource URL constraint or an exact fingerprint."
|
|
16747
|
+
});
|
|
16748
|
+
}
|
|
16749
|
+
}
|
|
16750
|
+
});
|
|
16751
|
+
var CaptureRuleCoreObjectSchema = external_exports.object({
|
|
16752
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
16753
|
+
description: external_exports.string().trim().max(500).nullable(),
|
|
16754
|
+
enabled: external_exports.boolean(),
|
|
16755
|
+
action: CaptureRuleActionSchema,
|
|
16756
|
+
matcher: CaptureRuleMatcherSchema,
|
|
16757
|
+
sample_rate: external_exports.number().min(0).max(1).nullable(),
|
|
16758
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable(),
|
|
16759
|
+
created_by_user_id: external_exports.string().min(1).max(120).nullable(),
|
|
16760
|
+
created_from_incident_id: external_exports.string().min(1).max(120).nullable(),
|
|
16761
|
+
created_from_event_id: external_exports.string().min(1).max(120).nullable(),
|
|
16762
|
+
expires_at: external_exports.string().datetime().nullable()
|
|
16763
|
+
});
|
|
16764
|
+
function addCaptureRuleActionValidation(schema) {
|
|
16765
|
+
return schema.superRefine((value, context) => {
|
|
16766
|
+
if (value["action"] === "sample") {
|
|
16767
|
+
if (value["sample_rate"] === null) {
|
|
16768
|
+
context.addIssue({
|
|
16769
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16770
|
+
path: ["sample_rate"],
|
|
16771
|
+
message: "Sample rules require sample_rate."
|
|
16772
|
+
});
|
|
16773
|
+
}
|
|
16774
|
+
if (value["sample_event_class"] === null) {
|
|
16775
|
+
context.addIssue({
|
|
16776
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16777
|
+
path: ["sample_event_class"],
|
|
16778
|
+
message: "Sample rules require sample_event_class."
|
|
16779
|
+
});
|
|
16780
|
+
}
|
|
16781
|
+
return;
|
|
16782
|
+
}
|
|
16783
|
+
if (value["sample_rate"] !== null) {
|
|
16784
|
+
context.addIssue({
|
|
16785
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16786
|
+
path: ["sample_rate"],
|
|
16787
|
+
message: "Only sample rules can set sample_rate."
|
|
16788
|
+
});
|
|
16789
|
+
}
|
|
16790
|
+
if (value["sample_event_class"] !== null) {
|
|
16791
|
+
context.addIssue({
|
|
16792
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16793
|
+
path: ["sample_event_class"],
|
|
16794
|
+
message: "Only sample rules can set sample_event_class."
|
|
16795
|
+
});
|
|
16796
|
+
}
|
|
16797
|
+
});
|
|
16798
|
+
}
|
|
16799
|
+
var CaptureRuleSchema = addCaptureRuleActionValidation(
|
|
16800
|
+
CaptureRuleCoreObjectSchema.extend({
|
|
16801
|
+
id: external_exports.string().uuid(),
|
|
16802
|
+
project_id: external_exports.string().min(1).max(120),
|
|
16803
|
+
hit_count: external_exports.number().int().nonnegative(),
|
|
16804
|
+
last_matched_at: external_exports.string().datetime().nullable(),
|
|
16805
|
+
created_at: external_exports.string().datetime(),
|
|
16806
|
+
updated_at: external_exports.string().datetime()
|
|
16807
|
+
})
|
|
16808
|
+
);
|
|
16809
|
+
var CaptureRuleCreateSchema = external_exports.object({
|
|
16810
|
+
name: external_exports.string().trim().min(1).max(120),
|
|
16811
|
+
description: external_exports.string().trim().max(500).nullable().default(null),
|
|
16812
|
+
enabled: external_exports.boolean().default(true),
|
|
16813
|
+
action: CaptureRuleActionSchema,
|
|
16814
|
+
matcher: CaptureRuleMatcherSchema,
|
|
16815
|
+
sample_rate: external_exports.number().min(0).max(1).nullable().optional(),
|
|
16816
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable().optional(),
|
|
16817
|
+
created_by_user_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16818
|
+
created_from_incident_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16819
|
+
created_from_event_id: external_exports.string().min(1).max(120).nullable().default(null),
|
|
16820
|
+
expires_at: external_exports.string().datetime().nullable().default(null)
|
|
16821
|
+
}).superRefine((value, context) => {
|
|
16822
|
+
if (value.action === "sample") {
|
|
16823
|
+
if (value.sample_rate === void 0 || value.sample_rate === null) {
|
|
16824
|
+
context.addIssue({
|
|
16825
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16826
|
+
path: ["sample_rate"],
|
|
16827
|
+
message: "Sample rules require sample_rate."
|
|
16828
|
+
});
|
|
16829
|
+
}
|
|
16830
|
+
return;
|
|
16831
|
+
}
|
|
16832
|
+
if (value.sample_rate !== void 0 && value.sample_rate !== null) {
|
|
16833
|
+
context.addIssue({
|
|
16834
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16835
|
+
path: ["sample_rate"],
|
|
16836
|
+
message: "Only sample rules can set sample_rate."
|
|
16837
|
+
});
|
|
16838
|
+
}
|
|
16839
|
+
if (value.sample_event_class !== void 0 && value.sample_event_class !== null) {
|
|
16840
|
+
context.addIssue({
|
|
16841
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16842
|
+
path: ["sample_event_class"],
|
|
16843
|
+
message: "Only sample rules can set sample_event_class."
|
|
16844
|
+
});
|
|
16845
|
+
}
|
|
16846
|
+
}).transform((value) => ({
|
|
16847
|
+
...value,
|
|
16848
|
+
sample_rate: value.action === "sample" ? value.sample_rate : null,
|
|
16849
|
+
sample_event_class: value.action === "sample" ? value.sample_event_class ?? "preserve" : null
|
|
16850
|
+
}));
|
|
16851
|
+
var CaptureRuleUpdateSchema = external_exports.object({
|
|
16852
|
+
name: external_exports.string().trim().min(1).max(120).optional(),
|
|
16853
|
+
description: external_exports.string().trim().max(500).nullable().optional(),
|
|
16854
|
+
enabled: external_exports.boolean().optional(),
|
|
16855
|
+
action: CaptureRuleActionSchema.optional(),
|
|
16856
|
+
matcher: CaptureRuleMatcherSchema.optional(),
|
|
16857
|
+
sample_rate: external_exports.number().min(0).max(1).nullable().optional(),
|
|
16858
|
+
sample_event_class: CaptureRuleSampleEventClassSchema.nullable().optional(),
|
|
16859
|
+
expires_at: external_exports.string().datetime().nullable().optional()
|
|
16860
|
+
}).superRefine((value, context) => {
|
|
16861
|
+
if (Object.keys(value).length === 0) {
|
|
16862
|
+
context.addIssue({
|
|
16863
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16864
|
+
message: "At least one capture rule field must be provided."
|
|
16865
|
+
});
|
|
16866
|
+
}
|
|
16867
|
+
const resolvedAction = value.action;
|
|
16868
|
+
if (resolvedAction === "sample") {
|
|
16869
|
+
if (!("sample_rate" in value)) {
|
|
16870
|
+
context.addIssue({
|
|
16871
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16872
|
+
path: ["sample_rate"],
|
|
16873
|
+
message: "Sample rule updates must include sample_rate when changing action to sample."
|
|
16874
|
+
});
|
|
16875
|
+
}
|
|
16876
|
+
if (!("sample_event_class" in value)) {
|
|
16877
|
+
context.addIssue({
|
|
16878
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16879
|
+
path: ["sample_event_class"],
|
|
16880
|
+
message: "Sample rule updates must include sample_event_class when changing action to sample."
|
|
16881
|
+
});
|
|
16882
|
+
}
|
|
16883
|
+
return;
|
|
16884
|
+
}
|
|
16885
|
+
if ("sample_rate" in value) {
|
|
16886
|
+
context.addIssue({
|
|
16887
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16888
|
+
path: ["sample_rate"],
|
|
16889
|
+
message: "Sample rule fields can only be updated while setting action to sample."
|
|
16890
|
+
});
|
|
16891
|
+
}
|
|
16892
|
+
if ("sample_event_class" in value) {
|
|
16893
|
+
context.addIssue({
|
|
16894
|
+
code: external_exports.ZodIssueCode.custom,
|
|
16895
|
+
path: ["sample_event_class"],
|
|
16896
|
+
message: "Sample rule fields can only be updated while setting action to sample."
|
|
16897
|
+
});
|
|
16898
|
+
}
|
|
16899
|
+
});
|
|
16900
|
+
var CaptureRuleResponseSchema = external_exports.object({
|
|
16901
|
+
rule: CaptureRuleSchema
|
|
16902
|
+
});
|
|
16903
|
+
var CaptureRulesResponseSchema = external_exports.object({
|
|
16904
|
+
access_mode: external_exports.enum(["manage", "preview"]),
|
|
16905
|
+
rules: external_exports.array(CaptureRuleSchema)
|
|
16906
|
+
});
|
|
16907
|
+
var CaptureRulesFileSchema = external_exports.object({
|
|
16908
|
+
version: external_exports.literal(1),
|
|
16909
|
+
rules: external_exports.array(CaptureRuleSchema)
|
|
16910
|
+
});
|
|
16911
|
+
var CaptureRuleEvaluationUrlSchema = external_exports.object({
|
|
16912
|
+
host: external_exports.string().min(1).transform((value) => value.toLowerCase()).optional(),
|
|
16913
|
+
path: external_exports.string().min(1).transform((value) => value.startsWith("/") ? value : `/${value}`)
|
|
16914
|
+
});
|
|
16915
|
+
var CaptureRuleEvaluationContextSchema = external_exports.object({
|
|
16916
|
+
project_id: external_exports.string().min(1).max(120),
|
|
16917
|
+
event_id: external_exports.string().uuid(),
|
|
16918
|
+
event_type: CaptureRuleEventTypeSchema,
|
|
16919
|
+
service: external_exports.string().min(1).optional(),
|
|
16920
|
+
environment: external_exports.string().min(1).optional(),
|
|
16921
|
+
runtime: CaptureRuleRuntimeSchema,
|
|
16922
|
+
first_party: external_exports.boolean().optional(),
|
|
16923
|
+
error_name: external_exports.string().min(1).optional(),
|
|
16924
|
+
message: external_exports.string().min(1).optional(),
|
|
16925
|
+
browser_event_kind: BrowserEventKindSchema.optional(),
|
|
16926
|
+
resource_url: CaptureRuleEvaluationUrlSchema.optional(),
|
|
16927
|
+
request_url: CaptureRuleEvaluationUrlSchema.optional(),
|
|
16928
|
+
status_code: external_exports.number().int().min(0).max(599).optional(),
|
|
16929
|
+
fingerprint: CaptureRuleFingerprintSchema.optional()
|
|
16930
|
+
});
|
|
16931
|
+
|
|
16932
|
+
// ../../packages/shared-types/src/capture-rule-suggestions.ts
|
|
16933
|
+
var CaptureRuleSuggestionConfidenceSchema = external_exports.enum(["high", "medium", "low"]);
|
|
16934
|
+
var CaptureRuleSuggestionSchema = external_exports.object({
|
|
16935
|
+
suggestion_id: external_exports.string().min(1).max(120),
|
|
16936
|
+
label: external_exports.string().min(1).max(200),
|
|
16937
|
+
recommended_action: CaptureRuleActionSchema,
|
|
16938
|
+
confidence: CaptureRuleSuggestionConfidenceSchema,
|
|
16939
|
+
reason: external_exports.string().min(1).max(500),
|
|
16940
|
+
requires_confirmation: external_exports.boolean(),
|
|
16941
|
+
rule: CaptureRuleCreateSchema
|
|
16942
|
+
});
|
|
16943
|
+
var CaptureRuleSuggestionsResponseSchema = external_exports.object({
|
|
16944
|
+
suggestions: external_exports.array(CaptureRuleSuggestionSchema),
|
|
16945
|
+
bundle_status: external_exports.enum(["ready", "pending", "failed"]).optional(),
|
|
16946
|
+
bundle_reason: external_exports.string().nullable().optional()
|
|
16947
|
+
});
|
|
16948
|
+
var CreateCaptureRuleFromSuggestionSchema = external_exports.object({
|
|
16949
|
+
suggestion_id: external_exports.string().min(1).max(120),
|
|
16950
|
+
name: external_exports.string().trim().min(1).max(120).optional(),
|
|
16951
|
+
description: external_exports.string().trim().max(500).nullable().optional(),
|
|
16952
|
+
enabled: external_exports.boolean().optional(),
|
|
16953
|
+
expires_at: external_exports.string().datetime().nullable().optional()
|
|
16954
|
+
});
|
|
16955
|
+
|
|
16555
16956
|
// ../../packages/shared-types/src/improvement-settings.ts
|
|
16556
16957
|
var ImprovementBundleSensitivityValues = [
|
|
16557
16958
|
"high_confidence",
|
|
@@ -16708,6 +17109,18 @@ var DeviceInfoSchema = external_exports.object({
|
|
|
16708
17109
|
connection_type: external_exports.string().nullable(),
|
|
16709
17110
|
color_scheme_preference: external_exports.enum(["light", "dark", "no-preference"]).nullable()
|
|
16710
17111
|
}).strict();
|
|
17112
|
+
var BrowserExceptionEventSchema = external_exports.object({
|
|
17113
|
+
kind: external_exports.enum(["window_error", "resource_error"]),
|
|
17114
|
+
message: external_exports.string().nullable(),
|
|
17115
|
+
file_name: external_exports.string().nullable(),
|
|
17116
|
+
line_number: external_exports.number().int().nonnegative().nullable(),
|
|
17117
|
+
column_number: external_exports.number().int().nonnegative().nullable(),
|
|
17118
|
+
target: external_exports.object({
|
|
17119
|
+
tag_name: external_exports.string().nullable(),
|
|
17120
|
+
source_url: external_exports.string().nullable()
|
|
17121
|
+
}).nullable(),
|
|
17122
|
+
opaque: external_exports.boolean()
|
|
17123
|
+
}).strict();
|
|
16711
17124
|
var FrontendExceptionPayloadSchema = external_exports.object({
|
|
16712
17125
|
name: external_exports.string().min(1),
|
|
16713
17126
|
message: external_exports.string().min(1),
|
|
@@ -16719,6 +17132,7 @@ var FrontendExceptionPayloadSchema = external_exports.object({
|
|
|
16719
17132
|
}),
|
|
16720
17133
|
breadcrumbs: external_exports.array(FrontendExceptionBreadcrumbSchema).optional(),
|
|
16721
17134
|
device: DeviceInfoSchema.nullable().optional(),
|
|
17135
|
+
browser_event: BrowserExceptionEventSchema.optional(),
|
|
16722
17136
|
dom_context: external_exports.object({
|
|
16723
17137
|
mode: external_exports.literal("lightweight"),
|
|
16724
17138
|
html_excerpt: external_exports.string().min(1)
|
|
@@ -17175,6 +17589,18 @@ function buildSkill() {
|
|
|
17175
17589
|
"- Run `debugbundle validate --fix` to restore missing generated setup files without overwriting the profile.",
|
|
17176
17590
|
"- Run `debugbundle process` after local events land in `.debugbundle/local/events/`.",
|
|
17177
17591
|
"",
|
|
17592
|
+
"## Browser Capture and Relay Setup",
|
|
17593
|
+
"",
|
|
17594
|
+
"When the repository has a browser frontend, verify capture end to end instead of stopping at backend SDK setup.",
|
|
17595
|
+
"",
|
|
17596
|
+
"1. Add `@debugbundle/sdk-browser` to each browser app that should capture console, error, navigation, or request context.",
|
|
17597
|
+
"2. Initialize the browser SDK from the app entrypoint with the active environment and a browser relay endpoint.",
|
|
17598
|
+
"3. Add a backend relay endpoint at `/debugbundle/browser` using the server SDK relay helper when available.",
|
|
17599
|
+
"4. For same-origin apps, keep the browser endpoint as `/debugbundle/browser`.",
|
|
17600
|
+
"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.",
|
|
17601
|
+
"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.",
|
|
17602
|
+
"7. Trigger a local browser smoke event, then run `debugbundle process --json` and confirm the incident or context event appears before marking setup complete.",
|
|
17603
|
+
"",
|
|
17178
17604
|
"## References",
|
|
17179
17605
|
"",
|
|
17180
17606
|
"- CLI reference: `references/cli.md`",
|
|
@@ -17311,6 +17737,8 @@ function buildProfileEnrichmentReference() {
|
|
|
17311
17737
|
"- add critical paths for ingestion, processing, retrieval, SDK capture, auth, billing, and any project-specific high-risk workflows",
|
|
17312
17738
|
"- confirm `repo.generated_paths` and `repo.do_not_edit_paths` match the local scaffold",
|
|
17313
17739
|
"- confirm build, test, lint, and install workflows in `developer_workflows`",
|
|
17740
|
+
"- for browser frontends, confirm `@debugbundle/sdk-browser` is initialized and a backend `/debugbundle/browser` relay is reachable",
|
|
17741
|
+
"- for split frontend/backend hosts, confirm the browser SDK uses the API relay URL and the backend allowlists the frontend origin",
|
|
17314
17742
|
"- update `debugbundle.last_reviewed_at` and set `debugbundle.validation_status` to `agent-validated` when complete",
|
|
17315
17743
|
""
|
|
17316
17744
|
].join("\n");
|
|
@@ -17504,10 +17932,37 @@ async function pathExists(path, stat) {
|
|
|
17504
17932
|
}
|
|
17505
17933
|
}
|
|
17506
17934
|
function formatZodErrors(error) {
|
|
17507
|
-
return error.issues.map((issue) =>
|
|
17508
|
-
path
|
|
17509
|
-
|
|
17510
|
-
|
|
17935
|
+
return error.issues.map((issue) => {
|
|
17936
|
+
const path = issue.path.join(".");
|
|
17937
|
+
if (path === "services" || path.startsWith("services.")) {
|
|
17938
|
+
return {
|
|
17939
|
+
path,
|
|
17940
|
+
message: issue.message,
|
|
17941
|
+
suggestion: "Add service entries with name, kind, runtime, framework, paths, owns_routes, and depends_on.",
|
|
17942
|
+
example: '[{"name":"api","kind":"backend","runtime":"Node.js","framework":"Fastify","paths":["apps/api"],"owns_routes":["POST /checkout"],"depends_on":["worker"]}]'
|
|
17943
|
+
};
|
|
17944
|
+
}
|
|
17945
|
+
if (path === "critical_paths" || path.startsWith("critical_paths.")) {
|
|
17946
|
+
return {
|
|
17947
|
+
path,
|
|
17948
|
+
message: issue.message,
|
|
17949
|
+
suggestion: "Use object entries so each critical path records its owner_service and review notes.",
|
|
17950
|
+
example: '[{"name":"checkout","owner_service":"api","notes":"Creates the order, charges the card, and enqueues fulfillment."}]'
|
|
17951
|
+
};
|
|
17952
|
+
}
|
|
17953
|
+
if (path === "developer_workflows" || path.startsWith("developer_workflows.")) {
|
|
17954
|
+
return {
|
|
17955
|
+
path,
|
|
17956
|
+
message: issue.message,
|
|
17957
|
+
suggestion: "Provide install, build, test, and lint as command strings so agents can run the standard repo workflows.",
|
|
17958
|
+
example: '{"install":"pnpm install","build":"pnpm build","test":"pnpm test","lint":"pnpm lint"}'
|
|
17959
|
+
};
|
|
17960
|
+
}
|
|
17961
|
+
return {
|
|
17962
|
+
path,
|
|
17963
|
+
message: issue.message
|
|
17964
|
+
};
|
|
17965
|
+
});
|
|
17511
17966
|
}
|
|
17512
17967
|
async function validateProfile(rootDirectory, dependencies = {}) {
|
|
17513
17968
|
const readFile = dependencies.readFile ?? ((filePath) => (0, import_promises.readFile)(filePath, "utf8"));
|
|
@@ -17854,6 +18309,118 @@ function createCliHttpClient(input, dependencies) {
|
|
|
17854
18309
|
};
|
|
17855
18310
|
}
|
|
17856
18311
|
|
|
18312
|
+
// ../cli/src/capture-rule-commands.ts
|
|
18313
|
+
var CaptureRuleApiError = class extends Error {
|
|
18314
|
+
status;
|
|
18315
|
+
constructor(status, message) {
|
|
18316
|
+
super(message);
|
|
18317
|
+
this.name = "CaptureRuleApiError";
|
|
18318
|
+
this.status = status;
|
|
18319
|
+
}
|
|
18320
|
+
};
|
|
18321
|
+
function toApiError(status, body, fallback) {
|
|
18322
|
+
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
18323
|
+
return new CaptureRuleApiError(status, body.error);
|
|
18324
|
+
}
|
|
18325
|
+
return new CaptureRuleApiError(status, fallback);
|
|
18326
|
+
}
|
|
18327
|
+
function createCaptureRuleApi(httpClient) {
|
|
18328
|
+
return {
|
|
18329
|
+
async listCaptureRules(input) {
|
|
18330
|
+
const response = await httpClient.request({
|
|
18331
|
+
method: "GET",
|
|
18332
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules`,
|
|
18333
|
+
bearerToken: input.bearerToken
|
|
18334
|
+
});
|
|
18335
|
+
if (response.status !== 200) {
|
|
18336
|
+
throw toApiError(response.status, response.body, "Failed to list capture rules.");
|
|
18337
|
+
}
|
|
18338
|
+
const parsed = CaptureRulesResponseSchema.safeParse(response.body);
|
|
18339
|
+
if (!parsed.success) {
|
|
18340
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule list response.");
|
|
18341
|
+
}
|
|
18342
|
+
return parsed.data;
|
|
18343
|
+
},
|
|
18344
|
+
async createCaptureRule(input) {
|
|
18345
|
+
const response = await httpClient.request({
|
|
18346
|
+
method: "POST",
|
|
18347
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules`,
|
|
18348
|
+
bearerToken: input.bearerToken,
|
|
18349
|
+
body: input.create
|
|
18350
|
+
});
|
|
18351
|
+
if (response.status !== 201) {
|
|
18352
|
+
throw toApiError(response.status, response.body, "Failed to create capture rule.");
|
|
18353
|
+
}
|
|
18354
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18355
|
+
if (!parsed.success) {
|
|
18356
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule create response.");
|
|
18357
|
+
}
|
|
18358
|
+
return parsed.data;
|
|
18359
|
+
},
|
|
18360
|
+
async suggestCaptureRulesFromIncident(input) {
|
|
18361
|
+
const response = await httpClient.request({
|
|
18362
|
+
method: "POST",
|
|
18363
|
+
path: `/v1/incidents/${encodeURIComponent(input.incidentId)}/capture-rule-suggestion`,
|
|
18364
|
+
bearerToken: input.bearerToken
|
|
18365
|
+
});
|
|
18366
|
+
if (response.status !== 200) {
|
|
18367
|
+
throw toApiError(response.status, response.body, "Failed to suggest capture rules.");
|
|
18368
|
+
}
|
|
18369
|
+
const parsed = CaptureRuleSuggestionsResponseSchema.safeParse(response.body);
|
|
18370
|
+
if (!parsed.success) {
|
|
18371
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule suggestion response.");
|
|
18372
|
+
}
|
|
18373
|
+
return parsed.data;
|
|
18374
|
+
},
|
|
18375
|
+
async createCaptureRuleFromIncidentSuggestion(input) {
|
|
18376
|
+
const response = await httpClient.request({
|
|
18377
|
+
method: "POST",
|
|
18378
|
+
path: `/v1/incidents/${encodeURIComponent(input.incidentId)}/capture-rules`,
|
|
18379
|
+
bearerToken: input.bearerToken,
|
|
18380
|
+
body: input.create
|
|
18381
|
+
});
|
|
18382
|
+
if (response.status !== 201) {
|
|
18383
|
+
throw toApiError(response.status, response.body, "Failed to create capture rule from suggestion.");
|
|
18384
|
+
}
|
|
18385
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18386
|
+
if (!parsed.success) {
|
|
18387
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule create-from-suggestion response.");
|
|
18388
|
+
}
|
|
18389
|
+
return parsed.data;
|
|
18390
|
+
},
|
|
18391
|
+
async updateCaptureRule(input) {
|
|
18392
|
+
const response = await httpClient.request({
|
|
18393
|
+
method: "PATCH",
|
|
18394
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules/${encodeURIComponent(input.ruleId)}`,
|
|
18395
|
+
bearerToken: input.bearerToken,
|
|
18396
|
+
body: input.update
|
|
18397
|
+
});
|
|
18398
|
+
if (response.status !== 200) {
|
|
18399
|
+
throw toApiError(response.status, response.body, "Failed to update capture rule.");
|
|
18400
|
+
}
|
|
18401
|
+
const parsed = CaptureRuleResponseSchema.safeParse(response.body);
|
|
18402
|
+
if (!parsed.success) {
|
|
18403
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule update response.");
|
|
18404
|
+
}
|
|
18405
|
+
return parsed.data;
|
|
18406
|
+
},
|
|
18407
|
+
async deleteCaptureRule(input) {
|
|
18408
|
+
const response = await httpClient.request({
|
|
18409
|
+
method: "DELETE",
|
|
18410
|
+
path: `/v1/projects/${encodeURIComponent(input.projectId)}/capture-rules/${encodeURIComponent(input.ruleId)}`,
|
|
18411
|
+
bearerToken: input.bearerToken
|
|
18412
|
+
});
|
|
18413
|
+
if (response.status !== 200) {
|
|
18414
|
+
throw toApiError(response.status, response.body, "Failed to delete capture rule.");
|
|
18415
|
+
}
|
|
18416
|
+
if (typeof response.body !== "object" || response.body === null || !("success" in response.body) || response.body.success !== true) {
|
|
18417
|
+
throw new CaptureRuleApiError(500, "Invalid capture rule delete response.");
|
|
18418
|
+
}
|
|
18419
|
+
return { success: true };
|
|
18420
|
+
}
|
|
18421
|
+
};
|
|
18422
|
+
}
|
|
18423
|
+
|
|
17857
18424
|
// ../cli/src/capture-policy-commands.ts
|
|
17858
18425
|
var CapturePolicyApiError = class extends Error {
|
|
17859
18426
|
status;
|
|
@@ -17863,7 +18430,7 @@ var CapturePolicyApiError = class extends Error {
|
|
|
17863
18430
|
this.status = status;
|
|
17864
18431
|
}
|
|
17865
18432
|
};
|
|
17866
|
-
function
|
|
18433
|
+
function toApiError2(status, body, fallback) {
|
|
17867
18434
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17868
18435
|
return new CapturePolicyApiError(status, body.error);
|
|
17869
18436
|
}
|
|
@@ -17878,7 +18445,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17878
18445
|
bearerToken: input.bearerToken
|
|
17879
18446
|
});
|
|
17880
18447
|
if (response.status !== 200) {
|
|
17881
|
-
throw
|
|
18448
|
+
throw toApiError2(response.status, response.body, "Failed to get capture policy.");
|
|
17882
18449
|
}
|
|
17883
18450
|
const parsed = CapturePolicyResponseSchema.safeParse(response.body);
|
|
17884
18451
|
if (!parsed.success) {
|
|
@@ -17894,7 +18461,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17894
18461
|
body: input.update
|
|
17895
18462
|
});
|
|
17896
18463
|
if (response.status !== 200) {
|
|
17897
|
-
throw
|
|
18464
|
+
throw toApiError2(response.status, response.body, "Failed to update capture policy.");
|
|
17898
18465
|
}
|
|
17899
18466
|
const parsed = CapturePolicyResponseSchema.safeParse(response.body);
|
|
17900
18467
|
if (!parsed.success) {
|
|
@@ -17914,7 +18481,7 @@ var ImprovementSettingsApiError = class extends Error {
|
|
|
17914
18481
|
this.status = status;
|
|
17915
18482
|
}
|
|
17916
18483
|
};
|
|
17917
|
-
function
|
|
18484
|
+
function toApiError3(status, body, fallback) {
|
|
17918
18485
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17919
18486
|
return new ImprovementSettingsApiError(status, body.error);
|
|
17920
18487
|
}
|
|
@@ -17929,7 +18496,7 @@ function createImprovementSettingsApi(httpClient) {
|
|
|
17929
18496
|
bearerToken: input.bearerToken
|
|
17930
18497
|
});
|
|
17931
18498
|
if (response.status !== 200) {
|
|
17932
|
-
throw
|
|
18499
|
+
throw toApiError3(response.status, response.body, "Failed to get improvement settings.");
|
|
17933
18500
|
}
|
|
17934
18501
|
const parsed = ImprovementSettingsResponseSchema.safeParse(response.body);
|
|
17935
18502
|
if (!parsed.success) {
|
|
@@ -17945,7 +18512,7 @@ function createImprovementSettingsApi(httpClient) {
|
|
|
17945
18512
|
body: input.update
|
|
17946
18513
|
});
|
|
17947
18514
|
if (response.status !== 200) {
|
|
17948
|
-
throw
|
|
18515
|
+
throw toApiError3(response.status, response.body, "Failed to update improvement settings.");
|
|
17949
18516
|
}
|
|
17950
18517
|
const parsed = ImprovementSettingsResponseSchema.safeParse(response.body);
|
|
17951
18518
|
if (!parsed.success) {
|
|
@@ -17967,7 +18534,7 @@ var MemberApiError = class extends Error {
|
|
|
17967
18534
|
this.code = code;
|
|
17968
18535
|
}
|
|
17969
18536
|
};
|
|
17970
|
-
function
|
|
18537
|
+
function toApiError4(status, body) {
|
|
17971
18538
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
17972
18539
|
return new MemberApiError(status, body.error);
|
|
17973
18540
|
}
|
|
@@ -17982,7 +18549,7 @@ function createMemberApi(httpClient) {
|
|
|
17982
18549
|
bearerToken: input.bearerToken
|
|
17983
18550
|
});
|
|
17984
18551
|
if (response.status !== 200) {
|
|
17985
|
-
throw
|
|
18552
|
+
throw toApiError4(response.status, response.body);
|
|
17986
18553
|
}
|
|
17987
18554
|
return response.body;
|
|
17988
18555
|
},
|
|
@@ -17993,7 +18560,7 @@ function createMemberApi(httpClient) {
|
|
|
17993
18560
|
bearerToken: input.bearerToken
|
|
17994
18561
|
});
|
|
17995
18562
|
if (response.status !== 200) {
|
|
17996
|
-
throw
|
|
18563
|
+
throw toApiError4(response.status, response.body);
|
|
17997
18564
|
}
|
|
17998
18565
|
return response.body;
|
|
17999
18566
|
},
|
|
@@ -18005,7 +18572,7 @@ function createMemberApi(httpClient) {
|
|
|
18005
18572
|
body: { email: input.email, role: input.role }
|
|
18006
18573
|
});
|
|
18007
18574
|
if (response.status !== 201) {
|
|
18008
|
-
throw
|
|
18575
|
+
throw toApiError4(response.status, response.body);
|
|
18009
18576
|
}
|
|
18010
18577
|
return response.body;
|
|
18011
18578
|
},
|
|
@@ -18016,7 +18583,7 @@ function createMemberApi(httpClient) {
|
|
|
18016
18583
|
bearerToken: input.bearerToken
|
|
18017
18584
|
});
|
|
18018
18585
|
if (response.status !== 200) {
|
|
18019
|
-
throw
|
|
18586
|
+
throw toApiError4(response.status, response.body);
|
|
18020
18587
|
}
|
|
18021
18588
|
return response.body;
|
|
18022
18589
|
},
|
|
@@ -18028,7 +18595,7 @@ function createMemberApi(httpClient) {
|
|
|
18028
18595
|
body: { role: input.role }
|
|
18029
18596
|
});
|
|
18030
18597
|
if (response.status !== 200) {
|
|
18031
|
-
throw
|
|
18598
|
+
throw toApiError4(response.status, response.body);
|
|
18032
18599
|
}
|
|
18033
18600
|
return response.body;
|
|
18034
18601
|
},
|
|
@@ -18039,7 +18606,7 @@ function createMemberApi(httpClient) {
|
|
|
18039
18606
|
bearerToken: input.bearerToken
|
|
18040
18607
|
});
|
|
18041
18608
|
if (response.status !== 200) {
|
|
18042
|
-
throw
|
|
18609
|
+
throw toApiError4(response.status, response.body);
|
|
18043
18610
|
}
|
|
18044
18611
|
return response.body;
|
|
18045
18612
|
}
|
|
@@ -18057,7 +18624,7 @@ var ProbeApiError = class extends Error {
|
|
|
18057
18624
|
this.code = code;
|
|
18058
18625
|
}
|
|
18059
18626
|
};
|
|
18060
|
-
function
|
|
18627
|
+
function toApiError5(status, body) {
|
|
18061
18628
|
if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
|
|
18062
18629
|
return new ProbeApiError(status, body.error);
|
|
18063
18630
|
}
|
|
@@ -18088,7 +18655,7 @@ function createProbeApi(httpClient) {
|
|
|
18088
18655
|
body
|
|
18089
18656
|
});
|
|
18090
18657
|
if (response.status !== 201) {
|
|
18091
|
-
throw
|
|
18658
|
+
throw toApiError5(response.status, response.body);
|
|
18092
18659
|
}
|
|
18093
18660
|
return response.body;
|
|
18094
18661
|
},
|
|
@@ -18099,7 +18666,7 @@ function createProbeApi(httpClient) {
|
|
|
18099
18666
|
bearerToken: input.bearerToken
|
|
18100
18667
|
});
|
|
18101
18668
|
if (response.status !== 200) {
|
|
18102
|
-
throw
|
|
18669
|
+
throw toApiError5(response.status, response.body);
|
|
18103
18670
|
}
|
|
18104
18671
|
return response.body;
|
|
18105
18672
|
},
|
|
@@ -18111,7 +18678,7 @@ function createProbeApi(httpClient) {
|
|
|
18111
18678
|
body: { activation_id: input.activationId }
|
|
18112
18679
|
});
|
|
18113
18680
|
if (response.status !== 200) {
|
|
18114
|
-
throw
|
|
18681
|
+
throw toApiError5(response.status, response.body);
|
|
18115
18682
|
}
|
|
18116
18683
|
return response.body;
|
|
18117
18684
|
}
|
|
@@ -18234,6 +18801,15 @@ function inferMatchedFields(event) {
|
|
|
18234
18801
|
if (event.top_frames.length > 0) {
|
|
18235
18802
|
matchedFields.push("top_frames");
|
|
18236
18803
|
}
|
|
18804
|
+
if (event.browser_event_kind != null) {
|
|
18805
|
+
matchedFields.push("browser_event_kind");
|
|
18806
|
+
}
|
|
18807
|
+
if (event.resource_host != null) {
|
|
18808
|
+
matchedFields.push("resource_host");
|
|
18809
|
+
}
|
|
18810
|
+
if (event.resource_path != null) {
|
|
18811
|
+
matchedFields.push("resource_path");
|
|
18812
|
+
}
|
|
18237
18813
|
if (event.http_method !== null) {
|
|
18238
18814
|
matchedFields.push("http_method");
|
|
18239
18815
|
}
|
|
@@ -18294,6 +18870,39 @@ function selectTopFrames(stack, limit = 5) {
|
|
|
18294
18870
|
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);
|
|
18295
18871
|
return frames;
|
|
18296
18872
|
}
|
|
18873
|
+
function normalizeResourceIdentity(value) {
|
|
18874
|
+
if (value === null) {
|
|
18875
|
+
return { host: null, path: null };
|
|
18876
|
+
}
|
|
18877
|
+
const trimmed = value.trim();
|
|
18878
|
+
if (trimmed.length === 0) {
|
|
18879
|
+
return { host: null, path: null };
|
|
18880
|
+
}
|
|
18881
|
+
if (trimmed.startsWith("/")) {
|
|
18882
|
+
return {
|
|
18883
|
+
host: null,
|
|
18884
|
+
path: normalizeRoute(trimmed)
|
|
18885
|
+
};
|
|
18886
|
+
}
|
|
18887
|
+
try {
|
|
18888
|
+
const parsed = new URL(trimmed);
|
|
18889
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:") {
|
|
18890
|
+
return {
|
|
18891
|
+
host: parsed.hostname.length > 0 ? parsed.hostname.toLowerCase() : null,
|
|
18892
|
+
path: normalizeRoute(parsed.pathname)
|
|
18893
|
+
};
|
|
18894
|
+
}
|
|
18895
|
+
return {
|
|
18896
|
+
host: null,
|
|
18897
|
+
path: parsed.protocol.replace(/:$/, "")
|
|
18898
|
+
};
|
|
18899
|
+
} catch {
|
|
18900
|
+
return {
|
|
18901
|
+
host: null,
|
|
18902
|
+
path: normalizeRoute(trimmed) ?? trimmed
|
|
18903
|
+
};
|
|
18904
|
+
}
|
|
18905
|
+
}
|
|
18297
18906
|
function stableJson(value) {
|
|
18298
18907
|
if (value === null || typeof value !== "object") {
|
|
18299
18908
|
return JSON.stringify(value);
|
|
@@ -18321,6 +18930,9 @@ function normalizeEvent(event) {
|
|
|
18321
18930
|
http_method: event.payload.request.method,
|
|
18322
18931
|
http_status: event.payload.response.status_code,
|
|
18323
18932
|
top_frames: selectTopFrames(event.payload.stack),
|
|
18933
|
+
browser_event_kind: null,
|
|
18934
|
+
resource_host: null,
|
|
18935
|
+
resource_path: null,
|
|
18324
18936
|
payload: redactedPayload
|
|
18325
18937
|
};
|
|
18326
18938
|
}
|
|
@@ -18334,6 +18946,9 @@ function normalizeEvent(event) {
|
|
|
18334
18946
|
http_method: event.payload.method,
|
|
18335
18947
|
http_status: event.payload.response_status,
|
|
18336
18948
|
top_frames: [],
|
|
18949
|
+
browser_event_kind: null,
|
|
18950
|
+
resource_host: null,
|
|
18951
|
+
resource_path: null,
|
|
18337
18952
|
payload: redactedPayload
|
|
18338
18953
|
};
|
|
18339
18954
|
}
|
|
@@ -18347,6 +18962,28 @@ function normalizeEvent(event) {
|
|
|
18347
18962
|
http_method: null,
|
|
18348
18963
|
http_status: null,
|
|
18349
18964
|
top_frames: [],
|
|
18965
|
+
browser_event_kind: null,
|
|
18966
|
+
resource_host: null,
|
|
18967
|
+
resource_path: null,
|
|
18968
|
+
payload: redactedPayload
|
|
18969
|
+
};
|
|
18970
|
+
}
|
|
18971
|
+
if (event.event_type === "frontend_exception") {
|
|
18972
|
+
const browserEvent = event.payload.browser_event;
|
|
18973
|
+
const resourceIdentity = browserEvent?.kind === "resource_error" ? normalizeResourceIdentity(browserEvent.target?.source_url ?? browserEvent.file_name) : { host: null, path: null };
|
|
18974
|
+
const topFrames = browserEvent?.opaque === true ? [] : selectTopFrames(event.payload.stack);
|
|
18975
|
+
return {
|
|
18976
|
+
event_type: event.event_type,
|
|
18977
|
+
environment: event.service.environment,
|
|
18978
|
+
error_type: event.payload.name,
|
|
18979
|
+
normalized_message: normalizeMessage(event.payload.message),
|
|
18980
|
+
route_template: normalizeRoute(event.payload.route ?? null),
|
|
18981
|
+
http_method: null,
|
|
18982
|
+
http_status: null,
|
|
18983
|
+
top_frames: topFrames,
|
|
18984
|
+
browser_event_kind: browserEvent?.kind ?? null,
|
|
18985
|
+
resource_host: resourceIdentity.host,
|
|
18986
|
+
resource_path: resourceIdentity.path,
|
|
18350
18987
|
payload: redactedPayload
|
|
18351
18988
|
};
|
|
18352
18989
|
}
|
|
@@ -18359,6 +18996,9 @@ function normalizeEvent(event) {
|
|
|
18359
18996
|
http_method: null,
|
|
18360
18997
|
http_status: null,
|
|
18361
18998
|
top_frames: [],
|
|
18999
|
+
browser_event_kind: null,
|
|
19000
|
+
resource_host: null,
|
|
19001
|
+
resource_path: null,
|
|
18362
19002
|
payload: redactedPayload
|
|
18363
19003
|
};
|
|
18364
19004
|
}
|
|
@@ -18368,6 +19008,9 @@ function fingerprint(event) {
|
|
|
18368
19008
|
normalized_message: event.normalized_message,
|
|
18369
19009
|
top_frames: event.top_frames,
|
|
18370
19010
|
route_template: event.route_template,
|
|
19011
|
+
browser_event_kind: event.browser_event_kind,
|
|
19012
|
+
resource_host: event.resource_host,
|
|
19013
|
+
resource_path: event.resource_path,
|
|
18371
19014
|
http_method: event.http_method,
|
|
18372
19015
|
http_status: event.http_status,
|
|
18373
19016
|
environment: event.environment
|
|
@@ -18422,18 +19065,18 @@ var ConnectionConfigSchema = external_exports.object({
|
|
|
18422
19065
|
}).strict();
|
|
18423
19066
|
|
|
18424
19067
|
// ../cli/src/doctor-command.ts
|
|
18425
|
-
var ProfileSchema2 = external_exports.object({
|
|
18426
|
-
debugbundle: external_exports.object({
|
|
18427
|
-
last_reviewed_at: external_exports.string(),
|
|
18428
|
-
validation_status: external_exports.enum(["static-analysis-only", "agent-validated"])
|
|
18429
|
-
})
|
|
18430
|
-
});
|
|
18431
19068
|
var HealthResponseSchema = external_exports.object({
|
|
18432
19069
|
status: external_exports.literal("ok")
|
|
18433
19070
|
});
|
|
18434
19071
|
var IncidentsProbeResponseSchema = external_exports.object({
|
|
18435
19072
|
incidents: external_exports.array(external_exports.unknown())
|
|
18436
19073
|
});
|
|
19074
|
+
var DoctorProfileSchema = external_exports.object({
|
|
19075
|
+
debugbundle: external_exports.object({
|
|
19076
|
+
last_reviewed_at: external_exports.string(),
|
|
19077
|
+
validation_status: external_exports.enum(["static-analysis-only", "agent-validated"])
|
|
19078
|
+
})
|
|
19079
|
+
});
|
|
18437
19080
|
var PROFILE_STALENESS_THRESHOLD_DAYS = 30;
|
|
18438
19081
|
var LOCAL_RELAY_SPOOL_DIRECTORY_PATH = ".debugbundle/local/browser-relay-spool";
|
|
18439
19082
|
var RELAY_SPOOL_DELIVERED_MARKER_SUFFIX = ".delivered";
|
|
@@ -18576,6 +19219,12 @@ async function buildFileCheck(rootDirectory, name, filePath, stat) {
|
|
|
18576
19219
|
message: exists ? `Found ${filePath}` : `Missing ${filePath}`
|
|
18577
19220
|
};
|
|
18578
19221
|
}
|
|
19222
|
+
function formatZodErrors2(error) {
|
|
19223
|
+
return error.issues.map((issue) => ({
|
|
19224
|
+
path: issue.path.join("."),
|
|
19225
|
+
message: issue.message
|
|
19226
|
+
}));
|
|
19227
|
+
}
|
|
18579
19228
|
async function loadProfile(rootDirectory, dependencies) {
|
|
18580
19229
|
const profilePath = (0, import_node_path4.join)(rootDirectory, PROFILE_FILE_PATH);
|
|
18581
19230
|
if (!await pathExists3(profilePath, dependencies.stat)) {
|
|
@@ -18585,29 +19234,46 @@ async function loadProfile(rootDirectory, dependencies) {
|
|
|
18585
19234
|
status: "missing",
|
|
18586
19235
|
message: `Missing ${PROFILE_FILE_PATH}`
|
|
18587
19236
|
},
|
|
18588
|
-
profile: null
|
|
19237
|
+
profile: null,
|
|
19238
|
+
validationErrors: []
|
|
18589
19239
|
};
|
|
18590
19240
|
}
|
|
19241
|
+
let parsedJson;
|
|
18591
19242
|
try {
|
|
18592
|
-
|
|
19243
|
+
parsedJson = JSON.parse(await dependencies.readFile(profilePath));
|
|
19244
|
+
} catch {
|
|
18593
19245
|
return {
|
|
18594
19246
|
check: {
|
|
18595
19247
|
name: "profile",
|
|
18596
|
-
status: "
|
|
18597
|
-
message: `
|
|
19248
|
+
status: "error",
|
|
19249
|
+
message: `Invalid ${PROFILE_FILE_PATH}`
|
|
18598
19250
|
},
|
|
18599
|
-
profile:
|
|
19251
|
+
profile: null,
|
|
19252
|
+
validationErrors: []
|
|
18600
19253
|
};
|
|
18601
|
-
}
|
|
19254
|
+
}
|
|
19255
|
+
const parsedDoctorProfile = DoctorProfileSchema.safeParse(parsedJson);
|
|
19256
|
+
if (!parsedDoctorProfile.success) {
|
|
18602
19257
|
return {
|
|
18603
19258
|
check: {
|
|
18604
19259
|
name: "profile",
|
|
18605
19260
|
status: "error",
|
|
18606
19261
|
message: `Invalid ${PROFILE_FILE_PATH}`
|
|
18607
19262
|
},
|
|
18608
|
-
profile: null
|
|
19263
|
+
profile: null,
|
|
19264
|
+
validationErrors: formatZodErrors2(parsedDoctorProfile.error)
|
|
18609
19265
|
};
|
|
18610
19266
|
}
|
|
19267
|
+
const parsedFullProfile = ProfileSchema.safeParse(parsedJson);
|
|
19268
|
+
return {
|
|
19269
|
+
check: {
|
|
19270
|
+
name: "profile",
|
|
19271
|
+
status: "ok",
|
|
19272
|
+
message: `Found ${PROFILE_FILE_PATH}`
|
|
19273
|
+
},
|
|
19274
|
+
profile: parsedDoctorProfile.data,
|
|
19275
|
+
validationErrors: parsedFullProfile.success ? [] : formatZodErrors2(parsedFullProfile.error)
|
|
19276
|
+
};
|
|
18611
19277
|
}
|
|
18612
19278
|
async function loadConnection(rootDirectory, dependencies) {
|
|
18613
19279
|
const connectionPath = (0, import_node_path4.join)(rootDirectory, CONNECTION_FILE_PATH);
|
|
@@ -18659,7 +19325,20 @@ function buildProjectModeCheck(connection) {
|
|
|
18659
19325
|
message: `Project mode is ${connection.mode}.`
|
|
18660
19326
|
};
|
|
18661
19327
|
}
|
|
18662
|
-
function
|
|
19328
|
+
function formatProfileValidationError(errors) {
|
|
19329
|
+
const firstError = errors[0];
|
|
19330
|
+
const path = firstError.path.length === 0 ? PROFILE_FILE_PATH : firstError.path;
|
|
19331
|
+
const totalErrors = errors.length === 1 ? "" : ` (${errors.length} total errors)`;
|
|
19332
|
+
return `Profile schema validation failed at ${path}: ${firstError.message}${totalErrors}.`;
|
|
19333
|
+
}
|
|
19334
|
+
function buildProfileValidationCheck(profile, validationErrors) {
|
|
19335
|
+
if (validationErrors.length > 0) {
|
|
19336
|
+
return {
|
|
19337
|
+
name: "profile-validation",
|
|
19338
|
+
status: "error",
|
|
19339
|
+
message: formatProfileValidationError(validationErrors)
|
|
19340
|
+
};
|
|
19341
|
+
}
|
|
18663
19342
|
if (profile === null) {
|
|
18664
19343
|
return {
|
|
18665
19344
|
name: "profile-validation",
|
|
@@ -18908,7 +19587,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18908
19587
|
const stat = dependencies.stat ?? import_promises4.stat;
|
|
18909
19588
|
const rootDirectory = cwd();
|
|
18910
19589
|
const currentTime = now();
|
|
18911
|
-
const { check: profileCheck, profile } = await loadProfile(rootDirectory, { readFile, stat });
|
|
19590
|
+
const { check: profileCheck, profile, validationErrors } = await loadProfile(rootDirectory, { readFile, stat });
|
|
18912
19591
|
const { check: connectionCheck, connection } = await loadConnection(rootDirectory, { readFile, stat });
|
|
18913
19592
|
const { check: authCheck, authState } = await buildAuthCheck(input, readAuthStateImpl);
|
|
18914
19593
|
const connectedApiCheck = await buildConnectedApiCheck({
|
|
@@ -18923,7 +19602,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18923
19602
|
authCheck,
|
|
18924
19603
|
buildProjectModeCheck(connection),
|
|
18925
19604
|
...connectedApiCheck === null ? [] : [connectedApiCheck],
|
|
18926
|
-
buildProfileValidationCheck(profile),
|
|
19605
|
+
buildProfileValidationCheck(profile, validationErrors),
|
|
18927
19606
|
buildProfileFreshnessCheck(profile, currentTime),
|
|
18928
19607
|
...input.checkRelay === true ? [await buildRelaySpoolCheck(rootDirectory, currentTime, { readdir, stat })] : []
|
|
18929
19608
|
];
|
|
@@ -18935,6 +19614,7 @@ async function doctorCommand(input, dependencies = {}) {
|
|
|
18935
19614
|
}
|
|
18936
19615
|
|
|
18937
19616
|
// ../cli/src/verify-command.ts
|
|
19617
|
+
var import_node_crypto6 = require("node:crypto");
|
|
18938
19618
|
var import_promises7 = require("node:fs/promises");
|
|
18939
19619
|
var import_node_path9 = require("node:path");
|
|
18940
19620
|
|
|
@@ -19232,9 +19912,872 @@ var import_ioredis3 = __toESM(require_built3(), 1);
|
|
|
19232
19912
|
|
|
19233
19913
|
// ../../packages/storage/src/redis-queue.ts
|
|
19234
19914
|
var import_ioredis4 = __toESM(require_built3(), 1);
|
|
19915
|
+
var DEFAULT_PROCESSING_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
19235
19916
|
|
|
19236
19917
|
// ../../packages/storage/src/schema-migrations.ts
|
|
19237
19918
|
var import_node_crypto3 = require("node:crypto");
|
|
19919
|
+
|
|
19920
|
+
// ../../packages/storage/src/migrations.ts
|
|
19921
|
+
var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
19922
|
+
`
|
|
19923
|
+
CREATE TABLE users (
|
|
19924
|
+
id uuid PRIMARY KEY,
|
|
19925
|
+
email text NOT NULL UNIQUE,
|
|
19926
|
+
accepted_terms_at timestamptz,
|
|
19927
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19928
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19929
|
+
email_verified_at timestamptz,
|
|
19930
|
+
avatar_source text,
|
|
19931
|
+
avatar_object_key text,
|
|
19932
|
+
avatar_content_type text,
|
|
19933
|
+
avatar_updated_at timestamptz
|
|
19934
|
+
)
|
|
19935
|
+
`,
|
|
19936
|
+
`
|
|
19937
|
+
CREATE TABLE organizations (
|
|
19938
|
+
id uuid PRIMARY KEY,
|
|
19939
|
+
name text NOT NULL,
|
|
19940
|
+
slug text NOT NULL UNIQUE,
|
|
19941
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19942
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19943
|
+
suspended_at timestamptz,
|
|
19944
|
+
plan text NOT NULL DEFAULT 'free',
|
|
19945
|
+
stripe_customer_id text,
|
|
19946
|
+
additional_capacity_units integer NOT NULL DEFAULT 0,
|
|
19947
|
+
stripe_subscription_id text,
|
|
19948
|
+
billing_state text,
|
|
19949
|
+
billing_period_ends_at timestamptz,
|
|
19950
|
+
last_billing_sync_at timestamptz,
|
|
19951
|
+
last_billing_event_id text,
|
|
19952
|
+
billing_period_starts_at timestamptz
|
|
19953
|
+
)
|
|
19954
|
+
`,
|
|
19955
|
+
`
|
|
19956
|
+
CREATE UNIQUE INDEX organizations_stripe_customer_id_key
|
|
19957
|
+
ON organizations (stripe_customer_id)
|
|
19958
|
+
WHERE stripe_customer_id IS NOT NULL
|
|
19959
|
+
`,
|
|
19960
|
+
`
|
|
19961
|
+
CREATE TABLE projects (
|
|
19962
|
+
id uuid PRIMARY KEY,
|
|
19963
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
19964
|
+
owner_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
19965
|
+
name text NOT NULL,
|
|
19966
|
+
slug text NOT NULL,
|
|
19967
|
+
environment_default text NOT NULL DEFAULT 'production',
|
|
19968
|
+
automated_improvement_bundles_enabled boolean NOT NULL DEFAULT true,
|
|
19969
|
+
improvement_bundle_sensitivity text NOT NULL DEFAULT 'high_confidence'
|
|
19970
|
+
CHECK (improvement_bundle_sensitivity IN ('high_confidence', 'balanced', 'verbose')),
|
|
19971
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19972
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19973
|
+
plan text NOT NULL DEFAULT 'free'
|
|
19974
|
+
)
|
|
19975
|
+
`,
|
|
19976
|
+
`
|
|
19977
|
+
CREATE UNIQUE INDEX projects_organization_id_slug_key
|
|
19978
|
+
ON projects (organization_id, slug)
|
|
19979
|
+
`,
|
|
19980
|
+
`
|
|
19981
|
+
CREATE TABLE services (
|
|
19982
|
+
id uuid PRIMARY KEY,
|
|
19983
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
19984
|
+
name text NOT NULL,
|
|
19985
|
+
runtime text,
|
|
19986
|
+
framework text,
|
|
19987
|
+
environment text NOT NULL DEFAULT 'production',
|
|
19988
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19989
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19990
|
+
UNIQUE (project_id, name, environment)
|
|
19991
|
+
)
|
|
19992
|
+
`,
|
|
19993
|
+
`
|
|
19994
|
+
CREATE TABLE project_tokens (
|
|
19995
|
+
id uuid PRIMARY KEY,
|
|
19996
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
19997
|
+
token_hash text UNIQUE NOT NULL,
|
|
19998
|
+
label text NOT NULL,
|
|
19999
|
+
allowed_origins jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
20000
|
+
last_used_at timestamptz,
|
|
20001
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20002
|
+
revoked_at timestamptz,
|
|
20003
|
+
expires_at timestamptz
|
|
20004
|
+
)
|
|
20005
|
+
`,
|
|
20006
|
+
`
|
|
20007
|
+
CREATE TABLE member_tokens (
|
|
20008
|
+
id uuid PRIMARY KEY,
|
|
20009
|
+
user_id uuid NOT NULL,
|
|
20010
|
+
organization_id uuid NOT NULL,
|
|
20011
|
+
token_hash text UNIQUE NOT NULL,
|
|
20012
|
+
label text NOT NULL,
|
|
20013
|
+
last_used_at timestamptz,
|
|
20014
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20015
|
+
revoked_at timestamptz,
|
|
20016
|
+
expires_at timestamptz
|
|
20017
|
+
)
|
|
20018
|
+
`,
|
|
20019
|
+
`
|
|
20020
|
+
CREATE INDEX member_tokens_org_idx
|
|
20021
|
+
ON member_tokens (organization_id)
|
|
20022
|
+
`,
|
|
20023
|
+
`
|
|
20024
|
+
CREATE TABLE audit_logs (
|
|
20025
|
+
id uuid PRIMARY KEY,
|
|
20026
|
+
organization_id uuid,
|
|
20027
|
+
actor_user_id uuid,
|
|
20028
|
+
actor_type text NOT NULL,
|
|
20029
|
+
action text NOT NULL,
|
|
20030
|
+
target_type text NOT NULL,
|
|
20031
|
+
target_id text,
|
|
20032
|
+
status text NOT NULL,
|
|
20033
|
+
ip_address text,
|
|
20034
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20035
|
+
occurred_at timestamptz NOT NULL,
|
|
20036
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20037
|
+
)
|
|
20038
|
+
`,
|
|
20039
|
+
`
|
|
20040
|
+
CREATE INDEX audit_logs_organization_occurred_at_idx
|
|
20041
|
+
ON audit_logs (organization_id, occurred_at DESC, created_at DESC)
|
|
20042
|
+
`,
|
|
20043
|
+
`
|
|
20044
|
+
CREATE INDEX audit_logs_action_occurred_at_idx
|
|
20045
|
+
ON audit_logs (action, occurred_at DESC, created_at DESC)
|
|
20046
|
+
`,
|
|
20047
|
+
`
|
|
20048
|
+
CREATE TABLE organization_members (
|
|
20049
|
+
id uuid PRIMARY KEY,
|
|
20050
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20051
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20052
|
+
role text NOT NULL DEFAULT 'member',
|
|
20053
|
+
suspended_at timestamptz,
|
|
20054
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20055
|
+
UNIQUE (organization_id, user_id)
|
|
20056
|
+
)
|
|
20057
|
+
`,
|
|
20058
|
+
`
|
|
20059
|
+
CREATE INDEX organization_members_org_idx
|
|
20060
|
+
ON organization_members (organization_id)
|
|
20061
|
+
`,
|
|
20062
|
+
`
|
|
20063
|
+
CREATE INDEX organization_members_user_idx
|
|
20064
|
+
ON organization_members (user_id)
|
|
20065
|
+
`,
|
|
20066
|
+
`
|
|
20067
|
+
CREATE TABLE sessions (
|
|
20068
|
+
id uuid PRIMARY KEY,
|
|
20069
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20070
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20071
|
+
session_token_hash text UNIQUE NOT NULL,
|
|
20072
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20073
|
+
expires_at timestamptz NOT NULL,
|
|
20074
|
+
revoked_at timestamptz
|
|
20075
|
+
)
|
|
20076
|
+
`,
|
|
20077
|
+
`
|
|
20078
|
+
CREATE INDEX sessions_token_hash_idx
|
|
20079
|
+
ON sessions (session_token_hash)
|
|
20080
|
+
`,
|
|
20081
|
+
`
|
|
20082
|
+
CREATE INDEX sessions_user_org_idx
|
|
20083
|
+
ON sessions (user_id, organization_id)
|
|
20084
|
+
`,
|
|
20085
|
+
`
|
|
20086
|
+
CREATE TABLE email_auth_challenges (
|
|
20087
|
+
id uuid PRIMARY KEY,
|
|
20088
|
+
email text NOT NULL,
|
|
20089
|
+
code_hash text NOT NULL,
|
|
20090
|
+
accepted_terms_at timestamptz,
|
|
20091
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20092
|
+
expires_at timestamptz NOT NULL,
|
|
20093
|
+
used_at timestamptz
|
|
20094
|
+
)
|
|
20095
|
+
`,
|
|
20096
|
+
`
|
|
20097
|
+
CREATE INDEX email_auth_challenges_email_idx
|
|
20098
|
+
ON email_auth_challenges (lower(email), created_at DESC)
|
|
20099
|
+
`,
|
|
20100
|
+
`
|
|
20101
|
+
CREATE INDEX email_auth_challenges_code_hash_idx
|
|
20102
|
+
ON email_auth_challenges (code_hash)
|
|
20103
|
+
`,
|
|
20104
|
+
`
|
|
20105
|
+
CREATE TABLE github_device_authorizations (
|
|
20106
|
+
id uuid PRIMARY KEY,
|
|
20107
|
+
device_code text NOT NULL UNIQUE,
|
|
20108
|
+
user_code text NOT NULL,
|
|
20109
|
+
verification_uri text NOT NULL,
|
|
20110
|
+
interval_seconds integer NOT NULL,
|
|
20111
|
+
expires_at timestamptz NOT NULL,
|
|
20112
|
+
accepted_terms_at timestamptz,
|
|
20113
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20114
|
+
completed_at timestamptz,
|
|
20115
|
+
claimed_at timestamptz,
|
|
20116
|
+
terminal_error text,
|
|
20117
|
+
user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20118
|
+
organization_id uuid REFERENCES organizations(id) ON DELETE SET NULL
|
|
20119
|
+
)
|
|
20120
|
+
`,
|
|
20121
|
+
`
|
|
20122
|
+
CREATE INDEX github_device_authorizations_user_code_idx
|
|
20123
|
+
ON github_device_authorizations (user_code, created_at DESC)
|
|
20124
|
+
`,
|
|
20125
|
+
`
|
|
20126
|
+
CREATE INDEX github_device_authorizations_expires_at_idx
|
|
20127
|
+
ON github_device_authorizations (expires_at)
|
|
20128
|
+
`,
|
|
20129
|
+
`
|
|
20130
|
+
CREATE TABLE project_members (
|
|
20131
|
+
id uuid PRIMARY KEY,
|
|
20132
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20133
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20134
|
+
role text NOT NULL,
|
|
20135
|
+
invited_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20136
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20137
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20138
|
+
UNIQUE (project_id, user_id)
|
|
20139
|
+
)
|
|
20140
|
+
`,
|
|
20141
|
+
`
|
|
20142
|
+
CREATE INDEX project_members_project_id_idx
|
|
20143
|
+
ON project_members (project_id, created_at DESC)
|
|
20144
|
+
`,
|
|
20145
|
+
`
|
|
20146
|
+
CREATE INDEX project_members_user_id_idx
|
|
20147
|
+
ON project_members (user_id, created_at DESC)
|
|
20148
|
+
`,
|
|
20149
|
+
`
|
|
20150
|
+
CREATE TABLE project_invites (
|
|
20151
|
+
id uuid PRIMARY KEY,
|
|
20152
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20153
|
+
email text NOT NULL,
|
|
20154
|
+
role text NOT NULL,
|
|
20155
|
+
invited_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20156
|
+
invite_token_hash text NOT NULL,
|
|
20157
|
+
accepted_at timestamptz,
|
|
20158
|
+
canceled_at timestamptz,
|
|
20159
|
+
expires_at timestamptz NOT NULL,
|
|
20160
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20161
|
+
)
|
|
20162
|
+
`,
|
|
20163
|
+
`
|
|
20164
|
+
CREATE INDEX project_invites_project_id_idx
|
|
20165
|
+
ON project_invites (project_id, created_at DESC)
|
|
20166
|
+
`,
|
|
20167
|
+
`
|
|
20168
|
+
CREATE UNIQUE INDEX project_invites_pending_project_email_key
|
|
20169
|
+
ON project_invites (project_id, lower(email))
|
|
20170
|
+
WHERE accepted_at IS NULL AND canceled_at IS NULL
|
|
20171
|
+
`,
|
|
20172
|
+
`
|
|
20173
|
+
CREATE UNIQUE INDEX project_invites_invite_token_hash_key
|
|
20174
|
+
ON project_invites (invite_token_hash)
|
|
20175
|
+
`,
|
|
20176
|
+
`
|
|
20177
|
+
CREATE TABLE oauth_identities (
|
|
20178
|
+
id uuid PRIMARY KEY,
|
|
20179
|
+
provider text NOT NULL,
|
|
20180
|
+
provider_user_id text NOT NULL,
|
|
20181
|
+
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20182
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20183
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20184
|
+
UNIQUE (provider, provider_user_id)
|
|
20185
|
+
)
|
|
20186
|
+
`,
|
|
20187
|
+
`
|
|
20188
|
+
CREATE INDEX oauth_identities_user_id_idx
|
|
20189
|
+
ON oauth_identities (user_id, provider)
|
|
20190
|
+
`,
|
|
20191
|
+
`
|
|
20192
|
+
CREATE TABLE probe_activations (
|
|
20193
|
+
id uuid PRIMARY KEY,
|
|
20194
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20195
|
+
created_by_member_id uuid NOT NULL,
|
|
20196
|
+
label_pattern text NOT NULL,
|
|
20197
|
+
service text NOT NULL DEFAULT '*',
|
|
20198
|
+
environment text NOT NULL DEFAULT '*',
|
|
20199
|
+
trigger_expires_at timestamptz NOT NULL,
|
|
20200
|
+
expires_at timestamptz NOT NULL,
|
|
20201
|
+
deactivated_at timestamptz,
|
|
20202
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
20203
|
+
)
|
|
20204
|
+
`,
|
|
20205
|
+
`
|
|
20206
|
+
CREATE INDEX probe_activations_project_active_idx
|
|
20207
|
+
ON probe_activations (project_id, expires_at DESC)
|
|
20208
|
+
WHERE deactivated_at IS NULL
|
|
20209
|
+
`,
|
|
20210
|
+
`
|
|
20211
|
+
CREATE TABLE capture_policies (
|
|
20212
|
+
project_id uuid PRIMARY KEY REFERENCES projects(id) ON DELETE CASCADE,
|
|
20213
|
+
preset text NOT NULL DEFAULT 'minimal',
|
|
20214
|
+
capture_logs text,
|
|
20215
|
+
capture_request_events text,
|
|
20216
|
+
capture_breadcrumbs text,
|
|
20217
|
+
capture_probe_events text,
|
|
20218
|
+
immediate_client_error_statuses jsonb,
|
|
20219
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20220
|
+
)
|
|
20221
|
+
`,
|
|
20222
|
+
`
|
|
20223
|
+
CREATE TABLE capture_rules (
|
|
20224
|
+
id uuid PRIMARY KEY,
|
|
20225
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20226
|
+
name text NOT NULL,
|
|
20227
|
+
description text,
|
|
20228
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
20229
|
+
action text NOT NULL,
|
|
20230
|
+
matcher jsonb NOT NULL,
|
|
20231
|
+
sample_rate double precision,
|
|
20232
|
+
sample_event_class text,
|
|
20233
|
+
created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20234
|
+
created_from_incident_id text,
|
|
20235
|
+
created_from_event_id text,
|
|
20236
|
+
expires_at timestamptz,
|
|
20237
|
+
hit_count bigint NOT NULL DEFAULT 0,
|
|
20238
|
+
last_matched_at timestamptz,
|
|
20239
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20240
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20241
|
+
)
|
|
20242
|
+
`,
|
|
20243
|
+
`
|
|
20244
|
+
CREATE INDEX capture_rules_project_enabled_idx
|
|
20245
|
+
ON capture_rules (project_id, enabled)
|
|
20246
|
+
`,
|
|
20247
|
+
`
|
|
20248
|
+
CREATE INDEX capture_rules_project_updated_idx
|
|
20249
|
+
ON capture_rules (project_id, updated_at DESC)
|
|
20250
|
+
`,
|
|
20251
|
+
`
|
|
20252
|
+
CREATE TABLE deployments (
|
|
20253
|
+
id uuid PRIMARY KEY,
|
|
20254
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20255
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20256
|
+
environment text NOT NULL,
|
|
20257
|
+
source_event_id uuid UNIQUE NOT NULL,
|
|
20258
|
+
commit_sha text,
|
|
20259
|
+
version text,
|
|
20260
|
+
branch text,
|
|
20261
|
+
deployed_at timestamptz NOT NULL,
|
|
20262
|
+
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20263
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20264
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20265
|
+
)
|
|
20266
|
+
`,
|
|
20267
|
+
`
|
|
20268
|
+
CREATE INDEX deployments_project_service_env_deployed_idx
|
|
20269
|
+
ON deployments (project_id, service_id, environment, deployed_at DESC)
|
|
20270
|
+
`,
|
|
20271
|
+
`
|
|
20272
|
+
CREATE TABLE incidents (
|
|
20273
|
+
id uuid PRIMARY KEY,
|
|
20274
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20275
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20276
|
+
environment text NOT NULL DEFAULT 'production',
|
|
20277
|
+
fingerprint text NOT NULL,
|
|
20278
|
+
fingerprint_version text NOT NULL DEFAULT 'v1',
|
|
20279
|
+
title text NOT NULL,
|
|
20280
|
+
severity text NOT NULL,
|
|
20281
|
+
status text NOT NULL DEFAULT 'open',
|
|
20282
|
+
first_seen_at timestamptz NOT NULL,
|
|
20283
|
+
last_seen_at timestamptz NOT NULL,
|
|
20284
|
+
occurrence_count integer NOT NULL DEFAULT 1,
|
|
20285
|
+
matched_fields text[],
|
|
20286
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20287
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20288
|
+
regressed_at timestamptz,
|
|
20289
|
+
spike_detected_at timestamptz,
|
|
20290
|
+
frequency_occurrences_1m integer,
|
|
20291
|
+
frequency_occurrences_5m integer,
|
|
20292
|
+
frequency_occurrences_1h integer,
|
|
20293
|
+
frequency_occurrences_24h integer,
|
|
20294
|
+
frequency_baseline_1h_per_5m double precision,
|
|
20295
|
+
frequency_spike_ratio_5m_to_1h double precision,
|
|
20296
|
+
frequency_has_sufficient_baseline boolean,
|
|
20297
|
+
frequency_is_spiking boolean,
|
|
20298
|
+
frequency_snapshot_at timestamptz,
|
|
20299
|
+
latest_deployment_id uuid REFERENCES deployments(id) ON DELETE SET NULL,
|
|
20300
|
+
bundle_generation_number integer NOT NULL DEFAULT 0,
|
|
20301
|
+
bundle_created_at timestamptz,
|
|
20302
|
+
bundle_updated_at timestamptz,
|
|
20303
|
+
bundle_source_event_id uuid,
|
|
20304
|
+
bundle_source_occurred_at timestamptz,
|
|
20305
|
+
bundle_trigger text,
|
|
20306
|
+
bundle_failure_reason text,
|
|
20307
|
+
resolved_at timestamptz,
|
|
20308
|
+
resolved_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20309
|
+
UNIQUE (project_id, environment, service_id, fingerprint)
|
|
20310
|
+
)
|
|
20311
|
+
`,
|
|
20312
|
+
`
|
|
20313
|
+
CREATE TABLE processed_events (
|
|
20314
|
+
event_id uuid PRIMARY KEY,
|
|
20315
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20316
|
+
event_type text NOT NULL,
|
|
20317
|
+
fingerprint text NOT NULL,
|
|
20318
|
+
normalized_message text NOT NULL,
|
|
20319
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20320
|
+
)
|
|
20321
|
+
`,
|
|
20322
|
+
`
|
|
20323
|
+
CREATE TABLE improvement_opportunities (
|
|
20324
|
+
id uuid PRIMARY KEY,
|
|
20325
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20326
|
+
service_id uuid REFERENCES services(id) ON DELETE SET NULL,
|
|
20327
|
+
service_name text NOT NULL,
|
|
20328
|
+
environment text NOT NULL DEFAULT 'production',
|
|
20329
|
+
kind text NOT NULL,
|
|
20330
|
+
status text NOT NULL DEFAULT 'open',
|
|
20331
|
+
severity text NOT NULL,
|
|
20332
|
+
confidence numeric NOT NULL,
|
|
20333
|
+
fingerprint text NOT NULL,
|
|
20334
|
+
title text NOT NULL,
|
|
20335
|
+
summary text NOT NULL,
|
|
20336
|
+
occurrence_count integer NOT NULL DEFAULT 1,
|
|
20337
|
+
evidence jsonb NOT NULL,
|
|
20338
|
+
first_detected_at timestamptz NOT NULL,
|
|
20339
|
+
last_detected_at timestamptz NOT NULL,
|
|
20340
|
+
last_source_event_id uuid,
|
|
20341
|
+
related_incident_ids uuid[] NOT NULL DEFAULT '{}',
|
|
20342
|
+
bundle_generation_number integer NOT NULL DEFAULT 0,
|
|
20343
|
+
bundle_created_at timestamptz,
|
|
20344
|
+
bundle_updated_at timestamptz,
|
|
20345
|
+
bundle_source_event_id uuid,
|
|
20346
|
+
bundle_failure_reason text,
|
|
20347
|
+
resolved_at timestamptz,
|
|
20348
|
+
resolved_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20349
|
+
snoozed_until timestamptz,
|
|
20350
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20351
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20352
|
+
UNIQUE (project_id, fingerprint)
|
|
20353
|
+
)
|
|
20354
|
+
`,
|
|
20355
|
+
`
|
|
20356
|
+
CREATE INDEX improvement_opportunities_project_status_detected_idx
|
|
20357
|
+
ON improvement_opportunities (project_id, status, last_detected_at DESC)
|
|
20358
|
+
`,
|
|
20359
|
+
`
|
|
20360
|
+
CREATE INDEX improvement_opportunities_project_kind_detected_idx
|
|
20361
|
+
ON improvement_opportunities (project_id, kind, last_detected_at DESC)
|
|
20362
|
+
`,
|
|
20363
|
+
`
|
|
20364
|
+
CREATE INDEX improvement_opportunities_project_service_env_idx
|
|
20365
|
+
ON improvement_opportunities (project_id, service_id, environment)
|
|
20366
|
+
`,
|
|
20367
|
+
`
|
|
20368
|
+
CREATE TABLE improvement_opportunity_events (
|
|
20369
|
+
improvement_opportunity_id uuid NOT NULL REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20370
|
+
event_id uuid NOT NULL,
|
|
20371
|
+
event_type text NOT NULL,
|
|
20372
|
+
occurred_at timestamptz NOT NULL,
|
|
20373
|
+
PRIMARY KEY (improvement_opportunity_id, event_id)
|
|
20374
|
+
)
|
|
20375
|
+
`,
|
|
20376
|
+
`
|
|
20377
|
+
CREATE INDEX improvement_opportunity_events_detected_idx
|
|
20378
|
+
ON improvement_opportunity_events (improvement_opportunity_id, occurred_at DESC, event_id DESC)
|
|
20379
|
+
`,
|
|
20380
|
+
`
|
|
20381
|
+
CREATE TABLE bundle_generations (
|
|
20382
|
+
id uuid PRIMARY KEY,
|
|
20383
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20384
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20385
|
+
improvement_opportunity_id uuid REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20386
|
+
bundle_type text NOT NULL,
|
|
20387
|
+
generation_number integer NOT NULL,
|
|
20388
|
+
source_event_id uuid NOT NULL,
|
|
20389
|
+
source_occurred_at timestamptz NOT NULL,
|
|
20390
|
+
trigger text NOT NULL,
|
|
20391
|
+
created_at timestamptz NOT NULL,
|
|
20392
|
+
updated_at timestamptz NOT NULL,
|
|
20393
|
+
CHECK (
|
|
20394
|
+
(incident_id IS NOT NULL AND improvement_opportunity_id IS NULL AND bundle_type = 'failure')
|
|
20395
|
+
OR (incident_id IS NULL AND improvement_opportunity_id IS NOT NULL AND bundle_type = 'improvement')
|
|
20396
|
+
)
|
|
20397
|
+
)
|
|
20398
|
+
`,
|
|
20399
|
+
`
|
|
20400
|
+
CREATE UNIQUE INDEX bundle_generations_incident_source_idx
|
|
20401
|
+
ON bundle_generations (incident_id, source_event_id)
|
|
20402
|
+
WHERE incident_id IS NOT NULL
|
|
20403
|
+
`,
|
|
20404
|
+
`
|
|
20405
|
+
CREATE UNIQUE INDEX bundle_generations_improvement_source_idx
|
|
20406
|
+
ON bundle_generations (improvement_opportunity_id, source_event_id)
|
|
20407
|
+
WHERE improvement_opportunity_id IS NOT NULL
|
|
20408
|
+
`,
|
|
20409
|
+
`
|
|
20410
|
+
CREATE INDEX bundle_generations_project_created_idx
|
|
20411
|
+
ON bundle_generations (project_id, created_at DESC, bundle_type)
|
|
20412
|
+
`,
|
|
20413
|
+
`
|
|
20414
|
+
CREATE INDEX bundle_generations_incident_generation_idx
|
|
20415
|
+
ON bundle_generations (incident_id, generation_number DESC)
|
|
20416
|
+
`,
|
|
20417
|
+
`
|
|
20418
|
+
CREATE INDEX bundle_generations_improvement_generation_idx
|
|
20419
|
+
ON bundle_generations (improvement_opportunity_id, generation_number DESC)
|
|
20420
|
+
WHERE improvement_opportunity_id IS NOT NULL
|
|
20421
|
+
`,
|
|
20422
|
+
`
|
|
20423
|
+
CREATE TABLE incident_events (
|
|
20424
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20425
|
+
event_id uuid NOT NULL,
|
|
20426
|
+
event_type text NOT NULL,
|
|
20427
|
+
event_class text NOT NULL DEFAULT 'context_signal',
|
|
20428
|
+
occurred_at timestamptz NOT NULL,
|
|
20429
|
+
is_sampled boolean NOT NULL DEFAULT false,
|
|
20430
|
+
level text,
|
|
20431
|
+
retain_first boolean NOT NULL DEFAULT false,
|
|
20432
|
+
retain_latest boolean NOT NULL DEFAULT false,
|
|
20433
|
+
retain_after_deploy boolean NOT NULL DEFAULT false,
|
|
20434
|
+
retain_highest_severity boolean NOT NULL DEFAULT false,
|
|
20435
|
+
retain_deploy_metadata boolean NOT NULL DEFAULT false,
|
|
20436
|
+
severity_rank integer NOT NULL DEFAULT 0,
|
|
20437
|
+
PRIMARY KEY (incident_id, event_id)
|
|
20438
|
+
)
|
|
20439
|
+
`,
|
|
20440
|
+
`
|
|
20441
|
+
CREATE INDEX incident_events_incident_occurred_event_idx
|
|
20442
|
+
ON incident_events (incident_id, occurred_at DESC, event_id DESC)
|
|
20443
|
+
`,
|
|
20444
|
+
`
|
|
20445
|
+
CREATE INDEX incident_events_incident_level_occurred_event_idx
|
|
20446
|
+
ON incident_events (incident_id, level, occurred_at DESC, event_id DESC)
|
|
20447
|
+
`,
|
|
20448
|
+
`
|
|
20449
|
+
CREATE INDEX incident_events_incident_sampled_idx
|
|
20450
|
+
ON incident_events (incident_id, is_sampled, occurred_at ASC, event_id ASC)
|
|
20451
|
+
`,
|
|
20452
|
+
`
|
|
20453
|
+
CREATE TABLE weekly_report_channels (
|
|
20454
|
+
id uuid PRIMARY KEY,
|
|
20455
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20456
|
+
channel text NOT NULL,
|
|
20457
|
+
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20458
|
+
schedule_day_of_week text NOT NULL,
|
|
20459
|
+
schedule_hour_of_day integer NOT NULL,
|
|
20460
|
+
schedule_timezone text NOT NULL,
|
|
20461
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20462
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20463
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20464
|
+
)
|
|
20465
|
+
`,
|
|
20466
|
+
`
|
|
20467
|
+
CREATE INDEX weekly_report_channels_project_created_idx
|
|
20468
|
+
ON weekly_report_channels (project_id, created_at ASC)
|
|
20469
|
+
`,
|
|
20470
|
+
`
|
|
20471
|
+
CREATE UNIQUE INDEX weekly_report_channels_project_email_unique_idx
|
|
20472
|
+
ON weekly_report_channels (project_id)
|
|
20473
|
+
WHERE channel = 'email'
|
|
20474
|
+
`,
|
|
20475
|
+
`
|
|
20476
|
+
CREATE TABLE weekly_report_deliveries (
|
|
20477
|
+
id uuid PRIMARY KEY,
|
|
20478
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20479
|
+
weekly_report_channel_id uuid REFERENCES weekly_report_channels(id) ON DELETE CASCADE,
|
|
20480
|
+
window_start timestamptz NOT NULL,
|
|
20481
|
+
window_end timestamptz NOT NULL,
|
|
20482
|
+
channel text NOT NULL,
|
|
20483
|
+
status text NOT NULL,
|
|
20484
|
+
last_error text,
|
|
20485
|
+
delivered_at timestamptz,
|
|
20486
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20487
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20488
|
+
)
|
|
20489
|
+
`,
|
|
20490
|
+
`
|
|
20491
|
+
CREATE INDEX weekly_report_deliveries_project_window_idx
|
|
20492
|
+
ON weekly_report_deliveries (project_id, window_end DESC, channel)
|
|
20493
|
+
`,
|
|
20494
|
+
`
|
|
20495
|
+
CREATE UNIQUE INDEX weekly_report_deliveries_channel_window_idx
|
|
20496
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_start, window_end)
|
|
20497
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
20498
|
+
`,
|
|
20499
|
+
`
|
|
20500
|
+
CREATE INDEX weekly_report_deliveries_channel_idx
|
|
20501
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_end DESC)
|
|
20502
|
+
`,
|
|
20503
|
+
`
|
|
20504
|
+
CREATE TABLE alert_rules (
|
|
20505
|
+
id uuid PRIMARY KEY,
|
|
20506
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20507
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20508
|
+
service_id uuid REFERENCES services(id) ON DELETE CASCADE,
|
|
20509
|
+
channel text NOT NULL,
|
|
20510
|
+
condition_type text NOT NULL,
|
|
20511
|
+
severity_min text,
|
|
20512
|
+
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20513
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20514
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20515
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20516
|
+
)
|
|
20517
|
+
`,
|
|
20518
|
+
`
|
|
20519
|
+
CREATE INDEX alert_rules_project_enabled_idx
|
|
20520
|
+
ON alert_rules (project_id, is_enabled)
|
|
20521
|
+
`,
|
|
20522
|
+
`
|
|
20523
|
+
CREATE TABLE slack_destinations (
|
|
20524
|
+
id uuid PRIMARY KEY,
|
|
20525
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20526
|
+
slack_team_id text NOT NULL,
|
|
20527
|
+
slack_team_name text,
|
|
20528
|
+
slack_channel_id text NOT NULL,
|
|
20529
|
+
slack_channel_name text,
|
|
20530
|
+
webhook_url_ciphertext text NOT NULL,
|
|
20531
|
+
installed_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
20532
|
+
is_active boolean NOT NULL DEFAULT true,
|
|
20533
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20534
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20535
|
+
UNIQUE (organization_id, slack_team_id, slack_channel_id)
|
|
20536
|
+
)
|
|
20537
|
+
`,
|
|
20538
|
+
`
|
|
20539
|
+
CREATE INDEX slack_destinations_org_active_idx
|
|
20540
|
+
ON slack_destinations (organization_id, is_active, created_at)
|
|
20541
|
+
`,
|
|
20542
|
+
`
|
|
20543
|
+
CREATE TABLE alert_deliveries (
|
|
20544
|
+
id uuid PRIMARY KEY,
|
|
20545
|
+
alert_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE,
|
|
20546
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20547
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20548
|
+
condition_type text NOT NULL,
|
|
20549
|
+
dedupe_key text NOT NULL,
|
|
20550
|
+
channel text NOT NULL,
|
|
20551
|
+
status text NOT NULL,
|
|
20552
|
+
payload jsonb NOT NULL,
|
|
20553
|
+
last_error text,
|
|
20554
|
+
delivered_at timestamptz,
|
|
20555
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20556
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20557
|
+
UNIQUE (alert_id, incident_id, dedupe_key)
|
|
20558
|
+
)
|
|
20559
|
+
`,
|
|
20560
|
+
`
|
|
20561
|
+
CREATE INDEX alert_deliveries_project_status_idx
|
|
20562
|
+
ON alert_deliveries (project_id, status, created_at DESC)
|
|
20563
|
+
`,
|
|
20564
|
+
`
|
|
20565
|
+
CREATE TABLE alert_email_digests (
|
|
20566
|
+
id uuid PRIMARY KEY,
|
|
20567
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20568
|
+
recipient text NOT NULL,
|
|
20569
|
+
status text NOT NULL,
|
|
20570
|
+
next_attempt_at timestamptz,
|
|
20571
|
+
claimed_at timestamptz,
|
|
20572
|
+
last_error text,
|
|
20573
|
+
delivered_at timestamptz,
|
|
20574
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20575
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20576
|
+
)
|
|
20577
|
+
`,
|
|
20578
|
+
`
|
|
20579
|
+
CREATE UNIQUE INDEX alert_email_digests_project_recipient_pending_idx
|
|
20580
|
+
ON alert_email_digests (project_id, recipient)
|
|
20581
|
+
WHERE status = 'pending' AND claimed_at IS NULL
|
|
20582
|
+
`,
|
|
20583
|
+
`
|
|
20584
|
+
CREATE INDEX alert_email_digests_status_next_attempt_idx
|
|
20585
|
+
ON alert_email_digests (status, next_attempt_at)
|
|
20586
|
+
`,
|
|
20587
|
+
`
|
|
20588
|
+
CREATE TABLE alert_email_digest_items (
|
|
20589
|
+
id uuid PRIMARY KEY,
|
|
20590
|
+
digest_id uuid NOT NULL REFERENCES alert_email_digests(id) ON DELETE CASCADE,
|
|
20591
|
+
alert_id uuid NOT NULL REFERENCES alert_rules(id) ON DELETE CASCADE,
|
|
20592
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20593
|
+
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20594
|
+
condition_type text NOT NULL,
|
|
20595
|
+
dedupe_key text NOT NULL,
|
|
20596
|
+
payload jsonb NOT NULL,
|
|
20597
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20598
|
+
UNIQUE (alert_id, incident_id, dedupe_key)
|
|
20599
|
+
)
|
|
20600
|
+
`,
|
|
20601
|
+
`
|
|
20602
|
+
CREATE INDEX alert_email_digest_items_digest_created_idx
|
|
20603
|
+
ON alert_email_digest_items (digest_id, created_at ASC)
|
|
20604
|
+
`,
|
|
20605
|
+
`
|
|
20606
|
+
CREATE TABLE agent_webhooks (
|
|
20607
|
+
id uuid PRIMARY KEY,
|
|
20608
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20609
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20610
|
+
url text NOT NULL,
|
|
20611
|
+
secret_hash text NOT NULL,
|
|
20612
|
+
events text[] NOT NULL,
|
|
20613
|
+
filters jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20614
|
+
is_enabled boolean NOT NULL DEFAULT true,
|
|
20615
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20616
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20617
|
+
)
|
|
20618
|
+
`,
|
|
20619
|
+
`
|
|
20620
|
+
CREATE INDEX agent_webhooks_project_enabled_idx
|
|
20621
|
+
ON agent_webhooks (project_id, is_enabled)
|
|
20622
|
+
`,
|
|
20623
|
+
`
|
|
20624
|
+
CREATE TABLE webhook_deliveries (
|
|
20625
|
+
id uuid PRIMARY KEY,
|
|
20626
|
+
webhook_id uuid REFERENCES agent_webhooks(id) ON DELETE CASCADE,
|
|
20627
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20628
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20629
|
+
event_type text NOT NULL,
|
|
20630
|
+
target_url text NOT NULL,
|
|
20631
|
+
signing_secret text NOT NULL,
|
|
20632
|
+
status text NOT NULL DEFAULT 'pending',
|
|
20633
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20634
|
+
occurred_at timestamptz NOT NULL,
|
|
20635
|
+
next_attempt_at timestamptz,
|
|
20636
|
+
last_response_code integer,
|
|
20637
|
+
last_attempted_at timestamptz,
|
|
20638
|
+
last_error text,
|
|
20639
|
+
payload jsonb NOT NULL,
|
|
20640
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20641
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20642
|
+
)
|
|
20643
|
+
`,
|
|
20644
|
+
`
|
|
20645
|
+
CREATE INDEX webhook_deliveries_status_next_attempt_idx
|
|
20646
|
+
ON webhook_deliveries (status, next_attempt_at)
|
|
20647
|
+
`,
|
|
20648
|
+
`
|
|
20649
|
+
CREATE TABLE processed_billing_events (
|
|
20650
|
+
event_id text PRIMARY KEY,
|
|
20651
|
+
event_type text NOT NULL,
|
|
20652
|
+
organization_id uuid,
|
|
20653
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20654
|
+
)
|
|
20655
|
+
`,
|
|
20656
|
+
`
|
|
20657
|
+
CREATE TABLE github_installations (
|
|
20658
|
+
id uuid PRIMARY KEY,
|
|
20659
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20660
|
+
installation_id bigint NOT NULL UNIQUE,
|
|
20661
|
+
account_login text NOT NULL,
|
|
20662
|
+
account_type text NOT NULL CHECK (account_type IN ('Organization', 'User')),
|
|
20663
|
+
status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'removed')),
|
|
20664
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20665
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20666
|
+
UNIQUE (organization_id)
|
|
20667
|
+
)
|
|
20668
|
+
`,
|
|
20669
|
+
`
|
|
20670
|
+
CREATE INDEX github_installations_status_idx
|
|
20671
|
+
ON github_installations (status)
|
|
20672
|
+
`,
|
|
20673
|
+
`
|
|
20674
|
+
CREATE TABLE project_github_repos (
|
|
20675
|
+
id uuid PRIMARY KEY,
|
|
20676
|
+
project_id uuid NOT NULL UNIQUE REFERENCES projects(id) ON DELETE CASCADE,
|
|
20677
|
+
installation_id uuid NOT NULL REFERENCES github_installations(id) ON DELETE CASCADE,
|
|
20678
|
+
repo_owner text NOT NULL,
|
|
20679
|
+
repo_name text NOT NULL,
|
|
20680
|
+
default_branch text NOT NULL DEFAULT 'main',
|
|
20681
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20682
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20683
|
+
)
|
|
20684
|
+
`,
|
|
20685
|
+
`
|
|
20686
|
+
CREATE TABLE github_dispatch_rules (
|
|
20687
|
+
id uuid PRIMARY KEY,
|
|
20688
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20689
|
+
created_by_user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
20690
|
+
name text NOT NULL,
|
|
20691
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
20692
|
+
event_types text[] NOT NULL,
|
|
20693
|
+
environments text[],
|
|
20694
|
+
services text[],
|
|
20695
|
+
severity_min text CHECK (severity_min IN ('low', 'medium', 'high', 'critical')),
|
|
20696
|
+
bundle_type text CHECK (bundle_type IN ('failure', 'improvement')),
|
|
20697
|
+
incident_status text NOT NULL DEFAULT 'new_or_reopened'
|
|
20698
|
+
CHECK (incident_status IN ('new_only', 'reopened_only', 'new_or_reopened')),
|
|
20699
|
+
cooldown_seconds integer NOT NULL DEFAULT 300,
|
|
20700
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20701
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20702
|
+
)
|
|
20703
|
+
`,
|
|
20704
|
+
`
|
|
20705
|
+
CREATE INDEX github_dispatch_rules_project_enabled_idx
|
|
20706
|
+
ON github_dispatch_rules (project_id, enabled)
|
|
20707
|
+
`,
|
|
20708
|
+
`
|
|
20709
|
+
CREATE TABLE github_dispatch_deliveries (
|
|
20710
|
+
id uuid PRIMARY KEY,
|
|
20711
|
+
rule_id uuid NOT NULL REFERENCES github_dispatch_rules(id) ON DELETE CASCADE,
|
|
20712
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20713
|
+
incident_id uuid REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20714
|
+
improvement_opportunity_id uuid REFERENCES improvement_opportunities(id) ON DELETE CASCADE,
|
|
20715
|
+
target_fingerprint text NOT NULL,
|
|
20716
|
+
installation_id bigint NOT NULL,
|
|
20717
|
+
repo_owner text NOT NULL,
|
|
20718
|
+
repo_name text NOT NULL,
|
|
20719
|
+
status text NOT NULL DEFAULT 'pending'
|
|
20720
|
+
CHECK (status IN ('pending', 'retrying', 'delivered', 'failed', 'skipped')),
|
|
20721
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20722
|
+
next_attempt_at timestamptz,
|
|
20723
|
+
last_attempt_at timestamptz,
|
|
20724
|
+
last_error text,
|
|
20725
|
+
github_status_code integer,
|
|
20726
|
+
dispatch_payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20727
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20728
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20729
|
+
dedupe_key text NOT NULL,
|
|
20730
|
+
CHECK (
|
|
20731
|
+
(incident_id IS NOT NULL AND improvement_opportunity_id IS NULL)
|
|
20732
|
+
OR (incident_id IS NULL AND improvement_opportunity_id IS NOT NULL)
|
|
20733
|
+
)
|
|
20734
|
+
)
|
|
20735
|
+
`,
|
|
20736
|
+
`
|
|
20737
|
+
CREATE INDEX github_dispatch_deliveries_status_next_attempt_idx
|
|
20738
|
+
ON github_dispatch_deliveries (status, next_attempt_at)
|
|
20739
|
+
`,
|
|
20740
|
+
`
|
|
20741
|
+
CREATE UNIQUE INDEX github_dispatch_deliveries_rule_dedupe_key_idx
|
|
20742
|
+
ON github_dispatch_deliveries (rule_id, target_fingerprint, dedupe_key)
|
|
20743
|
+
`,
|
|
20744
|
+
`
|
|
20745
|
+
CREATE TABLE org_usage_counters (
|
|
20746
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20747
|
+
period_starts_at timestamptz NOT NULL,
|
|
20748
|
+
raw_ingested_events integer NOT NULL DEFAULT 0,
|
|
20749
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20750
|
+
PRIMARY KEY (organization_id, period_starts_at)
|
|
20751
|
+
)
|
|
20752
|
+
`,
|
|
20753
|
+
`
|
|
20754
|
+
CREATE TABLE operational_email_deliveries (
|
|
20755
|
+
id uuid PRIMARY KEY,
|
|
20756
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
20757
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
20758
|
+
kind text NOT NULL
|
|
20759
|
+
CHECK (kind IN ('webhook_auto_disabled', 'allowance_warning_80', 'allowance_limit_reached', 'retention_rotation_notice')),
|
|
20760
|
+
dedupe_key text NOT NULL,
|
|
20761
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20762
|
+
status text NOT NULL DEFAULT 'pending'
|
|
20763
|
+
CHECK (status IN ('pending', 'retrying', 'delivered', 'failed')),
|
|
20764
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
20765
|
+
next_attempt_at timestamptz,
|
|
20766
|
+
last_error text,
|
|
20767
|
+
delivered_at timestamptz,
|
|
20768
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20769
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
20770
|
+
UNIQUE (organization_id, kind, dedupe_key)
|
|
20771
|
+
)
|
|
20772
|
+
`,
|
|
20773
|
+
`
|
|
20774
|
+
CREATE INDEX operational_email_deliveries_status_next_attempt_idx
|
|
20775
|
+
ON operational_email_deliveries (status, next_attempt_at, created_at)
|
|
20776
|
+
`
|
|
20777
|
+
];
|
|
20778
|
+
var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS.join(";\n\n");
|
|
20779
|
+
|
|
20780
|
+
// ../../packages/storage/src/schema-migrations.ts
|
|
19238
20781
|
function computeMigrationChecksum(input) {
|
|
19239
20782
|
return (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(input)).digest("hex");
|
|
19240
20783
|
}
|
|
@@ -19656,6 +21199,76 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
19656
21199
|
statements: [
|
|
19657
21200
|
"ALTER TABLE project_tokens ADD COLUMN IF NOT EXISTS allowed_origins jsonb NOT NULL DEFAULT '[]'::jsonb"
|
|
19658
21201
|
]
|
|
21202
|
+
}),
|
|
21203
|
+
defineStorageSchemaMigration({
|
|
21204
|
+
id: "202605260001_fix_weekly_report_delivery_conflict_index",
|
|
21205
|
+
description: "Ensure weekly report delivery dedupe rows and partial unique index exist for conflict claims.",
|
|
21206
|
+
statements: [
|
|
21207
|
+
`
|
|
21208
|
+
DELETE FROM weekly_report_deliveries
|
|
21209
|
+
WHERE id IN (
|
|
21210
|
+
SELECT id
|
|
21211
|
+
FROM (
|
|
21212
|
+
SELECT
|
|
21213
|
+
id,
|
|
21214
|
+
row_number() OVER (
|
|
21215
|
+
PARTITION BY weekly_report_channel_id, window_start, window_end
|
|
21216
|
+
ORDER BY created_at ASC, id ASC
|
|
21217
|
+
) AS row_number
|
|
21218
|
+
FROM weekly_report_deliveries
|
|
21219
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
21220
|
+
) ranked
|
|
21221
|
+
WHERE ranked.row_number > 1
|
|
21222
|
+
)
|
|
21223
|
+
`,
|
|
21224
|
+
`
|
|
21225
|
+
CREATE UNIQUE INDEX IF NOT EXISTS weekly_report_deliveries_channel_window_idx
|
|
21226
|
+
ON weekly_report_deliveries (weekly_report_channel_id, window_start, window_end)
|
|
21227
|
+
WHERE weekly_report_channel_id IS NOT NULL
|
|
21228
|
+
`
|
|
21229
|
+
]
|
|
21230
|
+
}),
|
|
21231
|
+
defineStorageSchemaMigration({
|
|
21232
|
+
id: "202605260001_set_high_confidence_as_project_improvement_default",
|
|
21233
|
+
description: "Make high-confidence the default hosted improvement sensitivity for new projects.",
|
|
21234
|
+
statements: [
|
|
21235
|
+
"ALTER TABLE projects ALTER COLUMN improvement_bundle_sensitivity SET DEFAULT 'high_confidence'"
|
|
21236
|
+
]
|
|
21237
|
+
}),
|
|
21238
|
+
defineStorageSchemaMigration({
|
|
21239
|
+
id: "202605260002_add_capture_rules",
|
|
21240
|
+
description: "Add persisted project capture rules for dynamic demote/sample/drop handling.",
|
|
21241
|
+
statements: [
|
|
21242
|
+
`
|
|
21243
|
+
CREATE TABLE IF NOT EXISTS capture_rules (
|
|
21244
|
+
id uuid PRIMARY KEY,
|
|
21245
|
+
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
21246
|
+
name text NOT NULL,
|
|
21247
|
+
description text,
|
|
21248
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
21249
|
+
action text NOT NULL,
|
|
21250
|
+
matcher jsonb NOT NULL,
|
|
21251
|
+
sample_rate double precision,
|
|
21252
|
+
sample_event_class text,
|
|
21253
|
+
created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
21254
|
+
created_from_incident_id text,
|
|
21255
|
+
created_from_event_id text,
|
|
21256
|
+
expires_at timestamptz,
|
|
21257
|
+
hit_count bigint NOT NULL DEFAULT 0,
|
|
21258
|
+
last_matched_at timestamptz,
|
|
21259
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
21260
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
21261
|
+
)
|
|
21262
|
+
`,
|
|
21263
|
+
`
|
|
21264
|
+
CREATE INDEX IF NOT EXISTS capture_rules_project_enabled_idx
|
|
21265
|
+
ON capture_rules (project_id, enabled)
|
|
21266
|
+
`,
|
|
21267
|
+
`
|
|
21268
|
+
CREATE INDEX IF NOT EXISTS capture_rules_project_updated_idx
|
|
21269
|
+
ON capture_rules (project_id, updated_at DESC)
|
|
21270
|
+
`
|
|
21271
|
+
]
|
|
19659
21272
|
})
|
|
19660
21273
|
];
|
|
19661
21274
|
|
|
@@ -19778,11 +21391,17 @@ function normalizeRouteTemplate(path) {
|
|
|
19778
21391
|
const normalizedSegments = pathWithoutQueryOrFragment.split("/").filter((segment) => segment.length > 0).map((segment) => isDynamicRouteSegment2(segment) ? "{param}" : segment);
|
|
19779
21392
|
return normalizedSegments.length === 0 ? "/" : `/${normalizedSegments.join("/")}`;
|
|
19780
21393
|
}
|
|
21394
|
+
function isBrowserSdkFallbackFrame(frame) {
|
|
21395
|
+
return frame.includes("debugbundle-browser-sdk") && frame.includes("onError");
|
|
21396
|
+
}
|
|
19781
21397
|
function deriveFirstApplicationFrame(errorContext) {
|
|
19782
21398
|
const firstFrame = errorContext?.top_frames[0];
|
|
19783
21399
|
if (firstFrame === void 0) {
|
|
19784
21400
|
return null;
|
|
19785
21401
|
}
|
|
21402
|
+
if (isBrowserSdkFallbackFrame(firstFrame)) {
|
|
21403
|
+
return null;
|
|
21404
|
+
}
|
|
19786
21405
|
const match = /at\s+(.*?)\s+\((.*?):(\d+):(\d+)\)$/.exec(firstFrame) ?? /at\s+(.*?):(\d+):(\d+)$/.exec(firstFrame);
|
|
19787
21406
|
if (match === null) {
|
|
19788
21407
|
return {
|
|
@@ -19804,6 +21423,20 @@ function deriveFirstApplicationFrame(errorContext) {
|
|
|
19804
21423
|
line: Number(match[2])
|
|
19805
21424
|
};
|
|
19806
21425
|
}
|
|
21426
|
+
function getPrimaryBrowserExceptionEvent(envelopes, primarySignalEnvelope) {
|
|
21427
|
+
if (primarySignalEnvelope !== null && isFrontendExceptionEnvelope(primarySignalEnvelope)) {
|
|
21428
|
+
return primarySignalEnvelope.payload.browser_event ?? null;
|
|
21429
|
+
}
|
|
21430
|
+
const envelope = selectLatestEnvelopeByType(envelopes, isFrontendExceptionEnvelope);
|
|
21431
|
+
return envelope?.payload.browser_event ?? null;
|
|
21432
|
+
}
|
|
21433
|
+
function isOpaqueBrowserError(errorContext, browserEvent) {
|
|
21434
|
+
if (browserEvent?.opaque === true) {
|
|
21435
|
+
return true;
|
|
21436
|
+
}
|
|
21437
|
+
const firstFrame = errorContext?.top_frames[0];
|
|
21438
|
+
return errorContext?.message === "Window error" && firstFrame !== void 0 && isBrowserSdkFallbackFrame(firstFrame);
|
|
21439
|
+
}
|
|
19807
21440
|
function buildErrorContext(envelopes, incident, primarySignalEnvelope) {
|
|
19808
21441
|
if (primarySignalEnvelope !== null && isBackendExceptionEnvelope(primarySignalEnvelope)) {
|
|
19809
21442
|
return {
|
|
@@ -19926,6 +21559,20 @@ function buildSummaryGuidance(input) {
|
|
|
19926
21559
|
recommended_action: null
|
|
19927
21560
|
};
|
|
19928
21561
|
}
|
|
21562
|
+
if (input.opaqueBrowserError) {
|
|
21563
|
+
if (input.browserEvent?.kind === "resource_error") {
|
|
21564
|
+
return {
|
|
21565
|
+
likely_cause: "The browser reported a resource load error without a usable application stack.",
|
|
21566
|
+
confidence: 0.35,
|
|
21567
|
+
recommended_action: "Inspect the captured resource target, browser network failures, CSP rules, and cross-origin asset configuration."
|
|
21568
|
+
};
|
|
21569
|
+
}
|
|
21570
|
+
return {
|
|
21571
|
+
likely_cause: "The browser reported an opaque window error without a usable application stack.",
|
|
21572
|
+
confidence: 0.35,
|
|
21573
|
+
recommended_action: "Inspect browser console output, resource loading, cross-origin script settings, and framework-level error boundaries for the affected route."
|
|
21574
|
+
};
|
|
21575
|
+
}
|
|
19929
21576
|
const route = input.requestContext?.route_template ?? input.requestContext?.path ?? null;
|
|
19930
21577
|
const requestDescription = input.requestContext !== null ? `${input.requestContext.method} ${route ?? input.requestContext.path}` : null;
|
|
19931
21578
|
const firstDependency = input.dependenciesContext?.items[0] ?? null;
|
|
@@ -20112,7 +21759,8 @@ function buildFrontendContext(envelopes) {
|
|
|
20112
21759
|
message: envelope.payload.message,
|
|
20113
21760
|
route: envelope.payload.route ?? null,
|
|
20114
21761
|
browser: envelope.payload.browser,
|
|
20115
|
-
ts: toIsoTimestamp(envelope.occurred_at)
|
|
21762
|
+
ts: toIsoTimestamp(envelope.occurred_at),
|
|
21763
|
+
...envelope.payload.browser_event !== void 0 ? { browser_event: envelope.payload.browser_event } : {}
|
|
20116
21764
|
});
|
|
20117
21765
|
}
|
|
20118
21766
|
}
|
|
@@ -20255,6 +21903,8 @@ function buildBundle(input) {
|
|
|
20255
21903
|
const gitContext = buildGitContext(sourceEnvelopes, input.configuredDeploy);
|
|
20256
21904
|
const deviceContext = buildDeviceContext(sourceEnvelopes);
|
|
20257
21905
|
const dependenciesContext = buildDependenciesContext(input.incident, errorContext, requestContext);
|
|
21906
|
+
const browserEvent = getPrimaryBrowserExceptionEvent(sourceEnvelopes, primarySignalEnvelope);
|
|
21907
|
+
const opaqueBrowserError = isOpaqueBrowserError(errorContext, browserEvent);
|
|
20258
21908
|
const primarySignalType = primarySignalEnvelope !== null ? mapSignalType(primarySignalEnvelope.event_type) : inferSignalTypeFromSourceEventTypes(sourceEventTypes);
|
|
20259
21909
|
const primarySourceEvent = errorContext?.name ?? sourceEventTypes[0] ?? "backend_exception";
|
|
20260
21910
|
const firstSeenAt = new Date(input.incident.first_seen_at).toISOString();
|
|
@@ -20269,7 +21919,9 @@ function buildBundle(input) {
|
|
|
20269
21919
|
requestContext,
|
|
20270
21920
|
responseContext,
|
|
20271
21921
|
dependenciesContext,
|
|
20272
|
-
firstApplicationFrame
|
|
21922
|
+
firstApplicationFrame,
|
|
21923
|
+
browserEvent,
|
|
21924
|
+
opaqueBrowserError
|
|
20273
21925
|
});
|
|
20274
21926
|
const candidate = {
|
|
20275
21927
|
bundle_version: 1,
|
|
@@ -21407,7 +23059,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
21407
23059
|
|
|
21408
23060
|
// ../cli/src/ingest-command.ts
|
|
21409
23061
|
var LOCAL_EVENTS_DIRECTORY_PATH2 = ".debugbundle/local/events";
|
|
21410
|
-
var
|
|
23062
|
+
var ProfileSchema2 = external_exports.object({
|
|
21411
23063
|
project: external_exports.object({
|
|
21412
23064
|
name: external_exports.string().min(1),
|
|
21413
23065
|
repo_url: external_exports.string()
|
|
@@ -21432,7 +23084,7 @@ function buildEventFileName(events, filePath) {
|
|
|
21432
23084
|
return `${lastOccurredAt}-${digest}-${slugify(events[0]?.service.name ?? (0, import_node_path7.basename)(filePath))}.events.json`;
|
|
21433
23085
|
}
|
|
21434
23086
|
async function readProfile(rootDirectory, readFile) {
|
|
21435
|
-
const parsedProfile =
|
|
23087
|
+
const parsedProfile = ProfileSchema2.safeParse(JSON.parse(await readFile((0, import_node_path7.join)(rootDirectory, PROFILE_FILE_PATH))));
|
|
21436
23088
|
if (!parsedProfile.success) {
|
|
21437
23089
|
throw new Error(`Invalid ${PROFILE_FILE_PATH}`);
|
|
21438
23090
|
}
|
|
@@ -21752,19 +23404,32 @@ function formatResult(input, exitCode, checks, errors, incidentId) {
|
|
|
21752
23404
|
output: input.json ? buildJsonOutput(checks, errors, incidentId) : formatHumanOutput(checks, incidentId)
|
|
21753
23405
|
};
|
|
21754
23406
|
}
|
|
21755
|
-
function buildCloudSuggestedActions(status, incidentId,
|
|
23407
|
+
function buildCloudSuggestedActions(status, incidentId, verification) {
|
|
23408
|
+
const mode = verification?.mode ?? "passive_recent_incident";
|
|
21756
23409
|
if (status === "healthy" && incidentId !== void 0 && (mode === "active_5xx" || mode === "active_4xx")) {
|
|
21757
23410
|
return [
|
|
21758
23411
|
`Run debugbundle inspect ${incidentId} --source cloud to inspect why the incident fired.`,
|
|
21759
23412
|
`Run debugbundle bundle ${incidentId} --source cloud to fetch the generated debug bundle.`
|
|
21760
23413
|
];
|
|
21761
23414
|
}
|
|
23415
|
+
if (status === "healthy" && incidentId !== void 0 && mode === "app_event") {
|
|
23416
|
+
return [
|
|
23417
|
+
`Run debugbundle inspect ${incidentId} --source cloud to inspect the captured app event.`,
|
|
23418
|
+
"Re-run debugbundle verify cloud --expect-app-event after instrumentation or deploy changes, using the same service, environment, and correlation hints when available."
|
|
23419
|
+
];
|
|
23420
|
+
}
|
|
21762
23421
|
if (status === "healthy" && incidentId !== void 0) {
|
|
21763
23422
|
return [
|
|
21764
23423
|
`Review incident ${incidentId} if you want to inspect the latest production bundle.`,
|
|
21765
23424
|
"Re-run debugbundle verify cloud after a fresh deploy or instrumentation change."
|
|
21766
23425
|
];
|
|
21767
23426
|
}
|
|
23427
|
+
if (mode === "app_event") {
|
|
23428
|
+
return [
|
|
23429
|
+
"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.",
|
|
23430
|
+
"Add --trace-id or --request-id when you have a correlation hint so the verification can match the hosted bundle deterministically."
|
|
23431
|
+
];
|
|
23432
|
+
}
|
|
21768
23433
|
return [
|
|
21769
23434
|
"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.",
|
|
21770
23435
|
"Generate a live cloud request, then re-run debugbundle verify cloud with the correct project and service filters."
|
|
@@ -21777,7 +23442,7 @@ function buildCloudJsonOutput(checks, errors, incidentId, verification) {
|
|
|
21777
23442
|
checks,
|
|
21778
23443
|
warnings: collectWarnings(checks),
|
|
21779
23444
|
errors,
|
|
21780
|
-
suggested_actions: buildCloudSuggestedActions(status, incidentId, verification
|
|
23445
|
+
suggested_actions: buildCloudSuggestedActions(status, incidentId, verification),
|
|
21781
23446
|
auto_fix_available: false
|
|
21782
23447
|
};
|
|
21783
23448
|
if (verification !== void 0) {
|
|
@@ -21792,7 +23457,7 @@ function formatCloudHumanOutput(checks, incidentId, verification) {
|
|
|
21792
23457
|
"Checks:",
|
|
21793
23458
|
...checks.map((check) => `- ${check.name}: ${check.status} - ${check.message}`),
|
|
21794
23459
|
"Suggested actions:",
|
|
21795
|
-
...buildCloudSuggestedActions(status, incidentId, verification
|
|
23460
|
+
...buildCloudSuggestedActions(status, incidentId, verification).map((action) => `- ${action}`)
|
|
21796
23461
|
].join("\n");
|
|
21797
23462
|
}
|
|
21798
23463
|
function formatCloudResult(input, exitCode, checks, errors, incidentId, verification) {
|
|
@@ -21823,6 +23488,19 @@ function localFailureStepName(checks) {
|
|
|
21823
23488
|
function cloudVerificationRunId(now) {
|
|
21824
23489
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
21825
23490
|
}
|
|
23491
|
+
function defaultCloudVerificationSuffix() {
|
|
23492
|
+
return (0, import_node_crypto6.randomUUID)().replace(/-/g, "").slice(0, 12);
|
|
23493
|
+
}
|
|
23494
|
+
function normalizeCloudVerificationSuffix(suffix) {
|
|
23495
|
+
const normalized = suffix.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 12);
|
|
23496
|
+
if (normalized.length > 0) {
|
|
23497
|
+
return normalized;
|
|
23498
|
+
}
|
|
23499
|
+
return defaultCloudVerificationSuffix();
|
|
23500
|
+
}
|
|
23501
|
+
function buildCloudVerificationRunId(now, suffix) {
|
|
23502
|
+
return `${cloudVerificationRunId(now)}-${normalizeCloudVerificationSuffix(suffix)}`;
|
|
23503
|
+
}
|
|
21826
23504
|
function requestFailureReason(responseStatus) {
|
|
21827
23505
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
21828
23506
|
event_type: "request_event",
|
|
@@ -21835,7 +23513,6 @@ function requestFailureReason(responseStatus) {
|
|
|
21835
23513
|
return incidentReason;
|
|
21836
23514
|
}
|
|
21837
23515
|
function buildCloudVerificationEvent(input) {
|
|
21838
|
-
const runId = cloudVerificationRunId(input.now);
|
|
21839
23516
|
const is5xxVerification = input.responseStatus >= 500;
|
|
21840
23517
|
const routeTemplate = is5xxVerification ? "/debugbundle/verify/cloud" : `/debugbundle/verify/cloud/client-error/${input.responseStatus}`;
|
|
21841
23518
|
const verificationLabel = is5xxVerification ? "true" : `client-error-${input.responseStatus}`;
|
|
@@ -21856,7 +23533,7 @@ function buildCloudVerificationEvent(input) {
|
|
|
21856
23533
|
route_template: routeTemplate,
|
|
21857
23534
|
query: {
|
|
21858
23535
|
debugbundle_verification: true,
|
|
21859
|
-
run_id: runId,
|
|
23536
|
+
run_id: input.runId,
|
|
21860
23537
|
synthetic_status: input.responseStatus
|
|
21861
23538
|
},
|
|
21862
23539
|
headers: {
|
|
@@ -21870,7 +23547,7 @@ function buildCloudVerificationEvent(input) {
|
|
|
21870
23547
|
response_body: {
|
|
21871
23548
|
error: is5xxVerification ? "debugbundle_cloud_verification" : "debugbundle_cloud_client_error_verification",
|
|
21872
23549
|
synthetic: true,
|
|
21873
|
-
run_id: runId,
|
|
23550
|
+
run_id: input.runId,
|
|
21874
23551
|
response_status: input.responseStatus
|
|
21875
23552
|
}
|
|
21876
23553
|
}
|
|
@@ -21885,6 +23562,45 @@ function validateActiveCloudVerificationInput(input) {
|
|
|
21885
23562
|
}
|
|
21886
23563
|
return null;
|
|
21887
23564
|
}
|
|
23565
|
+
function validateCloudVerificationInput(input) {
|
|
23566
|
+
const activeInputError = validateActiveCloudVerificationInput(input);
|
|
23567
|
+
if (activeInputError !== null) {
|
|
23568
|
+
return activeInputError;
|
|
23569
|
+
}
|
|
23570
|
+
const appEventVerificationEnabled = input.expectAppEvent === true || input.traceId !== void 0 || input.requestId !== void 0;
|
|
23571
|
+
if (appEventVerificationEnabled && (input.trigger5xx === true || input.trigger4xxStatus !== void 0)) {
|
|
23572
|
+
return "Choose either a synthetic trigger run or --expect-app-event, not both.";
|
|
23573
|
+
}
|
|
23574
|
+
if (appEventVerificationEnabled && input.service === void 0 && input.traceId === void 0 && input.requestId === void 0) {
|
|
23575
|
+
return "App-event verification requires --service, --trace-id, or --request-id so the check stays scoped.";
|
|
23576
|
+
}
|
|
23577
|
+
return null;
|
|
23578
|
+
}
|
|
23579
|
+
function buildCorrelationHints(input) {
|
|
23580
|
+
return {
|
|
23581
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23582
|
+
environment: input.environment,
|
|
23583
|
+
...input.traceId === void 0 ? {} : { trace_id: input.traceId },
|
|
23584
|
+
...input.requestId === void 0 ? {} : { request_id: input.requestId }
|
|
23585
|
+
};
|
|
23586
|
+
}
|
|
23587
|
+
function collectBundleHintMatches(bundle, input) {
|
|
23588
|
+
const serializedBundle = JSON.stringify(bundle);
|
|
23589
|
+
const matches = [];
|
|
23590
|
+
if (input.traceId !== void 0 && serializedBundle.includes(input.traceId)) {
|
|
23591
|
+
matches.push("trace_id");
|
|
23592
|
+
}
|
|
23593
|
+
if (input.requestId !== void 0 && serializedBundle.includes(input.requestId)) {
|
|
23594
|
+
matches.push("request_id");
|
|
23595
|
+
}
|
|
23596
|
+
return matches;
|
|
23597
|
+
}
|
|
23598
|
+
function requestedBundleHints(input) {
|
|
23599
|
+
return [
|
|
23600
|
+
...input.traceId === void 0 ? [] : ["trace_id"],
|
|
23601
|
+
...input.requestId === void 0 ? [] : ["request_id"]
|
|
23602
|
+
];
|
|
23603
|
+
}
|
|
21888
23604
|
async function sendEventsToApi(input, dependencies = {}) {
|
|
21889
23605
|
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
21890
23606
|
const baseUrl = input.baseUrl.endsWith("/") ? input.baseUrl.slice(0, -1) : input.baseUrl;
|
|
@@ -22076,7 +23792,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
22076
23792
|
const checks = [];
|
|
22077
23793
|
const environment = input.environment ?? "production";
|
|
22078
23794
|
const maxAgeMinutes = input.maxAgeMinutes ?? 15;
|
|
22079
|
-
const activeInputError =
|
|
23795
|
+
const activeInputError = validateCloudVerificationInput(input);
|
|
22080
23796
|
if (activeInputError !== null) {
|
|
22081
23797
|
checks.push({
|
|
22082
23798
|
name: "trigger-input",
|
|
@@ -22117,9 +23833,124 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
22117
23833
|
requestInput,
|
|
22118
23834
|
dependencies.fetchImpl === void 0 ? {} : { fetchImpl: dependencies.fetchImpl }
|
|
22119
23835
|
));
|
|
23836
|
+
const appEventVerificationEnabled = input.expectAppEvent === true || input.traceId !== void 0 || input.requestId !== void 0;
|
|
23837
|
+
if (appEventVerificationEnabled) {
|
|
23838
|
+
const verificationStartedAt = now();
|
|
23839
|
+
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
23840
|
+
const pollIntervalMs = dependencies.pollIntervalMs ?? 2e3;
|
|
23841
|
+
const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
23842
|
+
const requestedHints = requestedBundleHints(input);
|
|
23843
|
+
const verification = {
|
|
23844
|
+
mode: "app_event",
|
|
23845
|
+
bundle_status: "unknown",
|
|
23846
|
+
correlation_hints: buildCorrelationHints({
|
|
23847
|
+
environment,
|
|
23848
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23849
|
+
...input.traceId === void 0 ? {} : { traceId: input.traceId },
|
|
23850
|
+
...input.requestId === void 0 ? {} : { requestId: input.requestId }
|
|
23851
|
+
})
|
|
23852
|
+
};
|
|
23853
|
+
const oldestAcceptedIncidentTimestamp = verificationStartedAt.getTime() - maxAgeMinutes * 6e4;
|
|
23854
|
+
let incidentId;
|
|
23855
|
+
let exitCode = 0;
|
|
23856
|
+
let activeStep = "app-event-visibility";
|
|
23857
|
+
const errors = [];
|
|
23858
|
+
try {
|
|
23859
|
+
for (let attempt = 1; attempt <= pollAttempts; attempt += 1) {
|
|
23860
|
+
const result = await listIncidents({
|
|
23861
|
+
bearerToken: authState.bearer_token,
|
|
23862
|
+
projectId: input.projectId,
|
|
23863
|
+
environment,
|
|
23864
|
+
...input.service === void 0 ? {} : { service: input.service },
|
|
23865
|
+
limit: 5
|
|
23866
|
+
});
|
|
23867
|
+
const recentIncidents = result.incidents.filter((candidate) => {
|
|
23868
|
+
const lastSeenAt = new Date(candidate.last_seen_at);
|
|
23869
|
+
return !Number.isNaN(lastSeenAt.getTime()) && lastSeenAt.getTime() >= oldestAcceptedIncidentTimestamp;
|
|
23870
|
+
});
|
|
23871
|
+
for (const candidate of recentIncidents) {
|
|
23872
|
+
const lastSeenAt = new Date(candidate.last_seen_at);
|
|
23873
|
+
if (requestedHints.length === 0 && lastSeenAt.getTime() < verificationStartedAt.getTime()) {
|
|
23874
|
+
continue;
|
|
23875
|
+
}
|
|
23876
|
+
if (requestedHints.length === 0) {
|
|
23877
|
+
incidentId = candidate.incident_id;
|
|
23878
|
+
verification.incident_id = candidate.incident_id;
|
|
23879
|
+
break;
|
|
23880
|
+
}
|
|
23881
|
+
activeStep = "bundle-status";
|
|
23882
|
+
const bundle = await getBundle({
|
|
23883
|
+
bearerToken: authState.bearer_token,
|
|
23884
|
+
incidentId: candidate.incident_id
|
|
23885
|
+
});
|
|
23886
|
+
verification.bundle_status = "status" in bundle && bundle.status === "pending" ? "pending" : "ready";
|
|
23887
|
+
if (verification.bundle_status !== "ready") {
|
|
23888
|
+
continue;
|
|
23889
|
+
}
|
|
23890
|
+
const matchedHints = collectBundleHintMatches(bundle, input);
|
|
23891
|
+
verification.matched_hints = matchedHints;
|
|
23892
|
+
if (requestedHints.every((hint) => matchedHints.includes(hint))) {
|
|
23893
|
+
incidentId = candidate.incident_id;
|
|
23894
|
+
verification.incident_id = candidate.incident_id;
|
|
23895
|
+
verification.suggested_next_command = `debugbundle inspect ${candidate.incident_id} --source cloud`;
|
|
23896
|
+
break;
|
|
23897
|
+
}
|
|
23898
|
+
}
|
|
23899
|
+
if (incidentId !== void 0) {
|
|
23900
|
+
break;
|
|
23901
|
+
}
|
|
23902
|
+
if (attempt < pollAttempts) {
|
|
23903
|
+
await sleep(pollIntervalMs);
|
|
23904
|
+
}
|
|
23905
|
+
}
|
|
23906
|
+
if (incidentId === void 0) {
|
|
23907
|
+
if (requestedHints.length > 0) {
|
|
23908
|
+
throw new Error(`No recent cloud incident matched the requested ${requestedHints.join(" and ")} hints within the ${maxAgeMinutes} minute verification window.`);
|
|
23909
|
+
}
|
|
23910
|
+
throw new Error(`No new ${environment} app event was visible within the ${maxAgeMinutes} minute verification window.`);
|
|
23911
|
+
}
|
|
23912
|
+
checks.push({
|
|
23913
|
+
name: "app-event-visibility",
|
|
23914
|
+
status: "ok",
|
|
23915
|
+
message: `Observed cloud incident ${incidentId} for the requested app-driven verification window.`
|
|
23916
|
+
});
|
|
23917
|
+
if (requestedHints.length > 0) {
|
|
23918
|
+
checks.push({
|
|
23919
|
+
name: "bundle-hint-match",
|
|
23920
|
+
status: "ok",
|
|
23921
|
+
message: `Matched ${verification.matched_hints?.join(" and ")} in bundle ${incidentId}.`
|
|
23922
|
+
});
|
|
23923
|
+
} else {
|
|
23924
|
+
const bundle = await getBundle({
|
|
23925
|
+
bearerToken: authState.bearer_token,
|
|
23926
|
+
incidentId
|
|
23927
|
+
});
|
|
23928
|
+
verification.bundle_status = "status" in bundle && bundle.status === "pending" ? "pending" : "ready";
|
|
23929
|
+
verification.suggested_next_command = `debugbundle inspect ${incidentId} --source cloud`;
|
|
23930
|
+
checks.push({
|
|
23931
|
+
name: "bundle-status",
|
|
23932
|
+
status: verification.bundle_status === "ready" ? "ok" : "warning",
|
|
23933
|
+
message: verification.bundle_status === "ready" ? `Bundle for incident ${incidentId} is ready.` : `Bundle for incident ${incidentId} is still pending.`
|
|
23934
|
+
});
|
|
23935
|
+
}
|
|
23936
|
+
} catch (error) {
|
|
23937
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
23938
|
+
checks.push({
|
|
23939
|
+
name: activeStep,
|
|
23940
|
+
status: "error",
|
|
23941
|
+
message
|
|
23942
|
+
});
|
|
23943
|
+
errors.push(message);
|
|
23944
|
+
exitCode = 1;
|
|
23945
|
+
}
|
|
23946
|
+
return formatCloudResult(input, exitCode, checks, errors, incidentId, verification);
|
|
23947
|
+
}
|
|
22120
23948
|
if (input.trigger5xx === true || input.trigger4xxStatus !== void 0) {
|
|
22121
23949
|
const verificationStartedAt = now();
|
|
22122
|
-
const runId =
|
|
23950
|
+
const runId = buildCloudVerificationRunId(
|
|
23951
|
+
verificationStartedAt,
|
|
23952
|
+
(dependencies.randomId ?? defaultCloudVerificationSuffix)()
|
|
23953
|
+
);
|
|
22123
23954
|
const serviceName = input.service ?? `debugbundle-verify-cloud-${runId}`;
|
|
22124
23955
|
const tokenLabel = `debugbundle verify cloud ${runId}`;
|
|
22125
23956
|
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
@@ -22151,6 +23982,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
22151
23982
|
}
|
|
22152
23983
|
const event = buildCloudVerificationEvent({
|
|
22153
23984
|
now: verificationStartedAt,
|
|
23985
|
+
runId,
|
|
22154
23986
|
serviceName,
|
|
22155
23987
|
environment,
|
|
22156
23988
|
responseStatus
|
|
@@ -22870,8 +24702,85 @@ function createBillingMcpTools(api) {
|
|
|
22870
24702
|
};
|
|
22871
24703
|
}
|
|
22872
24704
|
|
|
22873
|
-
// src/capture-
|
|
24705
|
+
// src/capture-rule-tools.ts
|
|
22874
24706
|
function mapMcpError4(error) {
|
|
24707
|
+
if (error instanceof CaptureRuleApiError) {
|
|
24708
|
+
throw new Error(`mcp_tool_error:${error.message}`);
|
|
24709
|
+
}
|
|
24710
|
+
throw new Error("mcp_tool_error:unknown_error");
|
|
24711
|
+
}
|
|
24712
|
+
function createCaptureRuleMcpTools(api) {
|
|
24713
|
+
return {
|
|
24714
|
+
async list_capture_rules(input) {
|
|
24715
|
+
try {
|
|
24716
|
+
return await api.listCaptureRules({
|
|
24717
|
+
bearerToken: String(input["bearerToken"]),
|
|
24718
|
+
projectId: String(input["projectId"])
|
|
24719
|
+
});
|
|
24720
|
+
} catch (error) {
|
|
24721
|
+
mapMcpError4(error);
|
|
24722
|
+
}
|
|
24723
|
+
},
|
|
24724
|
+
async create_capture_rule(input) {
|
|
24725
|
+
try {
|
|
24726
|
+
return await api.createCaptureRule({
|
|
24727
|
+
bearerToken: String(input["bearerToken"]),
|
|
24728
|
+
projectId: String(input["projectId"]),
|
|
24729
|
+
create: typeof input["create"] === "object" && input["create"] !== null ? input["create"] : {}
|
|
24730
|
+
});
|
|
24731
|
+
} catch (error) {
|
|
24732
|
+
mapMcpError4(error);
|
|
24733
|
+
}
|
|
24734
|
+
},
|
|
24735
|
+
async update_capture_rule(input) {
|
|
24736
|
+
try {
|
|
24737
|
+
return await api.updateCaptureRule({
|
|
24738
|
+
bearerToken: String(input["bearerToken"]),
|
|
24739
|
+
projectId: String(input["projectId"]),
|
|
24740
|
+
ruleId: String(input["ruleId"]),
|
|
24741
|
+
update: typeof input["update"] === "object" && input["update"] !== null ? input["update"] : {}
|
|
24742
|
+
});
|
|
24743
|
+
} catch (error) {
|
|
24744
|
+
mapMcpError4(error);
|
|
24745
|
+
}
|
|
24746
|
+
},
|
|
24747
|
+
async delete_capture_rule(input) {
|
|
24748
|
+
try {
|
|
24749
|
+
return await api.deleteCaptureRule({
|
|
24750
|
+
bearerToken: String(input["bearerToken"]),
|
|
24751
|
+
projectId: String(input["projectId"]),
|
|
24752
|
+
ruleId: String(input["ruleId"])
|
|
24753
|
+
});
|
|
24754
|
+
} catch (error) {
|
|
24755
|
+
mapMcpError4(error);
|
|
24756
|
+
}
|
|
24757
|
+
},
|
|
24758
|
+
async suggest_capture_rules_from_incident(input) {
|
|
24759
|
+
try {
|
|
24760
|
+
return await api.suggestCaptureRulesFromIncident({
|
|
24761
|
+
bearerToken: String(input["bearerToken"]),
|
|
24762
|
+
incidentId: String(input["incidentId"])
|
|
24763
|
+
});
|
|
24764
|
+
} catch (error) {
|
|
24765
|
+
mapMcpError4(error);
|
|
24766
|
+
}
|
|
24767
|
+
},
|
|
24768
|
+
async create_capture_rule_from_incident_suggestion(input) {
|
|
24769
|
+
try {
|
|
24770
|
+
return await api.createCaptureRuleFromIncidentSuggestion({
|
|
24771
|
+
bearerToken: String(input["bearerToken"]),
|
|
24772
|
+
incidentId: String(input["incidentId"]),
|
|
24773
|
+
create: typeof input["create"] === "object" && input["create"] !== null ? input["create"] : {}
|
|
24774
|
+
});
|
|
24775
|
+
} catch (error) {
|
|
24776
|
+
mapMcpError4(error);
|
|
24777
|
+
}
|
|
24778
|
+
}
|
|
24779
|
+
};
|
|
24780
|
+
}
|
|
24781
|
+
|
|
24782
|
+
// src/capture-policy-tools.ts
|
|
24783
|
+
function mapMcpError5(error) {
|
|
22875
24784
|
if (error instanceof CapturePolicyApiError) {
|
|
22876
24785
|
throw new Error(`mcp_tool_error:${error.message}`);
|
|
22877
24786
|
}
|
|
@@ -22886,7 +24795,7 @@ function createCapturePolicyMcpTools(api) {
|
|
|
22886
24795
|
projectId: String(input["projectId"])
|
|
22887
24796
|
});
|
|
22888
24797
|
} catch (error) {
|
|
22889
|
-
|
|
24798
|
+
mapMcpError5(error);
|
|
22890
24799
|
}
|
|
22891
24800
|
},
|
|
22892
24801
|
async update_capture_policy(input) {
|
|
@@ -22898,14 +24807,14 @@ function createCapturePolicyMcpTools(api) {
|
|
|
22898
24807
|
update
|
|
22899
24808
|
});
|
|
22900
24809
|
} catch (error) {
|
|
22901
|
-
|
|
24810
|
+
mapMcpError5(error);
|
|
22902
24811
|
}
|
|
22903
24812
|
}
|
|
22904
24813
|
};
|
|
22905
24814
|
}
|
|
22906
24815
|
|
|
22907
24816
|
// src/github-tools.ts
|
|
22908
|
-
function
|
|
24817
|
+
function mapMcpError6(error) {
|
|
22909
24818
|
if (error instanceof GitHubManagementApiError) {
|
|
22910
24819
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22911
24820
|
}
|
|
@@ -22924,7 +24833,7 @@ function createGitHubMcpTools(api) {
|
|
|
22924
24833
|
const repo = projectId === void 0 || api.getProjectRepo === void 0 ? void 0 : await api.getProjectRepo({ bearerToken, projectId });
|
|
22925
24834
|
return repo === void 0 ? { installation } : { installation, repo };
|
|
22926
24835
|
} catch (error) {
|
|
22927
|
-
|
|
24836
|
+
mapMcpError6(error);
|
|
22928
24837
|
}
|
|
22929
24838
|
},
|
|
22930
24839
|
async list_github_repositories(input) {
|
|
@@ -22936,7 +24845,7 @@ function createGitHubMcpTools(api) {
|
|
|
22936
24845
|
})
|
|
22937
24846
|
};
|
|
22938
24847
|
} catch (error) {
|
|
22939
|
-
|
|
24848
|
+
mapMcpError6(error);
|
|
22940
24849
|
}
|
|
22941
24850
|
},
|
|
22942
24851
|
async list_github_dispatch_rules(input) {
|
|
@@ -22948,7 +24857,7 @@ function createGitHubMcpTools(api) {
|
|
|
22948
24857
|
})
|
|
22949
24858
|
};
|
|
22950
24859
|
} catch (error) {
|
|
22951
|
-
|
|
24860
|
+
mapMcpError6(error);
|
|
22952
24861
|
}
|
|
22953
24862
|
},
|
|
22954
24863
|
async create_github_dispatch_rule(input) {
|
|
@@ -22969,7 +24878,7 @@ function createGitHubMcpTools(api) {
|
|
|
22969
24878
|
})
|
|
22970
24879
|
};
|
|
22971
24880
|
} catch (error) {
|
|
22972
|
-
|
|
24881
|
+
mapMcpError6(error);
|
|
22973
24882
|
}
|
|
22974
24883
|
},
|
|
22975
24884
|
async update_github_dispatch_rule(input) {
|
|
@@ -22991,7 +24900,7 @@ function createGitHubMcpTools(api) {
|
|
|
22991
24900
|
})
|
|
22992
24901
|
};
|
|
22993
24902
|
} catch (error) {
|
|
22994
|
-
|
|
24903
|
+
mapMcpError6(error);
|
|
22995
24904
|
}
|
|
22996
24905
|
},
|
|
22997
24906
|
async delete_github_dispatch_rule(input) {
|
|
@@ -23007,7 +24916,7 @@ function createGitHubMcpTools(api) {
|
|
|
23007
24916
|
rule_id: String(input["ruleId"])
|
|
23008
24917
|
};
|
|
23009
24918
|
} catch (error) {
|
|
23010
|
-
|
|
24919
|
+
mapMcpError6(error);
|
|
23011
24920
|
}
|
|
23012
24921
|
},
|
|
23013
24922
|
async list_github_deliveries(input) {
|
|
@@ -23021,7 +24930,7 @@ function createGitHubMcpTools(api) {
|
|
|
23021
24930
|
})
|
|
23022
24931
|
};
|
|
23023
24932
|
} catch (error) {
|
|
23024
|
-
|
|
24933
|
+
mapMcpError6(error);
|
|
23025
24934
|
}
|
|
23026
24935
|
},
|
|
23027
24936
|
async retry_github_delivery(input) {
|
|
@@ -23034,7 +24943,7 @@ function createGitHubMcpTools(api) {
|
|
|
23034
24943
|
})
|
|
23035
24944
|
};
|
|
23036
24945
|
} catch (error) {
|
|
23037
|
-
|
|
24946
|
+
mapMcpError6(error);
|
|
23038
24947
|
}
|
|
23039
24948
|
},
|
|
23040
24949
|
async set_project_github_repo(input) {
|
|
@@ -23048,7 +24957,7 @@ function createGitHubMcpTools(api) {
|
|
|
23048
24957
|
})
|
|
23049
24958
|
};
|
|
23050
24959
|
} catch (error) {
|
|
23051
|
-
|
|
24960
|
+
mapMcpError6(error);
|
|
23052
24961
|
}
|
|
23053
24962
|
},
|
|
23054
24963
|
async remove_project_github_repo(input) {
|
|
@@ -23062,14 +24971,14 @@ function createGitHubMcpTools(api) {
|
|
|
23062
24971
|
project_id: String(input["projectId"])
|
|
23063
24972
|
};
|
|
23064
24973
|
} catch (error) {
|
|
23065
|
-
|
|
24974
|
+
mapMcpError6(error);
|
|
23066
24975
|
}
|
|
23067
24976
|
}
|
|
23068
24977
|
};
|
|
23069
24978
|
}
|
|
23070
24979
|
|
|
23071
24980
|
// src/improvement-tools.ts
|
|
23072
|
-
function
|
|
24981
|
+
function mapMcpError7(error) {
|
|
23073
24982
|
if (error instanceof RetrievalApiError) {
|
|
23074
24983
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23075
24984
|
}
|
|
@@ -23102,7 +25011,7 @@ function createImprovementMcpTools(api) {
|
|
|
23102
25011
|
...typeof input["limit"] === "number" ? { limit: input["limit"] } : {}
|
|
23103
25012
|
});
|
|
23104
25013
|
} catch (error) {
|
|
23105
|
-
|
|
25014
|
+
mapMcpError7(error);
|
|
23106
25015
|
}
|
|
23107
25016
|
},
|
|
23108
25017
|
async get_improvement(input) {
|
|
@@ -23112,7 +25021,7 @@ function createImprovementMcpTools(api) {
|
|
|
23112
25021
|
improvementId: readString2(input, "improvementId")
|
|
23113
25022
|
});
|
|
23114
25023
|
} catch (error) {
|
|
23115
|
-
|
|
25024
|
+
mapMcpError7(error);
|
|
23116
25025
|
}
|
|
23117
25026
|
},
|
|
23118
25027
|
async get_improvement_bundle(input) {
|
|
@@ -23123,7 +25032,7 @@ function createImprovementMcpTools(api) {
|
|
|
23123
25032
|
improvementId: readString2(input, "improvementId")
|
|
23124
25033
|
});
|
|
23125
25034
|
} catch (error) {
|
|
23126
|
-
|
|
25035
|
+
mapMcpError7(error);
|
|
23127
25036
|
}
|
|
23128
25037
|
},
|
|
23129
25038
|
async resolve_improvement(input) {
|
|
@@ -23133,7 +25042,7 @@ function createImprovementMcpTools(api) {
|
|
|
23133
25042
|
improvementId: readString2(input, "improvementId")
|
|
23134
25043
|
});
|
|
23135
25044
|
} catch (error) {
|
|
23136
|
-
|
|
25045
|
+
mapMcpError7(error);
|
|
23137
25046
|
}
|
|
23138
25047
|
},
|
|
23139
25048
|
async reopen_improvement(input) {
|
|
@@ -23143,7 +25052,7 @@ function createImprovementMcpTools(api) {
|
|
|
23143
25052
|
improvementId: readString2(input, "improvementId")
|
|
23144
25053
|
});
|
|
23145
25054
|
} catch (error) {
|
|
23146
|
-
|
|
25055
|
+
mapMcpError7(error);
|
|
23147
25056
|
}
|
|
23148
25057
|
},
|
|
23149
25058
|
async snooze_improvement(input) {
|
|
@@ -23154,14 +25063,14 @@ function createImprovementMcpTools(api) {
|
|
|
23154
25063
|
snoozedUntil: readString2(input, "snoozedUntil")
|
|
23155
25064
|
});
|
|
23156
25065
|
} catch (error) {
|
|
23157
|
-
|
|
25066
|
+
mapMcpError7(error);
|
|
23158
25067
|
}
|
|
23159
25068
|
}
|
|
23160
25069
|
};
|
|
23161
25070
|
}
|
|
23162
25071
|
|
|
23163
25072
|
// src/improvement-settings-tools.ts
|
|
23164
|
-
function
|
|
25073
|
+
function mapMcpError8(error) {
|
|
23165
25074
|
if (error instanceof ImprovementSettingsApiError) {
|
|
23166
25075
|
throw new Error(`mcp_tool_error:${error.message}`);
|
|
23167
25076
|
}
|
|
@@ -23176,7 +25085,7 @@ function createImprovementSettingsMcpTools(api) {
|
|
|
23176
25085
|
projectId: String(input["projectId"])
|
|
23177
25086
|
});
|
|
23178
25087
|
} catch (error) {
|
|
23179
|
-
|
|
25088
|
+
mapMcpError8(error);
|
|
23180
25089
|
}
|
|
23181
25090
|
},
|
|
23182
25091
|
async update_improvement_settings(input) {
|
|
@@ -23188,14 +25097,14 @@ function createImprovementSettingsMcpTools(api) {
|
|
|
23188
25097
|
update
|
|
23189
25098
|
});
|
|
23190
25099
|
} catch (error) {
|
|
23191
|
-
|
|
25100
|
+
mapMcpError8(error);
|
|
23192
25101
|
}
|
|
23193
25102
|
}
|
|
23194
25103
|
};
|
|
23195
25104
|
}
|
|
23196
25105
|
|
|
23197
25106
|
// src/member-tools.ts
|
|
23198
|
-
function
|
|
25107
|
+
function mapMcpError9(error) {
|
|
23199
25108
|
if (error instanceof MemberApiError) {
|
|
23200
25109
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23201
25110
|
}
|
|
@@ -23210,7 +25119,7 @@ function createMemberMcpTools(api) {
|
|
|
23210
25119
|
projectId: String(input["projectId"])
|
|
23211
25120
|
});
|
|
23212
25121
|
} catch (error) {
|
|
23213
|
-
|
|
25122
|
+
mapMcpError9(error);
|
|
23214
25123
|
}
|
|
23215
25124
|
},
|
|
23216
25125
|
async list_project_member_invites(input) {
|
|
@@ -23220,7 +25129,7 @@ function createMemberMcpTools(api) {
|
|
|
23220
25129
|
projectId: String(input["projectId"])
|
|
23221
25130
|
});
|
|
23222
25131
|
} catch (error) {
|
|
23223
|
-
|
|
25132
|
+
mapMcpError9(error);
|
|
23224
25133
|
}
|
|
23225
25134
|
},
|
|
23226
25135
|
async invite_project_member(input) {
|
|
@@ -23232,7 +25141,7 @@ function createMemberMcpTools(api) {
|
|
|
23232
25141
|
role: String(input["role"])
|
|
23233
25142
|
});
|
|
23234
25143
|
} catch (error) {
|
|
23235
|
-
|
|
25144
|
+
mapMcpError9(error);
|
|
23236
25145
|
}
|
|
23237
25146
|
},
|
|
23238
25147
|
async cancel_project_member_invite(input) {
|
|
@@ -23243,7 +25152,7 @@ function createMemberMcpTools(api) {
|
|
|
23243
25152
|
inviteId: String(input["inviteId"])
|
|
23244
25153
|
});
|
|
23245
25154
|
} catch (error) {
|
|
23246
|
-
|
|
25155
|
+
mapMcpError9(error);
|
|
23247
25156
|
}
|
|
23248
25157
|
},
|
|
23249
25158
|
async update_project_member_role(input) {
|
|
@@ -23255,7 +25164,7 @@ function createMemberMcpTools(api) {
|
|
|
23255
25164
|
role: String(input["role"])
|
|
23256
25165
|
});
|
|
23257
25166
|
} catch (error) {
|
|
23258
|
-
|
|
25167
|
+
mapMcpError9(error);
|
|
23259
25168
|
}
|
|
23260
25169
|
},
|
|
23261
25170
|
async remove_project_member(input) {
|
|
@@ -23266,14 +25175,14 @@ function createMemberMcpTools(api) {
|
|
|
23266
25175
|
userId: String(input["userId"])
|
|
23267
25176
|
});
|
|
23268
25177
|
} catch (error) {
|
|
23269
|
-
|
|
25178
|
+
mapMcpError9(error);
|
|
23270
25179
|
}
|
|
23271
25180
|
}
|
|
23272
25181
|
};
|
|
23273
25182
|
}
|
|
23274
25183
|
|
|
23275
25184
|
// src/probe-tools.ts
|
|
23276
|
-
function
|
|
25185
|
+
function mapMcpError10(error) {
|
|
23277
25186
|
if (error instanceof ProbeApiError) {
|
|
23278
25187
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23279
25188
|
}
|
|
@@ -23302,7 +25211,7 @@ function createProbeMcpTools(api) {
|
|
|
23302
25211
|
}
|
|
23303
25212
|
return await api.activateProbe(requestInput);
|
|
23304
25213
|
} catch (error) {
|
|
23305
|
-
|
|
25214
|
+
mapMcpError10(error);
|
|
23306
25215
|
}
|
|
23307
25216
|
},
|
|
23308
25217
|
async list_active_probes(input) {
|
|
@@ -23312,7 +25221,7 @@ function createProbeMcpTools(api) {
|
|
|
23312
25221
|
projectId: String(input["projectId"])
|
|
23313
25222
|
});
|
|
23314
25223
|
} catch (error) {
|
|
23315
|
-
|
|
25224
|
+
mapMcpError10(error);
|
|
23316
25225
|
}
|
|
23317
25226
|
},
|
|
23318
25227
|
async deactivate_probe(input) {
|
|
@@ -23323,14 +25232,14 @@ function createProbeMcpTools(api) {
|
|
|
23323
25232
|
activationId: String(input["activationId"])
|
|
23324
25233
|
});
|
|
23325
25234
|
} catch (error) {
|
|
23326
|
-
|
|
25235
|
+
mapMcpError10(error);
|
|
23327
25236
|
}
|
|
23328
25237
|
}
|
|
23329
25238
|
};
|
|
23330
25239
|
}
|
|
23331
25240
|
|
|
23332
25241
|
// src/project-tools.ts
|
|
23333
|
-
function
|
|
25242
|
+
function mapMcpError11(error) {
|
|
23334
25243
|
if (error instanceof ProjectManagementApiError) {
|
|
23335
25244
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23336
25245
|
}
|
|
@@ -23348,7 +25257,7 @@ function createProjectMcpTools(api) {
|
|
|
23348
25257
|
}
|
|
23349
25258
|
return { projects: await api.listProjects(requestInput) };
|
|
23350
25259
|
} catch (error) {
|
|
23351
|
-
|
|
25260
|
+
mapMcpError11(error);
|
|
23352
25261
|
}
|
|
23353
25262
|
},
|
|
23354
25263
|
async create_project(input) {
|
|
@@ -23363,7 +25272,7 @@ function createProjectMcpTools(api) {
|
|
|
23363
25272
|
}
|
|
23364
25273
|
return { project: await api.createProject(requestInput) };
|
|
23365
25274
|
} catch (error) {
|
|
23366
|
-
|
|
25275
|
+
mapMcpError11(error);
|
|
23367
25276
|
}
|
|
23368
25277
|
},
|
|
23369
25278
|
async update_project(input) {
|
|
@@ -23383,7 +25292,7 @@ function createProjectMcpTools(api) {
|
|
|
23383
25292
|
}
|
|
23384
25293
|
return { project: await api.updateProject(requestInput) };
|
|
23385
25294
|
} catch (error) {
|
|
23386
|
-
|
|
25295
|
+
mapMcpError11(error);
|
|
23387
25296
|
}
|
|
23388
25297
|
},
|
|
23389
25298
|
async delete_project(input) {
|
|
@@ -23395,7 +25304,7 @@ function createProjectMcpTools(api) {
|
|
|
23395
25304
|
})
|
|
23396
25305
|
};
|
|
23397
25306
|
} catch (error) {
|
|
23398
|
-
|
|
25307
|
+
mapMcpError11(error);
|
|
23399
25308
|
}
|
|
23400
25309
|
}
|
|
23401
25310
|
};
|
|
@@ -23602,7 +25511,7 @@ async function persistCloudArtifact(directoryPath, fileName, payload, dependenci
|
|
|
23602
25511
|
}
|
|
23603
25512
|
|
|
23604
25513
|
// src/retrieval-tools.ts
|
|
23605
|
-
function
|
|
25514
|
+
function mapMcpError12(error) {
|
|
23606
25515
|
if (error instanceof RetrievalApiError) {
|
|
23607
25516
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23608
25517
|
}
|
|
@@ -23784,7 +25693,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23784
25693
|
incidents: incidents.incidents.map((incident) => attachSourceToRecord(incident, "cloud"))
|
|
23785
25694
|
};
|
|
23786
25695
|
} catch (error) {
|
|
23787
|
-
|
|
25696
|
+
mapMcpError12(error);
|
|
23788
25697
|
}
|
|
23789
25698
|
},
|
|
23790
25699
|
async get_incident(input) {
|
|
@@ -23819,7 +25728,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23819
25728
|
)
|
|
23820
25729
|
};
|
|
23821
25730
|
} catch (error) {
|
|
23822
|
-
|
|
25731
|
+
mapMcpError12(error);
|
|
23823
25732
|
}
|
|
23824
25733
|
},
|
|
23825
25734
|
async get_incident_context(input) {
|
|
@@ -23848,7 +25757,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23848
25757
|
"cloud"
|
|
23849
25758
|
);
|
|
23850
25759
|
} catch (error) {
|
|
23851
|
-
|
|
25760
|
+
mapMcpError12(error);
|
|
23852
25761
|
}
|
|
23853
25762
|
},
|
|
23854
25763
|
async resolve_incident(input) {
|
|
@@ -23893,7 +25802,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23893
25802
|
})()
|
|
23894
25803
|
};
|
|
23895
25804
|
} catch (error) {
|
|
23896
|
-
|
|
25805
|
+
mapMcpError12(error);
|
|
23897
25806
|
}
|
|
23898
25807
|
},
|
|
23899
25808
|
async reopen_incident(input) {
|
|
@@ -23938,7 +25847,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23938
25847
|
})()
|
|
23939
25848
|
};
|
|
23940
25849
|
} catch (error) {
|
|
23941
|
-
|
|
25850
|
+
mapMcpError12(error);
|
|
23942
25851
|
}
|
|
23943
25852
|
},
|
|
23944
25853
|
async get_bundle(input) {
|
|
@@ -23969,7 +25878,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23969
25878
|
}
|
|
23970
25879
|
);
|
|
23971
25880
|
} catch (error) {
|
|
23972
|
-
|
|
25881
|
+
mapMcpError12(error);
|
|
23973
25882
|
}
|
|
23974
25883
|
},
|
|
23975
25884
|
async get_logs(input) {
|
|
@@ -23989,7 +25898,7 @@ function createRetrievalMcpTools(api) {
|
|
|
23989
25898
|
}
|
|
23990
25899
|
return await api.getLogs(requestInput);
|
|
23991
25900
|
} catch (error) {
|
|
23992
|
-
|
|
25901
|
+
mapMcpError12(error);
|
|
23993
25902
|
}
|
|
23994
25903
|
},
|
|
23995
25904
|
async get_reproduction(input) {
|
|
@@ -24020,14 +25929,14 @@ function createRetrievalMcpTools(api) {
|
|
|
24020
25929
|
}
|
|
24021
25930
|
);
|
|
24022
25931
|
} catch (error) {
|
|
24023
|
-
|
|
25932
|
+
mapMcpError12(error);
|
|
24024
25933
|
}
|
|
24025
25934
|
}
|
|
24026
25935
|
};
|
|
24027
25936
|
}
|
|
24028
25937
|
|
|
24029
25938
|
// src/services-tools.ts
|
|
24030
|
-
function
|
|
25939
|
+
function mapMcpError13(error) {
|
|
24031
25940
|
if (error instanceof RetrievalApiError) {
|
|
24032
25941
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24033
25942
|
}
|
|
@@ -24048,14 +25957,14 @@ function createServicesMcpTools(api) {
|
|
|
24048
25957
|
services: await api.listServices(requestInput)
|
|
24049
25958
|
};
|
|
24050
25959
|
} catch (error) {
|
|
24051
|
-
|
|
25960
|
+
mapMcpError13(error);
|
|
24052
25961
|
}
|
|
24053
25962
|
}
|
|
24054
25963
|
};
|
|
24055
25964
|
}
|
|
24056
25965
|
|
|
24057
25966
|
// src/setup-tools.ts
|
|
24058
|
-
function
|
|
25967
|
+
function mapMcpError14() {
|
|
24059
25968
|
throw new Error("mcp_tool_error:unknown_error");
|
|
24060
25969
|
}
|
|
24061
25970
|
function parseJsonOutput2(output) {
|
|
@@ -24070,7 +25979,7 @@ async function runJsonCommand2(command) {
|
|
|
24070
25979
|
const result = await command();
|
|
24071
25980
|
return parseJsonOutput2(result.output);
|
|
24072
25981
|
} catch {
|
|
24073
|
-
|
|
25982
|
+
mapMcpError14();
|
|
24074
25983
|
}
|
|
24075
25984
|
}
|
|
24076
25985
|
function createSetupMcpTools(commands) {
|
|
@@ -24129,7 +26038,7 @@ function createSetupMcpTools(commands) {
|
|
|
24129
26038
|
}
|
|
24130
26039
|
|
|
24131
26040
|
// src/slack-tools.ts
|
|
24132
|
-
function
|
|
26041
|
+
function mapMcpError15(error) {
|
|
24133
26042
|
if (error instanceof SlackApiError) {
|
|
24134
26043
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24135
26044
|
}
|
|
@@ -24146,7 +26055,7 @@ function createSlackMcpTools(api) {
|
|
|
24146
26055
|
})
|
|
24147
26056
|
};
|
|
24148
26057
|
} catch (error) {
|
|
24149
|
-
|
|
26058
|
+
mapMcpError15(error);
|
|
24150
26059
|
}
|
|
24151
26060
|
},
|
|
24152
26061
|
async get_slack_connect_url(input) {
|
|
@@ -24159,7 +26068,7 @@ function createSlackMcpTools(api) {
|
|
|
24159
26068
|
})
|
|
24160
26069
|
};
|
|
24161
26070
|
} catch (error) {
|
|
24162
|
-
|
|
26071
|
+
mapMcpError15(error);
|
|
24163
26072
|
}
|
|
24164
26073
|
},
|
|
24165
26074
|
async test_slack_destination(input) {
|
|
@@ -24172,7 +26081,7 @@ function createSlackMcpTools(api) {
|
|
|
24172
26081
|
})
|
|
24173
26082
|
};
|
|
24174
26083
|
} catch (error) {
|
|
24175
|
-
|
|
26084
|
+
mapMcpError15(error);
|
|
24176
26085
|
}
|
|
24177
26086
|
},
|
|
24178
26087
|
async delete_slack_destination(input) {
|
|
@@ -24185,14 +26094,14 @@ function createSlackMcpTools(api) {
|
|
|
24185
26094
|
})
|
|
24186
26095
|
};
|
|
24187
26096
|
} catch (error) {
|
|
24188
|
-
|
|
26097
|
+
mapMcpError15(error);
|
|
24189
26098
|
}
|
|
24190
26099
|
}
|
|
24191
26100
|
};
|
|
24192
26101
|
}
|
|
24193
26102
|
|
|
24194
26103
|
// src/token-tools.ts
|
|
24195
|
-
function
|
|
26104
|
+
function mapMcpError16(error) {
|
|
24196
26105
|
if (error instanceof TokenManagementApiError) {
|
|
24197
26106
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24198
26107
|
}
|
|
@@ -24213,7 +26122,7 @@ function createTokenMcpTools(api) {
|
|
|
24213
26122
|
tokens: await api.listProjectTokens(requestInput)
|
|
24214
26123
|
};
|
|
24215
26124
|
} catch (error) {
|
|
24216
|
-
|
|
26125
|
+
mapMcpError16(error);
|
|
24217
26126
|
}
|
|
24218
26127
|
},
|
|
24219
26128
|
async create_project_token(input) {
|
|
@@ -24228,7 +26137,7 @@ function createTokenMcpTools(api) {
|
|
|
24228
26137
|
})
|
|
24229
26138
|
};
|
|
24230
26139
|
} catch (error) {
|
|
24231
|
-
|
|
26140
|
+
mapMcpError16(error);
|
|
24232
26141
|
}
|
|
24233
26142
|
},
|
|
24234
26143
|
async revoke_project_token(input) {
|
|
@@ -24241,7 +26150,7 @@ function createTokenMcpTools(api) {
|
|
|
24241
26150
|
})
|
|
24242
26151
|
};
|
|
24243
26152
|
} catch (error) {
|
|
24244
|
-
|
|
26153
|
+
mapMcpError16(error);
|
|
24245
26154
|
}
|
|
24246
26155
|
},
|
|
24247
26156
|
async list_member_tokens(input) {
|
|
@@ -24256,7 +26165,7 @@ function createTokenMcpTools(api) {
|
|
|
24256
26165
|
tokens: await api.listMemberTokens(requestInput)
|
|
24257
26166
|
};
|
|
24258
26167
|
} catch (error) {
|
|
24259
|
-
|
|
26168
|
+
mapMcpError16(error);
|
|
24260
26169
|
}
|
|
24261
26170
|
},
|
|
24262
26171
|
async create_member_token(input) {
|
|
@@ -24268,7 +26177,7 @@ function createTokenMcpTools(api) {
|
|
|
24268
26177
|
})
|
|
24269
26178
|
};
|
|
24270
26179
|
} catch (error) {
|
|
24271
|
-
|
|
26180
|
+
mapMcpError16(error);
|
|
24272
26181
|
}
|
|
24273
26182
|
},
|
|
24274
26183
|
async revoke_member_token(input) {
|
|
@@ -24280,14 +26189,14 @@ function createTokenMcpTools(api) {
|
|
|
24280
26189
|
})
|
|
24281
26190
|
};
|
|
24282
26191
|
} catch (error) {
|
|
24283
|
-
|
|
26192
|
+
mapMcpError16(error);
|
|
24284
26193
|
}
|
|
24285
26194
|
}
|
|
24286
26195
|
};
|
|
24287
26196
|
}
|
|
24288
26197
|
|
|
24289
26198
|
// src/webhook-tools.ts
|
|
24290
|
-
function
|
|
26199
|
+
function mapMcpError17(error) {
|
|
24291
26200
|
if (error instanceof WebhookApiError) {
|
|
24292
26201
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24293
26202
|
}
|
|
@@ -24308,7 +26217,7 @@ function createWebhookMcpTools(api) {
|
|
|
24308
26217
|
webhooks: await api.listWebhooks(requestInput)
|
|
24309
26218
|
};
|
|
24310
26219
|
} catch (error) {
|
|
24311
|
-
|
|
26220
|
+
mapMcpError17(error);
|
|
24312
26221
|
}
|
|
24313
26222
|
},
|
|
24314
26223
|
async create_webhook(input) {
|
|
@@ -24329,7 +26238,7 @@ function createWebhookMcpTools(api) {
|
|
|
24329
26238
|
webhook: await api.createWebhook(requestInput)
|
|
24330
26239
|
};
|
|
24331
26240
|
} catch (error) {
|
|
24332
|
-
|
|
26241
|
+
mapMcpError17(error);
|
|
24333
26242
|
}
|
|
24334
26243
|
},
|
|
24335
26244
|
async update_webhook(input) {
|
|
@@ -24355,7 +26264,7 @@ function createWebhookMcpTools(api) {
|
|
|
24355
26264
|
webhook: await api.updateWebhook(requestInput)
|
|
24356
26265
|
};
|
|
24357
26266
|
} catch (error) {
|
|
24358
|
-
|
|
26267
|
+
mapMcpError17(error);
|
|
24359
26268
|
}
|
|
24360
26269
|
},
|
|
24361
26270
|
async delete_webhook(input) {
|
|
@@ -24368,7 +26277,7 @@ function createWebhookMcpTools(api) {
|
|
|
24368
26277
|
})
|
|
24369
26278
|
};
|
|
24370
26279
|
} catch (error) {
|
|
24371
|
-
|
|
26280
|
+
mapMcpError17(error);
|
|
24372
26281
|
}
|
|
24373
26282
|
},
|
|
24374
26283
|
async test_webhook(input) {
|
|
@@ -24385,7 +26294,7 @@ function createWebhookMcpTools(api) {
|
|
|
24385
26294
|
delivery: await api.testWebhook(requestInput)
|
|
24386
26295
|
};
|
|
24387
26296
|
} catch (error) {
|
|
24388
|
-
|
|
26297
|
+
mapMcpError17(error);
|
|
24389
26298
|
}
|
|
24390
26299
|
},
|
|
24391
26300
|
async list_webhook_deliveries(input) {
|
|
@@ -24402,7 +26311,7 @@ function createWebhookMcpTools(api) {
|
|
|
24402
26311
|
deliveries: await api.listWebhookDeliveries(requestInput)
|
|
24403
26312
|
};
|
|
24404
26313
|
} catch (error) {
|
|
24405
|
-
|
|
26314
|
+
mapMcpError17(error);
|
|
24406
26315
|
}
|
|
24407
26316
|
},
|
|
24408
26317
|
async retry_webhook_delivery(input) {
|
|
@@ -24414,14 +26323,14 @@ function createWebhookMcpTools(api) {
|
|
|
24414
26323
|
deliveryId: String(input["deliveryId"])
|
|
24415
26324
|
});
|
|
24416
26325
|
} catch (error) {
|
|
24417
|
-
|
|
26326
|
+
mapMcpError17(error);
|
|
24418
26327
|
}
|
|
24419
26328
|
}
|
|
24420
26329
|
};
|
|
24421
26330
|
}
|
|
24422
26331
|
|
|
24423
26332
|
// src/weekly-report-tools.ts
|
|
24424
|
-
function
|
|
26333
|
+
function mapMcpError18(error) {
|
|
24425
26334
|
if (error instanceof WeeklyReportApiError) {
|
|
24426
26335
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
24427
26336
|
}
|
|
@@ -24439,7 +26348,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24439
26348
|
})
|
|
24440
26349
|
};
|
|
24441
26350
|
} catch (error) {
|
|
24442
|
-
|
|
26351
|
+
mapMcpError18(error);
|
|
24443
26352
|
}
|
|
24444
26353
|
},
|
|
24445
26354
|
async create_weekly_report_channel(input) {
|
|
@@ -24455,7 +26364,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24455
26364
|
})
|
|
24456
26365
|
};
|
|
24457
26366
|
} catch (error) {
|
|
24458
|
-
|
|
26367
|
+
mapMcpError18(error);
|
|
24459
26368
|
}
|
|
24460
26369
|
},
|
|
24461
26370
|
async update_weekly_report_channel(input) {
|
|
@@ -24470,7 +26379,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24470
26379
|
})
|
|
24471
26380
|
};
|
|
24472
26381
|
} catch (error) {
|
|
24473
|
-
|
|
26382
|
+
mapMcpError18(error);
|
|
24474
26383
|
}
|
|
24475
26384
|
},
|
|
24476
26385
|
async delete_weekly_report_channel(input) {
|
|
@@ -24482,7 +26391,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24482
26391
|
})
|
|
24483
26392
|
};
|
|
24484
26393
|
} catch (error) {
|
|
24485
|
-
|
|
26394
|
+
mapMcpError18(error);
|
|
24486
26395
|
}
|
|
24487
26396
|
}
|
|
24488
26397
|
};
|
|
@@ -24490,6 +26399,15 @@ function createWeeklyReportMcpTools(api) {
|
|
|
24490
26399
|
|
|
24491
26400
|
// src/default-tools.ts
|
|
24492
26401
|
var DEFAULT_API_BASE_URL = "https://api.debugbundle.com";
|
|
26402
|
+
var MEMBER_TOKEN_ENV_VAR = "DEBUGBUNDLE_MEMBER_TOKEN";
|
|
26403
|
+
function readEnvMemberToken() {
|
|
26404
|
+
const rawToken = process.env[MEMBER_TOKEN_ENV_VAR];
|
|
26405
|
+
if (typeof rawToken !== "string") {
|
|
26406
|
+
return null;
|
|
26407
|
+
}
|
|
26408
|
+
const token = rawToken.trim();
|
|
26409
|
+
return token.length > 0 ? token : null;
|
|
26410
|
+
}
|
|
24493
26411
|
async function readLocalAuthState() {
|
|
24494
26412
|
try {
|
|
24495
26413
|
return await readCliAuthState({});
|
|
@@ -24510,8 +26428,8 @@ function withDefaultBearerToken(tools, bearerToken) {
|
|
|
24510
26428
|
}
|
|
24511
26429
|
async function createDefaultMcpTools(input = {}) {
|
|
24512
26430
|
const authState = await readLocalAuthState();
|
|
24513
|
-
const baseUrl = input.apiBaseUrl ??
|
|
24514
|
-
const defaultBearerToken = authState?.bearer_token ?? null;
|
|
26431
|
+
const baseUrl = input.apiBaseUrl ?? process.env["DEBUGBUNDLE_API_URL"] ?? authState?.base_url ?? DEFAULT_API_BASE_URL;
|
|
26432
|
+
const defaultBearerToken = readEnvMemberToken() ?? authState?.bearer_token ?? null;
|
|
24515
26433
|
const httpClient = createCliHttpClient({ baseUrl });
|
|
24516
26434
|
const retrievalApi = createRetrievalApi(httpClient);
|
|
24517
26435
|
return withDefaultBearerToken(
|
|
@@ -24538,6 +26456,7 @@ async function createDefaultMcpTools(input = {}) {
|
|
|
24538
26456
|
...createWeeklyReportMcpTools(createWeeklyReportApi(httpClient)),
|
|
24539
26457
|
...createAlertMcpTools(createAlertApi(httpClient)),
|
|
24540
26458
|
...createProjectMcpTools(createProjectManagementApi(httpClient)),
|
|
26459
|
+
...createCaptureRuleMcpTools(createCaptureRuleApi(httpClient)),
|
|
24541
26460
|
...createCapturePolicyMcpTools(createCapturePolicyApi(httpClient)),
|
|
24542
26461
|
...createImprovementSettingsMcpTools(createImprovementSettingsApi(httpClient)),
|
|
24543
26462
|
...createProbeMcpTools(createProbeApi(httpClient)),
|
|
@@ -25836,6 +27755,46 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
25836
27755
|
return combined;
|
|
25837
27756
|
};
|
|
25838
27757
|
|
|
27758
|
+
// package.json
|
|
27759
|
+
var package_default = {
|
|
27760
|
+
name: "@debugbundle/mcp",
|
|
27761
|
+
mcpName: "com.debugbundle/mcp",
|
|
27762
|
+
version: "0.1.10",
|
|
27763
|
+
private: false,
|
|
27764
|
+
description: "Model Context Protocol server for DebugBundle",
|
|
27765
|
+
license: "AGPL-3.0-only",
|
|
27766
|
+
repository: {
|
|
27767
|
+
type: "git",
|
|
27768
|
+
url: "https://github.com/debugbundle/debugbundle",
|
|
27769
|
+
directory: "apps/mcp"
|
|
27770
|
+
},
|
|
27771
|
+
homepage: "https://debugbundle.com/docs/mcp",
|
|
27772
|
+
bugs: {
|
|
27773
|
+
url: "https://github.com/debugbundle/debugbundle/issues"
|
|
27774
|
+
},
|
|
27775
|
+
keywords: ["debugbundle", "debugging", "ai-agent", "mcp", "model-context-protocol"],
|
|
27776
|
+
engines: {
|
|
27777
|
+
node: ">=22 <27"
|
|
27778
|
+
},
|
|
27779
|
+
type: "module",
|
|
27780
|
+
scripts: {
|
|
27781
|
+
start: "tsx src/entrypoint.ts",
|
|
27782
|
+
build: "esbuild src/entrypoint.ts --bundle --platform=node --format=cjs --target=node22 --external:@node-rs/argon2 --outfile=dist/main.cjs",
|
|
27783
|
+
prepack: "npm run build"
|
|
27784
|
+
},
|
|
27785
|
+
bin: {
|
|
27786
|
+
"debugbundle-mcp": "bin/debugbundle-mcp.js"
|
|
27787
|
+
},
|
|
27788
|
+
files: ["bin", "dist", "README.md", "LICENSE", "server.json"],
|
|
27789
|
+
dependencies: {
|
|
27790
|
+
"@node-rs/argon2": "^2.0.2"
|
|
27791
|
+
},
|
|
27792
|
+
devDependencies: {
|
|
27793
|
+
esbuild: "^0.27.3",
|
|
27794
|
+
tsx: "^4.20.5"
|
|
27795
|
+
}
|
|
27796
|
+
};
|
|
27797
|
+
|
|
25839
27798
|
// src/tool-catalog.ts
|
|
25840
27799
|
var jsonObjectSchema = external_exports.record(external_exports.unknown());
|
|
25841
27800
|
var optionalBearerTokenSchema = external_exports.string().optional();
|
|
@@ -26461,6 +28420,65 @@ var MCP_TOOL_CATALOG = [
|
|
|
26461
28420
|
projectId: external_exports.string()
|
|
26462
28421
|
})
|
|
26463
28422
|
},
|
|
28423
|
+
{
|
|
28424
|
+
name: "list_capture_rules",
|
|
28425
|
+
group: "capture_rules",
|
|
28426
|
+
description: "List project capture rules.",
|
|
28427
|
+
inputSchema: external_exports.object({
|
|
28428
|
+
bearerToken: external_exports.string(),
|
|
28429
|
+
projectId: external_exports.string()
|
|
28430
|
+
})
|
|
28431
|
+
},
|
|
28432
|
+
{
|
|
28433
|
+
name: "create_capture_rule",
|
|
28434
|
+
group: "capture_rules",
|
|
28435
|
+
description: "Create a project capture rule.",
|
|
28436
|
+
inputSchema: external_exports.object({
|
|
28437
|
+
bearerToken: external_exports.string(),
|
|
28438
|
+
projectId: external_exports.string(),
|
|
28439
|
+
create: jsonObjectSchema
|
|
28440
|
+
})
|
|
28441
|
+
},
|
|
28442
|
+
{
|
|
28443
|
+
name: "update_capture_rule",
|
|
28444
|
+
group: "capture_rules",
|
|
28445
|
+
description: "Update a project capture rule.",
|
|
28446
|
+
inputSchema: external_exports.object({
|
|
28447
|
+
bearerToken: external_exports.string(),
|
|
28448
|
+
projectId: external_exports.string(),
|
|
28449
|
+
ruleId: external_exports.string(),
|
|
28450
|
+
update: jsonObjectSchema
|
|
28451
|
+
})
|
|
28452
|
+
},
|
|
28453
|
+
{
|
|
28454
|
+
name: "delete_capture_rule",
|
|
28455
|
+
group: "capture_rules",
|
|
28456
|
+
description: "Delete a project capture rule.",
|
|
28457
|
+
inputSchema: external_exports.object({
|
|
28458
|
+
bearerToken: external_exports.string(),
|
|
28459
|
+
projectId: external_exports.string(),
|
|
28460
|
+
ruleId: external_exports.string()
|
|
28461
|
+
})
|
|
28462
|
+
},
|
|
28463
|
+
{
|
|
28464
|
+
name: "suggest_capture_rules_from_incident",
|
|
28465
|
+
group: "capture_rules",
|
|
28466
|
+
description: "Generate deterministic capture rule suggestions from an incident bundle.",
|
|
28467
|
+
inputSchema: external_exports.object({
|
|
28468
|
+
bearerToken: external_exports.string(),
|
|
28469
|
+
incidentId: external_exports.string()
|
|
28470
|
+
})
|
|
28471
|
+
},
|
|
28472
|
+
{
|
|
28473
|
+
name: "create_capture_rule_from_incident_suggestion",
|
|
28474
|
+
group: "capture_rules",
|
|
28475
|
+
description: "Create a capture rule from an incident-derived suggestion.",
|
|
28476
|
+
inputSchema: external_exports.object({
|
|
28477
|
+
bearerToken: external_exports.string(),
|
|
28478
|
+
incidentId: external_exports.string(),
|
|
28479
|
+
create: jsonObjectSchema
|
|
28480
|
+
})
|
|
28481
|
+
},
|
|
26464
28482
|
{
|
|
26465
28483
|
name: "get_capture_policy",
|
|
26466
28484
|
group: "capture_policy",
|
|
@@ -26650,6 +28668,7 @@ var MCP_TOOL_CATALOG = [
|
|
|
26650
28668
|
var MCP_TOOL_NAMES = MCP_TOOL_CATALOG.map((tool) => tool.name);
|
|
26651
28669
|
|
|
26652
28670
|
// src/server.ts
|
|
28671
|
+
var MCP_SERVER_VERSION = package_default.version;
|
|
26653
28672
|
function isRecord3(value) {
|
|
26654
28673
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26655
28674
|
}
|
|
@@ -26725,7 +28744,7 @@ function createMcpServer(input) {
|
|
|
26725
28744
|
},
|
|
26726
28745
|
serverInfo: {
|
|
26727
28746
|
name: "@debugbundle/mcp",
|
|
26728
|
-
version:
|
|
28747
|
+
version: MCP_SERVER_VERSION
|
|
26729
28748
|
}
|
|
26730
28749
|
}
|
|
26731
28750
|
};
|