@debugbundle/mcp 0.1.2 → 0.1.3
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 +522 -90
- 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,8 @@ 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);
|
|
16162
16279
|
var CapturePolicySchema = external_exports.object({
|
|
16163
16280
|
project_id: external_exports.string().uuid(),
|
|
16164
16281
|
preset: CapturePresetSchema,
|
|
@@ -16175,6 +16292,55 @@ var CapturePolicyUpdateSchema = external_exports.object({
|
|
|
16175
16292
|
capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable().optional(),
|
|
16176
16293
|
capture_probe_events: CaptureProbeEventsSchema.nullable().optional()
|
|
16177
16294
|
});
|
|
16295
|
+
var BALANCED_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([408, 423, 424, 425, 429]);
|
|
16296
|
+
var INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES = /* @__PURE__ */ new Set([...BALANCED_IMMEDIATE_REQUEST_STATUSES, 409]);
|
|
16297
|
+
var BALANCED_STANDARD_ANOMALY_STATUSES = /* @__PURE__ */ new Set([401, 403, 404, 409, 422]);
|
|
16298
|
+
var BALANCED_HIGH_VOLUME_ANOMALY_STATUSES = /* @__PURE__ */ new Set([400, 410]);
|
|
16299
|
+
var INVESTIGATIVE_ANOMALY_STATUSES = /* @__PURE__ */ new Set([...BALANCED_STANDARD_ANOMALY_STATUSES, ...BALANCED_HIGH_VOLUME_ANOMALY_STATUSES]);
|
|
16300
|
+
function classifyRequestStatus(input) {
|
|
16301
|
+
const { responseStatus, capturePreset } = input;
|
|
16302
|
+
if (responseStatus === null || !Number.isFinite(responseStatus)) {
|
|
16303
|
+
return "context_signal";
|
|
16304
|
+
}
|
|
16305
|
+
if (responseStatus >= 500) {
|
|
16306
|
+
return "incident_signal";
|
|
16307
|
+
}
|
|
16308
|
+
if (capturePreset === "investigative") {
|
|
16309
|
+
return INVESTIGATIVE_IMMEDIATE_REQUEST_STATUSES.has(responseStatus) ? "incident_signal" : "context_signal";
|
|
16310
|
+
}
|
|
16311
|
+
if (capturePreset === "balanced") {
|
|
16312
|
+
return BALANCED_IMMEDIATE_REQUEST_STATUSES.has(responseStatus) ? "incident_signal" : "context_signal";
|
|
16313
|
+
}
|
|
16314
|
+
return "context_signal";
|
|
16315
|
+
}
|
|
16316
|
+
function getRequestAnomalyThreshold(input) {
|
|
16317
|
+
const { responseStatus, capturePreset } = input;
|
|
16318
|
+
if (responseStatus === null || !Number.isFinite(responseStatus) || responseStatus < 400 || responseStatus >= 500) {
|
|
16319
|
+
return null;
|
|
16320
|
+
}
|
|
16321
|
+
if (capturePreset === "minimal") {
|
|
16322
|
+
return null;
|
|
16323
|
+
}
|
|
16324
|
+
if (capturePreset === "investigative") {
|
|
16325
|
+
return INVESTIGATIVE_ANOMALY_STATUSES.has(responseStatus) ? {
|
|
16326
|
+
minimum_occurrences_5m: 8,
|
|
16327
|
+
minimum_ratio_5m_to_1h: 2
|
|
16328
|
+
} : null;
|
|
16329
|
+
}
|
|
16330
|
+
if (BALANCED_STANDARD_ANOMALY_STATUSES.has(responseStatus)) {
|
|
16331
|
+
return {
|
|
16332
|
+
minimum_occurrences_5m: 20,
|
|
16333
|
+
minimum_ratio_5m_to_1h: 3
|
|
16334
|
+
};
|
|
16335
|
+
}
|
|
16336
|
+
if (BALANCED_HIGH_VOLUME_ANOMALY_STATUSES.has(responseStatus)) {
|
|
16337
|
+
return {
|
|
16338
|
+
minimum_occurrences_5m: 50,
|
|
16339
|
+
minimum_ratio_5m_to_1h: 5
|
|
16340
|
+
};
|
|
16341
|
+
}
|
|
16342
|
+
return null;
|
|
16343
|
+
}
|
|
16178
16344
|
|
|
16179
16345
|
// ../../packages/shared-types/src/index.ts
|
|
16180
16346
|
function createUuidV4() {
|
|
@@ -16783,7 +16949,7 @@ function buildCliReference() {
|
|
|
16783
16949
|
"- `debugbundle ingest <file> --format <format> [--json]`",
|
|
16784
16950
|
"- `debugbundle watch --log <file> --format <format> [--json]`",
|
|
16785
16951
|
"- `debugbundle watch --cloud --log <file> --format <format> [--json]`",
|
|
16786
|
-
"- `debugbundle process [--json]`",
|
|
16952
|
+
"- `debugbundle process [--preset <minimal|balanced|investigative>] [--json]`",
|
|
16787
16953
|
"",
|
|
16788
16954
|
"## Investigation",
|
|
16789
16955
|
"",
|
|
@@ -17875,7 +18041,7 @@ function getRequestResponseStatus(payload) {
|
|
|
17875
18041
|
const status = payload?.["response_status"];
|
|
17876
18042
|
return typeof status === "number" && Number.isFinite(status) ? status : null;
|
|
17877
18043
|
}
|
|
17878
|
-
function classifyEvent(eventType, logLevel, probeActivationId, payload) {
|
|
18044
|
+
function classifyEvent(eventType, logLevel, probeActivationId, payload, capturePreset = "minimal") {
|
|
17879
18045
|
switch (eventType) {
|
|
17880
18046
|
case "backend_exception":
|
|
17881
18047
|
case "frontend_exception":
|
|
@@ -17887,10 +18053,7 @@ function classifyEvent(eventType, logLevel, probeActivationId, payload) {
|
|
|
17887
18053
|
return "context_signal";
|
|
17888
18054
|
case "request_event": {
|
|
17889
18055
|
const responseStatus = getRequestResponseStatus(payload);
|
|
17890
|
-
|
|
17891
|
-
return "incident_signal";
|
|
17892
|
-
}
|
|
17893
|
-
return "context_signal";
|
|
18056
|
+
return classifyRequestStatus({ responseStatus, capturePreset });
|
|
17894
18057
|
}
|
|
17895
18058
|
case "frontend_breadcrumb":
|
|
17896
18059
|
case "deploy_metadata":
|
|
@@ -18052,7 +18215,7 @@ function buildPrivacyPreview() {
|
|
|
18052
18215
|
sample_event_type: sampleEvent.event_type,
|
|
18053
18216
|
sample_event_class: sampleEventClass,
|
|
18054
18217
|
sample_can_create_incident: sampleEventClass === "incident_signal",
|
|
18055
|
-
incident_rule: "request_event
|
|
18218
|
+
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
18219
|
redacted_fields,
|
|
18057
18220
|
omitted_fields: [],
|
|
18058
18221
|
retained_metadata: {
|
|
@@ -18563,7 +18726,8 @@ function buildRedactionRecord(bundleBody) {
|
|
|
18563
18726
|
function buildVisibilityRecord(input) {
|
|
18564
18727
|
const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
|
|
18565
18728
|
const matchedFields = input.incident.matched_fields.length === 0 ? "none" : input.incident.matched_fields.join(", ");
|
|
18566
|
-
const
|
|
18729
|
+
const isRequestAnomaly = input.incident.matched_fields.includes("request_anomaly");
|
|
18730
|
+
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
18731
|
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
18732
|
return {
|
|
18569
18733
|
grouping,
|
|
@@ -18574,15 +18738,16 @@ function buildVisibilityRecord(input) {
|
|
|
18574
18738
|
}
|
|
18575
18739
|
function buildSuggestedNextChecks(input) {
|
|
18576
18740
|
const suggestions = [];
|
|
18741
|
+
const isRequestAnomaly = input.incident.matched_fields.includes("request_anomaly");
|
|
18577
18742
|
if (input.bundle.status === "pending") {
|
|
18578
18743
|
suggestions.push("Wait for bundle generation to finish, then rerun the incident context command.");
|
|
18579
18744
|
} else if (input.bundle.status === "failed") {
|
|
18580
18745
|
suggestions.push("Inspect bundle generation status or retry bundle retrieval to recover missing context.");
|
|
18581
18746
|
}
|
|
18582
18747
|
const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
|
|
18583
|
-
if (input.primarySignal.
|
|
18748
|
+
if (input.primarySignal.kind === "request_failure" && input.primarySignal.request_method !== null && routeTarget !== null) {
|
|
18584
18749
|
suggestions.push(
|
|
18585
|
-
`Inspect the ${input.primarySignal.request_method} ${routeTarget
|
|
18750
|
+
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
18751
|
);
|
|
18587
18752
|
}
|
|
18588
18753
|
const firstApplicationFrame = input.primarySignal.first_application_frame;
|
|
@@ -18671,12 +18836,13 @@ function deriveIncidentReasonFromSignal(input) {
|
|
|
18671
18836
|
};
|
|
18672
18837
|
case "request_event": {
|
|
18673
18838
|
const responseStatus = typeof input.response_status === "number" && Number.isFinite(input.response_status) ? input.response_status : null;
|
|
18839
|
+
const isRequestAnomaly = input.request_anomaly === true;
|
|
18674
18840
|
return {
|
|
18675
|
-
kind: "
|
|
18676
|
-
description: responseStatus !== null
|
|
18841
|
+
kind: "request_failure",
|
|
18842
|
+
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
18843
|
event_type: "request_event",
|
|
18678
18844
|
event_class: "incident_signal",
|
|
18679
|
-
matched_policy: "
|
|
18845
|
+
matched_policy: isRequestAnomaly ? "Repeated contextual request failures crossed the request anomaly threshold" : "Immediate request failure statuses bypass capture_request_events suppression"
|
|
18680
18846
|
};
|
|
18681
18847
|
}
|
|
18682
18848
|
case "log_event": {
|
|
@@ -18779,6 +18945,39 @@ var STORAGE_SCHEMA_MIGRATIONS = [
|
|
|
18779
18945
|
ON github_device_authorizations (expires_at)
|
|
18780
18946
|
`
|
|
18781
18947
|
]
|
|
18948
|
+
}),
|
|
18949
|
+
defineStorageSchemaMigration({
|
|
18950
|
+
id: "202605130001_allow_synthetic_webhook_test_deliveries_without_incident_fk",
|
|
18951
|
+
description: "Allow webhook test deliveries to persist without requiring a backing incidents row.",
|
|
18952
|
+
statements: [
|
|
18953
|
+
"ALTER TABLE webhook_deliveries ALTER COLUMN incident_id DROP NOT NULL"
|
|
18954
|
+
]
|
|
18955
|
+
}),
|
|
18956
|
+
defineStorageSchemaMigration({
|
|
18957
|
+
id: "202605130002_add_slack_destinations",
|
|
18958
|
+
description: "Add reusable encrypted Slack alert destinations scoped to organizations.",
|
|
18959
|
+
statements: [
|
|
18960
|
+
`
|
|
18961
|
+
CREATE TABLE IF NOT EXISTS slack_destinations (
|
|
18962
|
+
id uuid PRIMARY KEY,
|
|
18963
|
+
organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
18964
|
+
slack_team_id text NOT NULL,
|
|
18965
|
+
slack_team_name text,
|
|
18966
|
+
slack_channel_id text NOT NULL,
|
|
18967
|
+
slack_channel_name text,
|
|
18968
|
+
webhook_url_ciphertext text NOT NULL,
|
|
18969
|
+
installed_by_member_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
18970
|
+
is_active boolean NOT NULL DEFAULT true,
|
|
18971
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
18972
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
18973
|
+
UNIQUE (organization_id, slack_team_id, slack_channel_id)
|
|
18974
|
+
)
|
|
18975
|
+
`,
|
|
18976
|
+
`
|
|
18977
|
+
CREATE INDEX IF NOT EXISTS slack_destinations_org_active_idx
|
|
18978
|
+
ON slack_destinations (organization_id, is_active, created_at)
|
|
18979
|
+
`
|
|
18980
|
+
]
|
|
18782
18981
|
})
|
|
18783
18982
|
];
|
|
18784
18983
|
|
|
@@ -19799,11 +19998,17 @@ var EVENT_TYPE_SET = new Set(EventTypeValues);
|
|
|
19799
19998
|
function isEventType(value) {
|
|
19800
19999
|
return typeof value === "string" && EVENT_TYPE_SET.has(value);
|
|
19801
20000
|
}
|
|
19802
|
-
function inferSeverity2(
|
|
19803
|
-
if (
|
|
20001
|
+
function inferSeverity2(event, capturePreset, incidentKind = "immediate") {
|
|
20002
|
+
if (incidentKind === "request_anomaly") {
|
|
20003
|
+
return "medium";
|
|
20004
|
+
}
|
|
20005
|
+
if (event.event_type === "request_event") {
|
|
20006
|
+
return classifyRequestStatus({ responseStatus: event.payload.response_status, capturePreset }) === "incident_signal" ? "high" : "low";
|
|
20007
|
+
}
|
|
20008
|
+
if (event.event_type === "backend_exception" || event.event_type === "frontend_exception") {
|
|
19804
20009
|
return "high";
|
|
19805
20010
|
}
|
|
19806
|
-
if (
|
|
20011
|
+
if (event.event_type === "error_suppressed") {
|
|
19807
20012
|
return "medium";
|
|
19808
20013
|
}
|
|
19809
20014
|
return "low";
|
|
@@ -19827,15 +20032,17 @@ function compareEventEnvelopes(left, right) {
|
|
|
19827
20032
|
}
|
|
19828
20033
|
return left.event_id.localeCompare(right.event_id);
|
|
19829
20034
|
}
|
|
19830
|
-
function classifyEnvelope(envelope) {
|
|
20035
|
+
function classifyEnvelope(envelope, capturePreset) {
|
|
19831
20036
|
return classifyEvent(
|
|
19832
20037
|
envelope.event_type,
|
|
19833
20038
|
envelope.event_type === "log_event" ? envelope.payload.level : void 0,
|
|
19834
|
-
envelope.event_type === "probe_event" ? envelope.payload.activation_id : void 0
|
|
20039
|
+
envelope.event_type === "probe_event" ? envelope.payload.activation_id : void 0,
|
|
20040
|
+
envelope.payload,
|
|
20041
|
+
capturePreset
|
|
19835
20042
|
);
|
|
19836
20043
|
}
|
|
19837
|
-
function isIncidentSignalEnvelope(envelope) {
|
|
19838
|
-
return classifyEnvelope(envelope) === "incident_signal";
|
|
20044
|
+
function isIncidentSignalEnvelope(envelope, capturePreset) {
|
|
20045
|
+
return classifyEnvelope(envelope, capturePreset) === "incident_signal";
|
|
19839
20046
|
}
|
|
19840
20047
|
function getTraceId(envelope) {
|
|
19841
20048
|
return envelope.correlation?.trace_id ?? null;
|
|
@@ -19880,7 +20087,10 @@ function mergeAggregateGroup(aggregates) {
|
|
|
19880
20087
|
newEvents: [...canonicalAggregate.newEvents],
|
|
19881
20088
|
mergedIncidentIds: new Set(canonicalAggregate.mergedIncidentIds),
|
|
19882
20089
|
signalEventTypes: new Set(canonicalAggregate.signalEventTypes),
|
|
19883
|
-
traceIds: new Set(canonicalAggregate.traceIds)
|
|
20090
|
+
traceIds: new Set(canonicalAggregate.traceIds),
|
|
20091
|
+
title: canonicalAggregate.title,
|
|
20092
|
+
kind: canonicalAggregate.kind,
|
|
20093
|
+
severity: canonicalAggregate.severity
|
|
19884
20094
|
});
|
|
19885
20095
|
}
|
|
19886
20096
|
function hashIdentifier(parts, prefix, length) {
|
|
@@ -19906,6 +20116,111 @@ function mergeSourceEvents(existingEvents, nextEvents) {
|
|
|
19906
20116
|
}
|
|
19907
20117
|
return [...merged.values()].sort(compareEventEnvelopes);
|
|
19908
20118
|
}
|
|
20119
|
+
function stableJson2(value) {
|
|
20120
|
+
if (value === null || typeof value !== "object") {
|
|
20121
|
+
return JSON.stringify(value);
|
|
20122
|
+
}
|
|
20123
|
+
if (Array.isArray(value)) {
|
|
20124
|
+
return `[${value.map((entry) => stableJson2(entry)).join(",")}]`;
|
|
20125
|
+
}
|
|
20126
|
+
const record = value;
|
|
20127
|
+
const keys = Object.keys(record).sort();
|
|
20128
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson2(record[key])}`).join(",")}}`;
|
|
20129
|
+
}
|
|
20130
|
+
function buildRequestAnomalyFingerprint(input) {
|
|
20131
|
+
return (0, import_node_crypto4.createHash)("sha256").update(
|
|
20132
|
+
stableJson2({
|
|
20133
|
+
kind: "request_status_anomaly",
|
|
20134
|
+
project_id: input.projectId,
|
|
20135
|
+
service_name: input.serviceName,
|
|
20136
|
+
environment: input.environment,
|
|
20137
|
+
method: input.method,
|
|
20138
|
+
route_template: input.routeTemplate,
|
|
20139
|
+
response_status: input.responseStatus
|
|
20140
|
+
})
|
|
20141
|
+
).digest("hex");
|
|
20142
|
+
}
|
|
20143
|
+
function buildRequestAnomalyTitle(input) {
|
|
20144
|
+
return `Request anomaly: ${input.method} ${input.routeTemplate} returned ${input.responseStatus} repeatedly`;
|
|
20145
|
+
}
|
|
20146
|
+
function toUnixSeconds(occurredAt) {
|
|
20147
|
+
return Math.floor(new Date(occurredAt).getTime() / 1e3);
|
|
20148
|
+
}
|
|
20149
|
+
function countOccurrencesInWindow(events, windowSeconds) {
|
|
20150
|
+
const latestEvent = events.at(-1);
|
|
20151
|
+
if (latestEvent === void 0) {
|
|
20152
|
+
return 0;
|
|
20153
|
+
}
|
|
20154
|
+
const latestOccurredAt = toUnixSeconds(latestEvent.occurred_at);
|
|
20155
|
+
const lowerBound = latestOccurredAt - windowSeconds + 1;
|
|
20156
|
+
return events.filter((event) => {
|
|
20157
|
+
const occurredAt = toUnixSeconds(event.occurred_at);
|
|
20158
|
+
return occurredAt >= lowerBound && occurredAt <= latestOccurredAt;
|
|
20159
|
+
}).length;
|
|
20160
|
+
}
|
|
20161
|
+
function passesRequestAnomalyThreshold(events, threshold) {
|
|
20162
|
+
const occurrences5m = countOccurrencesInWindow(events, 5 * 60);
|
|
20163
|
+
const occurrences1h = countOccurrencesInWindow(events, 60 * 60);
|
|
20164
|
+
const baseline1hPer5m = occurrences1h / 12;
|
|
20165
|
+
const ratio = occurrences5m / Math.max(baseline1hPer5m, 1);
|
|
20166
|
+
return occurrences5m >= threshold.minimum_occurrences_5m && ratio >= threshold.minimum_ratio_5m_to_1h;
|
|
20167
|
+
}
|
|
20168
|
+
function collectRequestAnomalyAggregates(batches, capturePreset) {
|
|
20169
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
20170
|
+
for (const batch of batches) {
|
|
20171
|
+
for (const event of batch.events) {
|
|
20172
|
+
if (event.event_type !== "request_event" || classifyEnvelope(event, capturePreset) !== "context_signal") {
|
|
20173
|
+
continue;
|
|
20174
|
+
}
|
|
20175
|
+
const normalizedEvent = normalizeEvent(event);
|
|
20176
|
+
const responseStatus = normalizedEvent.http_status;
|
|
20177
|
+
const method = normalizedEvent.http_method;
|
|
20178
|
+
const routeTemplate = normalizedEvent.route_template;
|
|
20179
|
+
const threshold = getRequestAnomalyThreshold({ responseStatus, capturePreset });
|
|
20180
|
+
if (threshold === null || responseStatus === null || method === null || routeTemplate === null) {
|
|
20181
|
+
continue;
|
|
20182
|
+
}
|
|
20183
|
+
const projectId = requireProjectId(event);
|
|
20184
|
+
const incidentFingerprint = buildRequestAnomalyFingerprint({
|
|
20185
|
+
projectId,
|
|
20186
|
+
serviceName: event.service.name,
|
|
20187
|
+
environment: event.service.environment,
|
|
20188
|
+
method,
|
|
20189
|
+
routeTemplate,
|
|
20190
|
+
responseStatus
|
|
20191
|
+
});
|
|
20192
|
+
const incidentId = deriveIncidentId(projectId, event.service.name, event.service.environment, incidentFingerprint);
|
|
20193
|
+
const aggregate = grouped.get(incidentId) ?? {
|
|
20194
|
+
incidentId,
|
|
20195
|
+
projectId,
|
|
20196
|
+
serviceName: event.service.name,
|
|
20197
|
+
environment: event.service.environment,
|
|
20198
|
+
fingerprint: incidentFingerprint,
|
|
20199
|
+
matchedFields: /* @__PURE__ */ new Set(["request_anomaly", "route_template", "http_method", "http_status", "environment"]),
|
|
20200
|
+
newEvents: [],
|
|
20201
|
+
mergedIncidentIds: /* @__PURE__ */ new Set([incidentId]),
|
|
20202
|
+
signalEventTypes: /* @__PURE__ */ new Set(["request_event"]),
|
|
20203
|
+
traceIds: /* @__PURE__ */ new Set(),
|
|
20204
|
+
title: buildRequestAnomalyTitle({ method, routeTemplate, responseStatus }),
|
|
20205
|
+
kind: "request_anomaly",
|
|
20206
|
+
severity: "medium"
|
|
20207
|
+
};
|
|
20208
|
+
aggregate.newEvents.push(event);
|
|
20209
|
+
grouped.set(incidentId, aggregate);
|
|
20210
|
+
}
|
|
20211
|
+
}
|
|
20212
|
+
return [...grouped.values()].filter((aggregate) => {
|
|
20213
|
+
const latestEvent = aggregate.newEvents.at(-1);
|
|
20214
|
+
if (latestEvent === void 0 || latestEvent.event_type !== "request_event") {
|
|
20215
|
+
return false;
|
|
20216
|
+
}
|
|
20217
|
+
const threshold = getRequestAnomalyThreshold({
|
|
20218
|
+
responseStatus: normalizeEvent(latestEvent).http_status,
|
|
20219
|
+
capturePreset
|
|
20220
|
+
});
|
|
20221
|
+
return threshold !== null && passesRequestAnomalyThreshold(aggregate.newEvents, threshold);
|
|
20222
|
+
}).sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20223
|
+
}
|
|
19909
20224
|
function buildBundleContext(incident) {
|
|
19910
20225
|
return {
|
|
19911
20226
|
incident_id: incident.incident_id,
|
|
@@ -19935,12 +20250,12 @@ function formatServiceSummary(services) {
|
|
|
19935
20250
|
}
|
|
19936
20251
|
function formatProcessOutput(summary) {
|
|
19937
20252
|
if (!summary.processed) {
|
|
19938
|
-
return summary.message
|
|
20253
|
+
return summary.message;
|
|
19939
20254
|
}
|
|
19940
20255
|
return [
|
|
19941
20256
|
`Processed ${summary.events_processed} events from ${summary.files_processed} files into ${summary.incidents_processed} incidents.`,
|
|
19942
20257
|
...formatServiceSummary(summary.services),
|
|
19943
|
-
`Last processed event file: ${summary.last_processed_event_file
|
|
20258
|
+
`Last processed event file: ${summary.last_processed_event_file}`
|
|
19944
20259
|
].join("\n");
|
|
19945
20260
|
}
|
|
19946
20261
|
async function pathExists4(path, stat) {
|
|
@@ -20180,6 +20495,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20180
20495
|
const statePath = (0, import_node_path6.join)(rootDirectory, LOCAL_STATE_FILE_PATH);
|
|
20181
20496
|
const bundleDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_BUNDLE_DIRECTORY_PATH2);
|
|
20182
20497
|
const reproductionDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_REPRODUCTION_DIRECTORY_PATH);
|
|
20498
|
+
const capturePreset = input.preset ?? "minimal";
|
|
20183
20499
|
await mkdir((0, import_node_path6.join)(rootDirectory, ".debugbundle", "local"), { recursive: true });
|
|
20184
20500
|
await mkdir(bundleDirectoryPath, { recursive: true });
|
|
20185
20501
|
await mkdir(reproductionDirectoryPath, { recursive: true });
|
|
@@ -20187,22 +20503,26 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20187
20503
|
const eventFileNames = await pathExists4(eventsDirectoryPath, stat) ? (await readdir(eventsDirectoryPath)).filter((fileName) => fileName.endsWith(".events.json")).sort() : [];
|
|
20188
20504
|
const lastProcessedEventFile = previousState?.last_processed_event_file ?? null;
|
|
20189
20505
|
const newEventFileNames = lastProcessedEventFile === null ? eventFileNames : eventFileNames.filter((fileName) => fileName > lastProcessedEventFile);
|
|
20190
|
-
|
|
20506
|
+
const processAllEventFiles = input.preset !== void 0;
|
|
20507
|
+
const targetEventFileNames = processAllEventFiles ? eventFileNames : newEventFileNames;
|
|
20508
|
+
if (targetEventFileNames.length === 0) {
|
|
20191
20509
|
const summary2 = buildNoNewEventsSummary(previousState?.last_processed_event_file ?? eventFileNames.at(-1) ?? null);
|
|
20192
20510
|
return {
|
|
20193
20511
|
exitCode: 0,
|
|
20194
20512
|
output: input.json === true ? JSON.stringify(summary2) : formatProcessOutput(summary2)
|
|
20195
20513
|
};
|
|
20196
20514
|
}
|
|
20197
|
-
const batches = await readEventBatches(eventsDirectoryPath,
|
|
20198
|
-
const incidents = new Map(
|
|
20515
|
+
const batches = await readEventBatches(eventsDirectoryPath, targetEventFileNames, readFile);
|
|
20516
|
+
const incidents = new Map(
|
|
20517
|
+
processAllEventFiles ? [] : Object.entries(previousState?.incidents ?? {})
|
|
20518
|
+
);
|
|
20199
20519
|
const aggregates = /* @__PURE__ */ new Map();
|
|
20200
20520
|
const traceCorrelationGroups = /* @__PURE__ */ new Map();
|
|
20201
20521
|
let eventsProcessed = 0;
|
|
20202
20522
|
for (const batch of batches) {
|
|
20203
20523
|
for (const event of batch.events) {
|
|
20204
20524
|
eventsProcessed += 1;
|
|
20205
|
-
if (!isIncidentSignalEnvelope(event)) {
|
|
20525
|
+
if (!isIncidentSignalEnvelope(event, capturePreset)) {
|
|
20206
20526
|
continue;
|
|
20207
20527
|
}
|
|
20208
20528
|
const normalizedEvent = normalizeEvent(event);
|
|
@@ -20219,7 +20539,10 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20219
20539
|
newEvents: [],
|
|
20220
20540
|
mergedIncidentIds: /* @__PURE__ */ new Set([incidentId]),
|
|
20221
20541
|
signalEventTypes: /* @__PURE__ */ new Set(),
|
|
20222
|
-
traceIds: /* @__PURE__ */ new Set()
|
|
20542
|
+
traceIds: /* @__PURE__ */ new Set(),
|
|
20543
|
+
title: normalizedEvent.normalized_message,
|
|
20544
|
+
kind: "immediate",
|
|
20545
|
+
severity: inferSeverity2(event, capturePreset)
|
|
20223
20546
|
};
|
|
20224
20547
|
for (const matchedField of inferMatchedFields(normalizedEvent)) {
|
|
20225
20548
|
aggregate.matchedFields.add(matchedField);
|
|
@@ -20286,14 +20609,16 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20286
20609
|
mergedAggregatesByRoot.set(rootIncidentId, aggregateGroup);
|
|
20287
20610
|
}
|
|
20288
20611
|
const mergedAggregates = [...mergedAggregatesByRoot.values()].map((aggregateGroup) => mergeAggregateGroup(aggregateGroup)).sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20612
|
+
const requestAnomalyAggregates = input.preset === void 0 ? [] : collectRequestAnomalyAggregates(batches, capturePreset);
|
|
20613
|
+
const finalizedAggregates = [...mergedAggregates, ...requestAnomalyAggregates].sort((left, right) => left.incidentId.localeCompare(right.incidentId));
|
|
20289
20614
|
const services = /* @__PURE__ */ new Map();
|
|
20290
|
-
for (const aggregate of
|
|
20615
|
+
for (const aggregate of finalizedAggregates) {
|
|
20291
20616
|
const incidentId = aggregate.incidentId;
|
|
20292
20617
|
const existingIncidents = [...aggregate.mergedIncidentIds].map((mergedIncidentId) => incidents.get(mergedIncidentId)).filter((incident2) => incident2 !== void 0);
|
|
20293
20618
|
const existing = existingIncidents.find((incident2) => incident2.incident_id === incidentId) ?? existingIncidents[0];
|
|
20294
20619
|
const existingSourceEvents = existingIncidents.flatMap((incident2) => incident2.source_events);
|
|
20295
20620
|
const combinedSourceEvents = mergeSourceEvents(existingSourceEvents, aggregate.newEvents);
|
|
20296
|
-
const signalEvents = combinedSourceEvents.filter(isIncidentSignalEnvelope);
|
|
20621
|
+
const signalEvents = aggregate.kind === "request_anomaly" ? combinedSourceEvents : combinedSourceEvents.filter((event) => isIncidentSignalEnvelope(event, capturePreset));
|
|
20297
20622
|
if (signalEvents.length === 0) {
|
|
20298
20623
|
continue;
|
|
20299
20624
|
}
|
|
@@ -20303,8 +20628,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20303
20628
|
continue;
|
|
20304
20629
|
}
|
|
20305
20630
|
const sourceEventTypes = [...new Set(signalEvents.map((event) => event.event_type))].sort();
|
|
20306
|
-
const severity = signalEvents.map((event) => inferSeverity2(event.
|
|
20307
|
-
const latestNormalizedEvent = normalizeEvent(latestSignalEvent);
|
|
20631
|
+
const severity = signalEvents.map((event) => inferSeverity2(event, capturePreset, aggregate.kind)).sort((left, right) => severityRank(right) - severityRank(left))[0] ?? aggregate.severity;
|
|
20308
20632
|
const generationNumber = signalEvents.length;
|
|
20309
20633
|
const bundlePath = `${LOCAL_BUNDLE_DIRECTORY_PATH2}/${incidentId}.bundle.json`;
|
|
20310
20634
|
const reproductionPath = `${LOCAL_REPRODUCTION_DIRECTORY_PATH}/${incidentId}.reproduction.json`;
|
|
@@ -20319,7 +20643,7 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20319
20643
|
environment: aggregate.environment,
|
|
20320
20644
|
fingerprint: aggregate.fingerprint,
|
|
20321
20645
|
fingerprint_version: FINGERPRINT_VERSION,
|
|
20322
|
-
title:
|
|
20646
|
+
title: aggregate.title,
|
|
20323
20647
|
severity,
|
|
20324
20648
|
status: existingIncidents.some((incidentState) => incidentState.status === "resolved") ? "open" : existing?.status ?? "open",
|
|
20325
20649
|
first_seen_at: firstSignalEvent.occurred_at,
|
|
@@ -20380,21 +20704,22 @@ async function processCommand(input, dependencies = {}) {
|
|
|
20380
20704
|
incidents.set(incidentId, incident);
|
|
20381
20705
|
services.set(incident.service_name, (services.get(incident.service_name) ?? 0) + 1);
|
|
20382
20706
|
}
|
|
20707
|
+
const finalProcessedEventFile = targetEventFileNames[targetEventFileNames.length - 1];
|
|
20383
20708
|
const nextState = {
|
|
20384
20709
|
version: 1,
|
|
20385
|
-
last_processed_event_file:
|
|
20710
|
+
last_processed_event_file: finalProcessedEventFile,
|
|
20386
20711
|
incidents: Object.fromEntries([...incidents.entries()].sort(([left], [right]) => left.localeCompare(right)))
|
|
20387
20712
|
};
|
|
20388
20713
|
await writeFile(statePath, serializeState(nextState));
|
|
20389
20714
|
const summary = buildProcessedSummary({
|
|
20390
20715
|
filesProcessed: newEventFileNames.length,
|
|
20391
20716
|
eventsProcessed,
|
|
20392
|
-
incidentsProcessed:
|
|
20717
|
+
incidentsProcessed: finalizedAggregates.length,
|
|
20393
20718
|
services: [...services.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([service, count]) => ({
|
|
20394
20719
|
service,
|
|
20395
20720
|
incidents: count
|
|
20396
20721
|
})),
|
|
20397
|
-
lastProcessedEventFile:
|
|
20722
|
+
lastProcessedEventFile: finalProcessedEventFile
|
|
20398
20723
|
});
|
|
20399
20724
|
return {
|
|
20400
20725
|
exitCode: 0,
|
|
@@ -20510,7 +20835,11 @@ function parseLocalIncident(candidate) {
|
|
|
20510
20835
|
}
|
|
20511
20836
|
const serviceRuntime = candidate["service_runtime"];
|
|
20512
20837
|
const serviceFramework = candidate["service_framework"];
|
|
20513
|
-
const incidentReason =
|
|
20838
|
+
const incidentReason = candidate["matched_fields"].includes("request_anomaly") ? deriveIncidentReasonFromSignal({
|
|
20839
|
+
event_type: "request_event",
|
|
20840
|
+
event_class: "incident_signal",
|
|
20841
|
+
request_anomaly: true
|
|
20842
|
+
}) : deriveIncidentReasonFromSourceEventTypes(candidate["source_event_types"]);
|
|
20514
20843
|
if (serviceRuntime !== null && typeof serviceRuntime !== "string") {
|
|
20515
20844
|
throw createReadError(400, "invalid_local_state");
|
|
20516
20845
|
}
|
|
@@ -20816,14 +21145,14 @@ function localFailureStepName(checks) {
|
|
|
20816
21145
|
function cloudVerificationRunId(now) {
|
|
20817
21146
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
20818
21147
|
}
|
|
20819
|
-
function
|
|
21148
|
+
function requestFailureReason() {
|
|
20820
21149
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
20821
21150
|
event_type: "request_event",
|
|
20822
21151
|
event_class: "incident_signal",
|
|
20823
21152
|
response_status: 503
|
|
20824
21153
|
});
|
|
20825
21154
|
if (incidentReason === null) {
|
|
20826
|
-
throw new Error("
|
|
21155
|
+
throw new Error("request_failure_reason_unavailable");
|
|
20827
21156
|
}
|
|
20828
21157
|
return incidentReason;
|
|
20829
21158
|
}
|
|
@@ -21098,7 +21427,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21098
21427
|
const verification = {
|
|
21099
21428
|
mode: "active_5xx",
|
|
21100
21429
|
bundle_status: "unknown",
|
|
21101
|
-
classification_reason:
|
|
21430
|
+
classification_reason: requestFailureReason()
|
|
21102
21431
|
};
|
|
21103
21432
|
const errors = [];
|
|
21104
21433
|
let exitCode = 0;
|
|
@@ -21150,7 +21479,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21150
21479
|
if (candidate !== void 0) {
|
|
21151
21480
|
incidentId = candidate.incident_id;
|
|
21152
21481
|
verification.incident_id = candidate.incident_id;
|
|
21153
|
-
verification.classification_reason = candidate.incident_reason ??
|
|
21482
|
+
verification.classification_reason = candidate.incident_reason ?? requestFailureReason();
|
|
21154
21483
|
break;
|
|
21155
21484
|
}
|
|
21156
21485
|
if (attempt < pollAttempts) {
|
|
@@ -22927,8 +23256,71 @@ function createSetupMcpTools(commands) {
|
|
|
22927
23256
|
};
|
|
22928
23257
|
}
|
|
22929
23258
|
|
|
22930
|
-
// src/
|
|
23259
|
+
// src/slack-tools.ts
|
|
22931
23260
|
function mapMcpError12(error) {
|
|
23261
|
+
if (error instanceof SlackApiError) {
|
|
23262
|
+
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23263
|
+
}
|
|
23264
|
+
throw new Error("mcp_tool_error:unknown_error");
|
|
23265
|
+
}
|
|
23266
|
+
function createSlackMcpTools(api) {
|
|
23267
|
+
return {
|
|
23268
|
+
async list_slack_destinations(input) {
|
|
23269
|
+
try {
|
|
23270
|
+
return {
|
|
23271
|
+
destinations: await api.listSlackDestinations({
|
|
23272
|
+
bearerToken: String(input["bearerToken"]),
|
|
23273
|
+
projectId: String(input["projectId"])
|
|
23274
|
+
})
|
|
23275
|
+
};
|
|
23276
|
+
} catch (error) {
|
|
23277
|
+
mapMcpError12(error);
|
|
23278
|
+
}
|
|
23279
|
+
},
|
|
23280
|
+
async get_slack_connect_url(input) {
|
|
23281
|
+
try {
|
|
23282
|
+
return {
|
|
23283
|
+
install_url: await api.getSlackInstallUrl({
|
|
23284
|
+
bearerToken: String(input["bearerToken"]),
|
|
23285
|
+
projectId: String(input["projectId"]),
|
|
23286
|
+
...typeof input["returnTo"] === "string" ? { returnTo: input["returnTo"] } : {}
|
|
23287
|
+
})
|
|
23288
|
+
};
|
|
23289
|
+
} catch (error) {
|
|
23290
|
+
mapMcpError12(error);
|
|
23291
|
+
}
|
|
23292
|
+
},
|
|
23293
|
+
async test_slack_destination(input) {
|
|
23294
|
+
try {
|
|
23295
|
+
return {
|
|
23296
|
+
delivery: await api.testSlackDestination({
|
|
23297
|
+
bearerToken: String(input["bearerToken"]),
|
|
23298
|
+
projectId: String(input["projectId"]),
|
|
23299
|
+
destinationId: String(input["destinationId"])
|
|
23300
|
+
})
|
|
23301
|
+
};
|
|
23302
|
+
} catch (error) {
|
|
23303
|
+
mapMcpError12(error);
|
|
23304
|
+
}
|
|
23305
|
+
},
|
|
23306
|
+
async delete_slack_destination(input) {
|
|
23307
|
+
try {
|
|
23308
|
+
return {
|
|
23309
|
+
destination: await api.deleteSlackDestination({
|
|
23310
|
+
bearerToken: String(input["bearerToken"]),
|
|
23311
|
+
projectId: String(input["projectId"]),
|
|
23312
|
+
destinationId: String(input["destinationId"])
|
|
23313
|
+
})
|
|
23314
|
+
};
|
|
23315
|
+
} catch (error) {
|
|
23316
|
+
mapMcpError12(error);
|
|
23317
|
+
}
|
|
23318
|
+
}
|
|
23319
|
+
};
|
|
23320
|
+
}
|
|
23321
|
+
|
|
23322
|
+
// src/token-tools.ts
|
|
23323
|
+
function mapMcpError13(error) {
|
|
22932
23324
|
if (error instanceof TokenManagementApiError) {
|
|
22933
23325
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
22934
23326
|
}
|
|
@@ -22949,7 +23341,7 @@ function createTokenMcpTools(api) {
|
|
|
22949
23341
|
tokens: await api.listProjectTokens(requestInput)
|
|
22950
23342
|
};
|
|
22951
23343
|
} catch (error) {
|
|
22952
|
-
|
|
23344
|
+
mapMcpError13(error);
|
|
22953
23345
|
}
|
|
22954
23346
|
},
|
|
22955
23347
|
async create_project_token(input) {
|
|
@@ -22962,7 +23354,7 @@ function createTokenMcpTools(api) {
|
|
|
22962
23354
|
})
|
|
22963
23355
|
};
|
|
22964
23356
|
} catch (error) {
|
|
22965
|
-
|
|
23357
|
+
mapMcpError13(error);
|
|
22966
23358
|
}
|
|
22967
23359
|
},
|
|
22968
23360
|
async revoke_project_token(input) {
|
|
@@ -22975,7 +23367,7 @@ function createTokenMcpTools(api) {
|
|
|
22975
23367
|
})
|
|
22976
23368
|
};
|
|
22977
23369
|
} catch (error) {
|
|
22978
|
-
|
|
23370
|
+
mapMcpError13(error);
|
|
22979
23371
|
}
|
|
22980
23372
|
},
|
|
22981
23373
|
async list_member_tokens(input) {
|
|
@@ -22990,7 +23382,7 @@ function createTokenMcpTools(api) {
|
|
|
22990
23382
|
tokens: await api.listMemberTokens(requestInput)
|
|
22991
23383
|
};
|
|
22992
23384
|
} catch (error) {
|
|
22993
|
-
|
|
23385
|
+
mapMcpError13(error);
|
|
22994
23386
|
}
|
|
22995
23387
|
},
|
|
22996
23388
|
async create_member_token(input) {
|
|
@@ -23002,7 +23394,7 @@ function createTokenMcpTools(api) {
|
|
|
23002
23394
|
})
|
|
23003
23395
|
};
|
|
23004
23396
|
} catch (error) {
|
|
23005
|
-
|
|
23397
|
+
mapMcpError13(error);
|
|
23006
23398
|
}
|
|
23007
23399
|
},
|
|
23008
23400
|
async revoke_member_token(input) {
|
|
@@ -23014,14 +23406,14 @@ function createTokenMcpTools(api) {
|
|
|
23014
23406
|
})
|
|
23015
23407
|
};
|
|
23016
23408
|
} catch (error) {
|
|
23017
|
-
|
|
23409
|
+
mapMcpError13(error);
|
|
23018
23410
|
}
|
|
23019
23411
|
}
|
|
23020
23412
|
};
|
|
23021
23413
|
}
|
|
23022
23414
|
|
|
23023
23415
|
// src/webhook-tools.ts
|
|
23024
|
-
function
|
|
23416
|
+
function mapMcpError14(error) {
|
|
23025
23417
|
if (error instanceof WebhookApiError) {
|
|
23026
23418
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23027
23419
|
}
|
|
@@ -23042,7 +23434,7 @@ function createWebhookMcpTools(api) {
|
|
|
23042
23434
|
webhooks: await api.listWebhooks(requestInput)
|
|
23043
23435
|
};
|
|
23044
23436
|
} catch (error) {
|
|
23045
|
-
|
|
23437
|
+
mapMcpError14(error);
|
|
23046
23438
|
}
|
|
23047
23439
|
},
|
|
23048
23440
|
async create_webhook(input) {
|
|
@@ -23063,7 +23455,7 @@ function createWebhookMcpTools(api) {
|
|
|
23063
23455
|
webhook: await api.createWebhook(requestInput)
|
|
23064
23456
|
};
|
|
23065
23457
|
} catch (error) {
|
|
23066
|
-
|
|
23458
|
+
mapMcpError14(error);
|
|
23067
23459
|
}
|
|
23068
23460
|
},
|
|
23069
23461
|
async update_webhook(input) {
|
|
@@ -23088,7 +23480,7 @@ function createWebhookMcpTools(api) {
|
|
|
23088
23480
|
webhook: await api.updateWebhook(requestInput)
|
|
23089
23481
|
};
|
|
23090
23482
|
} catch (error) {
|
|
23091
|
-
|
|
23483
|
+
mapMcpError14(error);
|
|
23092
23484
|
}
|
|
23093
23485
|
},
|
|
23094
23486
|
async delete_webhook(input) {
|
|
@@ -23100,7 +23492,7 @@ function createWebhookMcpTools(api) {
|
|
|
23100
23492
|
})
|
|
23101
23493
|
};
|
|
23102
23494
|
} catch (error) {
|
|
23103
|
-
|
|
23495
|
+
mapMcpError14(error);
|
|
23104
23496
|
}
|
|
23105
23497
|
},
|
|
23106
23498
|
async test_webhook(input) {
|
|
@@ -23116,7 +23508,7 @@ function createWebhookMcpTools(api) {
|
|
|
23116
23508
|
delivery: await api.testWebhook(requestInput)
|
|
23117
23509
|
};
|
|
23118
23510
|
} catch (error) {
|
|
23119
|
-
|
|
23511
|
+
mapMcpError14(error);
|
|
23120
23512
|
}
|
|
23121
23513
|
},
|
|
23122
23514
|
async list_webhook_deliveries(input) {
|
|
@@ -23132,7 +23524,7 @@ function createWebhookMcpTools(api) {
|
|
|
23132
23524
|
deliveries: await api.listWebhookDeliveries(requestInput)
|
|
23133
23525
|
};
|
|
23134
23526
|
} catch (error) {
|
|
23135
|
-
|
|
23527
|
+
mapMcpError14(error);
|
|
23136
23528
|
}
|
|
23137
23529
|
},
|
|
23138
23530
|
async retry_webhook_delivery(input) {
|
|
@@ -23143,14 +23535,14 @@ function createWebhookMcpTools(api) {
|
|
|
23143
23535
|
deliveryId: String(input["deliveryId"])
|
|
23144
23536
|
});
|
|
23145
23537
|
} catch (error) {
|
|
23146
|
-
|
|
23538
|
+
mapMcpError14(error);
|
|
23147
23539
|
}
|
|
23148
23540
|
}
|
|
23149
23541
|
};
|
|
23150
23542
|
}
|
|
23151
23543
|
|
|
23152
23544
|
// src/weekly-report-tools.ts
|
|
23153
|
-
function
|
|
23545
|
+
function mapMcpError15(error) {
|
|
23154
23546
|
if (error instanceof WeeklyReportApiError) {
|
|
23155
23547
|
throw new Error(`mcp_tool_error:${error.code}`);
|
|
23156
23548
|
}
|
|
@@ -23168,7 +23560,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23168
23560
|
})
|
|
23169
23561
|
};
|
|
23170
23562
|
} catch (error) {
|
|
23171
|
-
|
|
23563
|
+
mapMcpError15(error);
|
|
23172
23564
|
}
|
|
23173
23565
|
},
|
|
23174
23566
|
async create_weekly_report_channel(input) {
|
|
@@ -23184,7 +23576,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23184
23576
|
})
|
|
23185
23577
|
};
|
|
23186
23578
|
} catch (error) {
|
|
23187
|
-
|
|
23579
|
+
mapMcpError15(error);
|
|
23188
23580
|
}
|
|
23189
23581
|
},
|
|
23190
23582
|
async update_weekly_report_channel(input) {
|
|
@@ -23199,7 +23591,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23199
23591
|
})
|
|
23200
23592
|
};
|
|
23201
23593
|
} catch (error) {
|
|
23202
|
-
|
|
23594
|
+
mapMcpError15(error);
|
|
23203
23595
|
}
|
|
23204
23596
|
},
|
|
23205
23597
|
async delete_weekly_report_channel(input) {
|
|
@@ -23211,7 +23603,7 @@ function createWeeklyReportMcpTools(api) {
|
|
|
23211
23603
|
})
|
|
23212
23604
|
};
|
|
23213
23605
|
} catch (error) {
|
|
23214
|
-
|
|
23606
|
+
mapMcpError15(error);
|
|
23215
23607
|
}
|
|
23216
23608
|
}
|
|
23217
23609
|
};
|
|
@@ -23262,6 +23654,7 @@ async function createDefaultMcpTools(input = {}) {
|
|
|
23262
23654
|
...createServicesMcpTools(retrievalApi),
|
|
23263
23655
|
...createTokenMcpTools(createTokenManagementApi(httpClient)),
|
|
23264
23656
|
...createWebhookMcpTools(createWebhookApi(httpClient)),
|
|
23657
|
+
...createSlackMcpTools(createSlackApi(httpClient)),
|
|
23265
23658
|
...createWeeklyReportMcpTools(createWeeklyReportApi(httpClient)),
|
|
23266
23659
|
...createAlertMcpTools(createAlertApi(httpClient)),
|
|
23267
23660
|
...createProjectMcpTools(createProjectManagementApi(httpClient)),
|
|
@@ -24946,6 +25339,45 @@ var MCP_TOOL_CATALOG = [
|
|
|
24946
25339
|
deliveryId: external_exports.string()
|
|
24947
25340
|
})
|
|
24948
25341
|
},
|
|
25342
|
+
{
|
|
25343
|
+
name: "list_slack_destinations",
|
|
25344
|
+
group: "slack",
|
|
25345
|
+
description: "List reusable connected Slack destinations for a project organization.",
|
|
25346
|
+
inputSchema: external_exports.object({
|
|
25347
|
+
bearerToken: external_exports.string(),
|
|
25348
|
+
projectId: external_exports.string()
|
|
25349
|
+
})
|
|
25350
|
+
},
|
|
25351
|
+
{
|
|
25352
|
+
name: "get_slack_connect_url",
|
|
25353
|
+
group: "slack",
|
|
25354
|
+
description: "Return a browser Slack connect URL for a project.",
|
|
25355
|
+
inputSchema: external_exports.object({
|
|
25356
|
+
bearerToken: external_exports.string(),
|
|
25357
|
+
projectId: external_exports.string(),
|
|
25358
|
+
returnTo: external_exports.string().optional()
|
|
25359
|
+
})
|
|
25360
|
+
},
|
|
25361
|
+
{
|
|
25362
|
+
name: "test_slack_destination",
|
|
25363
|
+
group: "slack",
|
|
25364
|
+
description: "Send a test message to a connected Slack destination.",
|
|
25365
|
+
inputSchema: external_exports.object({
|
|
25366
|
+
bearerToken: external_exports.string(),
|
|
25367
|
+
projectId: external_exports.string(),
|
|
25368
|
+
destinationId: external_exports.string()
|
|
25369
|
+
})
|
|
25370
|
+
},
|
|
25371
|
+
{
|
|
25372
|
+
name: "delete_slack_destination",
|
|
25373
|
+
group: "slack",
|
|
25374
|
+
description: "Delete a connected Slack destination from a project organization.",
|
|
25375
|
+
inputSchema: external_exports.object({
|
|
25376
|
+
bearerToken: external_exports.string(),
|
|
25377
|
+
projectId: external_exports.string(),
|
|
25378
|
+
destinationId: external_exports.string()
|
|
25379
|
+
})
|
|
25380
|
+
},
|
|
24949
25381
|
{
|
|
24950
25382
|
name: "list_weekly_report_channels",
|
|
24951
25383
|
group: "weekly_reports",
|