@debugbundle/mcp 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +412 -55
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/main.cjs
CHANGED
|
@@ -14475,6 +14475,7 @@ var AlertSchema = external_exports.object({
|
|
|
14475
14475
|
channel: AlertChannelSchema,
|
|
14476
14476
|
condition_type: AlertConditionTypeSchema,
|
|
14477
14477
|
severity_min: external_exports.enum(["low", "medium", "high", "critical"]).nullable(),
|
|
14478
|
+
cooldown_seconds: external_exports.number().int().min(0),
|
|
14478
14479
|
config: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
14479
14480
|
is_enabled: external_exports.boolean(),
|
|
14480
14481
|
created_at: external_exports.string(),
|
|
@@ -14561,6 +14562,9 @@ function createAlertApi(client) {
|
|
|
14561
14562
|
if (input.severityMin !== void 0) {
|
|
14562
14563
|
body.severity_min = input.severityMin;
|
|
14563
14564
|
}
|
|
14565
|
+
if (input.cooldownSeconds !== void 0) {
|
|
14566
|
+
body.cooldown_seconds = input.cooldownSeconds;
|
|
14567
|
+
}
|
|
14564
14568
|
if (input.isEnabled !== void 0) {
|
|
14565
14569
|
body.is_enabled = input.isEnabled;
|
|
14566
14570
|
}
|
|
@@ -14587,6 +14591,9 @@ function createAlertApi(client) {
|
|
|
14587
14591
|
if (input.severityMin !== void 0) {
|
|
14588
14592
|
body.severity_min = input.severityMin;
|
|
14589
14593
|
}
|
|
14594
|
+
if (input.cooldownSeconds !== void 0) {
|
|
14595
|
+
body.cooldown_seconds = input.cooldownSeconds;
|
|
14596
|
+
}
|
|
14590
14597
|
if (input.config !== void 0) {
|
|
14591
14598
|
body.config = input.config;
|
|
14592
14599
|
}
|
|
@@ -17117,8 +17124,24 @@ var BrowserExceptionEventSchema = external_exports.object({
|
|
|
17117
17124
|
column_number: external_exports.number().int().nonnegative().nullable(),
|
|
17118
17125
|
target: external_exports.object({
|
|
17119
17126
|
tag_name: external_exports.string().nullable(),
|
|
17120
|
-
source_url: external_exports.string().nullable()
|
|
17121
|
-
|
|
17127
|
+
source_url: external_exports.string().nullable(),
|
|
17128
|
+
attributes: external_exports.object({
|
|
17129
|
+
rel: external_exports.string().optional(),
|
|
17130
|
+
as: external_exports.string().optional(),
|
|
17131
|
+
type: external_exports.string().optional(),
|
|
17132
|
+
media: external_exports.string().optional(),
|
|
17133
|
+
cross_origin: external_exports.string().optional(),
|
|
17134
|
+
async: external_exports.boolean().optional(),
|
|
17135
|
+
defer: external_exports.boolean().optional(),
|
|
17136
|
+
integrity_present: external_exports.boolean().optional()
|
|
17137
|
+
}).strict().optional()
|
|
17138
|
+
}).strict().nullable(),
|
|
17139
|
+
page: external_exports.object({
|
|
17140
|
+
url: external_exports.string().nullable(),
|
|
17141
|
+
referrer: external_exports.string().nullable(),
|
|
17142
|
+
ready_state: external_exports.enum(["loading", "interactive", "complete"]).nullable(),
|
|
17143
|
+
visibility_state: external_exports.enum(["visible", "hidden", "prerender", "unloaded"]).nullable()
|
|
17144
|
+
}).strict().optional(),
|
|
17122
17145
|
opaque: external_exports.boolean()
|
|
17123
17146
|
}).strict();
|
|
17124
17147
|
var FrontendExceptionPayloadSchema = external_exports.object({
|
|
@@ -18609,6 +18632,17 @@ function createMemberApi(httpClient) {
|
|
|
18609
18632
|
throw toApiError4(response.status, response.body);
|
|
18610
18633
|
}
|
|
18611
18634
|
return response.body;
|
|
18635
|
+
},
|
|
18636
|
+
async leaveProject(input) {
|
|
18637
|
+
const response = await httpClient.request({
|
|
18638
|
+
method: "DELETE",
|
|
18639
|
+
path: `/v1/projects/${input.projectId}/membership`,
|
|
18640
|
+
bearerToken: input.bearerToken
|
|
18641
|
+
});
|
|
18642
|
+
if (response.status !== 200) {
|
|
18643
|
+
throw toApiError4(response.status, response.body);
|
|
18644
|
+
}
|
|
18645
|
+
return response.body;
|
|
18612
18646
|
}
|
|
18613
18647
|
};
|
|
18614
18648
|
}
|
|
@@ -18824,11 +18858,129 @@ var ISO_TIMESTAMP_PATTERN = /\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z\b/
|
|
|
18824
18858
|
var IPV4_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
18825
18859
|
var HEX_PATTERN = /\b0x[0-9a-f]+\b/gi;
|
|
18826
18860
|
var BARE_HEX_PATTERN = /\b(?=[0-9a-f]{8,}\b)(?=[0-9a-f]*[a-f])[0-9a-f]+\b/gi;
|
|
18861
|
+
var LONG_ALPHANUMERIC_TOKEN_PATTERN = /\b(?=[A-Za-z0-9_-]{16,}\b)(?=[A-Za-z0-9_-]*[A-Za-z])(?=[A-Za-z0-9_-]*\d)[A-Za-z0-9_-]+\b/g;
|
|
18827
18862
|
var LARGE_NUMBER_PATTERN = /\b\d{2,}\b/g;
|
|
18828
18863
|
var DYNAMIC_SEGMENT_PATTERN = /^(?:\d+|[0-9a-f]{8}-[0-9a-f-]{27}|[A-Za-z0-9_-]{24,})$/;
|
|
18829
18864
|
var FRAME_NOISE_PATTERNS = ["node_modules/", "vendor/", "site-packages/", ".venv/"];
|
|
18865
|
+
var KNOWN_DATABASE_MESSAGE_FAMILIES = [
|
|
18866
|
+
{
|
|
18867
|
+
summary: "PostgreSQL access rejected by pg_hba.conf",
|
|
18868
|
+
when: (message) => looksLikePostgresMessage(message) && message.includes("pg_hba.conf")
|
|
18869
|
+
},
|
|
18870
|
+
{
|
|
18871
|
+
summary: "PostgreSQL authentication failed",
|
|
18872
|
+
when: (message) => looksLikePostgresMessage(message) && (message.includes("password authentication failed") || message.includes("authentication failed for user"))
|
|
18873
|
+
},
|
|
18874
|
+
{
|
|
18875
|
+
summary: "PostgreSQL host resolution failed",
|
|
18876
|
+
when: (message) => looksLikePostgresMessage(message) && (message.includes("could not translate host name") || message.includes("getaddrinfo enotfound"))
|
|
18877
|
+
},
|
|
18878
|
+
{
|
|
18879
|
+
summary: "PostgreSQL connection timed out",
|
|
18880
|
+
when: (message) => looksLikePostgresMessage(message) && (message.includes("connection timed out") || message.includes("timeout expired") || message.includes("etimedout"))
|
|
18881
|
+
},
|
|
18882
|
+
{
|
|
18883
|
+
summary: "PostgreSQL connection limit reached",
|
|
18884
|
+
when: (message) => looksLikePostgresMessage(message) && (message.includes("too many connections") || message.includes("remaining connection slots are reserved"))
|
|
18885
|
+
},
|
|
18886
|
+
{
|
|
18887
|
+
summary: "PostgreSQL database does not exist",
|
|
18888
|
+
when: (message) => looksLikePostgresMessage(message) && message.includes("does not exist")
|
|
18889
|
+
},
|
|
18890
|
+
{
|
|
18891
|
+
summary: "PostgreSQL connection refused",
|
|
18892
|
+
when: (message) => looksLikePostgresMessage(message) && message.includes("connection refused")
|
|
18893
|
+
},
|
|
18894
|
+
{
|
|
18895
|
+
summary: "MySQL authentication failed",
|
|
18896
|
+
when: (message) => looksLikeMySqlMessage(message) && (message.includes("access denied for user") || message.includes("authentication failed"))
|
|
18897
|
+
},
|
|
18898
|
+
{
|
|
18899
|
+
summary: "MySQL connection refused",
|
|
18900
|
+
when: (message) => looksLikeMySqlMessage(message) && (message.includes("connection refused") || message.includes("can't connect to mysql server"))
|
|
18901
|
+
},
|
|
18902
|
+
{
|
|
18903
|
+
summary: "MySQL connection dropped",
|
|
18904
|
+
when: (message) => looksLikeMySqlMessage(message) && message.includes("server has gone away")
|
|
18905
|
+
},
|
|
18906
|
+
{
|
|
18907
|
+
summary: "MySQL connection limit reached",
|
|
18908
|
+
when: (message) => looksLikeMySqlMessage(message) && message.includes("too many connections")
|
|
18909
|
+
},
|
|
18910
|
+
{
|
|
18911
|
+
summary: "MySQL database does not exist",
|
|
18912
|
+
when: (message) => looksLikeMySqlMessage(message) && message.includes("unknown database")
|
|
18913
|
+
},
|
|
18914
|
+
{
|
|
18915
|
+
summary: "MongoDB authentication failed",
|
|
18916
|
+
when: (message) => looksLikeMongoMessage(message) && message.includes("authentication failed")
|
|
18917
|
+
},
|
|
18918
|
+
{
|
|
18919
|
+
summary: "MongoDB host resolution failed",
|
|
18920
|
+
when: (message) => looksLikeMongoMessage(message) && (message.includes("getaddrinfo enotfound") || message.includes("ename not found"))
|
|
18921
|
+
},
|
|
18922
|
+
{
|
|
18923
|
+
summary: "MongoDB connection timed out",
|
|
18924
|
+
when: (message) => looksLikeMongoMessage(message) && (message.includes("connection timed out") || message.includes("etimedout") || message.includes("server selection timed out"))
|
|
18925
|
+
},
|
|
18926
|
+
{
|
|
18927
|
+
summary: "MongoDB connection refused",
|
|
18928
|
+
when: (message) => looksLikeMongoMessage(message) && message.includes("connection refused")
|
|
18929
|
+
},
|
|
18930
|
+
{
|
|
18931
|
+
summary: "Redis authentication failed",
|
|
18932
|
+
when: (message) => looksLikeRedisMessage(message) && message.includes("wrongpass")
|
|
18933
|
+
},
|
|
18934
|
+
{
|
|
18935
|
+
summary: "Redis replica is read-only",
|
|
18936
|
+
when: (message) => looksLikeRedisMessage(message) && message.includes("readonly")
|
|
18937
|
+
},
|
|
18938
|
+
{
|
|
18939
|
+
summary: "Redis host resolution failed",
|
|
18940
|
+
when: (message) => looksLikeRedisMessage(message) && (message.includes("getaddrinfo enotfound") || message.includes("ename not found"))
|
|
18941
|
+
},
|
|
18942
|
+
{
|
|
18943
|
+
summary: "Redis connection timed out",
|
|
18944
|
+
when: (message) => looksLikeRedisMessage(message) && (message.includes("connection timed out") || message.includes("etimedout") || message.includes("timeout"))
|
|
18945
|
+
},
|
|
18946
|
+
{
|
|
18947
|
+
summary: "Redis connection refused",
|
|
18948
|
+
when: (message) => looksLikeRedisMessage(message) && message.includes("connection refused")
|
|
18949
|
+
}
|
|
18950
|
+
];
|
|
18951
|
+
function looksLikePostgresMessage(message) {
|
|
18952
|
+
return message.includes("postgres") || message.includes("pgsql") || message.includes("pg_hba.conf") || message.includes("connection to server at");
|
|
18953
|
+
}
|
|
18954
|
+
function looksLikeMySqlMessage(message) {
|
|
18955
|
+
return message.includes("mysql") || message.includes("mariadb");
|
|
18956
|
+
}
|
|
18957
|
+
function looksLikeMongoMessage(message) {
|
|
18958
|
+
return message.includes("mongodb") || message.includes("mongoserver") || message.includes("mongo");
|
|
18959
|
+
}
|
|
18960
|
+
function looksLikeRedisMessage(message) {
|
|
18961
|
+
return message.includes("redis");
|
|
18962
|
+
}
|
|
18963
|
+
function normalizeScalarTokens(message) {
|
|
18964
|
+
return message.replace(UUID_PATTERN, "{dynamic}").replace(EMAIL_PATTERN, "{dynamic}").replace(ISO_TIMESTAMP_PATTERN, "{dynamic}").replace(IPV4_PATTERN, "{dynamic}").replace(HEX_PATTERN, "{dynamic}").replace(BARE_HEX_PATTERN, "{dynamic}").replace(LONG_ALPHANUMERIC_TOKEN_PATTERN, "{dynamic}").replace(LARGE_NUMBER_PATTERN, "{dynamic}");
|
|
18965
|
+
}
|
|
18966
|
+
function collapseWhitespace(message) {
|
|
18967
|
+
return message.replace(/\s+/g, " ").trim();
|
|
18968
|
+
}
|
|
18969
|
+
function normalizeKnownDatabaseMessage(message) {
|
|
18970
|
+
const lowerMessage = message.toLowerCase();
|
|
18971
|
+
for (const family of KNOWN_DATABASE_MESSAGE_FAMILIES) {
|
|
18972
|
+
if (family.when(lowerMessage)) {
|
|
18973
|
+
return family.summary;
|
|
18974
|
+
}
|
|
18975
|
+
}
|
|
18976
|
+
return null;
|
|
18977
|
+
}
|
|
18830
18978
|
function normalizeMessage(message) {
|
|
18831
|
-
|
|
18979
|
+
const knownDatabaseMessage = normalizeKnownDatabaseMessage(message);
|
|
18980
|
+
if (knownDatabaseMessage !== null) {
|
|
18981
|
+
return knownDatabaseMessage;
|
|
18982
|
+
}
|
|
18983
|
+
return collapseWhitespace(normalizeScalarTokens(message));
|
|
18832
18984
|
}
|
|
18833
18985
|
function normalizeRoute(path) {
|
|
18834
18986
|
if (path === null || path.length === 0) {
|
|
@@ -20509,6 +20661,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20509
20661
|
channel text NOT NULL,
|
|
20510
20662
|
condition_type text NOT NULL,
|
|
20511
20663
|
severity_min text,
|
|
20664
|
+
cooldown_seconds integer NOT NULL DEFAULT 0,
|
|
20512
20665
|
config jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
20513
20666
|
is_enabled boolean NOT NULL DEFAULT true,
|
|
20514
20667
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
@@ -20547,6 +20700,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20547
20700
|
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20548
20701
|
condition_type text NOT NULL,
|
|
20549
20702
|
dedupe_key text NOT NULL,
|
|
20703
|
+
notification_key text NOT NULL DEFAULT '',
|
|
20550
20704
|
channel text NOT NULL,
|
|
20551
20705
|
status text NOT NULL,
|
|
20552
20706
|
payload jsonb NOT NULL,
|
|
@@ -20561,6 +20715,10 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20561
20715
|
CREATE INDEX alert_deliveries_project_status_idx
|
|
20562
20716
|
ON alert_deliveries (project_id, status, created_at DESC)
|
|
20563
20717
|
`,
|
|
20718
|
+
`
|
|
20719
|
+
CREATE INDEX alert_deliveries_alert_notification_idx
|
|
20720
|
+
ON alert_deliveries (alert_id, notification_key, created_at DESC)
|
|
20721
|
+
`,
|
|
20564
20722
|
`
|
|
20565
20723
|
CREATE TABLE alert_email_digests (
|
|
20566
20724
|
id uuid PRIMARY KEY,
|
|
@@ -20593,6 +20751,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20593
20751
|
incident_id uuid NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
|
|
20594
20752
|
condition_type text NOT NULL,
|
|
20595
20753
|
dedupe_key text NOT NULL,
|
|
20754
|
+
notification_key text NOT NULL DEFAULT '',
|
|
20596
20755
|
payload jsonb NOT NULL,
|
|
20597
20756
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20598
20757
|
UNIQUE (alert_id, incident_id, dedupe_key)
|
|
@@ -20602,6 +20761,10 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20602
20761
|
CREATE INDEX alert_email_digest_items_digest_created_idx
|
|
20603
20762
|
ON alert_email_digest_items (digest_id, created_at ASC)
|
|
20604
20763
|
`,
|
|
20764
|
+
`
|
|
20765
|
+
CREATE INDEX alert_email_digest_items_alert_notification_idx
|
|
20766
|
+
ON alert_email_digest_items (alert_id, notification_key, created_at DESC)
|
|
20767
|
+
`,
|
|
20605
20768
|
`
|
|
20606
20769
|
CREATE TABLE agent_webhooks (
|
|
20607
20770
|
id uuid PRIMARY KEY,
|
|
@@ -20653,6 +20816,19 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20653
20816
|
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20654
20817
|
)
|
|
20655
20818
|
`,
|
|
20819
|
+
`
|
|
20820
|
+
CREATE TABLE processed_github_marketplace_events (
|
|
20821
|
+
delivery_id text PRIMARY KEY,
|
|
20822
|
+
event_name text NOT NULL,
|
|
20823
|
+
marketplace_account_id bigint,
|
|
20824
|
+
action text,
|
|
20825
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
20826
|
+
)
|
|
20827
|
+
`,
|
|
20828
|
+
`
|
|
20829
|
+
CREATE INDEX processed_github_marketplace_events_account_idx
|
|
20830
|
+
ON processed_github_marketplace_events (marketplace_account_id, processed_at DESC)
|
|
20831
|
+
`,
|
|
20656
20832
|
`
|
|
20657
20833
|
CREATE TABLE github_installations (
|
|
20658
20834
|
id uuid PRIMARY KEY,
|
|
@@ -20670,6 +20846,41 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
|
|
|
20670
20846
|
CREATE INDEX github_installations_status_idx
|
|
20671
20847
|
ON github_installations (status)
|
|
20672
20848
|
`,
|
|
20849
|
+
`
|
|
20850
|
+
CREATE TABLE github_marketplace_accounts (
|
|
20851
|
+
id uuid PRIMARY KEY,
|
|
20852
|
+
organization_id uuid REFERENCES organizations(id) ON DELETE SET NULL,
|
|
20853
|
+
marketplace_account_id bigint NOT NULL UNIQUE,
|
|
20854
|
+
marketplace_account_login text NOT NULL,
|
|
20855
|
+
marketplace_account_type text NOT NULL CHECK (marketplace_account_type IN ('Organization', 'User')),
|
|
20856
|
+
marketplace_account_node_id text,
|
|
20857
|
+
marketplace_listing_plan_id bigint NOT NULL,
|
|
20858
|
+
marketplace_listing_plan_name text NOT NULL,
|
|
20859
|
+
marketplace_plan_price_model text,
|
|
20860
|
+
billing_cycle text CHECK (billing_cycle IN ('monthly', 'yearly')),
|
|
20861
|
+
unit_count integer,
|
|
20862
|
+
on_free_trial boolean NOT NULL DEFAULT false,
|
|
20863
|
+
free_trial_ends_on timestamptz,
|
|
20864
|
+
next_billing_date timestamptz,
|
|
20865
|
+
effective_date timestamptz NOT NULL,
|
|
20866
|
+
installation_id bigint,
|
|
20867
|
+
marketplace_purchase_status text NOT NULL
|
|
20868
|
+
CHECK (marketplace_purchase_status IN ('purchased', 'cancelled', 'pending_change', 'pending_change_cancelled', 'changed')),
|
|
20869
|
+
last_event_id text NOT NULL,
|
|
20870
|
+
last_event_action text NOT NULL,
|
|
20871
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
20872
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
20873
|
+
)
|
|
20874
|
+
`,
|
|
20875
|
+
`
|
|
20876
|
+
CREATE INDEX github_marketplace_accounts_org_idx
|
|
20877
|
+
ON github_marketplace_accounts (organization_id, updated_at DESC)
|
|
20878
|
+
`,
|
|
20879
|
+
`
|
|
20880
|
+
CREATE UNIQUE INDEX github_marketplace_accounts_installation_idx
|
|
20881
|
+
ON github_marketplace_accounts (installation_id)
|
|
20882
|
+
WHERE installation_id IS NOT NULL
|
|
20883
|
+
`,
|
|
20673
20884
|
`
|
|
20674
20885
|
CREATE TABLE project_github_repos (
|
|
20675
20886
|
id uuid PRIMARY KEY,
|
|
@@ -21269,6 +21480,86 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
21269
21480
|
ON capture_rules (project_id, updated_at DESC)
|
|
21270
21481
|
`
|
|
21271
21482
|
]
|
|
21483
|
+
}),
|
|
21484
|
+
defineStorageSchemaMigration({
|
|
21485
|
+
id: "202606020001_add_github_marketplace_tracking",
|
|
21486
|
+
description: "Add GitHub Marketplace purchase tracking tables and webhook idempotency ledger.",
|
|
21487
|
+
statements: [
|
|
21488
|
+
`
|
|
21489
|
+
CREATE TABLE IF NOT EXISTS processed_github_marketplace_events (
|
|
21490
|
+
delivery_id text PRIMARY KEY,
|
|
21491
|
+
event_name text NOT NULL,
|
|
21492
|
+
marketplace_account_id bigint,
|
|
21493
|
+
action text,
|
|
21494
|
+
processed_at timestamptz NOT NULL DEFAULT now()
|
|
21495
|
+
)
|
|
21496
|
+
`,
|
|
21497
|
+
`
|
|
21498
|
+
CREATE INDEX IF NOT EXISTS processed_github_marketplace_events_account_idx
|
|
21499
|
+
ON processed_github_marketplace_events (marketplace_account_id, processed_at DESC)
|
|
21500
|
+
`,
|
|
21501
|
+
`
|
|
21502
|
+
CREATE TABLE IF NOT EXISTS github_marketplace_accounts (
|
|
21503
|
+
id uuid PRIMARY KEY,
|
|
21504
|
+
organization_id uuid REFERENCES organizations(id) ON DELETE SET NULL,
|
|
21505
|
+
marketplace_account_id bigint NOT NULL UNIQUE,
|
|
21506
|
+
marketplace_account_login text NOT NULL,
|
|
21507
|
+
marketplace_account_type text NOT NULL CHECK (marketplace_account_type IN ('Organization', 'User')),
|
|
21508
|
+
marketplace_account_node_id text,
|
|
21509
|
+
marketplace_listing_plan_id bigint NOT NULL,
|
|
21510
|
+
marketplace_listing_plan_name text NOT NULL,
|
|
21511
|
+
marketplace_plan_price_model text,
|
|
21512
|
+
billing_cycle text CHECK (billing_cycle IN ('monthly', 'yearly')),
|
|
21513
|
+
unit_count integer,
|
|
21514
|
+
on_free_trial boolean NOT NULL DEFAULT false,
|
|
21515
|
+
free_trial_ends_on timestamptz,
|
|
21516
|
+
next_billing_date timestamptz,
|
|
21517
|
+
effective_date timestamptz NOT NULL,
|
|
21518
|
+
installation_id bigint,
|
|
21519
|
+
marketplace_purchase_status text NOT NULL
|
|
21520
|
+
CHECK (marketplace_purchase_status IN ('purchased', 'cancelled', 'pending_change', 'pending_change_cancelled', 'changed')),
|
|
21521
|
+
last_event_id text NOT NULL,
|
|
21522
|
+
last_event_action text NOT NULL,
|
|
21523
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
21524
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
21525
|
+
)
|
|
21526
|
+
`,
|
|
21527
|
+
`
|
|
21528
|
+
CREATE INDEX IF NOT EXISTS github_marketplace_accounts_org_idx
|
|
21529
|
+
ON github_marketplace_accounts (organization_id, updated_at DESC)
|
|
21530
|
+
`,
|
|
21531
|
+
`
|
|
21532
|
+
CREATE UNIQUE INDEX IF NOT EXISTS github_marketplace_accounts_installation_idx
|
|
21533
|
+
ON github_marketplace_accounts (installation_id)
|
|
21534
|
+
WHERE installation_id IS NOT NULL
|
|
21535
|
+
`
|
|
21536
|
+
]
|
|
21537
|
+
}),
|
|
21538
|
+
defineStorageSchemaMigration({
|
|
21539
|
+
id: "202606030001_add_alert_notification_cooldowns_and_rule_window",
|
|
21540
|
+
description: "Add configurable alert cooldown windows and notification keys for cross-incident suppression.",
|
|
21541
|
+
statements: [
|
|
21542
|
+
"ALTER TABLE alert_rules ADD COLUMN IF NOT EXISTS cooldown_seconds integer",
|
|
21543
|
+
"UPDATE alert_rules SET cooldown_seconds = 0 WHERE cooldown_seconds IS NULL",
|
|
21544
|
+
"ALTER TABLE alert_rules ALTER COLUMN cooldown_seconds SET DEFAULT 0",
|
|
21545
|
+
"ALTER TABLE alert_rules ALTER COLUMN cooldown_seconds SET NOT NULL",
|
|
21546
|
+
"ALTER TABLE alert_deliveries ADD COLUMN IF NOT EXISTS notification_key text",
|
|
21547
|
+
"UPDATE alert_deliveries SET notification_key = dedupe_key WHERE notification_key IS NULL",
|
|
21548
|
+
"ALTER TABLE alert_deliveries ALTER COLUMN notification_key SET DEFAULT ''",
|
|
21549
|
+
"ALTER TABLE alert_deliveries ALTER COLUMN notification_key SET NOT NULL",
|
|
21550
|
+
`
|
|
21551
|
+
CREATE INDEX IF NOT EXISTS alert_deliveries_alert_notification_idx
|
|
21552
|
+
ON alert_deliveries (alert_id, notification_key, created_at DESC)
|
|
21553
|
+
`,
|
|
21554
|
+
"ALTER TABLE alert_email_digest_items ADD COLUMN IF NOT EXISTS notification_key text",
|
|
21555
|
+
"UPDATE alert_email_digest_items SET notification_key = dedupe_key WHERE notification_key IS NULL",
|
|
21556
|
+
"ALTER TABLE alert_email_digest_items ALTER COLUMN notification_key SET DEFAULT ''",
|
|
21557
|
+
"ALTER TABLE alert_email_digest_items ALTER COLUMN notification_key SET NOT NULL",
|
|
21558
|
+
`
|
|
21559
|
+
CREATE INDEX IF NOT EXISTS alert_email_digest_items_alert_notification_idx
|
|
21560
|
+
ON alert_email_digest_items (alert_id, notification_key, created_at DESC)
|
|
21561
|
+
`
|
|
21562
|
+
]
|
|
21272
21563
|
})
|
|
21273
21564
|
];
|
|
21274
21565
|
|
|
@@ -21392,7 +21683,8 @@ function normalizeRouteTemplate(path) {
|
|
|
21392
21683
|
return normalizedSegments.length === 0 ? "/" : `/${normalizedSegments.join("/")}`;
|
|
21393
21684
|
}
|
|
21394
21685
|
function isBrowserSdkFallbackFrame(frame) {
|
|
21395
|
-
|
|
21686
|
+
const normalizedFrame = frame.toLowerCase();
|
|
21687
|
+
return normalizedFrame.includes("onerror") && (normalizedFrame.includes("debugbundle-browser-sdk") || normalizedFrame.includes("debugbundle-browser.js") || normalizedFrame.includes("wp-content/plugins/debugbundle/"));
|
|
21396
21688
|
}
|
|
21397
21689
|
function deriveFirstApplicationFrame(errorContext) {
|
|
21398
21690
|
const firstFrame = errorContext?.top_frames[0];
|
|
@@ -21437,6 +21729,20 @@ function isOpaqueBrowserError(errorContext, browserEvent) {
|
|
|
21437
21729
|
const firstFrame = errorContext?.top_frames[0];
|
|
21438
21730
|
return errorContext?.message === "Window error" && firstFrame !== void 0 && isBrowserSdkFallbackFrame(firstFrame);
|
|
21439
21731
|
}
|
|
21732
|
+
function stableJson2(value) {
|
|
21733
|
+
if (value === null || typeof value !== "object") {
|
|
21734
|
+
return JSON.stringify(value);
|
|
21735
|
+
}
|
|
21736
|
+
if (Array.isArray(value)) {
|
|
21737
|
+
return `[${value.map((entry) => stableJson2(entry)).join(",")}]`;
|
|
21738
|
+
}
|
|
21739
|
+
const record = value;
|
|
21740
|
+
const keys = Object.keys(record).sort();
|
|
21741
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson2(record[key])}`).join(",")}}`;
|
|
21742
|
+
}
|
|
21743
|
+
function buildFrontendBreadcrumbKey(input) {
|
|
21744
|
+
return `${input.breadcrumb_type}:${input.ts}:${input.route ?? ""}:${stableJson2(input.data)}`;
|
|
21745
|
+
}
|
|
21440
21746
|
function buildErrorContext(envelopes, incident, primarySignalEnvelope) {
|
|
21441
21747
|
if (primarySignalEnvelope !== null && isBackendExceptionEnvelope(primarySignalEnvelope)) {
|
|
21442
21748
|
return {
|
|
@@ -21698,6 +22004,7 @@ function buildLogsContext(envelopes) {
|
|
|
21698
22004
|
};
|
|
21699
22005
|
}
|
|
21700
22006
|
function buildFrontendContext(envelopes) {
|
|
22007
|
+
const breadcrumbs = /* @__PURE__ */ new Map();
|
|
21701
22008
|
const routeChanges = [];
|
|
21702
22009
|
const clicks = [];
|
|
21703
22010
|
const formSubmissions = [];
|
|
@@ -21706,54 +22013,24 @@ function buildFrontendContext(envelopes) {
|
|
|
21706
22013
|
const exceptions = [];
|
|
21707
22014
|
for (const envelope of envelopes) {
|
|
21708
22015
|
if (isFrontendBreadcrumbEnvelope(envelope)) {
|
|
21709
|
-
const
|
|
21710
|
-
|
|
21711
|
-
|
|
21712
|
-
|
|
21713
|
-
|
|
21714
|
-
}
|
|
21715
|
-
|
|
21716
|
-
|
|
21717
|
-
|
|
21718
|
-
|
|
21719
|
-
ts: timestamp
|
|
21720
|
-
});
|
|
21721
|
-
}
|
|
21722
|
-
if (envelope.payload.breadcrumb_type === "form_submit") {
|
|
21723
|
-
formSubmissions.push({
|
|
21724
|
-
form: typeof envelope.payload.data["form"] === "string" ? envelope.payload.data["form"] : "unknown",
|
|
21725
|
-
fields: envelope.payload.data["fields"] !== null && typeof envelope.payload.data["fields"] === "object" ? envelope.payload.data["fields"] : {},
|
|
21726
|
-
ts: timestamp
|
|
21727
|
-
});
|
|
21728
|
-
}
|
|
21729
|
-
if (envelope.payload.breadcrumb_type === "console_log") {
|
|
21730
|
-
consoleLogs.push({
|
|
21731
|
-
ts: timestamp,
|
|
21732
|
-
...envelope.payload.data
|
|
21733
|
-
});
|
|
21734
|
-
}
|
|
21735
|
-
if (envelope.payload.breadcrumb_type === "network_request") {
|
|
21736
|
-
const d = envelope.payload.data;
|
|
22016
|
+
const entry = {
|
|
22017
|
+
breadcrumb_type: envelope.payload.breadcrumb_type,
|
|
22018
|
+
route: envelope.payload.route,
|
|
22019
|
+
data: envelope.payload.data,
|
|
22020
|
+
ts: toIsoTimestamp(envelope.occurred_at)
|
|
22021
|
+
};
|
|
22022
|
+
breadcrumbs.set(buildFrontendBreadcrumbKey(entry), entry);
|
|
22023
|
+
}
|
|
22024
|
+
if (isFrontendExceptionEnvelope(envelope)) {
|
|
22025
|
+
for (const breadcrumb of envelope.payload.breadcrumbs ?? []) {
|
|
21737
22026
|
const entry = {
|
|
21738
|
-
|
|
21739
|
-
|
|
21740
|
-
|
|
21741
|
-
ts:
|
|
22027
|
+
breadcrumb_type: breadcrumb.breadcrumb_type,
|
|
22028
|
+
route: breadcrumb.route,
|
|
22029
|
+
data: breadcrumb.data,
|
|
22030
|
+
ts: toIsoTimestamp(breadcrumb.ts)
|
|
21742
22031
|
};
|
|
21743
|
-
|
|
21744
|
-
if (Array.isArray(d["caller_trace"])) entry.caller_trace = d["caller_trace"];
|
|
21745
|
-
if (d["response_body"] !== void 0) entry.response_body = d["response_body"];
|
|
21746
|
-
if (d["request_body"] !== void 0) entry.request_body = d["request_body"];
|
|
21747
|
-
if (typeof d["response_headers"] === "object" && d["response_headers"] !== null) {
|
|
21748
|
-
entry.response_headers = d["response_headers"];
|
|
21749
|
-
}
|
|
21750
|
-
if (typeof d["response_content_length"] === "number") {
|
|
21751
|
-
entry.response_content_length = d["response_content_length"];
|
|
21752
|
-
}
|
|
21753
|
-
networkRequests.push(entry);
|
|
22032
|
+
breadcrumbs.set(buildFrontendBreadcrumbKey(entry), entry);
|
|
21754
22033
|
}
|
|
21755
|
-
}
|
|
21756
|
-
if (isFrontendExceptionEnvelope(envelope)) {
|
|
21757
22034
|
exceptions.push({
|
|
21758
22035
|
name: envelope.payload.name,
|
|
21759
22036
|
message: envelope.payload.message,
|
|
@@ -21764,6 +22041,59 @@ function buildFrontendContext(envelopes) {
|
|
|
21764
22041
|
});
|
|
21765
22042
|
}
|
|
21766
22043
|
}
|
|
22044
|
+
const sortedBreadcrumbs = [...breadcrumbs.values()].sort((left, right) => {
|
|
22045
|
+
const timestampComparison = left.ts.localeCompare(right.ts);
|
|
22046
|
+
if (timestampComparison !== 0) {
|
|
22047
|
+
return timestampComparison;
|
|
22048
|
+
}
|
|
22049
|
+
return buildFrontendBreadcrumbKey(left).localeCompare(buildFrontendBreadcrumbKey(right));
|
|
22050
|
+
});
|
|
22051
|
+
for (const breadcrumb of sortedBreadcrumbs) {
|
|
22052
|
+
if (breadcrumb.breadcrumb_type === "route_change") {
|
|
22053
|
+
const from = typeof breadcrumb.data["from"] === "string" ? breadcrumb.data["from"] : "unknown";
|
|
22054
|
+
const to = typeof breadcrumb.data["to"] === "string" ? breadcrumb.data["to"] : breadcrumb.route ?? "unknown";
|
|
22055
|
+
routeChanges.push({ from, to, ts: breadcrumb.ts });
|
|
22056
|
+
}
|
|
22057
|
+
if (breadcrumb.breadcrumb_type === "click") {
|
|
22058
|
+
clicks.push({
|
|
22059
|
+
selector: typeof breadcrumb.data["selector"] === "string" ? breadcrumb.data["selector"] : "unknown",
|
|
22060
|
+
label: typeof breadcrumb.data["label"] === "string" ? breadcrumb.data["label"] : "unknown",
|
|
22061
|
+
ts: breadcrumb.ts
|
|
22062
|
+
});
|
|
22063
|
+
}
|
|
22064
|
+
if (breadcrumb.breadcrumb_type === "form_submit") {
|
|
22065
|
+
formSubmissions.push({
|
|
22066
|
+
form: typeof breadcrumb.data["form"] === "string" ? breadcrumb.data["form"] : "unknown",
|
|
22067
|
+
fields: breadcrumb.data["fields"] !== null && typeof breadcrumb.data["fields"] === "object" ? breadcrumb.data["fields"] : {},
|
|
22068
|
+
ts: breadcrumb.ts
|
|
22069
|
+
});
|
|
22070
|
+
}
|
|
22071
|
+
if (breadcrumb.breadcrumb_type === "console_log") {
|
|
22072
|
+
consoleLogs.push({
|
|
22073
|
+
ts: breadcrumb.ts,
|
|
22074
|
+
...breadcrumb.data
|
|
22075
|
+
});
|
|
22076
|
+
}
|
|
22077
|
+
if (breadcrumb.breadcrumb_type === "network_request") {
|
|
22078
|
+
const entry = {
|
|
22079
|
+
method: typeof breadcrumb.data["method"] === "string" ? breadcrumb.data["method"] : "GET",
|
|
22080
|
+
url: typeof breadcrumb.data["url"] === "string" ? breadcrumb.data["url"] : "unknown",
|
|
22081
|
+
status: typeof breadcrumb.data["status_code"] === "number" && Number.isInteger(breadcrumb.data["status_code"]) ? breadcrumb.data["status_code"] : typeof breadcrumb.data["status"] === "number" && Number.isInteger(breadcrumb.data["status"]) ? breadcrumb.data["status"] : 0,
|
|
22082
|
+
ts: breadcrumb.ts
|
|
22083
|
+
};
|
|
22084
|
+
if (typeof breadcrumb.data["duration_ms"] === "number") entry.duration_ms = breadcrumb.data["duration_ms"];
|
|
22085
|
+
if (Array.isArray(breadcrumb.data["caller_trace"])) entry.caller_trace = breadcrumb.data["caller_trace"];
|
|
22086
|
+
if (breadcrumb.data["response_body"] !== void 0) entry.response_body = breadcrumb.data["response_body"];
|
|
22087
|
+
if (breadcrumb.data["request_body"] !== void 0) entry.request_body = breadcrumb.data["request_body"];
|
|
22088
|
+
if (typeof breadcrumb.data["response_headers"] === "object" && breadcrumb.data["response_headers"] !== null) {
|
|
22089
|
+
entry.response_headers = breadcrumb.data["response_headers"];
|
|
22090
|
+
}
|
|
22091
|
+
if (typeof breadcrumb.data["response_content_length"] === "number") {
|
|
22092
|
+
entry.response_content_length = breadcrumb.data["response_content_length"];
|
|
22093
|
+
}
|
|
22094
|
+
networkRequests.push(entry);
|
|
22095
|
+
}
|
|
22096
|
+
}
|
|
21767
22097
|
const latestFrontendException = selectLatestEnvelopeByType(envelopes, isFrontendExceptionEnvelope);
|
|
21768
22098
|
const domContext = latestFrontendException?.payload.dom_context ?? null;
|
|
21769
22099
|
if (routeChanges.length === 0 && clicks.length === 0 && formSubmissions.length === 0 && consoleLogs.length === 0 && networkRequests.length === 0 && exceptions.length === 0 && domContext === null) {
|
|
@@ -21913,7 +22243,7 @@ function buildBundle(input) {
|
|
|
21913
22243
|
const serviceRuntime = input.incident.service_runtime ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.runtime ?? null;
|
|
21914
22244
|
const serviceFramework = input.incident.service_framework ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.framework ?? null;
|
|
21915
22245
|
const customerVisible = frontendContext !== null;
|
|
21916
|
-
const firstApplicationFrame = deriveFirstApplicationFrame(errorContext);
|
|
22246
|
+
const firstApplicationFrame = opaqueBrowserError ? null : deriveFirstApplicationFrame(errorContext);
|
|
21917
22247
|
const summaryGuidance = buildSummaryGuidance({
|
|
21918
22248
|
errorContext,
|
|
21919
22249
|
requestContext,
|
|
@@ -22446,20 +22776,20 @@ function mergeSourceEvents(existingEvents, nextEvents) {
|
|
|
22446
22776
|
}
|
|
22447
22777
|
return [...merged.values()].sort(compareEventEnvelopes);
|
|
22448
22778
|
}
|
|
22449
|
-
function
|
|
22779
|
+
function stableJson3(value) {
|
|
22450
22780
|
if (value === null || typeof value !== "object") {
|
|
22451
22781
|
return JSON.stringify(value);
|
|
22452
22782
|
}
|
|
22453
22783
|
if (Array.isArray(value)) {
|
|
22454
|
-
return `[${value.map((entry) =>
|
|
22784
|
+
return `[${value.map((entry) => stableJson3(entry)).join(",")}]`;
|
|
22455
22785
|
}
|
|
22456
22786
|
const record = value;
|
|
22457
22787
|
const keys = Object.keys(record).sort();
|
|
22458
|
-
return `{${keys.map((key) => `${JSON.stringify(key)}:${
|
|
22788
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson3(record[key])}`).join(",")}}`;
|
|
22459
22789
|
}
|
|
22460
22790
|
function buildRequestAnomalyFingerprint(input) {
|
|
22461
22791
|
return (0, import_node_crypto4.createHash)("sha256").update(
|
|
22462
|
-
|
|
22792
|
+
stableJson3({
|
|
22463
22793
|
kind: "request_status_anomaly",
|
|
22464
22794
|
project_id: input.projectId,
|
|
22465
22795
|
service_name: input.serviceName,
|
|
@@ -24553,6 +24883,9 @@ function createAlertMcpTools(api) {
|
|
|
24553
24883
|
if (typeof input["severityMin"] === "string") {
|
|
24554
24884
|
requestInput.severityMin = input["severityMin"];
|
|
24555
24885
|
}
|
|
24886
|
+
if (typeof input["cooldownSeconds"] === "number") {
|
|
24887
|
+
requestInput.cooldownSeconds = input["cooldownSeconds"];
|
|
24888
|
+
}
|
|
24556
24889
|
if (typeof input["isEnabled"] === "boolean") {
|
|
24557
24890
|
requestInput.isEnabled = input["isEnabled"];
|
|
24558
24891
|
}
|
|
@@ -24584,6 +24917,9 @@ function createAlertMcpTools(api) {
|
|
|
24584
24917
|
} else if (input["severityMin"] === null) {
|
|
24585
24918
|
requestInput.severityMin = null;
|
|
24586
24919
|
}
|
|
24920
|
+
if (typeof input["cooldownSeconds"] === "number") {
|
|
24921
|
+
requestInput.cooldownSeconds = input["cooldownSeconds"];
|
|
24922
|
+
}
|
|
24587
24923
|
if (typeof input["config"] === "object") {
|
|
24588
24924
|
requestInput.config = input["config"];
|
|
24589
24925
|
}
|
|
@@ -25177,6 +25513,16 @@ function createMemberMcpTools(api) {
|
|
|
25177
25513
|
} catch (error) {
|
|
25178
25514
|
mapMcpError9(error);
|
|
25179
25515
|
}
|
|
25516
|
+
},
|
|
25517
|
+
async leave_project(input) {
|
|
25518
|
+
try {
|
|
25519
|
+
return await api.leaveProject({
|
|
25520
|
+
bearerToken: String(input["bearerToken"]),
|
|
25521
|
+
projectId: String(input["projectId"])
|
|
25522
|
+
});
|
|
25523
|
+
} catch (error) {
|
|
25524
|
+
mapMcpError9(error);
|
|
25525
|
+
}
|
|
25180
25526
|
}
|
|
25181
25527
|
};
|
|
25182
25528
|
}
|
|
@@ -27759,7 +28105,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
27759
28105
|
var package_default = {
|
|
27760
28106
|
name: "@debugbundle/mcp",
|
|
27761
28107
|
mcpName: "com.debugbundle/mcp",
|
|
27762
|
-
version: "1.0.
|
|
28108
|
+
version: "1.0.2",
|
|
27763
28109
|
private: false,
|
|
27764
28110
|
description: "Model Context Protocol server for DebugBundle",
|
|
27765
28111
|
license: "AGPL-3.0-only",
|
|
@@ -28349,6 +28695,7 @@ var MCP_TOOL_CATALOG = [
|
|
|
28349
28695
|
channel: external_exports.string(),
|
|
28350
28696
|
conditionType: external_exports.string(),
|
|
28351
28697
|
severityMin: external_exports.string().optional(),
|
|
28698
|
+
cooldownSeconds: external_exports.number().int().min(0).max(604800).optional(),
|
|
28352
28699
|
config: jsonObjectSchema,
|
|
28353
28700
|
isEnabled: external_exports.boolean().optional()
|
|
28354
28701
|
})
|
|
@@ -28365,6 +28712,7 @@ var MCP_TOOL_CATALOG = [
|
|
|
28365
28712
|
channel: external_exports.string().optional(),
|
|
28366
28713
|
conditionType: external_exports.string().optional(),
|
|
28367
28714
|
severityMin: external_exports.string().nullable().optional(),
|
|
28715
|
+
cooldownSeconds: external_exports.number().int().min(0).max(604800).optional(),
|
|
28368
28716
|
config: jsonObjectSchema.nullable().optional(),
|
|
28369
28717
|
isEnabled: external_exports.boolean().optional()
|
|
28370
28718
|
})
|
|
@@ -28654,6 +29002,15 @@ var MCP_TOOL_CATALOG = [
|
|
|
28654
29002
|
userId: external_exports.string()
|
|
28655
29003
|
})
|
|
28656
29004
|
},
|
|
29005
|
+
{
|
|
29006
|
+
name: "leave_project",
|
|
29007
|
+
group: "members",
|
|
29008
|
+
description: "Leave a shared project as the authenticated collaborator.",
|
|
29009
|
+
inputSchema: external_exports.object({
|
|
29010
|
+
bearerToken: external_exports.string(),
|
|
29011
|
+
projectId: external_exports.string()
|
|
29012
|
+
})
|
|
29013
|
+
},
|
|
28657
29014
|
{
|
|
28658
29015
|
name: "list_services",
|
|
28659
29016
|
group: "services",
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"source": "github",
|
|
9
9
|
"subfolder": "apps/mcp"
|
|
10
10
|
},
|
|
11
|
-
"version": "1.0.
|
|
11
|
+
"version": "1.0.2",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "@debugbundle/mcp",
|
|
17
|
-
"version": "1.0.
|
|
17
|
+
"version": "1.0.2",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|