@debugbundle/mcp 0.1.2 → 0.1.5
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 +596 -117
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -15198,7 +15198,7 @@ function createProjectManagementApi(client) {
|
|
|
15198
15198
|
|
|
15199
15199
|
// ../../packages/retrieval-client/src/index.ts
|
|
15200
15200
|
var IncidentReasonSchema = external_exports.object({
|
|
15201
|
-
kind: external_exports.enum(["backend_exception", "frontend_exception", "
|
|
15201
|
+
kind: external_exports.enum(["backend_exception", "frontend_exception", "request_failure", "error_log"]),
|
|
15202
15202
|
description: external_exports.string(),
|
|
15203
15203
|
event_type: external_exports.enum(["backend_exception", "frontend_exception", "request_event", "log_event"]),
|
|
15204
15204
|
event_class: external_exports.literal("incident_signal"),
|
|
@@ -15520,6 +15520,121 @@ function createRetrievalApi(client) {
|
|
|
15520
15520
|
};
|
|
15521
15521
|
}
|
|
15522
15522
|
|
|
15523
|
+
// ../../packages/slack-client/src/index.ts
|
|
15524
|
+
var SlackDestinationRecordSchema = external_exports.object({
|
|
15525
|
+
slack_destination_id: external_exports.string(),
|
|
15526
|
+
organization_id: external_exports.string(),
|
|
15527
|
+
slack_team_id: external_exports.string(),
|
|
15528
|
+
slack_team_name: external_exports.string().nullable(),
|
|
15529
|
+
slack_channel_id: external_exports.string(),
|
|
15530
|
+
slack_channel_name: external_exports.string().nullable(),
|
|
15531
|
+
installed_by_member_id: external_exports.string().nullable(),
|
|
15532
|
+
is_active: external_exports.boolean(),
|
|
15533
|
+
created_at: external_exports.string(),
|
|
15534
|
+
updated_at: external_exports.string()
|
|
15535
|
+
}).strict();
|
|
15536
|
+
var SlackDestinationListResponseSchema = external_exports.object({
|
|
15537
|
+
destinations: external_exports.array(SlackDestinationRecordSchema)
|
|
15538
|
+
}).strict();
|
|
15539
|
+
var SlackInstallUrlResponseSchema = external_exports.object({
|
|
15540
|
+
install_url: external_exports.string().url()
|
|
15541
|
+
}).strict();
|
|
15542
|
+
var SlackDestinationTestResponseSchema = external_exports.object({
|
|
15543
|
+
delivered: external_exports.boolean()
|
|
15544
|
+
}).strict();
|
|
15545
|
+
var ApiErrorResponseSchema6 = external_exports.object({
|
|
15546
|
+
error: external_exports.string()
|
|
15547
|
+
}).strict();
|
|
15548
|
+
var SlackApiError = class extends Error {
|
|
15549
|
+
status;
|
|
15550
|
+
code;
|
|
15551
|
+
constructor(status, code) {
|
|
15552
|
+
super(`slack_api_error: ${status}:${code}`);
|
|
15553
|
+
this.status = status;
|
|
15554
|
+
this.code = code;
|
|
15555
|
+
}
|
|
15556
|
+
};
|
|
15557
|
+
function parseApiError6(status, body) {
|
|
15558
|
+
const parsed = ApiErrorResponseSchema6.safeParse(body);
|
|
15559
|
+
if (!parsed.success) {
|
|
15560
|
+
throw new SlackApiError(status, "unknown_error");
|
|
15561
|
+
}
|
|
15562
|
+
throw new SlackApiError(status, parsed.data.error);
|
|
15563
|
+
}
|
|
15564
|
+
function buildQuery2(input) {
|
|
15565
|
+
const params = new URLSearchParams();
|
|
15566
|
+
for (const [key, value] of Object.entries(input)) {
|
|
15567
|
+
if (value !== void 0) {
|
|
15568
|
+
params.set(key, String(value));
|
|
15569
|
+
}
|
|
15570
|
+
}
|
|
15571
|
+
const query = params.toString();
|
|
15572
|
+
return query.length === 0 ? "" : `?${query}`;
|
|
15573
|
+
}
|
|
15574
|
+
function createSlackApi(client) {
|
|
15575
|
+
return {
|
|
15576
|
+
async getSlackInstallUrl(input) {
|
|
15577
|
+
const response = await client.request({
|
|
15578
|
+
method: "GET",
|
|
15579
|
+
path: `/v1/slack/app/install-url${buildQuery2({
|
|
15580
|
+
project_id: input.projectId,
|
|
15581
|
+
return_to: input.returnTo
|
|
15582
|
+
})}`,
|
|
15583
|
+
bearerToken: input.bearerToken
|
|
15584
|
+
});
|
|
15585
|
+
if (response.status < 200 || response.status >= 300) {
|
|
15586
|
+
parseApiError6(response.status, response.body);
|
|
15587
|
+
}
|
|
15588
|
+
const parsed = SlackInstallUrlResponseSchema.safeParse(response.body);
|
|
15589
|
+
if (!parsed.success) {
|
|
15590
|
+
throw new SlackApiError(response.status, "invalid_response_shape");
|
|
15591
|
+
}
|
|
15592
|
+
return parsed.data.install_url;
|
|
15593
|
+
},
|
|
15594
|
+
async listSlackDestinations(input) {
|
|
15595
|
+
const response = await client.request({
|
|
15596
|
+
method: "GET",
|
|
15597
|
+
path: `/v1/projects/${input.projectId}/slack/destinations`,
|
|
15598
|
+
bearerToken: input.bearerToken
|
|
15599
|
+
});
|
|
15600
|
+
if (response.status < 200 || response.status >= 300) {
|
|
15601
|
+
parseApiError6(response.status, response.body);
|
|
15602
|
+
}
|
|
15603
|
+
const parsed = SlackDestinationListResponseSchema.safeParse(response.body);
|
|
15604
|
+
if (!parsed.success) {
|
|
15605
|
+
throw new SlackApiError(response.status, "invalid_response_shape");
|
|
15606
|
+
}
|
|
15607
|
+
return parsed.data.destinations;
|
|
15608
|
+
},
|
|
15609
|
+
async testSlackDestination(input) {
|
|
15610
|
+
const response = await client.request({
|
|
15611
|
+
method: "POST",
|
|
15612
|
+
path: `/v1/projects/${input.projectId}/slack/destinations/${input.destinationId}/test`,
|
|
15613
|
+
bearerToken: input.bearerToken
|
|
15614
|
+
});
|
|
15615
|
+
if (response.status < 200 || response.status >= 300) {
|
|
15616
|
+
parseApiError6(response.status, response.body);
|
|
15617
|
+
}
|
|
15618
|
+
const parsed = SlackDestinationTestResponseSchema.safeParse(response.body);
|
|
15619
|
+
if (!parsed.success || parsed.data.delivered !== true) {
|
|
15620
|
+
throw new SlackApiError(response.status, "invalid_response_shape");
|
|
15621
|
+
}
|
|
15622
|
+
return { delivered: true };
|
|
15623
|
+
},
|
|
15624
|
+
async deleteSlackDestination(input) {
|
|
15625
|
+
const response = await client.request({
|
|
15626
|
+
method: "DELETE",
|
|
15627
|
+
path: `/v1/projects/${input.projectId}/slack/destinations/${input.destinationId}`,
|
|
15628
|
+
bearerToken: input.bearerToken
|
|
15629
|
+
});
|
|
15630
|
+
if (response.status < 200 || response.status >= 300) {
|
|
15631
|
+
parseApiError6(response.status, response.body);
|
|
15632
|
+
}
|
|
15633
|
+
return { slack_destination_id: input.destinationId };
|
|
15634
|
+
}
|
|
15635
|
+
};
|
|
15636
|
+
}
|
|
15637
|
+
|
|
15523
15638
|
// ../../packages/token-management/src/index.ts
|
|
15524
15639
|
var ProjectTokenSchema = external_exports.object({
|
|
15525
15640
|
token_id: external_exports.string(),
|
|
@@ -15548,7 +15663,7 @@ var TokenListResponseSchema = external_exports.object({
|
|
|
15548
15663
|
var TokenCreateResponseSchema = external_exports.object({
|
|
15549
15664
|
token: external_exports.union([ProjectTokenSchema, MemberTokenSchema])
|
|
15550
15665
|
}).strict();
|
|
15551
|
-
var
|
|
15666
|
+
var ApiErrorResponseSchema7 = external_exports.object({
|
|
15552
15667
|
error: external_exports.string()
|
|
15553
15668
|
}).strict();
|
|
15554
15669
|
var TokenManagementApiError = class extends Error {
|
|
@@ -15560,8 +15675,8 @@ var TokenManagementApiError = class extends Error {
|
|
|
15560
15675
|
this.code = code;
|
|
15561
15676
|
}
|
|
15562
15677
|
};
|
|
15563
|
-
function
|
|
15564
|
-
const parsed =
|
|
15678
|
+
function parseApiError7(status, body) {
|
|
15679
|
+
const parsed = ApiErrorResponseSchema7.safeParse(body);
|
|
15565
15680
|
if (!parsed.success) {
|
|
15566
15681
|
throw new TokenManagementApiError(status, "unknown_error");
|
|
15567
15682
|
}
|
|
@@ -15570,7 +15685,7 @@ function parseApiError6(status, body) {
|
|
|
15570
15685
|
async function expectTokenList(responsePromise) {
|
|
15571
15686
|
const response = await responsePromise;
|
|
15572
15687
|
if (response.status < 200 || response.status >= 300) {
|
|
15573
|
-
|
|
15688
|
+
parseApiError7(response.status, response.body);
|
|
15574
15689
|
}
|
|
15575
15690
|
const parsed = TokenListResponseSchema.safeParse(response.body);
|
|
15576
15691
|
if (!parsed.success) {
|
|
@@ -15581,7 +15696,7 @@ async function expectTokenList(responsePromise) {
|
|
|
15581
15696
|
async function expectToken(responsePromise) {
|
|
15582
15697
|
const response = await responsePromise;
|
|
15583
15698
|
if (response.status < 200 || response.status >= 300) {
|
|
15584
|
-
|
|
15699
|
+
parseApiError7(response.status, response.body);
|
|
15585
15700
|
}
|
|
15586
15701
|
const parsed = TokenCreateResponseSchema.safeParse(response.body);
|
|
15587
15702
|
if (!parsed.success) {
|
|
@@ -15773,7 +15888,7 @@ var RetryWebhookDeliveryResponseSchema = external_exports.object({
|
|
|
15773
15888
|
delivery_id: external_exports.string(),
|
|
15774
15889
|
event_type: WebhookEventTypeSchema
|
|
15775
15890
|
}).strict();
|
|
15776
|
-
var
|
|
15891
|
+
var ApiErrorResponseSchema8 = external_exports.object({
|
|
15777
15892
|
error: external_exports.string()
|
|
15778
15893
|
}).strict();
|
|
15779
15894
|
var WebhookApiError = class extends Error {
|
|
@@ -15785,14 +15900,14 @@ var WebhookApiError = class extends Error {
|
|
|
15785
15900
|
this.code = code;
|
|
15786
15901
|
}
|
|
15787
15902
|
};
|
|
15788
|
-
function
|
|
15789
|
-
const parsed =
|
|
15903
|
+
function parseApiError8(status, body) {
|
|
15904
|
+
const parsed = ApiErrorResponseSchema8.safeParse(body);
|
|
15790
15905
|
if (!parsed.success) {
|
|
15791
15906
|
throw new WebhookApiError(status, "unknown_error");
|
|
15792
15907
|
}
|
|
15793
15908
|
throw new WebhookApiError(status, parsed.data.error);
|
|
15794
15909
|
}
|
|
15795
|
-
function
|
|
15910
|
+
function buildQuery3(input) {
|
|
15796
15911
|
const params = new URLSearchParams();
|
|
15797
15912
|
for (const [key, value] of Object.entries(input)) {
|
|
15798
15913
|
if (value !== void 0) {
|
|
@@ -15805,7 +15920,7 @@ function buildQuery2(input) {
|
|
|
15805
15920
|
async function expectWebhookList(responsePromise) {
|
|
15806
15921
|
const response = await responsePromise;
|
|
15807
15922
|
if (response.status < 200 || response.status >= 300) {
|
|
15808
|
-
|
|
15923
|
+
parseApiError8(response.status, response.body);
|
|
15809
15924
|
}
|
|
15810
15925
|
const parsed = WebhookListResponseSchema.safeParse(response.body);
|
|
15811
15926
|
if (!parsed.success) {
|
|
@@ -15816,7 +15931,7 @@ async function expectWebhookList(responsePromise) {
|
|
|
15816
15931
|
async function expectWebhook(responsePromise) {
|
|
15817
15932
|
const response = await responsePromise;
|
|
15818
15933
|
if (response.status < 200 || response.status >= 300) {
|
|
15819
|
-
|
|
15934
|
+
parseApiError8(response.status, response.body);
|
|
15820
15935
|
}
|
|
15821
15936
|
const parsed = WebhookResponseSchema.safeParse(response.body);
|
|
15822
15937
|
if (!parsed.success) {
|
|
@@ -15827,7 +15942,7 @@ async function expectWebhook(responsePromise) {
|
|
|
15827
15942
|
async function expectCreatedWebhook(responsePromise) {
|
|
15828
15943
|
const response = await responsePromise;
|
|
15829
15944
|
if (response.status < 200 || response.status >= 300) {
|
|
15830
|
-
|
|
15945
|
+
parseApiError8(response.status, response.body);
|
|
15831
15946
|
}
|
|
15832
15947
|
const parsed = WebhookCreateResponseSchema.safeParse(response.body);
|
|
15833
15948
|
if (!parsed.success) {
|
|
@@ -15838,7 +15953,7 @@ async function expectCreatedWebhook(responsePromise) {
|
|
|
15838
15953
|
async function expectWebhookDeliveries(responsePromise) {
|
|
15839
15954
|
const response = await responsePromise;
|
|
15840
15955
|
if (response.status < 200 || response.status >= 300) {
|
|
15841
|
-
|
|
15956
|
+
parseApiError8(response.status, response.body);
|
|
15842
15957
|
}
|
|
15843
15958
|
const parsed = WebhookDeliveriesResponseSchema.safeParse(response.body);
|
|
15844
15959
|
if (!parsed.success) {
|
|
@@ -15849,7 +15964,7 @@ async function expectWebhookDeliveries(responsePromise) {
|
|
|
15849
15964
|
async function expectWebhookTestDelivery(responsePromise) {
|
|
15850
15965
|
const response = await responsePromise;
|
|
15851
15966
|
if (response.status < 200 || response.status >= 300) {
|
|
15852
|
-
|
|
15967
|
+
parseApiError8(response.status, response.body);
|
|
15853
15968
|
}
|
|
15854
15969
|
const parsed = WebhookTestResponseSchema.safeParse(response.body);
|
|
15855
15970
|
if (!parsed.success) {
|
|
@@ -15860,7 +15975,7 @@ async function expectWebhookTestDelivery(responsePromise) {
|
|
|
15860
15975
|
async function expectRetryDelivery(responsePromise) {
|
|
15861
15976
|
const response = await responsePromise;
|
|
15862
15977
|
if (response.status < 200 || response.status >= 300) {
|
|
15863
|
-
|
|
15978
|
+
parseApiError8(response.status, response.body);
|
|
15864
15979
|
}
|
|
15865
15980
|
const parsed = RetryWebhookDeliveryResponseSchema.safeParse(response.body);
|
|
15866
15981
|
if (!parsed.success) {
|
|
@@ -15874,7 +15989,7 @@ function createWebhookApi(client) {
|
|
|
15874
15989
|
return expectWebhookList(
|
|
15875
15990
|
client.request({
|
|
15876
15991
|
method: "GET",
|
|
15877
|
-
path: `/v1/webhooks${
|
|
15992
|
+
path: `/v1/webhooks${buildQuery3({ project_id: input.projectId, limit: input.limit })}`,
|
|
15878
15993
|
bearerToken: input.bearerToken
|
|
15879
15994
|
})
|
|
15880
15995
|
);
|
|
@@ -15939,7 +16054,7 @@ function createWebhookApi(client) {
|
|
|
15939
16054
|
bearerToken: input.bearerToken
|
|
15940
16055
|
});
|
|
15941
16056
|
if (response.status < 200 || response.status >= 300) {
|
|
15942
|
-
|
|
16057
|
+
parseApiError8(response.status, response.body);
|
|
15943
16058
|
}
|
|
15944
16059
|
return {
|
|
15945
16060
|
webhook_id: input.webhookId
|
|
@@ -15963,7 +16078,7 @@ function createWebhookApi(client) {
|
|
|
15963
16078
|
return expectWebhookDeliveries(
|
|
15964
16079
|
client.request({
|
|
15965
16080
|
method: "GET",
|
|
15966
|
-
path: `/v1/webhooks/${input.webhookId}/deliveries${
|
|
16081
|
+
path: `/v1/webhooks/${input.webhookId}/deliveries${buildQuery3({ limit: input.limit })}`,
|
|
15967
16082
|
bearerToken: input.bearerToken
|
|
15968
16083
|
})
|
|
15969
16084
|
);
|
|
@@ -16013,7 +16128,7 @@ var WeeklyReportChannelListResponseSchema = external_exports.object({
|
|
|
16013
16128
|
var WeeklyReportChannelResponseSchema = external_exports.object({
|
|
16014
16129
|
channel: WeeklyReportChannelRecordSchema
|
|
16015
16130
|
}).strict();
|
|
16016
|
-
var
|
|
16131
|
+
var ApiErrorResponseSchema9 = external_exports.object({
|
|
16017
16132
|
error: external_exports.string()
|
|
16018
16133
|
}).strict();
|
|
16019
16134
|
var WeeklyReportApiError = class extends Error {
|
|
@@ -16025,14 +16140,14 @@ var WeeklyReportApiError = class extends Error {
|
|
|
16025
16140
|
this.code = code;
|
|
16026
16141
|
}
|
|
16027
16142
|
};
|
|
16028
|
-
function
|
|
16029
|
-
const parsed =
|
|
16143
|
+
function parseApiError9(status, body) {
|
|
16144
|
+
const parsed = ApiErrorResponseSchema9.safeParse(body);
|
|
16030
16145
|
if (!parsed.success) {
|
|
16031
16146
|
throw new WeeklyReportApiError(status, "unknown_error");
|
|
16032
16147
|
}
|
|
16033
16148
|
throw new WeeklyReportApiError(status, parsed.data.error);
|
|
16034
16149
|
}
|
|
16035
|
-
function
|
|
16150
|
+
function buildQuery4(input) {
|
|
16036
16151
|
const params = new URLSearchParams();
|
|
16037
16152
|
for (const [key, value] of Object.entries(input)) {
|
|
16038
16153
|
if (value !== void 0) {
|
|
@@ -16045,7 +16160,7 @@ function buildQuery3(input) {
|
|
|
16045
16160
|
async function expectChannelList(responsePromise) {
|
|
16046
16161
|
const response = await responsePromise;
|
|
16047
16162
|
if (response.status < 200 || response.status >= 300) {
|
|
16048
|
-
|
|
16163
|
+
parseApiError9(response.status, response.body);
|
|
16049
16164
|
}
|
|
16050
16165
|
const parsed = WeeklyReportChannelListResponseSchema.safeParse(response.body);
|
|
16051
16166
|
if (!parsed.success) {
|
|
@@ -16056,7 +16171,7 @@ async function expectChannelList(responsePromise) {
|
|
|
16056
16171
|
async function expectChannel(responsePromise) {
|
|
16057
16172
|
const response = await responsePromise;
|
|
16058
16173
|
if (response.status < 200 || response.status >= 300) {
|
|
16059
|
-
|
|
16174
|
+
parseApiError9(response.status, response.body);
|
|
16060
16175
|
}
|
|
16061
16176
|
const parsed = WeeklyReportChannelResponseSchema.safeParse(response.body);
|
|
16062
16177
|
if (!parsed.success) {
|
|
@@ -16070,13 +16185,13 @@ function createWeeklyReportApi(client) {
|
|
|
16070
16185
|
return expectChannelList(
|
|
16071
16186
|
client.request({
|
|
16072
16187
|
method: "GET",
|
|
16073
|
-
path: `/v1/weekly-report-channels${
|
|
16188
|
+
path: `/v1/weekly-report-channels${buildQuery4({ project_id: input.projectId, limit: input.limit })}`,
|
|
16074
16189
|
bearerToken: input.bearerToken
|
|
16075
16190
|
})
|
|
16076
16191
|
);
|
|
16077
16192
|
},
|
|
16078
16193
|
async createWeeklyReportChannel(input) {
|
|
16079
|
-
const config = input.channel === "email" ? { to: input.config.to } : { webhook_url: input.config.webhookUrl };
|
|
16194
|
+
const config = input.channel === "email" ? { to: input.config.to } : "webhookUrl" in input.config ? { webhook_url: input.config.webhookUrl } : { slack_destination_id: input.config.slackDestinationId };
|
|
16080
16195
|
return expectChannel(
|
|
16081
16196
|
client.request({
|
|
16082
16197
|
method: "POST",
|
|
@@ -16099,7 +16214,7 @@ function createWeeklyReportApi(client) {
|
|
|
16099
16214
|
async updateWeeklyReportChannel(input) {
|
|
16100
16215
|
const body = {};
|
|
16101
16216
|
if (input.config !== void 0) {
|
|
16102
|
-
body["config"] = "to" in input.config ? { to: input.config.to } : { webhook_url: input.config.webhookUrl };
|
|
16217
|
+
body["config"] = "to" in input.config ? { to: input.config.to } : "webhookUrl" in input.config ? { webhook_url: input.config.webhookUrl } : { slack_destination_id: input.config.slackDestinationId };
|
|
16103
16218
|
}
|
|
16104
16219
|
if (input.schedule !== void 0) {
|
|
16105
16220
|
body["schedule"] = {
|
|
@@ -16127,7 +16242,7 @@ function createWeeklyReportApi(client) {
|
|
|
16127
16242
|
bearerToken: input.bearerToken
|
|
16128
16243
|
});
|
|
16129
16244
|
if (response.status < 200 || response.status >= 300) {
|
|
16130
|
-
|
|
16245
|
+
parseApiError9(response.status, response.body);
|
|
16131
16246
|
}
|
|
16132
16247
|
return { channel_id: input.channelId };
|
|
16133
16248
|
}
|
|
@@ -16159,6 +16274,33 @@ var CaptureBreadcrumbsValues = ["local_only", "exception_only", "standalone"];
|
|
|
16159
16274
|
var CaptureBreadcrumbsSchema = external_exports.enum(CaptureBreadcrumbsValues);
|
|
16160
16275
|
var CaptureProbeEventsValues = ["buffer_only", "standalone_when_activated"];
|
|
16161
16276
|
var CaptureProbeEventsSchema = external_exports.enum(CaptureProbeEventsValues);
|
|
16277
|
+
var RequestSignalClassificationValues = ["incident_signal", "context_signal"];
|
|
16278
|
+
var RequestSignalClassificationSchema = external_exports.enum(RequestSignalClassificationValues);
|
|
16279
|
+
var RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES = [401, 403, 409, 422];
|
|
16280
|
+
var ImmediateClientErrorStatusSchema = external_exports.number().int().min(400).max(499);
|
|
16281
|
+
function normalizeImmediateClientErrorStatuses(statuses) {
|
|
16282
|
+
return Array.from(new Set(statuses)).sort((left, right) => left - right);
|
|
16283
|
+
}
|
|
16284
|
+
var ImmediateClientErrorStatusesSchema = external_exports.array(ImmediateClientErrorStatusSchema).max(12).transform((statuses) => normalizeImmediateClientErrorStatuses(statuses));
|
|
16285
|
+
var ResolvedCapturePolicySchema = external_exports.object({
|
|
16286
|
+
preset: CapturePresetSchema,
|
|
16287
|
+
capture_logs: CaptureLogsSchema,
|
|
16288
|
+
capture_request_events: CaptureRequestEventsSchema,
|
|
16289
|
+
capture_breadcrumbs: CaptureBreadcrumbsSchema,
|
|
16290
|
+
capture_probe_events: CaptureProbeEventsSchema,
|
|
16291
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema
|
|
16292
|
+
});
|
|
16293
|
+
var CapturePolicyOverridesSchema = external_exports.object({
|
|
16294
|
+
capture_logs: CaptureLogsSchema.nullable(),
|
|
16295
|
+
capture_request_events: CaptureRequestEventsSchema.nullable(),
|
|
16296
|
+
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable(),
|
|
16297
|
+
capture_probe_events: CaptureProbeEventsSchema.nullable(),
|
|
16298
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable()
|
|
16299
|
+
});
|
|
16300
|
+
var CapturePolicyResponseSchema = external_exports.object({
|
|
16301
|
+
policy: ResolvedCapturePolicySchema,
|
|
16302
|
+
overrides: CapturePolicyOverridesSchema
|
|
16303
|
+
});
|
|
16162
16304
|
var CapturePolicySchema = external_exports.object({
|
|
16163
16305
|
project_id: external_exports.string().uuid(),
|
|
16164
16306
|
preset: CapturePresetSchema,
|
|
@@ -16166,6 +16308,7 @@ var CapturePolicySchema = external_exports.object({
|
|
|
16166
16308
|
capture_request_events: CaptureRequestEventsSchema.nullable(),
|
|
16167
16309
|
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable(),
|
|
16168
16310
|
capture_probe_events: CaptureProbeEventsSchema.nullable(),
|
|
16311
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable(),
|
|
16169
16312
|
updated_at: external_exports.string().datetime()
|
|
16170
16313
|
});
|
|
16171
16314
|
var CapturePolicyUpdateSchema = external_exports.object({
|
|
@@ -16173,8 +16316,84 @@ var CapturePolicyUpdateSchema = external_exports.object({
|
|
|
16173
16316
|
capture_logs: CaptureLogsSchema.nullable().optional(),
|
|
16174
16317
|
capture_request_events: CaptureRequestEventsSchema.nullable().optional(),
|
|
16175
16318
|
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable().optional(),
|
|
16176
|
-
capture_probe_events: CaptureProbeEventsSchema.nullable().optional()
|
|
16319
|
+
capture_probe_events: CaptureProbeEventsSchema.nullable().optional(),
|
|
16320
|
+
immediate_client_error_statuses: ImmediateClientErrorStatusesSchema.nullable().optional()
|
|
16177
16321
|
});
|
|
16322
|
+
var PRESET_DEFAULTS = {
|
|
16323
|
+
minimal: {
|
|
16324
|
+
capture_logs: "error",
|
|
16325
|
+
capture_request_events: "failures_only",
|
|
16326
|
+
capture_breadcrumbs: "local_only",
|
|
16327
|
+
capture_probe_events: "buffer_only",
|
|
16328
|
+
immediate_client_error_statuses: []
|
|
16329
|
+
},
|
|
16330
|
+
balanced: {
|
|
16331
|
+
capture_logs: "warning",
|
|
16332
|
+
capture_request_events: "failures_only",
|
|
16333
|
+
capture_breadcrumbs: "exception_only",
|
|
16334
|
+
capture_probe_events: "buffer_only",
|
|
16335
|
+
immediate_client_error_statuses: []
|
|
16336
|
+
},
|
|
16337
|
+
investigative: {
|
|
16338
|
+
capture_logs: "info",
|
|
16339
|
+
capture_request_events: "all",
|
|
16340
|
+
capture_breadcrumbs: "standalone",
|
|
16341
|
+
capture_probe_events: "standalone_when_activated",
|
|
16342
|
+
immediate_client_error_statuses: [...RECOMMENDED_IMMEDIATE_CLIENT_ERROR_STATUSES]
|
|
16343
|
+
}
|
|
16344
|
+
};
|
|
16345
|
+
var BALANCED_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([408, 423, 424, 425, 429]);
|
|
16346
|
+
var INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([...BALANCED_IMMEDIATE_REQUEST_STATUSES, 409]);
|
|
16347
|
+
var BALANCED_STANDARD_ANOMALY_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 409, 422]);
|
|
16348
|
+
var BALANCED_HIGH_VOLUME_ANOMALY_STATUSES = /* @__PURE__ */ new Set([400, 410]);
|
|
16349
|
+
var INVESTIGATIVE_ANOMALY_STATUSES = /* @__PURE__ */ new Set([...BALANCED_STANDARD_ANOMALY_STATUSES, ...BALANCED_HIGH_VOLUME_ANOMALY_STATUSES]);
|
|
16350
|
+
function classifyRequestStatus(input) {
|
|
16351
|
+
const { responseStatus, capturePreset, immediateClientErrorStatuses = [] } = input;
|
|
16352
|
+
if (responseStatus === null || !Number.isFinite(responseStatus)) {
|
|
16353
|
+
return "context_signal";
|
|
16354
|
+
}
|
|
16355
|
+
if (responseStatus >= 500) {
|
|
16356
|
+
return "incident_signal";
|
|
16357
|
+
}
|
|
16358
|
+
if (immediateClientErrorStatuses.includes(responseStatus)) {
|
|
16359
|
+
return "incident_signal";
|
|
16360
|
+
}
|
|
16361
|
+
if (capturePreset === "investigative") {
|
|
16362
|
+
return INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES.has(responseStatus) ? "incident_signal" : "context_signal";
|
|
16363
|
+
}
|
|
16364
|
+
if (capturePreset === "balanced") {
|
|
16365
|
+
return BALANCED_IMMEDIATE_REQUEST_STATUSES.has(responseStatus) ? "incident_signal" : "context_signal";
|
|
16366
|
+
}
|
|
16367
|
+
return "context_signal";
|
|
16368
|
+
}
|
|
16369
|
+
function getRequestAnomalyThreshold(input) {
|
|
16370
|
+
const { responseStatus, capturePreset } = input;
|
|
16371
|
+
if (responseStatus === null || !Number.isFinite(responseStatus) || responseStatus < 400 || responseStatus >= 500) {
|
|
16372
|
+
return null;
|
|
16373
|
+
}
|
|
16374
|
+
if (capturePreset === "minimal") {
|
|
16375
|
+
return null;
|
|
16376
|
+
}
|
|
16377
|
+
if (capturePreset === "investigative") {
|
|
16378
|
+
return INVESTIGATIVE_ANOMALY_STATUSES.has(responseStatus) ? {
|
|
16379
|
+
minimum_occurrences_5m: 8,
|
|
16380
|
+
minimum_ratio_5m_to_1h: 2
|
|
16381
|
+
} : null;
|
|
16382
|
+
}
|
|
16383
|
+
if (BALANCED_STANDARD_ANOMALY_STATUSES.has(responseStatus)) {
|
|
16384
|
+
return {
|
|
16385
|
+
minimum_occurrences_5m: 20,
|
|
16386
|
+
minimum_ratio_5m_to_1h: 3
|
|
16387
|
+
};
|
|
16388
|
+
}
|
|
16389
|
+
if (BALANCED_HIGH_VOLUME_ANOMALY_STATUSES.has(responseStatus)) {
|
|
16390
|
+
return {
|
|
16391
|
+
minimum_occurrences_5m: 50,
|
|
16392
|
+
minimum_ratio_5m_to_1h: 5
|
|
16393
|
+
};
|
|
16394
|
+
}
|
|
16395
|
+
return null;
|
|
16396
|
+
}
|
|
16178
16397
|
|
|
16179
16398
|
// ../../packages/shared-types/src/index.ts
|
|
16180
16399
|
function createUuidV4() {
|
|
@@ -16783,7 +17002,7 @@ function buildCliReference() {
|
|
|
16783
17002
|
"- `debugbundle ingest <file> --format <format> [--json]`",
|
|
16784
17003
|
"- `debugbundle watch --log <file> --format <format> [--json]`",
|
|
16785
17004
|
"- `debugbundle watch --cloud --log <file> --format <format> [--json]`",
|
|
16786
|
-
"- `debugbundle process [--json]`",
|
|
17005
|
+
"- `debugbundle process [--preset <minimal|balanced|investigative>] [--json]`",
|
|
16787
17006
|
"",
|
|
16788
17007
|
"## Investigation",
|
|
16789
17008
|
"",
|
|
@@ -17392,16 +17611,6 @@ function createCliHttpClient(input, dependencies) {
|
|
|
17392
17611
|
}
|
|
17393
17612
|
|
|
17394
17613
|
// ../cli/src/capture-policy-commands.ts
|
|
17395
|
-
var ResolvedCapturePolicySchema = external_exports.object({
|
|
17396
|
-
preset: CapturePresetSchema,
|
|
17397
|
-
capture_logs: CaptureLogsSchema,
|
|
17398
|
-
capture_request_events: CaptureRequestEventsSchema,
|
|
17399
|
-
capture_breadcrumbs: CaptureBreadcrumbsSchema,
|
|
17400
|
-
capture_probe_events: CaptureProbeEventsSchema
|
|
17401
|
-
});
|
|
17402
|
-
var CapturePolicyResponseSchema = external_exports.object({
|
|
17403
|
-
policy: ResolvedCapturePolicySchema
|
|
17404
|
-
});
|
|
17405
17614
|
var CapturePolicyApiError = class extends Error {
|
|
17406
17615
|
status;
|
|
17407
17616
|
constructor(status, message) {
|
|
@@ -17431,7 +17640,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17431
17640
|
if (!parsed.success) {
|
|
17432
17641
|
throw new CapturePolicyApiError(500, "Invalid capture policy response.");
|
|
17433
17642
|
}
|
|
17434
|
-
return parsed.data
|
|
17643
|
+
return parsed.data;
|
|
17435
17644
|
},
|
|
17436
17645
|
async updateCapturePolicy(input) {
|
|
17437
17646
|
const response = await httpClient.request({
|
|
@@ -17447,7 +17656,7 @@ function createCapturePolicyApi(httpClient) {
|
|
|
17447
17656
|
if (!parsed.success) {
|
|
17448
17657
|
throw new CapturePolicyApiError(500, "Invalid capture policy response.");
|
|
17449
17658
|
}
|
|
17450
|
-
return parsed.data
|
|
17659
|
+
return parsed.data;
|
|
17451
17660
|
}
|
|
17452
17661
|
};
|
|
17453
17662
|
}
|
|
@@ -17875,7 +18084,7 @@ function getRequestResponseStatus(payload) {
|
|
|
17875
18084
|
const status = payload?.["response_status"];
|
|
17876
18085
|
return typeof status === "number" && Number.isFinite(status) ? status : null;
|
|
17877
18086
|
}
|
|
17878
|
-
function classifyEvent(eventType, logLevel, probeActivationId, payload) {
|
|
18087
|
+
function classifyEvent(eventType, logLevel, probeActivationId, payload, capturePreset = "minimal", immediateClientErrorStatuses = []) {
|
|
17879
18088
|
switch (eventType) {
|
|
17880
18089
|
case "backend_exception":
|
|
17881
18090
|
case "frontend_exception":
|
|
@@ -17887,10 +18096,7 @@ function classifyEvent(eventType, logLevel, probeActivationId, payload) {
|
|
|
17887
18096
|
return "context_signal";
|
|
17888
18097
|
case "request_event": {
|
|
17889
18098
|
const responseStatus = getRequestResponseStatus(payload);
|
|
17890
|
-
|
|
17891
|
-
return "incident_signal";
|
|
17892
|
-
}
|
|
17893
|
-
return "context_signal";
|
|
18099
|
+
return classifyRequestStatus({ responseStatus, capturePreset, immediateClientErrorStatuses });
|
|
17894
18100
|
}
|
|
17895
18101
|
case "frontend_breadcrumb":
|
|
17896
18102
|
case "deploy_metadata":
|
|
@@ -18052,7 +18258,7 @@ function buildPrivacyPreview() {
|
|
|
18052
18258
|
sample_event_type: sampleEvent.event_type,
|
|
18053
18259
|
sample_event_class: sampleEventClass,
|
|
18054
18260
|
sample_can_create_incident: sampleEventClass === "incident_signal",
|
|
18055
|
-
incident_rule: "request_event
|
|
18261
|
+
incident_rule: "request_event incident classification follows the resolved capture preset: 5xx always create incidents, balanced also promotes 408/423/424/425/429, and investigative also promotes 409.",
|
|
18056
18262
|
redacted_fields,
|
|
18057
18263
|
omitted_fields: [],
|
|
18058
18264
|
retained_metadata: {
|
|
@@ -18563,7 +18769,8 @@ function buildRedactionRecord(bundleBody) {
|
|
|
18563
18769
|
function buildVisibilityRecord(input) {
|
|
18564
18770
|
const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
|
|
18565
18771
|
const matchedFields = input.incident.matched_fields.length === 0 ? "none" : input.incident.matched_fields.join(", ");
|
|
18566
|
-
const
|
|
18772
|
+
const isRequestAnomaly = input.incident.matched_fields.includes("request_anomaly");
|
|
18773
|
+
const grouping = input.primarySignal.kind === "request_failure" && input.primarySignal.request_method !== null && routeTarget !== null ? isRequestAnomaly ? `Repeated request-anomaly incidents with the same normalized route template, request method, response status, service, and environment reuse this incident fingerprint once the anomaly threshold fires. This incident currently groups ${input.primarySignal.request_method} ${routeTarget} with matched fields ${matchedFields}.` : `Repeated request-failure incidents with the same normalized route template, request method, response status, service, and environment reuse this incident fingerprint. This incident currently groups ${input.primarySignal.request_method} ${routeTarget} with matched fields ${matchedFields}.` : `This incident groups repeated failures by fingerprint version ${input.incident.fingerprint_version} inside the service and environment boundary, with matched fields ${matchedFields}.`;
|
|
18567
18774
|
const spikeLead = input.incident.spike_detected_at === void 0 || input.incident.spike_detected_at === null ? "This incident is not currently marked as spiking." : `This incident was marked as spiking at ${input.incident.spike_detected_at}.`;
|
|
18568
18775
|
return {
|
|
18569
18776
|
grouping,
|
|
@@ -18574,15 +18781,16 @@ function buildVisibilityRecord(input) {
|
|
|
18574
18781
|
}
|
|
18575
18782
|
function buildSuggestedNextChecks(input) {
|
|
18576
18783
|
const suggestions = [];
|
|
18784
|
+
const isRequestAnomaly = input.incident.matched_fields.includes("request_anomaly");
|
|
18577
18785
|
if (input.bundle.status === "pending") {
|
|
18578
18786
|
suggestions.push("Wait for bundle generation to finish, then rerun the incident context command.");
|
|
18579
18787
|
} else if (input.bundle.status === "failed") {
|
|
18580
18788
|
suggestions.push("Inspect bundle generation status or retry bundle retrieval to recover missing context.");
|
|
18581
18789
|
}
|
|
18582
18790
|
const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
|
|
18583
|
-
if (input.primarySignal.
|
|
18791
|
+
if (input.primarySignal.kind === "request_failure" && input.primarySignal.request_method !== null && routeTarget !== null) {
|
|
18584
18792
|
suggestions.push(
|
|
18585
|
-
`Inspect the ${input.primarySignal.request_method} ${routeTarget
|
|
18793
|
+
isRequestAnomaly ? `Inspect the ${input.primarySignal.request_method} ${routeTarget} handler behind this repeated request-anomaly path.` : `Inspect the ${input.primarySignal.request_method} ${routeTarget} handler behind this request-failure path.`
|
|
18586
18794
|
);
|
|
18587
18795
|
}
|
|
18588
18796
|
const firstApplicationFrame = input.primarySignal.first_application_frame;
|
|
@@ -18671,12 +18879,13 @@ function deriveIncidentReasonFromSignal(input) {
|
|
|
18671
18879
|
};
|
|
18672
18880
|
case "request_event": {
|
|
18673
18881
|
const responseStatus = typeof input.response_status === "number" && Number.isFinite(input.response_status) ? input.response_status : null;
|
|
18882
|
+
const isRequestAnomaly = input.request_anomaly === true;
|
|
18674
18883
|
return {
|
|
18675
|
-
kind: "
|
|
18676
|
-
description: responseStatus !== null
|
|
18884
|
+
kind: "request_failure",
|
|
18885
|
+
description: isRequestAnomaly ? responseStatus !== null ? `request_event response_status=${responseStatus} crossed the repeated request anomaly threshold` : "request_event crossed the repeated request anomaly threshold" : responseStatus !== null ? `request_event response_status=${responseStatus} matched the immediate request failure incident rule` : "request_event matched the immediate request failure incident rule",
|
|
18677
18886
|
event_type: "request_event",
|
|
18678
18887
|
event_class: "incident_signal",
|
|
18679
|
-
matched_policy: "
|
|
18888
|
+
matched_policy: isRequestAnomaly ? "Repeated contextual request failures crossed the request anomaly threshold" : "Immediate request failure statuses bypass capture_request_events suppression"
|
|
18680
18889
|
};
|
|
18681
18890
|
}
|
|
18682
18891
|
case "log_event": {
|
|
@@ -18779,6 +18988,46 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
18779
18988
|
ON github_device_authorizations (expires_at)
|
|
18780
18989
|
`
|
|
18781
18990
|
]
|
|
18991
|
+
}),
|
|
18992
|
+
defineStorageSchemaMigration({
|
|
18993
|
+
id: "202605130001_allow_synthetic_webhook_test_deliveries_without_incident_fk",
|
|
18994
|
+
description: "Allow webhook test deliveries to persist without requiring a backing incidents row.",
|
|
18995
|
+
statements: [
|
|
18996
|
+
"ALTER TABLE webhook_deliveries ALTER COLUMN incident_id DROP NOT NULL"
|
|
18997
|
+
]
|
|
18998
|
+
}),
|
|
18999
|
+
defineStorageSchemaMigration({
|
|
19000
|
+
id: "202605130002_add_slack_destinations",
|
|
19001
|
+
description: "Add reusable encrypted Slack alert destinations scoped to organizations.",
|
|
19002
|
+
statements: [
|
|
19003
|
+
`
|
|
19004
|
+
CREATE TABLE IF NOT EXISTS slack_destinations (
|
|
19005
|
+
id uuid PRIMARY KEY,
|
|
19006
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
19007
|
+
slack_team_id text NOT NULL,
|
|
19008
|
+
slack_team_name text,
|
|
19009
|
+
slack_channel_id text NOT NULL,
|
|
19010
|
+
slack_channel_name text,
|
|
19011
|
+
webhook_url_ciphertext text NOT NULL,
|
|
19012
|
+
installed_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
19013
|
+
is_active boolean NOT NULL DEFAULT true,
|
|
19014
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
19015
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
19016
|
+
UNIQUE (organization_id, slack_team_id, slack_channel_id)
|
|
19017
|
+
)
|
|
19018
|
+
`,
|
|
19019
|
+
`
|
|
19020
|
+
CREATE INDEX IF NOT EXISTS slack_destinations_org_active_idx
|
|
19021
|
+
ON slack_destinations (organization_id, is_active, created_at)
|
|
19022
|
+
`
|
|
19023
|
+
]
|
|
19024
|
+
}),
|
|
19025
|
+
defineStorageSchemaMigration({
|
|
19026
|
+
id: "202605140001_add_capture_policy_immediate_client_error_statuses",
|
|
19027
|
+
description: "Add nullable immediate client error status overrides to capture policies.",
|
|
19028
|
+
statements: [
|
|
19029
|
+
"ALTER TABLE capture_policies ADD COLUMN IF NOT EXISTS immediate_client_error_statuses jsonb"
|
|
19030
|
+
]
|
|
18782
19031
|
})
|
|
18783
19032
|
];
|
|
18784
19033
|
|
|
@@ -19799,11 +20048,17 @@ var EVENT_TYPE_SET = new Set(EventTypeValues);
|
|
|
19799
20048
|
function isEventType(value) {
|
|
19800
20049
|
return typeof value === "string" && EVENT_TYPE_SET.has(value);
|
|
19801
20050
|
}
|
|
19802
|
-
function inferSeverity2(
|
|
19803
|
-
if (
|
|
20051
|
+
function inferSeverity2(event, capturePreset, incidentKind = "immediate") {
|
|
20052
|
+
if (incidentKind === "request_anomaly") {
|
|
20053
|
+
return "medium";
|
|
20054
|
+
}
|
|
20055
|
+
if (event.event_type === "request_event") {
|
|
20056
|
+
return classifyRequestStatus({ responseStatus: event.payload.response_status, capturePreset }) === "incident_signal" ? "high" : "low";
|
|
20057
|
+
}
|
|
20058
|
+
if (event.event_type === "backend_exception" || event.event_type === "frontend_exception") {
|
|
19804
20059
|
return "high";
|
|
19805
20060
|
}
|
|
19806
|
-
if (
|
|
20061
|
+
if (event.event_type === "error_suppressed") {
|
|
19807
20062
|
return "medium";
|
|
19808
20063
|
}
|
|
19809
20064
|
return "low";
|
|
@@ -19827,15 +20082,17 @@ function compareEventEnvelopes(left, right) {
|
|
|
19827
20082
|
}
|
|
19828
20083
|
return left.event_id.localeCompare(right.event_id);
|
|
19829
20084
|
}
|
|
19830
|
-
function classifyEnvelope(envelope) {
|
|
20085
|
+
function classifyEnvelope(envelope, capturePreset) {
|
|
19831
20086
|
return classifyEvent(
|
|
19832
20087
|
envelope.event_type,
|
|
19833
20088
|
envelope.event_type === "log_event" ? envelope.payload.level : void 0,
|
|
19834
|
-
envelope.event_type === "probe_event" ? envelope.payload.activation_id : void 0
|
|
20089
|
+
envelope.event_type === "probe_event" ? envelope.payload.activation_id : void 0,
|
|
20090
|
+
envelope.payload,
|
|
20091
|
+
capturePreset
|
|
19835
20092
|
);
|
|
19836
20093
|
}
|
|
19837
|
-
function isIncidentSignalEnvelope(envelope) {
|
|
19838
|
-
return classifyEnvelope(envelope) === "incident_signal";
|
|
20094
|
+
function isIncidentSignalEnvelope(envelope, capturePreset) {
|
|
20095
|
+
return classifyEnvelope(envelope, capturePreset) === "incident_signal";
|
|
19839
20096
|
}
|
|
19840
20097
|
function getTraceId(envelope) {
|
|
19841
20098
|
return envelope.correlation?.trace_id ?? null;
|
|
@@ -19880,7 +20137,10 @@ function mergeAggregateGroup(aggregates) {
|
|
|
19880
20137
|
newEvents: [...canonicalAggregate.newEvents],
|
|
19881
20138
|
mergedIncidentIds: new Set(canonicalAggregate.mergedIncidentIds),
|
|
19882
20139
|
signalEventTypes: new Set(canonicalAggregate.signalEventTypes),
|
|
19883
|
-
traceIds: new Set(canonicalAggregate.traceIds)
|
|
20140
|
+
traceIds: new Set(canonicalAggregate.traceIds),
|
|
20141
|
+
title: canonicalAggregate.title,
|
|
20142
|
+
kind: canonicalAggregate.kind,
|
|
20143
|
+
severity: canonicalAggregate.severity
|
|
19884
20144
|
});
|
|
19885
20145
|
}
|
|
19886
20146
|
function hashIdentifier(parts, prefix, length) {
|
|
@@ -19906,6 +20166,111 @@ function mergeSourceEvents(existingEvents, nextEvents) {
|
|
|
19906
20166
|
}
|
|
19907
20167
|
return [...merged.values()].sort(compareEventEnvelopes);
|
|
19908
20168
|
}
|
|
20169
|
+
function stableJson2(value) {
|
|
20170
|
+
if (value === null || typeof value !== "object") {
|
|
20171
|
+
return JSON.stringify(value);
|
|
20172
|
+
}
|
|
20173
|
+
if (Array.isArray(value)) {
|
|
20174
|
+
return `[${value.map((entry) => stableJson2(entry)).join(",")}]`;
|
|
20175
|
+
}
|
|
20176
|
+
const record = value;
|
|
20177
|
+
const keys = Object.keys(record).sort();
|
|
20178
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson2(record[key])}`).join(",")}}`;
|
|
20179
|
+
}
|
|
20180
|
+
function buildRequestAnomalyFingerprint(input) {
|
|
20181
|
+
return (0, import_node_crypto4.createHash)("sha256").update(
|
|
20182
|
+
stableJson2({
|
|
20183
|
+
kind: "request_status_anomaly",
|
|
20184
|
+
project_id: input.projectId,
|
|
20185
|
+
service_name: input.serviceName,
|
|
20186
|
+
environment: input.environment,
|
|
20187
|
+
method: input.method,
|
|
20188
|
+
route_template: input.routeTemplate,
|
|
20189
|
+
response_status: input.responseStatus
|
|
20190
|
+
})
|
|
20191
|
+
).digest("hex");
|
|
20192
|
+
}
|
|
20193
|
+
function buildRequestAnomalyTitle(input) {
|
|
20194
|
+
return `Request anomaly: ${input.method} ${input.routeTemplate} returned ${input.responseStatus} repeatedly`;
|
|
20195
|
+
}
|
|
20196
|
+
function toUnixSeconds(occurredAt) {
|
|
20197
|
+
return Math.floor(new Date(occurredAt).getTime() / 1e3);
|
|
20198
|
+
}
|
|
20199
|
+
function countOccurrencesInWindow(events, windowSeconds) {
|
|
20200
|
+
const latestEvent = events.at(-1);
|
|
20201
|
+
if (latestEvent === void 0) {
|
|
20202
|
+
return 0;
|
|
20203
|
+
}
|
|
20204
|
+
const latestOccurredAt = toUnixSeconds(latestEvent.occurred_at);
|
|
20205
|
+
const lowerBound = latestOccurredAt - windowSeconds + 1;
|
|
20206
|
+
return events.filter((event) => {
|
|
20207
|
+
const occurredAt = toUnixSeconds(event.occurred_at);
|
|
20208
|
+
return occurredAt >= lowerBound && occurredAt <= latestOccurredAt;
|
|
20209
|
+
}).length;
|
|
20210
|
+
}
|
|
20211
|
+
function passesRequestAnomalyThreshold(events, threshold) {
|
|
20212
|
+
const occurrences5m = countOccurrencesInWindow(events, 5 * 60);
|
|
20213
|
+
const occurrences1h = countOccurrencesInWindow(events, 60 * 60);
|
|
20214
|
+
const baseline1hPer5m = occurrences1h / 12;
|
|
20215
|
+
const ratio = occurrences5m / Math.max(baseline1hPer5m, 1);
|
|
20216
|
+
return occurrences5m >= threshold.minimum_occurrences_5m && ratio >= threshold.minimum_ratio_5m_to_1h;
|
|
20217
|
+
}
|
|
20218
|
+
function collectRequestAnomalyAggregates(batches, capturePreset) {
|
|
20219
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
20220
|
+
for (const batch of batches) {
|
|
20221
|
+
for (const event of batch.events) {
|
|
20222
|
+
if (event.event_type !== "request_event" || classifyEnvelope(event, capturePreset) !== "context_signal") {
|
|
20223
|
+
continue;
|
|
20224
|
+
}
|
|
20225
|
+
const normalizedEvent = normalizeEvent(event);
|
|
20226
|
+
const responseStatus = normalizedEvent.http_status;
|
|
20227
|
+
const method = normalizedEvent.http_method;
|
|
20228
|
+
const routeTemplate = normalizedEvent.route_template;
|
|
20229
|
+
const threshold = getRequestAnomalyThreshold({ responseStatus, capturePreset });
|
|
20230
|
+
if (threshold === null || responseStatus === null || method === null || routeTemplate === null) {
|
|
20231
|
+
continue;
|
|
20232
|
+
}
|
|
20233
|
+
const projectId = requireProjectId(event);
|
|
20234
|
+
const incidentFingerprint = buildRequestAnomalyFingerprint({
|
|
20235
|
+
projectId,
|
|
20236
|
+
serviceName: event.service.name,
|
|
20237
|
+
environment: event.service.environment,
|
|
20238
|
+
method,
|
|
20239
|
+
routeTemplate,
|
|
20240
|
+
responseStatus
|
|
20241
|
+
});
|
|
20242
|
+
const incidentId = deriveIncidentId(projectId, event.service.name, event.service.environment, incidentFingerprint);
|
|
20243
|
+
const aggregate = grouped.get(incidentId) ?? {
|
|
20244
|
+
incidentId,
|
|
20245
|
+
projectId,
|
|
20246
|
+
serviceName: event.service.name,
|
|
20247
|
+
environment: event.service.environment,
|
|
20248
|
+
fingerprint: incidentFingerprint,
|
|
20249
|
+
matchedFields: /* @__PURE__ */ new Set(["request_anomaly", "route_template", "http_method", "http_status", "environment"]),
|
|
20250
|
+
newEvents: [],
|
|
20251
|
+
mergedIncidentIds: /* @__PURE__ */ new Set([incidentId]),
|
|
20252
|
+
signalEventTypes: /* @__PURE__ */ new Set(["request_event"]),
|
|
20253
|
+
traceIds: /* @__PURE__ */ new Set(),
|
|
20254
|
+
title: buildRequestAnomalyTitle({ method, routeTemplate, responseStatus }),
|
|
20255
|
+
kind: "request_anomaly",
|
|
20256
|
+
severity: "medium"
|
|
20257
|
+
};
|
|
20258
|
+
aggregate.newEvents.push(event);
|
|
20259
|
+
grouped.set(incidentId, aggregate);
|
|
20260
|
+
}
|
|
20261
|
+
}
|
|
20262
|
+
return [...grouped.values()].filter((aggregate) => {
|
|
20263
|
+
const latestEvent = aggregate.newEvents.at(-1);
|
|
20264
|
+
if (latestEvent === void 0 || latestEvent.event_type !== "request_event") {
|
|
20265
|
+
return false;
|
|
20266
|
+
}
|
|
20267
|
+
const threshold = getRequestAnomalyThreshold({
|
|
20268
|
+
responseStatus: normalizeEvent(latestEvent).http_status,
|
|
20269
|
+
capturePreset
|
|
20270
|
+
});
|
|
20271
|
+
return threshold !== null && passesRequestAnomalyThreshold(aggregate.newEvents, threshold);
|
|
20272
|
+
}).sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20273
|
+
}
|
|
19909
20274
|
function buildBundleContext(incident) {
|
|
19910
20275
|
return {
|
|
19911
20276
|
incident_id: incident.incident_id,
|
|
@@ -19935,12 +20300,12 @@ function formatServiceSummary(services) {
|
|
|
19935
20300
|
}
|
|
19936
20301
|
function formatProcessOutput(summary) {
|
|
19937
20302
|
if (!summary.processed) {
|
|
19938
|
-
return summary.message
|
|
20303
|
+
return summary.message;
|
|
19939
20304
|
}
|
|
19940
20305
|
return [
|
|
19941
20306
|
`Processed ${summary.events_processed} events from ${summary.files_processed} files into ${summary.incidents_processed} incidents.`,
|
|
19942
20307
|
...formatServiceSummary(summary.services),
|
|
19943
|
-
`Last processed event file: ${summary.last_processed_event_file
|
|
20308
|
+
`Last processed event file: ${summary.last_processed_event_file}`
|
|
19944
20309
|
].join("\n");
|
|
19945
20310
|
}
|
|
19946
20311
|
async function pathExists4(path, stat) {
|
|
@@ -20180,6 +20545,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20180
20545
|
const statePath = (0, import_node_path6.join)(rootDirectory, LOCAL_STATE_FILE_PATH);
|
|
20181
20546
|
const bundleDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_BUNDLE_DIRECTORY_PATH2);
|
|
20182
20547
|
const reproductionDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_REPRODUCTION_DIRECTORY_PATH);
|
|
20548
|
+
const capturePreset = input.preset ?? "minimal";
|
|
20183
20549
|
await mkdir((0, import_node_path6.join)(rootDirectory, ".debugbundle", "local"), { recursive: true });
|
|
20184
20550
|
await mkdir(bundleDirectoryPath, { recursive: true });
|
|
20185
20551
|
await mkdir(reproductionDirectoryPath, { recursive: true });
|
|
@@ -20187,22 +20553,26 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20187
20553
|
const eventFileNames = await pathExists4(eventsDirectoryPath, stat) ? (await readdir(eventsDirectoryPath)).filter((fileName) => fileName.endsWith(".events.json")).sort() : [];
|
|
20188
20554
|
const lastProcessedEventFile = previousState?.last_processed_event_file ?? null;
|
|
20189
20555
|
const newEventFileNames = lastProcessedEventFile === null ? eventFileNames : eventFileNames.filter((fileName) => fileName > lastProcessedEventFile);
|
|
20190
|
-
|
|
20556
|
+
const processAllEventFiles = input.preset !== void 0;
|
|
20557
|
+
const targetEventFileNames = processAllEventFiles ? eventFileNames : newEventFileNames;
|
|
20558
|
+
if (targetEventFileNames.length === 0) {
|
|
20191
20559
|
const summary2 = buildNoNewEventsSummary(previousState?.last_processed_event_file ?? eventFileNames.at(-1) ?? null);
|
|
20192
20560
|
return {
|
|
20193
20561
|
exitCode: 0,
|
|
20194
20562
|
output: input.json === true ? JSON.stringify(summary2) : formatProcessOutput(summary2)
|
|
20195
20563
|
};
|
|
20196
20564
|
}
|
|
20197
|
-
const batches = await readEventBatches(eventsDirectoryPath,
|
|
20198
|
-
const incidents = new Map(
|
|
20565
|
+
const batches = await readEventBatches(eventsDirectoryPath, targetEventFileNames, readFile);
|
|
20566
|
+
const incidents = new Map(
|
|
20567
|
+
processAllEventFiles ? [] : Object.entries(previousState?.incidents ?? {})
|
|
20568
|
+
);
|
|
20199
20569
|
const aggregates = /* @__PURE__ */ new Map();
|
|
20200
20570
|
const traceCorrelationGroups = /* @__PURE__ */ new Map();
|
|
20201
20571
|
let eventsProcessed = 0;
|
|
20202
20572
|
for (const batch of batches) {
|
|
20203
20573
|
for (const event of batch.events) {
|
|
20204
20574
|
eventsProcessed += 1;
|
|
20205
|
-
if (!isIncidentSignalEnvelope(event)) {
|
|
20575
|
+
if (!isIncidentSignalEnvelope(event, capturePreset)) {
|
|
20206
20576
|
continue;
|
|
20207
20577
|
}
|
|
20208
20578
|
const normalizedEvent = normalizeEvent(event);
|
|
@@ -20219,7 +20589,10 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20219
20589
|
newEvents: [],
|
|
20220
20590
|
mergedIncidentIds: /* @__PURE__ */ new Set([incidentId]),
|
|
20221
20591
|
signalEventTypes: /* @__PURE__ */ new Set(),
|
|
20222
|
-
traceIds: /* @__PURE__ */ new Set()
|
|
20592
|
+
traceIds: /* @__PURE__ */ new Set(),
|
|
20593
|
+
title: normalizedEvent.normalized_message,
|
|
20594
|
+
kind: "immediate",
|
|
20595
|
+
severity: inferSeverity2(event, capturePreset)
|
|
20223
20596
|
};
|
|
20224
20597
|
for (const matchedField of inferMatchedFields(normalizedEvent)) {
|
|
20225
20598
|
aggregate.matchedFields.add(matchedField);
|
|
@@ -20286,14 +20659,16 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20286
20659
|
mergedAggregatesByRoot.set(rootIncidentId, aggregateGroup);
|
|
20287
20660
|
}
|
|
20288
20661
|
const mergedAggregates = [...mergedAggregatesByRoot.values()].map((aggregateGroup) => mergeAggregateGroup(aggregateGroup)).sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20662
|
+
const requestAnomalyAggregates = input.preset === void 0 ? [] : collectRequestAnomalyAggregates(batches, capturePreset);
|
|
20663
|
+
const finalizedAggregates = [...mergedAggregates, ...requestAnomalyAggregates].sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20289
20664
|
const services = /* @__PURE__ */ new Map();
|
|
20290
|
-
for (const aggregate of
|
|
20665
|
+
for (const aggregate of finalizedAggregates) {
|
|
20291
20666
|
const incidentId = aggregate.incidentId;
|
|
20292
20667
|
const existingIncidents = [...aggregate.mergedIncidentIds].map((mergedIncidentId) => incidents.get(mergedIncidentId)).filter((incident2) => incident2 !== void 0);
|
|
20293
20668
|
const existing = existingIncidents.find((incident2) => incident2.incident_id === incidentId) ?? existingIncidents[0];
|
|
20294
20669
|
const existingSourceEvents = existingIncidents.flatMap((incident2) => incident2.source_events);
|
|
20295
20670
|
const combinedSourceEvents = mergeSourceEvents(existingSourceEvents, aggregate.newEvents);
|
|
20296
|
-
const signalEvents = combinedSourceEvents.filter(isIncidentSignalEnvelope);
|
|
20671
|
+
const signalEvents = aggregate.kind === "request_anomaly" ? combinedSourceEvents : combinedSourceEvents.filter((event) => isIncidentSignalEnvelope(event, capturePreset));
|
|
20297
20672
|
if (signalEvents.length === 0) {
|
|
20298
20673
|
continue;
|
|
20299
20674
|
}
|
|
@@ -20303,8 +20678,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20303
20678
|
continue;
|
|
20304
20679
|
}
|
|
20305
20680
|
const sourceEventTypes = [...new Set(signalEvents.map((event) => event.event_type))].sort();
|
|
20306
|
-
const severity = signalEvents.map((event) => inferSeverity2(event.
|
|
20307
|
-
const latestNormalizedEvent = normalizeEvent(latestSignalEvent);
|
|
20681
|
+
const severity = signalEvents.map((event) => inferSeverity2(event, capturePreset, aggregate.kind)).sort((left, right) => severityRank(right) - severityRank(left))[0] ?? aggregate.severity;
|
|
20308
20682
|
const generationNumber = signalEvents.length;
|
|
20309
20683
|
const bundlePath = `${LOCAL_BUNDLE_DIRECTORY_PATH2}/${incidentId}.bundle.json`;
|
|
20310
20684
|
const reproductionPath = `${LOCAL_REPRODUCTION_DIRECTORY_PATH}/${incidentId}.reproduction.json`;
|
|
@@ -20319,7 +20693,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20319
20693
|
environment: aggregate.environment,
|
|
20320
20694
|
fingerprint: aggregate.fingerprint,
|
|
20321
20695
|
fingerprint_version: FINGERPRINT_VERSION,
|
|
20322
|
-
title:
|
|
20696
|
+
title: aggregate.title,
|
|
20323
20697
|
severity,
|
|
20324
20698
|
status: existingIncidents.some((incidentState) => incidentState.status === "resolved") ? "open" : existing?.status ?? "open",
|
|
20325
20699
|
first_seen_at: firstSignalEvent.occurred_at,
|
|
@@ -20380,21 +20754,22 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20380
20754
|
incidents.set(incidentId, incident);
|
|
20381
20755
|
services.set(incident.service_name, (services.get(incident.service_name) ?? 0) + 1);
|
|
20382
20756
|
}
|
|
20757
|
+
const finalProcessedEventFile = targetEventFileNames[targetEventFileNames.length - 1];
|
|
20383
20758
|
const nextState = {
|
|
20384
20759
|
version: 1,
|
|
20385
|
-
last_processed_event_file:
|
|
20760
|
+
last_processed_event_file: finalProcessedEventFile,
|
|
20386
20761
|
incidents: Object.fromEntries([...incidents.entries()].sort(([left], [right]) => left.localeCompare(right)))
|
|
20387
20762
|
};
|
|
20388
20763
|
await writeFile(statePath, serializeState(nextState));
|
|
20389
20764
|
const summary = buildProcessedSummary({
|
|
20390
20765
|
filesProcessed: newEventFileNames.length,
|
|
20391
20766
|
eventsProcessed,
|
|
20392
|
-
incidentsProcessed:
|
|
20767
|
+
incidentsProcessed: finalizedAggregates.length,
|
|
20393
20768
|
services: [...services.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([service, count]) => ({
|
|
20394
20769
|
service,
|
|
20395
20770
|
incidents: count
|
|
20396
20771
|
})),
|
|
20397
|
-
lastProcessedEventFile:
|
|
20772
|
+
lastProcessedEventFile: finalProcessedEventFile
|
|
20398
20773
|
});
|
|
20399
20774
|
return {
|
|
20400
20775
|
exitCode: 0,
|
|
@@ -20510,7 +20885,11 @@ function parseLocalIncident(candidate) {
|
|
|
20510
20885
|
}
|
|
20511
20886
|
const serviceRuntime = candidate["service_runtime"];
|
|
20512
20887
|
const serviceFramework = candidate["service_framework"];
|
|
20513
|
-
const incidentReason =
|
|
20888
|
+
const incidentReason = candidate["matched_fields"].includes("request_anomaly") ? deriveIncidentReasonFromSignal({
|
|
20889
|
+
event_type: "request_event",
|
|
20890
|
+
event_class: "incident_signal",
|
|
20891
|
+
request_anomaly: true
|
|
20892
|
+
}) : deriveIncidentReasonFromSourceEventTypes(candidate["source_event_types"]);
|
|
20514
20893
|
if (serviceRuntime !== null && typeof serviceRuntime !== "string") {
|
|
20515
20894
|
throw createReadError(400, "invalid_local_state");
|
|
20516
20895
|
}
|
|
@@ -20816,14 +21195,14 @@ function localFailureStepName(checks) {
|
|
|
20816
21195
|
function cloudVerificationRunId(now) {
|
|
20817
21196
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
20818
21197
|
}
|
|
20819
|
-
function
|
|
21198
|
+
function requestFailureReason() {
|
|
20820
21199
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
20821
21200
|
event_type: "request_event",
|
|
20822
21201
|
event_class: "incident_signal",
|
|
20823
21202
|
response_status: 503
|
|
20824
21203
|
});
|
|
20825
21204
|
if (incidentReason === null) {
|
|
20826
|
-
throw new Error("
|
|
21205
|
+
throw new Error("request_failure_reason_unavailable");
|
|
20827
21206
|
}
|
|
20828
21207
|
return incidentReason;
|
|
20829
21208
|
}
|
|
@@ -21098,7 +21477,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21098
21477
|
const verification = {
|
|
21099
21478
|
mode: "active_5xx",
|
|
21100
21479
|
bundle_status: "unknown",
|
|
21101
|
-
classification_reason:
|
|
21480
|
+
classification_reason: requestFailureReason()
|
|
21102
21481
|
};
|
|
21103
21482
|
const errors = [];
|
|
21104
21483
|
let exitCode = 0;
|
|
@@ -21150,7 +21529,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21150
21529
|
if (candidate !== void 0) {
|
|
21151
21530
|
incidentId = candidate.incident_id;
|
|
21152
21531
|
verification.incident_id = candidate.incident_id;
|
|
21153
|
-
verification.classification_reason = candidate.incident_reason ??
|
|
21532
|
+
verification.classification_reason = candidate.incident_reason ?? requestFailureReason();
|
|
21154
21533
|
break;
|
|
21155
21534
|
}
|
|
21156
21535
|
if (attempt < pollAttempts) {
|
|
@@ -21813,12 +22192,10 @@ function createCapturePolicyMcpTools(api) {
|
|
|
21813
22192
|
return {
|
|
21814
22193
|
async get_capture_policy(input) {
|
|
21815
22194
|
try {
|
|
21816
|
-
return {
|
|
21817
|
-
|
|
21818
|
-
|
|
21819
|
-
|
|
21820
|
-
})
|
|
21821
|
-
};
|
|
22195
|
+
return await api.getCapturePolicy({
|
|
22196
|
+
bearerToken: String(input["bearerToken"]),
|
|
22197
|
+
projectId: String(input["projectId"])
|
|
22198
|
+
});
|
|
21822
22199
|
} catch (error) {
|
|
21823
22200
|
mapMcpError4(error);
|
|
21824
22201
|
}
|
|
@@ -21826,13 +22203,11 @@ function createCapturePolicyMcpTools(api) {
|
|
|
21826
22203
|
async update_capture_policy(input) {
|
|
21827
22204
|
try {
|
|
21828
22205
|
const update = typeof input["update"] === "object" && input["update"] !== null ? input["update"] : {};
|
|
21829
|
-
return {
|
|
21830
|
-
|
|
21831
|
-
|
|
21832
|
-
|
|
21833
|
-
|
|
21834
|
-
})
|
|
21835
|
-
};
|
|
22206
|
+
return await api.updateCapturePolicy({
|
|
22207
|
+
bearerToken: String(input["bearerToken"]),
|
|
22208
|
+
projectId: String(input["projectId"]),
|
|
22209
|
+
update
|
|
22210
|
+
});
|
|
21836
22211
|
} catch (error) {
|
|
21837
22212
|
mapMcpError4(error);
|
|
21838
22213
|
}
|
|
@@ -22927,8 +23302,71 @@ function createSetupMcpTools(commands) {
|
|
|
22927
23302
|
};
|
|
22928
23303
|
}
|
|
22929
23304
|
|
|
22930
|
-
// src/
|
|
23305
|
+
// src/slack-tools.ts
|
|
22931
23306
|
function mapMcpError12(error) {
|
|
23307
|
+
if (error instanceof SlackApiError) {
|
|
23308
|
+
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23309
|
+
}
|
|
23310
|
+
throw new Error("mcp_tool_error:unknown_error");
|
|
23311
|
+
}
|
|
23312
|
+
function createSlackMcpTools(api) {
|
|
23313
|
+
return {
|
|
23314
|
+
async list_slack_destinations(input) {
|
|
23315
|
+
try {
|
|
23316
|
+
return {
|
|
23317
|
+
destinations: await api.listSlackDestinations({
|
|
23318
|
+
bearerToken: String(input["bearerToken"]),
|
|
23319
|
+
projectId: String(input["projectId"])
|
|
23320
|
+
})
|
|
23321
|
+
};
|
|
23322
|
+
} catch (error) {
|
|
23323
|
+
mapMcpError12(error);
|
|
23324
|
+
}
|
|
23325
|
+
},
|
|
23326
|
+
async get_slack_connect_url(input) {
|
|
23327
|
+
try {
|
|
23328
|
+
return {
|
|
23329
|
+
install_url: await api.getSlackInstallUrl({
|
|
23330
|
+
bearerToken: String(input["bearerToken"]),
|
|
23331
|
+
projectId: String(input["projectId"]),
|
|
23332
|
+
...typeof input["returnTo"] === "string" ? { returnTo: input["returnTo"] } : {}
|
|
23333
|
+
})
|
|
23334
|
+
};
|
|
23335
|
+
} catch (error) {
|
|
23336
|
+
mapMcpError12(error);
|
|
23337
|
+
}
|
|
23338
|
+
},
|
|
23339
|
+
async test_slack_destination(input) {
|
|
23340
|
+
try {
|
|
23341
|
+
return {
|
|
23342
|
+
delivery: await api.testSlackDestination({
|
|
23343
|
+
bearerToken: String(input["bearerToken"]),
|
|
23344
|
+
projectId: String(input["projectId"]),
|
|
23345
|
+
destinationId: String(input["destinationId"])
|
|
23346
|
+
})
|
|
23347
|
+
};
|
|
23348
|
+
} catch (error) {
|
|
23349
|
+
mapMcpError12(error);
|
|
23350
|
+
}
|
|
23351
|
+
},
|
|
23352
|
+
async delete_slack_destination(input) {
|
|
23353
|
+
try {
|
|
23354
|
+
return {
|
|
23355
|
+
destination: await api.deleteSlackDestination({
|
|
23356
|
+
bearerToken: String(input["bearerToken"]),
|
|
23357
|
+
projectId: String(input["projectId"]),
|
|
23358
|
+
destinationId: String(input["destinationId"])
|
|
23359
|
+
})
|
|
23360
|
+
};
|
|
23361
|
+
} catch (error) {
|
|
23362
|
+
mapMcpError12(error);
|
|
23363
|
+
}
|
|
23364
|
+
}
|
|
23365
|
+
};
|
|
23366
|
+
}
|
|
23367
|
+
|
|
23368
|
+
// src/token-tools.ts
|
|
23369
|
+
function mapMcpError13(error) {
|
|
22932
23370
|
if (error instanceof TokenManagementApiError) {
|
|
22933
23371
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22934
23372
|
}
|
|
@@ -22949,7 +23387,7 @@ function createTokenMcpTools(api) {
|
|
|
22949
23387
|
tokens: await api.listProjectTokens(requestInput)
|
|
22950
23388
|
};
|
|
22951
23389
|
} catch (error) {
|
|
22952
|
-
|
|
23390
|
+
mapMcpError13(error);
|
|
22953
23391
|
}
|
|
22954
23392
|
},
|
|
22955
23393
|
async create_project_token(input) {
|
|
@@ -22962,7 +23400,7 @@ function createTokenMcpTools(api) {
|
|
|
22962
23400
|
})
|
|
22963
23401
|
};
|
|
22964
23402
|
} catch (error) {
|
|
22965
|
-
|
|
23403
|
+
mapMcpError13(error);
|
|
22966
23404
|
}
|
|
22967
23405
|
},
|
|
22968
23406
|
async revoke_project_token(input) {
|
|
@@ -22975,7 +23413,7 @@ function createTokenMcpTools(api) {
|
|
|
22975
23413
|
})
|
|
22976
23414
|
};
|
|
22977
23415
|
} catch (error) {
|
|
22978
|
-
|
|
23416
|
+
mapMcpError13(error);
|
|
22979
23417
|
}
|
|
22980
23418
|
},
|
|
22981
23419
|
async list_member_tokens(input) {
|
|
@@ -22990,7 +23428,7 @@ function createTokenMcpTools(api) {
|
|
|
22990
23428
|
tokens: await api.listMemberTokens(requestInput)
|
|
22991
23429
|
};
|
|
22992
23430
|
} catch (error) {
|
|
22993
|
-
|
|
23431
|
+
mapMcpError13(error);
|
|
22994
23432
|
}
|
|
22995
23433
|
},
|
|
22996
23434
|
async create_member_token(input) {
|
|
@@ -23002,7 +23440,7 @@ function createTokenMcpTools(api) {
|
|
|
23002
23440
|
})
|
|
23003
23441
|
};
|
|
23004
23442
|
} catch (error) {
|
|
23005
|
-
|
|
23443
|
+
mapMcpError13(error);
|
|
23006
23444
|
}
|
|
23007
23445
|
},
|
|
23008
23446
|
async revoke_member_token(input) {
|
|
@@ -23014,14 +23452,14 @@ function createTokenMcpTools(api) {
|
|
|
23014
23452
|
})
|
|
23015
23453
|
};
|
|
23016
23454
|
} catch (error) {
|
|
23017
|
-
|
|
23455
|
+
mapMcpError13(error);
|
|
23018
23456
|
}
|
|
23019
23457
|
}
|
|
23020
23458
|
};
|
|
23021
23459
|
}
|
|
23022
23460
|
|
|
23023
23461
|
// src/webhook-tools.ts
|
|
23024
|
-
function
|
|
23462
|
+
function mapMcpError14(error) {
|
|
23025
23463
|
if (error instanceof WebhookApiError) {
|
|
23026
23464
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23027
23465
|
}
|
|
@@ -23042,7 +23480,7 @@ function createWebhookMcpTools(api) {
|
|
|
23042
23480
|
webhooks: await api.listWebhooks(requestInput)
|
|
23043
23481
|
};
|
|
23044
23482
|
} catch (error) {
|
|
23045
|
-
|
|
23483
|
+
mapMcpError14(error);
|
|
23046
23484
|
}
|
|
23047
23485
|
},
|
|
23048
23486
|
async create_webhook(input) {
|
|
@@ -23063,7 +23501,7 @@ function createWebhookMcpTools(api) {
|
|
|
23063
23501
|
webhook: await api.createWebhook(requestInput)
|
|
23064
23502
|
};
|
|
23065
23503
|
} catch (error) {
|
|
23066
|
-
|
|
23504
|
+
mapMcpError14(error);
|
|
23067
23505
|
}
|
|
23068
23506
|
},
|
|
23069
23507
|
async update_webhook(input) {
|
|
@@ -23088,7 +23526,7 @@ function createWebhookMcpTools(api) {
|
|
|
23088
23526
|
webhook: await api.updateWebhook(requestInput)
|
|
23089
23527
|
};
|
|
23090
23528
|
} catch (error) {
|
|
23091
|
-
|
|
23529
|
+
mapMcpError14(error);
|
|
23092
23530
|
}
|
|
23093
23531
|
},
|
|
23094
23532
|
async delete_webhook(input) {
|
|
@@ -23100,7 +23538,7 @@ function createWebhookMcpTools(api) {
|
|
|
23100
23538
|
})
|
|
23101
23539
|
};
|
|
23102
23540
|
} catch (error) {
|
|
23103
|
-
|
|
23541
|
+
mapMcpError14(error);
|
|
23104
23542
|
}
|
|
23105
23543
|
},
|
|
23106
23544
|
async test_webhook(input) {
|
|
@@ -23116,7 +23554,7 @@ function createWebhookMcpTools(api) {
|
|
|
23116
23554
|
delivery: await api.testWebhook(requestInput)
|
|
23117
23555
|
};
|
|
23118
23556
|
} catch (error) {
|
|
23119
|
-
|
|
23557
|
+
mapMcpError14(error);
|
|
23120
23558
|
}
|
|
23121
23559
|
},
|
|
23122
23560
|
async list_webhook_deliveries(input) {
|
|
@@ -23132,7 +23570,7 @@ function createWebhookMcpTools(api) {
|
|
|
23132
23570
|
deliveries: await api.listWebhookDeliveries(requestInput)
|
|
23133
23571
|
};
|
|
23134
23572
|
} catch (error) {
|
|
23135
|
-
|
|
23573
|
+
mapMcpError14(error);
|
|
23136
23574
|
}
|
|
23137
23575
|
},
|
|
23138
23576
|
async retry_webhook_delivery(input) {
|
|
@@ -23143,14 +23581,14 @@ function createWebhookMcpTools(api) {
|
|
|
23143
23581
|
deliveryId: String(input["deliveryId"])
|
|
23144
23582
|
});
|
|
23145
23583
|
} catch (error) {
|
|
23146
|
-
|
|
23584
|
+
mapMcpError14(error);
|
|
23147
23585
|
}
|
|
23148
23586
|
}
|
|
23149
23587
|
};
|
|
23150
23588
|
}
|
|
23151
23589
|
|
|
23152
23590
|
// src/weekly-report-tools.ts
|
|
23153
|
-
function
|
|
23591
|
+
function mapMcpError15(error) {
|
|
23154
23592
|
if (error instanceof WeeklyReportApiError) {
|
|
23155
23593
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23156
23594
|
}
|
|
@@ -23168,7 +23606,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23168
23606
|
})
|
|
23169
23607
|
};
|
|
23170
23608
|
} catch (error) {
|
|
23171
|
-
|
|
23609
|
+
mapMcpError15(error);
|
|
23172
23610
|
}
|
|
23173
23611
|
},
|
|
23174
23612
|
async create_weekly_report_channel(input) {
|
|
@@ -23184,7 +23622,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23184
23622
|
})
|
|
23185
23623
|
};
|
|
23186
23624
|
} catch (error) {
|
|
23187
|
-
|
|
23625
|
+
mapMcpError15(error);
|
|
23188
23626
|
}
|
|
23189
23627
|
},
|
|
23190
23628
|
async update_weekly_report_channel(input) {
|
|
@@ -23199,7 +23637,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23199
23637
|
})
|
|
23200
23638
|
};
|
|
23201
23639
|
} catch (error) {
|
|
23202
|
-
|
|
23640
|
+
mapMcpError15(error);
|
|
23203
23641
|
}
|
|
23204
23642
|
},
|
|
23205
23643
|
async delete_weekly_report_channel(input) {
|
|
@@ -23211,7 +23649,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23211
23649
|
})
|
|
23212
23650
|
};
|
|
23213
23651
|
} catch (error) {
|
|
23214
|
-
|
|
23652
|
+
mapMcpError15(error);
|
|
23215
23653
|
}
|
|
23216
23654
|
}
|
|
23217
23655
|
};
|
|
@@ -23262,6 +23700,7 @@ async function createDefaultMcpTools(input = {}) {
|
|
|
23262
23700
|
...createServicesMcpTools(retrievalApi),
|
|
23263
23701
|
...createTokenMcpTools(createTokenManagementApi(httpClient)),
|
|
23264
23702
|
...createWebhookMcpTools(createWebhookApi(httpClient)),
|
|
23703
|
+
...createSlackMcpTools(createSlackApi(httpClient)),
|
|
23265
23704
|
...createWeeklyReportMcpTools(createWeeklyReportApi(httpClient)),
|
|
23266
23705
|
...createAlertMcpTools(createAlertApi(httpClient)),
|
|
23267
23706
|
...createProjectMcpTools(createProjectManagementApi(httpClient)),
|
|
@@ -24946,6 +25385,45 @@ var MCP_TOOL_CATALOG = [
|
|
|
24946
25385
|
deliveryId: external_exports.string()
|
|
24947
25386
|
})
|
|
24948
25387
|
},
|
|
25388
|
+
{
|
|
25389
|
+
name: "list_slack_destinations",
|
|
25390
|
+
group: "slack",
|
|
25391
|
+
description: "List reusable connected Slack destinations for a project organization.",
|
|
25392
|
+
inputSchema: external_exports.object({
|
|
25393
|
+
bearerToken: external_exports.string(),
|
|
25394
|
+
projectId: external_exports.string()
|
|
25395
|
+
})
|
|
25396
|
+
},
|
|
25397
|
+
{
|
|
25398
|
+
name: "get_slack_connect_url",
|
|
25399
|
+
group: "slack",
|
|
25400
|
+
description: "Return a browser Slack connect URL for a project.",
|
|
25401
|
+
inputSchema: external_exports.object({
|
|
25402
|
+
bearerToken: external_exports.string(),
|
|
25403
|
+
projectId: external_exports.string(),
|
|
25404
|
+
returnTo: external_exports.string().optional()
|
|
25405
|
+
})
|
|
25406
|
+
},
|
|
25407
|
+
{
|
|
25408
|
+
name: "test_slack_destination",
|
|
25409
|
+
group: "slack",
|
|
25410
|
+
description: "Send a test message to a connected Slack destination.",
|
|
25411
|
+
inputSchema: external_exports.object({
|
|
25412
|
+
bearerToken: external_exports.string(),
|
|
25413
|
+
projectId: external_exports.string(),
|
|
25414
|
+
destinationId: external_exports.string()
|
|
25415
|
+
})
|
|
25416
|
+
},
|
|
25417
|
+
{
|
|
25418
|
+
name: "delete_slack_destination",
|
|
25419
|
+
group: "slack",
|
|
25420
|
+
description: "Delete a connected Slack destination from a project organization.",
|
|
25421
|
+
inputSchema: external_exports.object({
|
|
25422
|
+
bearerToken: external_exports.string(),
|
|
25423
|
+
projectId: external_exports.string(),
|
|
25424
|
+
destinationId: external_exports.string()
|
|
25425
|
+
})
|
|
25426
|
+
},
|
|
24949
25427
|
{
|
|
24950
25428
|
name: "list_weekly_report_channels",
|
|
24951
25429
|
group: "weekly_reports",
|
|
@@ -25101,7 +25579,8 @@ var MCP_TOOL_CATALOG = [
|
|
|
25101
25579
|
capture_logs: external_exports.string().nullable().optional(),
|
|
25102
25580
|
capture_request_events: external_exports.string().nullable().optional(),
|
|
25103
25581
|
capture_breadcrumbs: external_exports.string().nullable().optional(),
|
|
25104
|
-
capture_probe_events: external_exports.string().nullable().optional()
|
|
25582
|
+
capture_probe_events: external_exports.string().nullable().optional(),
|
|
25583
|
+
immediate_client_error_statuses: external_exports.array(external_exports.number().int().min(400).max(499)).nullable().optional()
|
|
25105
25584
|
})
|
|
25106
25585
|
})
|
|
25107
25586
|
},
|