@debugbundle/mcp 0.1.1 → 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.
Files changed (2) hide show
  1. package/dist/main.cjs +870 -153
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -14551,7 +14551,8 @@ function createAlertApi(client) {
14551
14551
  const body = {
14552
14552
  project_id: input.projectId,
14553
14553
  channel: input.channel,
14554
- condition_type: input.conditionType
14554
+ condition_type: input.conditionType,
14555
+ config: input.config
14555
14556
  };
14556
14557
  if (input.serviceId !== void 0) {
14557
14558
  body.service_id = input.serviceId;
@@ -14559,9 +14560,6 @@ function createAlertApi(client) {
14559
14560
  if (input.severityMin !== void 0) {
14560
14561
  body.severity_min = input.severityMin;
14561
14562
  }
14562
- if (input.config !== void 0) {
14563
- body.config = input.config;
14564
- }
14565
14563
  if (input.isEnabled !== void 0) {
14566
14564
  body.is_enabled = input.isEnabled;
14567
14565
  }
@@ -15200,7 +15198,7 @@ function createProjectManagementApi(client) {
15200
15198
 
15201
15199
  // ../../packages/retrieval-client/src/index.ts
15202
15200
  var IncidentReasonSchema = external_exports.object({
15203
- kind: external_exports.enum(["backend_exception", "frontend_exception", "request_failure_5xx", "error_log"]),
15201
+ kind: external_exports.enum(["backend_exception", "frontend_exception", "request_failure", "error_log"]),
15204
15202
  description: external_exports.string(),
15205
15203
  event_type: external_exports.enum(["backend_exception", "frontend_exception", "request_event", "log_event"]),
15206
15204
  event_class: external_exports.literal("incident_signal"),
@@ -15522,6 +15520,121 @@ function createRetrievalApi(client) {
15522
15520
  };
15523
15521
  }
15524
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
+
15525
15638
  // ../../packages/token-management/src/index.ts
15526
15639
  var ProjectTokenSchema = external_exports.object({
15527
15640
  token_id: external_exports.string(),
@@ -15550,7 +15663,7 @@ var TokenListResponseSchema = external_exports.object({
15550
15663
  var TokenCreateResponseSchema = external_exports.object({
15551
15664
  token: external_exports.union([ProjectTokenSchema, MemberTokenSchema])
15552
15665
  }).strict();
15553
- var ApiErrorResponseSchema6 = external_exports.object({
15666
+ var ApiErrorResponseSchema7 = external_exports.object({
15554
15667
  error: external_exports.string()
15555
15668
  }).strict();
15556
15669
  var TokenManagementApiError = class extends Error {
@@ -15562,8 +15675,8 @@ var TokenManagementApiError = class extends Error {
15562
15675
  this.code = code;
15563
15676
  }
15564
15677
  };
15565
- function parseApiError6(status, body) {
15566
- const parsed = ApiErrorResponseSchema6.safeParse(body);
15678
+ function parseApiError7(status, body) {
15679
+ const parsed = ApiErrorResponseSchema7.safeParse(body);
15567
15680
  if (!parsed.success) {
15568
15681
  throw new TokenManagementApiError(status, "unknown_error");
15569
15682
  }
@@ -15572,7 +15685,7 @@ function parseApiError6(status, body) {
15572
15685
  async function expectTokenList(responsePromise) {
15573
15686
  const response = await responsePromise;
15574
15687
  if (response.status < 200 || response.status >= 300) {
15575
- parseApiError6(response.status, response.body);
15688
+ parseApiError7(response.status, response.body);
15576
15689
  }
15577
15690
  const parsed = TokenListResponseSchema.safeParse(response.body);
15578
15691
  if (!parsed.success) {
@@ -15583,7 +15696,7 @@ async function expectTokenList(responsePromise) {
15583
15696
  async function expectToken(responsePromise) {
15584
15697
  const response = await responsePromise;
15585
15698
  if (response.status < 200 || response.status >= 300) {
15586
- parseApiError6(response.status, response.body);
15699
+ parseApiError7(response.status, response.body);
15587
15700
  }
15588
15701
  const parsed = TokenCreateResponseSchema.safeParse(response.body);
15589
15702
  if (!parsed.success) {
@@ -15775,7 +15888,7 @@ var RetryWebhookDeliveryResponseSchema = external_exports.object({
15775
15888
  delivery_id: external_exports.string(),
15776
15889
  event_type: WebhookEventTypeSchema
15777
15890
  }).strict();
15778
- var ApiErrorResponseSchema7 = external_exports.object({
15891
+ var ApiErrorResponseSchema8 = external_exports.object({
15779
15892
  error: external_exports.string()
15780
15893
  }).strict();
15781
15894
  var WebhookApiError = class extends Error {
@@ -15787,14 +15900,14 @@ var WebhookApiError = class extends Error {
15787
15900
  this.code = code;
15788
15901
  }
15789
15902
  };
15790
- function parseApiError7(status, body) {
15791
- const parsed = ApiErrorResponseSchema7.safeParse(body);
15903
+ function parseApiError8(status, body) {
15904
+ const parsed = ApiErrorResponseSchema8.safeParse(body);
15792
15905
  if (!parsed.success) {
15793
15906
  throw new WebhookApiError(status, "unknown_error");
15794
15907
  }
15795
15908
  throw new WebhookApiError(status, parsed.data.error);
15796
15909
  }
15797
- function buildQuery2(input) {
15910
+ function buildQuery3(input) {
15798
15911
  const params = new URLSearchParams();
15799
15912
  for (const [key, value] of Object.entries(input)) {
15800
15913
  if (value !== void 0) {
@@ -15807,7 +15920,7 @@ function buildQuery2(input) {
15807
15920
  async function expectWebhookList(responsePromise) {
15808
15921
  const response = await responsePromise;
15809
15922
  if (response.status < 200 || response.status >= 300) {
15810
- parseApiError7(response.status, response.body);
15923
+ parseApiError8(response.status, response.body);
15811
15924
  }
15812
15925
  const parsed = WebhookListResponseSchema.safeParse(response.body);
15813
15926
  if (!parsed.success) {
@@ -15818,7 +15931,7 @@ async function expectWebhookList(responsePromise) {
15818
15931
  async function expectWebhook(responsePromise) {
15819
15932
  const response = await responsePromise;
15820
15933
  if (response.status < 200 || response.status >= 300) {
15821
- parseApiError7(response.status, response.body);
15934
+ parseApiError8(response.status, response.body);
15822
15935
  }
15823
15936
  const parsed = WebhookResponseSchema.safeParse(response.body);
15824
15937
  if (!parsed.success) {
@@ -15829,7 +15942,7 @@ async function expectWebhook(responsePromise) {
15829
15942
  async function expectCreatedWebhook(responsePromise) {
15830
15943
  const response = await responsePromise;
15831
15944
  if (response.status < 200 || response.status >= 300) {
15832
- parseApiError7(response.status, response.body);
15945
+ parseApiError8(response.status, response.body);
15833
15946
  }
15834
15947
  const parsed = WebhookCreateResponseSchema.safeParse(response.body);
15835
15948
  if (!parsed.success) {
@@ -15840,7 +15953,7 @@ async function expectCreatedWebhook(responsePromise) {
15840
15953
  async function expectWebhookDeliveries(responsePromise) {
15841
15954
  const response = await responsePromise;
15842
15955
  if (response.status < 200 || response.status >= 300) {
15843
- parseApiError7(response.status, response.body);
15956
+ parseApiError8(response.status, response.body);
15844
15957
  }
15845
15958
  const parsed = WebhookDeliveriesResponseSchema.safeParse(response.body);
15846
15959
  if (!parsed.success) {
@@ -15851,7 +15964,7 @@ async function expectWebhookDeliveries(responsePromise) {
15851
15964
  async function expectWebhookTestDelivery(responsePromise) {
15852
15965
  const response = await responsePromise;
15853
15966
  if (response.status < 200 || response.status >= 300) {
15854
- parseApiError7(response.status, response.body);
15967
+ parseApiError8(response.status, response.body);
15855
15968
  }
15856
15969
  const parsed = WebhookTestResponseSchema.safeParse(response.body);
15857
15970
  if (!parsed.success) {
@@ -15862,7 +15975,7 @@ async function expectWebhookTestDelivery(responsePromise) {
15862
15975
  async function expectRetryDelivery(responsePromise) {
15863
15976
  const response = await responsePromise;
15864
15977
  if (response.status < 200 || response.status >= 300) {
15865
- parseApiError7(response.status, response.body);
15978
+ parseApiError8(response.status, response.body);
15866
15979
  }
15867
15980
  const parsed = RetryWebhookDeliveryResponseSchema.safeParse(response.body);
15868
15981
  if (!parsed.success) {
@@ -15876,7 +15989,7 @@ function createWebhookApi(client) {
15876
15989
  return expectWebhookList(
15877
15990
  client.request({
15878
15991
  method: "GET",
15879
- path: `/v1/webhooks${buildQuery2({ project_id: input.projectId, limit: input.limit })}`,
15992
+ path: `/v1/webhooks${buildQuery3({ project_id: input.projectId, limit: input.limit })}`,
15880
15993
  bearerToken: input.bearerToken
15881
15994
  })
15882
15995
  );
@@ -15941,7 +16054,7 @@ function createWebhookApi(client) {
15941
16054
  bearerToken: input.bearerToken
15942
16055
  });
15943
16056
  if (response.status < 200 || response.status >= 300) {
15944
- parseApiError7(response.status, response.body);
16057
+ parseApiError8(response.status, response.body);
15945
16058
  }
15946
16059
  return {
15947
16060
  webhook_id: input.webhookId
@@ -15965,7 +16078,7 @@ function createWebhookApi(client) {
15965
16078
  return expectWebhookDeliveries(
15966
16079
  client.request({
15967
16080
  method: "GET",
15968
- path: `/v1/webhooks/${input.webhookId}/deliveries${buildQuery2({ limit: input.limit })}`,
16081
+ path: `/v1/webhooks/${input.webhookId}/deliveries${buildQuery3({ limit: input.limit })}`,
15969
16082
  bearerToken: input.bearerToken
15970
16083
  })
15971
16084
  );
@@ -16015,7 +16128,7 @@ var WeeklyReportChannelListResponseSchema = external_exports.object({
16015
16128
  var WeeklyReportChannelResponseSchema = external_exports.object({
16016
16129
  channel: WeeklyReportChannelRecordSchema
16017
16130
  }).strict();
16018
- var ApiErrorResponseSchema8 = external_exports.object({
16131
+ var ApiErrorResponseSchema9 = external_exports.object({
16019
16132
  error: external_exports.string()
16020
16133
  }).strict();
16021
16134
  var WeeklyReportApiError = class extends Error {
@@ -16027,14 +16140,14 @@ var WeeklyReportApiError = class extends Error {
16027
16140
  this.code = code;
16028
16141
  }
16029
16142
  };
16030
- function parseApiError8(status, body) {
16031
- const parsed = ApiErrorResponseSchema8.safeParse(body);
16143
+ function parseApiError9(status, body) {
16144
+ const parsed = ApiErrorResponseSchema9.safeParse(body);
16032
16145
  if (!parsed.success) {
16033
16146
  throw new WeeklyReportApiError(status, "unknown_error");
16034
16147
  }
16035
16148
  throw new WeeklyReportApiError(status, parsed.data.error);
16036
16149
  }
16037
- function buildQuery3(input) {
16150
+ function buildQuery4(input) {
16038
16151
  const params = new URLSearchParams();
16039
16152
  for (const [key, value] of Object.entries(input)) {
16040
16153
  if (value !== void 0) {
@@ -16047,7 +16160,7 @@ function buildQuery3(input) {
16047
16160
  async function expectChannelList(responsePromise) {
16048
16161
  const response = await responsePromise;
16049
16162
  if (response.status < 200 || response.status >= 300) {
16050
- parseApiError8(response.status, response.body);
16163
+ parseApiError9(response.status, response.body);
16051
16164
  }
16052
16165
  const parsed = WeeklyReportChannelListResponseSchema.safeParse(response.body);
16053
16166
  if (!parsed.success) {
@@ -16058,7 +16171,7 @@ async function expectChannelList(responsePromise) {
16058
16171
  async function expectChannel(responsePromise) {
16059
16172
  const response = await responsePromise;
16060
16173
  if (response.status < 200 || response.status >= 300) {
16061
- parseApiError8(response.status, response.body);
16174
+ parseApiError9(response.status, response.body);
16062
16175
  }
16063
16176
  const parsed = WeeklyReportChannelResponseSchema.safeParse(response.body);
16064
16177
  if (!parsed.success) {
@@ -16072,13 +16185,13 @@ function createWeeklyReportApi(client) {
16072
16185
  return expectChannelList(
16073
16186
  client.request({
16074
16187
  method: "GET",
16075
- path: `/v1/weekly-report-channels${buildQuery3({ project_id: input.projectId, limit: input.limit })}`,
16188
+ path: `/v1/weekly-report-channels${buildQuery4({ project_id: input.projectId, limit: input.limit })}`,
16076
16189
  bearerToken: input.bearerToken
16077
16190
  })
16078
16191
  );
16079
16192
  },
16080
16193
  async createWeeklyReportChannel(input) {
16081
- 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 };
16082
16195
  return expectChannel(
16083
16196
  client.request({
16084
16197
  method: "POST",
@@ -16101,7 +16214,7 @@ function createWeeklyReportApi(client) {
16101
16214
  async updateWeeklyReportChannel(input) {
16102
16215
  const body = {};
16103
16216
  if (input.config !== void 0) {
16104
- 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 };
16105
16218
  }
16106
16219
  if (input.schedule !== void 0) {
16107
16220
  body["schedule"] = {
@@ -16129,7 +16242,7 @@ function createWeeklyReportApi(client) {
16129
16242
  bearerToken: input.bearerToken
16130
16243
  });
16131
16244
  if (response.status < 200 || response.status >= 300) {
16132
- parseApiError8(response.status, response.body);
16245
+ parseApiError9(response.status, response.body);
16133
16246
  }
16134
16247
  return { channel_id: input.channelId };
16135
16248
  }
@@ -16161,6 +16274,8 @@ var CaptureBreadcrumbsValues = ["local_only", "exception_only", "standalone"];
16161
16274
  var CaptureBreadcrumbsSchema = external_exports.enum(CaptureBreadcrumbsValues);
16162
16275
  var CaptureProbeEventsValues = ["buffer_only", "standalone_when_activated"];
16163
16276
  var CaptureProbeEventsSchema = external_exports.enum(CaptureProbeEventsValues);
16277
+ var RequestSignalClassificationValues = ["incident_signal", "context_signal"];
16278
+ var RequestSignalClassificationSchema = external_exports.enum(RequestSignalClassificationValues);
16164
16279
  var CapturePolicySchema = external_exports.object({
16165
16280
  project_id: external_exports.string().uuid(),
16166
16281
  preset: CapturePresetSchema,
@@ -16177,6 +16292,55 @@ var CapturePolicyUpdateSchema = external_exports.object({
16177
16292
  capture_breadcrumbs: CaptureBreadcrumbsSchema.nullable().optional(),
16178
16293
  capture_probe_events: CaptureProbeEventsSchema.nullable().optional()
16179
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
+ }
16180
16344
 
16181
16345
  // ../../packages/shared-types/src/index.ts
16182
16346
  function createUuidV4() {
@@ -16225,6 +16389,26 @@ var InlineProbeDataSchema = external_exports.object({
16225
16389
  version: external_exports.literal(1),
16226
16390
  items: external_exports.array(InlineProbeDataItemSchema)
16227
16391
  }).strict();
16392
+ var RuntimeMemoryStatsSchema = external_exports.object({
16393
+ rss: external_exports.number().nonnegative().nullable(),
16394
+ heap_total: external_exports.number().nonnegative().nullable(),
16395
+ heap_used: external_exports.number().nonnegative().nullable(),
16396
+ external: external_exports.number().nonnegative().nullable(),
16397
+ peak: external_exports.number().nonnegative().nullable()
16398
+ }).strict();
16399
+ var BackendRuntimePayloadSchema = external_exports.object({
16400
+ version: external_exports.string().min(1),
16401
+ platform: external_exports.string().min(1).nullable().optional(),
16402
+ arch: external_exports.string().min(1).nullable().optional(),
16403
+ pid: external_exports.number().int().nonnegative().nullable().optional(),
16404
+ cwd: external_exports.string().min(1).nullable().optional(),
16405
+ uptime_sec: external_exports.number().nonnegative().nullable().optional(),
16406
+ hostname: external_exports.string().min(1).nullable().optional(),
16407
+ thread_id: external_exports.union([external_exports.string(), external_exports.number()]).nullable().optional(),
16408
+ framework_version: external_exports.string().min(1).nullable().optional(),
16409
+ memory: RuntimeMemoryStatsSchema.nullable().optional(),
16410
+ framework_extras: external_exports.record(external_exports.string(), external_exports.unknown()).nullable().optional()
16411
+ }).strict();
16228
16412
  var BackendExceptionPayloadSchema = external_exports.object({
16229
16413
  name: external_exports.string().min(1),
16230
16414
  message: external_exports.string().min(1),
@@ -16242,9 +16426,7 @@ var BackendExceptionPayloadSchema = external_exports.object({
16242
16426
  headers: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
16243
16427
  body: external_exports.unknown().optional()
16244
16428
  }),
16245
- runtime: external_exports.object({
16246
- version: external_exports.string().min(1)
16247
- }),
16429
+ runtime: BackendRuntimePayloadSchema,
16248
16430
  probe_data: InlineProbeDataSchema.optional()
16249
16431
  }).strict();
16250
16432
  var RequestEventPayloadSchema = external_exports.object({
@@ -16515,13 +16697,7 @@ var ContextDeploySchema = external_exports.object({
16515
16697
  deployed_at: external_exports.string().datetime().nullable(),
16516
16698
  regression_window: external_exports.boolean().nullable()
16517
16699
  });
16518
- var MemoryStatsSchema = external_exports.object({
16519
- rss: external_exports.number().nonnegative().nullable(),
16520
- heap_total: external_exports.number().nonnegative().nullable(),
16521
- heap_used: external_exports.number().nonnegative().nullable(),
16522
- external: external_exports.number().nonnegative().nullable(),
16523
- peak: external_exports.number().nonnegative().nullable()
16524
- });
16700
+ var MemoryStatsSchema = RuntimeMemoryStatsSchema;
16525
16701
  var ContextRuntimeSchema = external_exports.object({
16526
16702
  version: external_exports.literal(1),
16527
16703
  name: external_exports.string().min(1),
@@ -16773,7 +16949,7 @@ function buildCliReference() {
16773
16949
  "- `debugbundle ingest <file> --format <format> [--json]`",
16774
16950
  "- `debugbundle watch --log <file> --format <format> [--json]`",
16775
16951
  "- `debugbundle watch --cloud --log <file> --format <format> [--json]`",
16776
- "- `debugbundle process [--json]`",
16952
+ "- `debugbundle process [--preset <minimal|balanced|investigative>] [--json]`",
16777
16953
  "",
16778
16954
  "## Investigation",
16779
16955
  "",
@@ -17865,7 +18041,7 @@ function getRequestResponseStatus(payload) {
17865
18041
  const status = payload?.["response_status"];
17866
18042
  return typeof status === "number" && Number.isFinite(status) ? status : null;
17867
18043
  }
17868
- function classifyEvent(eventType, logLevel, probeActivationId, payload) {
18044
+ function classifyEvent(eventType, logLevel, probeActivationId, payload, capturePreset = "minimal") {
17869
18045
  switch (eventType) {
17870
18046
  case "backend_exception":
17871
18047
  case "frontend_exception":
@@ -17877,10 +18053,7 @@ function classifyEvent(eventType, logLevel, probeActivationId, payload) {
17877
18053
  return "context_signal";
17878
18054
  case "request_event": {
17879
18055
  const responseStatus = getRequestResponseStatus(payload);
17880
- if (responseStatus !== null && responseStatus >= 500) {
17881
- return "incident_signal";
17882
- }
17883
- return "context_signal";
18056
+ return classifyRequestStatus({ responseStatus, capturePreset });
17884
18057
  }
17885
18058
  case "frontend_breadcrumb":
17886
18059
  case "deploy_metadata":
@@ -17929,7 +18102,7 @@ var RELAY_SPOOL_DELIVERED_MARKER_SUFFIX = ".delivered";
17929
18102
  var RELAY_SPOOL_EVENT_SUFFIX = ".events.json";
17930
18103
  var SUGGESTED_ACTIONS = [
17931
18104
  "Run debugbundle setup if local scaffold files are missing.",
17932
- "Run debugbundle login to create ~/.debugbundle/auth.json.",
18105
+ "Run debugbundle login to choose an auth flow, or use debugbundle login --github, debugbundle login --github-device, or debugbundle login <dbundle_mem_...> to create ~/.debugbundle/auth.json.",
17933
18106
  "Review .debugbundle/profile.json when architecture changes or the profile becomes stale."
17934
18107
  ];
17935
18108
  async function pathExists3(path, stat) {
@@ -18042,7 +18215,7 @@ function buildPrivacyPreview() {
18042
18215
  sample_event_type: sampleEvent.event_type,
18043
18216
  sample_event_class: sampleEventClass,
18044
18217
  sample_can_create_incident: sampleEventClass === "incident_signal",
18045
- incident_rule: "request_event with response_status >= 500 is classified as an incident_signal",
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.",
18046
18219
  redacted_fields,
18047
18220
  omitted_fields: [],
18048
18221
  retained_metadata: {
@@ -18553,7 +18726,8 @@ function buildRedactionRecord(bundleBody) {
18553
18726
  function buildVisibilityRecord(input) {
18554
18727
  const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
18555
18728
  const matchedFields = input.incident.matched_fields.length === 0 ? "none" : input.incident.matched_fields.join(", ");
18556
- const grouping = input.primarySignal.kind === "request_failure_5xx" && input.primarySignal.request_method !== null && routeTarget !== null ? `Repeated 5xx request failures 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}.`;
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}.`;
18557
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}.`;
18558
18732
  return {
18559
18733
  grouping,
@@ -18564,15 +18738,16 @@ function buildVisibilityRecord(input) {
18564
18738
  }
18565
18739
  function buildSuggestedNextChecks(input) {
18566
18740
  const suggestions = [];
18741
+ const isRequestAnomaly = input.incident.matched_fields.includes("request_anomaly");
18567
18742
  if (input.bundle.status === "pending") {
18568
18743
  suggestions.push("Wait for bundle generation to finish, then rerun the incident context command.");
18569
18744
  } else if (input.bundle.status === "failed") {
18570
18745
  suggestions.push("Inspect bundle generation status or retry bundle retrieval to recover missing context.");
18571
18746
  }
18572
18747
  const routeTarget = input.primarySignal.route_template ?? input.primarySignal.request_path;
18573
- if (input.primarySignal.request_method !== null && input.primarySignal.response_status !== null && input.primarySignal.response_status >= 500) {
18748
+ if (input.primarySignal.kind === "request_failure" && input.primarySignal.request_method !== null && routeTarget !== null) {
18574
18749
  suggestions.push(
18575
- `Inspect the ${input.primarySignal.request_method} ${routeTarget ?? "request"} handler behind this 5xx path.`
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.`
18576
18751
  );
18577
18752
  }
18578
18753
  const firstApplicationFrame = input.primarySignal.first_application_frame;
@@ -18661,12 +18836,13 @@ function deriveIncidentReasonFromSignal(input) {
18661
18836
  };
18662
18837
  case "request_event": {
18663
18838
  const responseStatus = typeof input.response_status === "number" && Number.isFinite(input.response_status) ? input.response_status : null;
18839
+ const isRequestAnomaly = input.request_anomaly === true;
18664
18840
  return {
18665
- kind: "request_failure_5xx",
18666
- description: responseStatus !== null && responseStatus >= 500 ? `request_event response_status=${responseStatus} matched the 5xx request incident rule` : "request_event matched the 5xx request incident rule",
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",
18667
18843
  event_type: "request_event",
18668
18844
  event_class: "incident_signal",
18669
- matched_policy: "5xx request failures bypass capture_request_events suppression"
18845
+ matched_policy: isRequestAnomaly ? "Repeated contextual request failures crossed the request anomaly threshold" : "Immediate request failure statuses bypass capture_request_events suppression"
18670
18846
  };
18671
18847
  }
18672
18848
  case "log_event": {
@@ -18695,9 +18871,11 @@ function deriveIncidentReasonFromSourceEventTypes(eventTypes) {
18695
18871
  return null;
18696
18872
  }
18697
18873
 
18698
- // ../../packages/auth/src/index.ts
18874
+ // ../../packages/auth/src/primitives.ts
18699
18875
  var import_argon2 = require("@node-rs/argon2");
18700
- var DEFAULT_SESSION_LIFETIME_MS = 1e3 * 60 * 60 * 4;
18876
+
18877
+ // ../../packages/auth/src/web-session-auth.ts
18878
+ var DEFAULT_SESSION_LIFETIME_MS = 1e3 * 60 * 60 * 24 * 7;
18701
18879
  var DEFAULT_EMAIL_AUTH_CODE_LIFETIME_MS = 1e3 * 60 * 10;
18702
18880
  var DEFAULT_GITHUB_OAUTH_STATE_LIFETIME_MS = 1e3 * 60 * 10;
18703
18881
 
@@ -18736,6 +18914,70 @@ var STORAGE_SCHEMA_MIGRATIONS = [
18736
18914
  "ALTER TABLE organizations ADD COLUMN IF NOT EXISTS suspended_at timestamptz",
18737
18915
  "ALTER TABLE organization_members ADD COLUMN IF NOT EXISTS suspended_at timestamptz"
18738
18916
  ]
18917
+ }),
18918
+ defineStorageSchemaMigration({
18919
+ id: "202605120001_add_github_device_authorizations",
18920
+ description: "Add persisted GitHub CLI bootstrap state for device-flow login.",
18921
+ statements: [
18922
+ `
18923
+ CREATE TABLE IF NOT EXISTS github_device_authorizations (
18924
+ id uuid PRIMARY KEY,
18925
+ device_code text NOT NULL UNIQUE,
18926
+ user_code text NOT NULL,
18927
+ verification_uri text NOT NULL,
18928
+ interval_seconds integer NOT NULL,
18929
+ expires_at timestamptz NOT NULL,
18930
+ accepted_terms_at timestamptz,
18931
+ created_at timestamptz NOT NULL DEFAULT now(),
18932
+ completed_at timestamptz,
18933
+ claimed_at timestamptz,
18934
+ terminal_error text,
18935
+ user_id uuid REFERENCES users(id) ON DELETE SET NULL,
18936
+ organization_id uuid REFERENCES organizations(id) ON DELETE SET NULL
18937
+ )
18938
+ `,
18939
+ `
18940
+ CREATE INDEX IF NOT EXISTS github_device_authorizations_user_code_idx
18941
+ ON github_device_authorizations (user_code, created_at DESC)
18942
+ `,
18943
+ `
18944
+ CREATE INDEX IF NOT EXISTS github_device_authorizations_expires_at_idx
18945
+ ON github_device_authorizations (expires_at)
18946
+ `
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
+ ]
18739
18981
  })
18740
18982
  ];
18741
18983
 
@@ -18749,6 +18991,7 @@ var import_promises5 = require("node:fs/promises");
18749
18991
  var import_node_path6 = require("node:path");
18750
18992
 
18751
18993
  // ../../packages/bundle-engine/src/index.ts
18994
+ var DYNAMIC_SEGMENT_PATTERN2 = /^(?:\d+|[0-9a-f]{8}-[0-9a-f-]{27}|[A-Za-z0-9_-]{24,})$/;
18752
18995
  function toIsoTimestamp(value) {
18753
18996
  return new Date(value).toISOString();
18754
18997
  }
@@ -18822,6 +19065,41 @@ function inferSignalTypeFromSourceEventTypes(sourceEventTypes) {
18822
19065
  function extractTopFrames(stack) {
18823
19066
  return stack.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("at ")).slice(0, 3);
18824
19067
  }
19068
+ function decodeRouteSegment2(segment) {
19069
+ try {
19070
+ return decodeURIComponent(segment);
19071
+ } catch {
19072
+ return segment.replace(
19073
+ /%([0-9A-Fa-f]{2})/g,
19074
+ (_match, hexByte) => String.fromCharCode(parseInt(hexByte, 16))
19075
+ );
19076
+ }
19077
+ }
19078
+ function isDynamicRouteSegment2(segment) {
19079
+ if (DYNAMIC_SEGMENT_PATTERN2.test(segment)) {
19080
+ return true;
19081
+ }
19082
+ const decodedSegment = decodeRouteSegment2(segment);
19083
+ if (decodedSegment.includes("/")) {
19084
+ return true;
19085
+ }
19086
+ if (decodedSegment !== segment && DYNAMIC_SEGMENT_PATTERN2.test(decodedSegment)) {
19087
+ return true;
19088
+ }
19089
+ const strippedMalformedPercent = decodedSegment.replace(/%+/g, "");
19090
+ return strippedMalformedPercent !== decodedSegment && DYNAMIC_SEGMENT_PATTERN2.test(strippedMalformedPercent);
19091
+ }
19092
+ function normalizeRouteTemplate(path) {
19093
+ if (path === null || path.length === 0) {
19094
+ return null;
19095
+ }
19096
+ const pathWithoutQueryOrFragment = path.split(/[?#]/, 1)[0] ?? "";
19097
+ if (pathWithoutQueryOrFragment.length === 0) {
19098
+ return "/";
19099
+ }
19100
+ const normalizedSegments = pathWithoutQueryOrFragment.split("/").filter((segment) => segment.length > 0).map((segment) => isDynamicRouteSegment2(segment) ? "{param}" : segment);
19101
+ return normalizedSegments.length === 0 ? "/" : `/${normalizedSegments.join("/")}`;
19102
+ }
18825
19103
  function deriveFirstApplicationFrame(errorContext) {
18826
19104
  const firstFrame = errorContext?.top_frames[0];
18827
19105
  if (firstFrame === void 0) {
@@ -18915,13 +19193,135 @@ function buildRequestContext(envelopes) {
18915
19193
  version: 1,
18916
19194
  method: exceptionEvent.payload.request.method,
18917
19195
  path: exceptionEvent.payload.request.path,
18918
- route_template: null,
19196
+ route_template: normalizeRouteTemplate(exceptionEvent.payload.request.path),
18919
19197
  query: exceptionEvent.payload.request.query,
18920
19198
  headers: exceptionEvent.payload.request.headers,
18921
19199
  body: exceptionEvent.payload.request.body ?? null,
18922
19200
  request_id: exceptionEvent.correlation?.request_id ?? null
18923
19201
  };
18924
19202
  }
19203
+ function titleCaseWord(value) {
19204
+ if (value.toLowerCase() === "github") {
19205
+ return "GitHub";
19206
+ }
19207
+ if (value.toLowerCase() === "api") {
19208
+ return "API";
19209
+ }
19210
+ return `${value.slice(0, 1).toUpperCase()}${value.slice(1)}`;
19211
+ }
19212
+ function formatDependencyName(name) {
19213
+ return name.split("_").filter((part) => part.length > 0).map(titleCaseWord).join(" ");
19214
+ }
19215
+ function inferDependencyName(text) {
19216
+ const match = /\b([a-z][a-z0-9]*_api)_(?:invalid_response|error|failure|failed|unavailable|timeout)\b/.exec(text);
19217
+ return match?.[1] ?? null;
19218
+ }
19219
+ function buildDependenciesContext(incident, errorContext, requestContext) {
19220
+ if (errorContext === null) {
19221
+ return null;
19222
+ }
19223
+ const text = `${incident.title} ${errorContext.name} ${errorContext.message}`.toLowerCase();
19224
+ const dependencyName = inferDependencyName(text);
19225
+ if (dependencyName === null) {
19226
+ return null;
19227
+ }
19228
+ const displayName = formatDependencyName(dependencyName);
19229
+ const route = requestContext?.route_template ?? requestContext?.path ?? null;
19230
+ const requestDescription = requestContext !== null ? `${requestContext.method} ${route ?? requestContext.path}` : "the failing request";
19231
+ const invalidResponse = text.includes("invalid_response");
19232
+ return {
19233
+ version: 1,
19234
+ items: [
19235
+ {
19236
+ name: dependencyName,
19237
+ status: "failed",
19238
+ notes: invalidResponse ? `${displayName} returned an unexpected response shape while handling ${requestDescription}.` : `${displayName} failed while handling ${requestDescription}.`
19239
+ }
19240
+ ]
19241
+ };
19242
+ }
19243
+ function buildSummaryGuidance(input) {
19244
+ if (input.errorContext === null) {
19245
+ return {
19246
+ likely_cause: null,
19247
+ confidence: 0,
19248
+ recommended_action: null
19249
+ };
19250
+ }
19251
+ const route = input.requestContext?.route_template ?? input.requestContext?.path ?? null;
19252
+ const requestDescription = input.requestContext !== null ? `${input.requestContext.method} ${route ?? input.requestContext.path}` : null;
19253
+ const firstDependency = input.dependenciesContext?.items[0] ?? null;
19254
+ const dependencyDisplayName = firstDependency !== null ? formatDependencyName(firstDependency.name) : null;
19255
+ const firstFrame = input.firstApplicationFrame;
19256
+ const frameDescription = firstFrame?.file !== null && firstFrame?.file !== void 0 ? ` in ${firstFrame.file}` : "";
19257
+ const invalidResponse = input.errorContext.message.toLowerCase().includes("invalid_response");
19258
+ let likelyCause = null;
19259
+ let recommendedAction = null;
19260
+ if (firstDependency !== null && dependencyDisplayName !== null && requestDescription !== null && invalidResponse) {
19261
+ likelyCause = `${dependencyDisplayName} returned a response that did not match the expected schema while handling ${requestDescription}.`;
19262
+ recommendedAction = `Inspect the ${dependencyDisplayName} response handling${frameDescription}, including schema validation and sanitized upstream response shape.`;
19263
+ } else if (firstDependency !== null && dependencyDisplayName !== null && requestDescription !== null) {
19264
+ likelyCause = `${dependencyDisplayName} failed while handling ${requestDescription}.`;
19265
+ recommendedAction = `Inspect the ${dependencyDisplayName} call path${frameDescription} and compare the captured dependency notes with upstream status.`;
19266
+ } else if (requestDescription !== null) {
19267
+ likelyCause = `${input.errorContext.name} occurred while handling ${requestDescription}${frameDescription}.`;
19268
+ recommendedAction = `Inspect the first application frame${frameDescription} and the captured request/response context.`;
19269
+ } else if (firstFrame !== null) {
19270
+ likelyCause = `${input.errorContext.name} originated from the first captured application frame${frameDescription}.`;
19271
+ recommendedAction = `Inspect the first application frame${frameDescription} and surrounding error handling.`;
19272
+ }
19273
+ if (likelyCause === null || recommendedAction === null) {
19274
+ return {
19275
+ likely_cause: null,
19276
+ confidence: 0,
19277
+ recommended_action: null
19278
+ };
19279
+ }
19280
+ let confidence = 0.25;
19281
+ if (input.requestContext !== null) confidence += 0.15;
19282
+ if (input.responseContext !== null) confidence += 0.1;
19283
+ if (firstFrame !== null && firstFrame.file !== null) confidence += 0.1;
19284
+ if (firstDependency !== null) confidence += 0.1;
19285
+ if (input.errorContext.message.length > 0) confidence += 0.05;
19286
+ return {
19287
+ likely_cause: likelyCause,
19288
+ confidence: Math.min(0.8, Number(confidence.toFixed(2))),
19289
+ recommended_action: recommendedAction
19290
+ };
19291
+ }
19292
+ function normalizeBaseUrl3(value) {
19293
+ const trimmed = value?.trim();
19294
+ if (trimmed === void 0 || trimmed.length === 0) {
19295
+ return null;
19296
+ }
19297
+ return trimmed.replace(/\/+$/, "");
19298
+ }
19299
+ function buildLinks(incident, linkBaseUrls) {
19300
+ const apiBaseUrl = normalizeBaseUrl3(linkBaseUrls?.api);
19301
+ const appBaseUrl = normalizeBaseUrl3(linkBaseUrls?.app);
19302
+ const docsBaseUrl = normalizeBaseUrl3(linkBaseUrls?.docs);
19303
+ const incidentPath = `/v1/incidents/${encodeURIComponent(incident.incident_id)}`;
19304
+ const appIncidentPath = `/incidents/${encodeURIComponent(incident.incident_id)}`;
19305
+ const appProjectPath = `/projects/${encodeURIComponent(incident.project_id)}`;
19306
+ return {
19307
+ self: apiBaseUrl !== null ? `${apiBaseUrl}${incidentPath}/bundle` : null,
19308
+ reproduction: apiBaseUrl !== null ? `${apiBaseUrl}${incidentPath}/reproduction` : null,
19309
+ incident: appBaseUrl !== null ? `${appBaseUrl}${appIncidentPath}` : null,
19310
+ project: appBaseUrl !== null ? `${appBaseUrl}${appProjectPath}` : null,
19311
+ docs: docsBaseUrl !== null ? `${docsBaseUrl}/bundles` : null
19312
+ };
19313
+ }
19314
+ function applyBundleRedaction(candidate) {
19315
+ const redactionResult = redact(candidate);
19316
+ const fields = [...new Set(redactionResult.redacted_fields)].sort();
19317
+ const redactedBundle = redactionResult.redacted;
19318
+ redactedBundle["redaction"] = {
19319
+ redacted: true,
19320
+ fields,
19321
+ notes: fields.length > 0 ? "Sensitive bundle fields were redacted before storage." : null
19322
+ };
19323
+ return redactedBundle;
19324
+ }
18925
19325
  function buildResponseContext(envelopes) {
18926
19326
  const requestEvent = selectLatestEnvelopeByType(envelopes, isRequestEventEnvelope);
18927
19327
  if (requestEvent !== null) {
@@ -19054,17 +19454,31 @@ function buildFrontendContext(envelopes) {
19054
19454
  dom_context: domContext
19055
19455
  };
19056
19456
  }
19057
- function buildDeployContext(envelopes, trigger) {
19457
+ function buildDeployContext(envelopes, trigger, configuredDeploy) {
19058
19458
  const envelope = selectLatestEnvelopeByType(envelopes, isDeployMetadataEnvelope);
19059
- if (envelope === null) {
19459
+ if (envelope !== null) {
19460
+ return {
19461
+ version: 1,
19462
+ commit_sha: envelope.payload.commit_sha,
19463
+ deploy_version: envelope.payload.version,
19464
+ branch: envelope.payload.branch,
19465
+ deployed_at: toIsoTimestamp(envelope.payload.deployed_at),
19466
+ regression_window: trigger === "regression_reopen"
19467
+ };
19468
+ }
19469
+ const commitSha = configuredDeploy?.commit_sha ?? null;
19470
+ const deployVersion = configuredDeploy?.deploy_version ?? null;
19471
+ const branch = configuredDeploy?.branch ?? null;
19472
+ const deployedAt = configuredDeploy?.deployed_at ?? null;
19473
+ if (commitSha === null && deployVersion === null && branch === null && deployedAt === null) {
19060
19474
  return null;
19061
19475
  }
19062
19476
  return {
19063
19477
  version: 1,
19064
- commit_sha: envelope.payload.commit_sha,
19065
- deploy_version: envelope.payload.version,
19066
- branch: envelope.payload.branch,
19067
- deployed_at: toIsoTimestamp(envelope.payload.deployed_at),
19478
+ commit_sha: commitSha,
19479
+ deploy_version: deployVersion,
19480
+ branch,
19481
+ deployed_at: deployedAt === null ? null : toIsoTimestamp(deployedAt),
19068
19482
  regression_window: trigger === "regression_reopen"
19069
19483
  };
19070
19484
  }
@@ -19073,34 +19487,49 @@ function buildRuntimeContext(envelopes) {
19073
19487
  if (backendException === null) {
19074
19488
  return null;
19075
19489
  }
19490
+ const runtime = backendException.payload.runtime;
19076
19491
  return {
19077
19492
  version: 1,
19078
19493
  name: backendException.service.runtime ?? "unknown",
19079
- runtime_version: backendException.payload.runtime.version,
19080
- platform: null,
19081
- arch: null,
19082
- pid: null,
19083
- cwd: null,
19084
- uptime_sec: null,
19085
- hostname: null,
19086
- thread_id: null,
19494
+ runtime_version: runtime.version,
19495
+ platform: runtime.platform ?? null,
19496
+ arch: runtime.arch ?? null,
19497
+ pid: runtime.pid ?? null,
19498
+ cwd: runtime.cwd ?? null,
19499
+ uptime_sec: runtime.uptime_sec ?? null,
19500
+ hostname: runtime.hostname ?? null,
19501
+ thread_id: runtime.thread_id ?? null,
19087
19502
  framework: backendException.service.framework ?? null,
19088
- framework_version: null,
19089
- memory: null,
19090
- framework_extras: null
19503
+ framework_version: runtime.framework_version ?? null,
19504
+ memory: runtime.memory ?? null,
19505
+ framework_extras: runtime.framework_extras ?? null
19091
19506
  };
19092
19507
  }
19093
- function buildGitContext(envelopes) {
19508
+ function buildGitContext(envelopes, configuredDeploy) {
19094
19509
  const deployEnvelope = selectLatestEnvelopeByType(envelopes, isDeployMetadataEnvelope);
19095
19510
  if (deployEnvelope === null) {
19096
- return null;
19511
+ const commit = configuredDeploy?.commit_sha ?? null;
19512
+ const branch = configuredDeploy?.branch ?? null;
19513
+ const repo = configuredDeploy?.repo ?? null;
19514
+ if (commit === null && branch === null && repo === null) {
19515
+ return null;
19516
+ }
19517
+ return {
19518
+ version: 1,
19519
+ commit,
19520
+ commit_short: commit === null ? null : commit.slice(0, 7),
19521
+ branch,
19522
+ repo,
19523
+ dirty: false,
19524
+ source: "env"
19525
+ };
19097
19526
  }
19098
19527
  return {
19099
19528
  version: 1,
19100
19529
  commit: deployEnvelope.payload.commit_sha,
19101
19530
  commit_short: deployEnvelope.payload.commit_sha.slice(0, 7),
19102
19531
  branch: deployEnvelope.payload.branch,
19103
- repo: null,
19532
+ repo: configuredDeploy?.repo ?? null,
19104
19533
  dirty: false,
19105
19534
  source: "env"
19106
19535
  };
@@ -19143,10 +19572,11 @@ function buildBundle(input) {
19143
19572
  const responseContext = buildResponseContext(sourceEnvelopes);
19144
19573
  const logsContext = buildLogsContext(sourceEnvelopes);
19145
19574
  const frontendContext = buildFrontendContext(sourceEnvelopes);
19146
- const deployContext = buildDeployContext(sourceEnvelopes, input.job.trigger);
19575
+ const deployContext = buildDeployContext(sourceEnvelopes, input.job.trigger, input.configuredDeploy);
19147
19576
  const runtimeContext = buildRuntimeContext(sourceEnvelopes);
19148
- const gitContext = buildGitContext(sourceEnvelopes);
19577
+ const gitContext = buildGitContext(sourceEnvelopes, input.configuredDeploy);
19149
19578
  const deviceContext = buildDeviceContext(sourceEnvelopes);
19579
+ const dependenciesContext = buildDependenciesContext(input.incident, errorContext, requestContext);
19150
19580
  const primarySignalType = primarySignalEnvelope !== null ? mapSignalType(primarySignalEnvelope.event_type) : inferSignalTypeFromSourceEventTypes(sourceEventTypes);
19151
19581
  const primarySourceEvent = errorContext?.name ?? sourceEventTypes[0] ?? "backend_exception";
19152
19582
  const firstSeenAt = new Date(input.incident.first_seen_at).toISOString();
@@ -19155,7 +19585,15 @@ function buildBundle(input) {
19155
19585
  const serviceRuntime = input.incident.service_runtime ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.runtime ?? null;
19156
19586
  const serviceFramework = input.incident.service_framework ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.framework ?? null;
19157
19587
  const customerVisible = frontendContext !== null;
19158
- return BundleV1Schema.parse({
19588
+ const firstApplicationFrame = deriveFirstApplicationFrame(errorContext);
19589
+ const summaryGuidance = buildSummaryGuidance({
19590
+ errorContext,
19591
+ requestContext,
19592
+ responseContext,
19593
+ dependenciesContext,
19594
+ firstApplicationFrame
19595
+ });
19596
+ const candidate = {
19159
19597
  bundle_version: 1,
19160
19598
  bundle_id: `bnd_${input.incident.incident_id}`,
19161
19599
  bundle_type: "failure",
@@ -19190,13 +19628,13 @@ function buildBundle(input) {
19190
19628
  summary: {
19191
19629
  title: input.incident.title,
19192
19630
  description: `Deterministic bundle generated from ${input.job.trigger}`,
19193
- likely_cause: null,
19194
- confidence: 0,
19195
- recommended_action: null,
19631
+ likely_cause: summaryGuidance.likely_cause,
19632
+ confidence: summaryGuidance.confidence,
19633
+ recommended_action: summaryGuidance.recommended_action,
19196
19634
  severity: input.incident.severity,
19197
19635
  error_type: primarySourceEvent,
19198
19636
  error_message: errorContext?.message ?? input.incident.title,
19199
- first_application_frame: deriveFirstApplicationFrame(errorContext),
19637
+ first_application_frame: firstApplicationFrame,
19200
19638
  primary_signal: primarySignalType,
19201
19639
  signals: {
19202
19640
  new_deploy: input.job.trigger === "deploy_metadata",
@@ -19221,7 +19659,7 @@ function buildBundle(input) {
19221
19659
  deploy: deployContext,
19222
19660
  runtime: runtimeContext,
19223
19661
  git: gitContext,
19224
- dependencies: null,
19662
+ dependencies: dependenciesContext,
19225
19663
  probe_data: {
19226
19664
  version: 1,
19227
19665
  items: input.probeDataItems
@@ -19242,11 +19680,7 @@ function buildBundle(input) {
19242
19680
  production_verified: false
19243
19681
  },
19244
19682
  links: {
19245
- self: null,
19246
- reproduction: null,
19247
- incident: null,
19248
- project: null,
19249
- docs: null
19683
+ ...buildLinks(input.incident, input.linkBaseUrls)
19250
19684
  },
19251
19685
  redaction: {
19252
19686
  redacted: true,
@@ -19259,7 +19693,8 @@ function buildBundle(input) {
19259
19693
  generator_version: "worker-build-bundle-v2",
19260
19694
  generation_number: input.bundleMetadata.generation_number
19261
19695
  }
19262
- });
19696
+ };
19697
+ return BundleV1Schema.parse(applyBundleRedaction(candidate));
19263
19698
  }
19264
19699
 
19265
19700
  // ../../packages/repro-engine/src/index.ts
@@ -19279,6 +19714,44 @@ function shellQuote(value) {
19279
19714
  function sortRecordEntries(record) {
19280
19715
  return Object.entries(record).sort(([left], [right]) => left.localeCompare(right));
19281
19716
  }
19717
+ var REPLAY_HEADER_PRIORITY = [
19718
+ "authorization",
19719
+ "cookie",
19720
+ "accept",
19721
+ "content-type",
19722
+ "origin",
19723
+ "accept-language",
19724
+ "access-control-request-method",
19725
+ "access-control-request-headers",
19726
+ "x-request-id",
19727
+ "x-correlation-id",
19728
+ "x-debugbundle-trace-id"
19729
+ ];
19730
+ var DROPPED_REPLAY_HEADERS = /* @__PURE__ */ new Set([
19731
+ "host",
19732
+ "x-forwarded-host",
19733
+ "x-forwarded-proto",
19734
+ "connection",
19735
+ "keep-alive",
19736
+ "transfer-encoding",
19737
+ "upgrade",
19738
+ "te",
19739
+ "trailer",
19740
+ "proxy-connection",
19741
+ "accept-encoding",
19742
+ "content-length",
19743
+ "cache-control",
19744
+ "pragma",
19745
+ "priority",
19746
+ "sec-ch-ua",
19747
+ "sec-ch-ua-mobile",
19748
+ "sec-ch-ua-platform",
19749
+ "sec-fetch-dest",
19750
+ "sec-fetch-mode",
19751
+ "sec-fetch-site",
19752
+ "sec-fetch-user",
19753
+ "user-agent"
19754
+ ]);
19282
19755
  function serializeScalarValue(value) {
19283
19756
  if (typeof value === "string") {
19284
19757
  return value;
@@ -19357,12 +19830,25 @@ function buildStructuredReplayQuery(query) {
19357
19830
  return hasStructuredQueryAmbiguity(normalizedQuery) ? normalizedQuery : void 0;
19358
19831
  }
19359
19832
  function buildReplayHeaders(headers) {
19360
- return Object.fromEntries(
19361
- sortRecordEntries(headers).filter(([headerName]) => !["host", "x-forwarded-host", "x-forwarded-proto"].includes(headerName.toLowerCase())).map(([headerName, headerValue]) => [headerName, normalizeHeaderValue(headerValue)])
19362
- );
19833
+ const entries = sortRecordEntries(headers).filter(([headerName]) => !DROPPED_REPLAY_HEADERS.has(headerName.toLowerCase())).map(([headerName, headerValue]) => [headerName, normalizeHeaderValue(headerValue)]);
19834
+ entries.sort(([left], [right]) => {
19835
+ const leftPriority = REPLAY_HEADER_PRIORITY.indexOf(left.toLowerCase());
19836
+ const rightPriority = REPLAY_HEADER_PRIORITY.indexOf(right.toLowerCase());
19837
+ if (leftPriority !== -1 || rightPriority !== -1) {
19838
+ if (leftPriority === -1) {
19839
+ return 1;
19840
+ }
19841
+ if (rightPriority === -1) {
19842
+ return -1;
19843
+ }
19844
+ return leftPriority - rightPriority;
19845
+ }
19846
+ return left.localeCompare(right);
19847
+ });
19848
+ return Object.fromEntries(entries);
19363
19849
  }
19364
19850
  function expandHeaderValues(headers) {
19365
- return sortRecordEntries(headers).flatMap(([headerName, headerValue]) => {
19851
+ return Object.entries(headers).flatMap(([headerName, headerValue]) => {
19366
19852
  if (Array.isArray(headerValue)) {
19367
19853
  return headerValue.map((item) => [headerName, serializeScalarValue(item)]);
19368
19854
  }
@@ -19512,11 +19998,17 @@ var EVENT_TYPE_SET = new Set(EventTypeValues);
19512
19998
  function isEventType(value) {
19513
19999
  return typeof value === "string" && EVENT_TYPE_SET.has(value);
19514
20000
  }
19515
- function inferSeverity2(eventType) {
19516
- if (eventType === "backend_exception" || eventType === "frontend_exception") {
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") {
19517
20009
  return "high";
19518
20010
  }
19519
- if (eventType === "error_suppressed") {
20011
+ if (event.event_type === "error_suppressed") {
19520
20012
  return "medium";
19521
20013
  }
19522
20014
  return "low";
@@ -19540,15 +20032,17 @@ function compareEventEnvelopes(left, right) {
19540
20032
  }
19541
20033
  return left.event_id.localeCompare(right.event_id);
19542
20034
  }
19543
- function classifyEnvelope(envelope) {
20035
+ function classifyEnvelope(envelope, capturePreset) {
19544
20036
  return classifyEvent(
19545
20037
  envelope.event_type,
19546
20038
  envelope.event_type === "log_event" ? envelope.payload.level : void 0,
19547
- 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
19548
20042
  );
19549
20043
  }
19550
- function isIncidentSignalEnvelope(envelope) {
19551
- return classifyEnvelope(envelope) === "incident_signal";
20044
+ function isIncidentSignalEnvelope(envelope, capturePreset) {
20045
+ return classifyEnvelope(envelope, capturePreset) === "incident_signal";
19552
20046
  }
19553
20047
  function getTraceId(envelope) {
19554
20048
  return envelope.correlation?.trace_id ?? null;
@@ -19593,7 +20087,10 @@ function mergeAggregateGroup(aggregates) {
19593
20087
  newEvents: [...canonicalAggregate.newEvents],
19594
20088
  mergedIncidentIds: new Set(canonicalAggregate.mergedIncidentIds),
19595
20089
  signalEventTypes: new Set(canonicalAggregate.signalEventTypes),
19596
- traceIds: new Set(canonicalAggregate.traceIds)
20090
+ traceIds: new Set(canonicalAggregate.traceIds),
20091
+ title: canonicalAggregate.title,
20092
+ kind: canonicalAggregate.kind,
20093
+ severity: canonicalAggregate.severity
19597
20094
  });
19598
20095
  }
19599
20096
  function hashIdentifier(parts, prefix, length) {
@@ -19619,6 +20116,111 @@ function mergeSourceEvents(existingEvents, nextEvents) {
19619
20116
  }
19620
20117
  return [...merged.values()].sort(compareEventEnvelopes);
19621
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
+ }
19622
20224
  function buildBundleContext(incident) {
19623
20225
  return {
19624
20226
  incident_id: incident.incident_id,
@@ -19648,12 +20250,12 @@ function formatServiceSummary(services) {
19648
20250
  }
19649
20251
  function formatProcessOutput(summary) {
19650
20252
  if (!summary.processed) {
19651
- return summary.message ?? "No new events to process.";
20253
+ return summary.message;
19652
20254
  }
19653
20255
  return [
19654
20256
  `Processed ${summary.events_processed} events from ${summary.files_processed} files into ${summary.incidents_processed} incidents.`,
19655
20257
  ...formatServiceSummary(summary.services),
19656
- `Last processed event file: ${summary.last_processed_event_file ?? "none"}`
20258
+ `Last processed event file: ${summary.last_processed_event_file}`
19657
20259
  ].join("\n");
19658
20260
  }
19659
20261
  async function pathExists4(path, stat) {
@@ -19893,6 +20495,7 @@ async function processCommand(input, dependencies = {}) {
19893
20495
  const statePath = (0, import_node_path6.join)(rootDirectory, LOCAL_STATE_FILE_PATH);
19894
20496
  const bundleDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_BUNDLE_DIRECTORY_PATH2);
19895
20497
  const reproductionDirectoryPath = (0, import_node_path6.join)(rootDirectory, LOCAL_REPRODUCTION_DIRECTORY_PATH);
20498
+ const capturePreset = input.preset ?? "minimal";
19896
20499
  await mkdir((0, import_node_path6.join)(rootDirectory, ".debugbundle", "local"), { recursive: true });
19897
20500
  await mkdir(bundleDirectoryPath, { recursive: true });
19898
20501
  await mkdir(reproductionDirectoryPath, { recursive: true });
@@ -19900,22 +20503,26 @@ async function processCommand(input, dependencies = {}) {
19900
20503
  const eventFileNames = await pathExists4(eventsDirectoryPath, stat) ? (await readdir(eventsDirectoryPath)).filter((fileName) => fileName.endsWith(".events.json")).sort() : [];
19901
20504
  const lastProcessedEventFile = previousState?.last_processed_event_file ?? null;
19902
20505
  const newEventFileNames = lastProcessedEventFile === null ? eventFileNames : eventFileNames.filter((fileName) => fileName > lastProcessedEventFile);
19903
- if (newEventFileNames.length === 0) {
20506
+ const processAllEventFiles = input.preset !== void 0;
20507
+ const targetEventFileNames = processAllEventFiles ? eventFileNames : newEventFileNames;
20508
+ if (targetEventFileNames.length === 0) {
19904
20509
  const summary2 = buildNoNewEventsSummary(previousState?.last_processed_event_file ?? eventFileNames.at(-1) ?? null);
19905
20510
  return {
19906
20511
  exitCode: 0,
19907
20512
  output: input.json === true ? JSON.stringify(summary2) : formatProcessOutput(summary2)
19908
20513
  };
19909
20514
  }
19910
- const batches = await readEventBatches(eventsDirectoryPath, newEventFileNames, readFile);
19911
- const incidents = new Map(Object.entries(previousState?.incidents ?? {}));
20515
+ const batches = await readEventBatches(eventsDirectoryPath, targetEventFileNames, readFile);
20516
+ const incidents = new Map(
20517
+ processAllEventFiles ? [] : Object.entries(previousState?.incidents ?? {})
20518
+ );
19912
20519
  const aggregates = /* @__PURE__ */ new Map();
19913
20520
  const traceCorrelationGroups = /* @__PURE__ */ new Map();
19914
20521
  let eventsProcessed = 0;
19915
20522
  for (const batch of batches) {
19916
20523
  for (const event of batch.events) {
19917
20524
  eventsProcessed += 1;
19918
- if (!isIncidentSignalEnvelope(event)) {
20525
+ if (!isIncidentSignalEnvelope(event, capturePreset)) {
19919
20526
  continue;
19920
20527
  }
19921
20528
  const normalizedEvent = normalizeEvent(event);
@@ -19932,7 +20539,10 @@ async function processCommand(input, dependencies = {}) {
19932
20539
  newEvents: [],
19933
20540
  mergedIncidentIds: /* @__PURE__ */ new Set([incidentId]),
19934
20541
  signalEventTypes: /* @__PURE__ */ new Set(),
19935
- traceIds: /* @__PURE__ */ new Set()
20542
+ traceIds: /* @__PURE__ */ new Set(),
20543
+ title: normalizedEvent.normalized_message,
20544
+ kind: "immediate",
20545
+ severity: inferSeverity2(event, capturePreset)
19936
20546
  };
19937
20547
  for (const matchedField of inferMatchedFields(normalizedEvent)) {
19938
20548
  aggregate.matchedFields.add(matchedField);
@@ -19999,14 +20609,16 @@ async function processCommand(input, dependencies = {}) {
19999
20609
  mergedAggregatesByRoot.set(rootIncidentId, aggregateGroup);
20000
20610
  }
20001
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));
20002
20614
  const services = /* @__PURE__ */ new Map();
20003
- for (const aggregate of mergedAggregates) {
20615
+ for (const aggregate of finalizedAggregates) {
20004
20616
  const incidentId = aggregate.incidentId;
20005
20617
  const existingIncidents = [...aggregate.mergedIncidentIds].map((mergedIncidentId) => incidents.get(mergedIncidentId)).filter((incident2) => incident2 !== void 0);
20006
20618
  const existing = existingIncidents.find((incident2) => incident2.incident_id === incidentId) ?? existingIncidents[0];
20007
20619
  const existingSourceEvents = existingIncidents.flatMap((incident2) => incident2.source_events);
20008
20620
  const combinedSourceEvents = mergeSourceEvents(existingSourceEvents, aggregate.newEvents);
20009
- const signalEvents = combinedSourceEvents.filter(isIncidentSignalEnvelope);
20621
+ const signalEvents = aggregate.kind === "request_anomaly" ? combinedSourceEvents : combinedSourceEvents.filter((event) => isIncidentSignalEnvelope(event, capturePreset));
20010
20622
  if (signalEvents.length === 0) {
20011
20623
  continue;
20012
20624
  }
@@ -20016,8 +20628,7 @@ async function processCommand(input, dependencies = {}) {
20016
20628
  continue;
20017
20629
  }
20018
20630
  const sourceEventTypes = [...new Set(signalEvents.map((event) => event.event_type))].sort();
20019
- const severity = signalEvents.map((event) => inferSeverity2(event.event_type)).sort((left, right) => severityRank(right) - severityRank(left))[0] ?? "low";
20020
- 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;
20021
20632
  const generationNumber = signalEvents.length;
20022
20633
  const bundlePath = `${LOCAL_BUNDLE_DIRECTORY_PATH2}/${incidentId}.bundle.json`;
20023
20634
  const reproductionPath = `${LOCAL_REPRODUCTION_DIRECTORY_PATH}/${incidentId}.reproduction.json`;
@@ -20032,7 +20643,7 @@ async function processCommand(input, dependencies = {}) {
20032
20643
  environment: aggregate.environment,
20033
20644
  fingerprint: aggregate.fingerprint,
20034
20645
  fingerprint_version: FINGERPRINT_VERSION,
20035
- title: latestNormalizedEvent.normalized_message,
20646
+ title: aggregate.title,
20036
20647
  severity,
20037
20648
  status: existingIncidents.some((incidentState) => incidentState.status === "resolved") ? "open" : existing?.status ?? "open",
20038
20649
  first_seen_at: firstSignalEvent.occurred_at,
@@ -20093,21 +20704,22 @@ async function processCommand(input, dependencies = {}) {
20093
20704
  incidents.set(incidentId, incident);
20094
20705
  services.set(incident.service_name, (services.get(incident.service_name) ?? 0) + 1);
20095
20706
  }
20707
+ const finalProcessedEventFile = targetEventFileNames[targetEventFileNames.length - 1];
20096
20708
  const nextState = {
20097
20709
  version: 1,
20098
- last_processed_event_file: newEventFileNames.at(-1) ?? previousState?.last_processed_event_file ?? null,
20710
+ last_processed_event_file: finalProcessedEventFile,
20099
20711
  incidents: Object.fromEntries([...incidents.entries()].sort(([left], [right]) => left.localeCompare(right)))
20100
20712
  };
20101
20713
  await writeFile(statePath, serializeState(nextState));
20102
20714
  const summary = buildProcessedSummary({
20103
20715
  filesProcessed: newEventFileNames.length,
20104
20716
  eventsProcessed,
20105
- incidentsProcessed: mergedAggregates.length,
20717
+ incidentsProcessed: finalizedAggregates.length,
20106
20718
  services: [...services.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([service, count]) => ({
20107
20719
  service,
20108
20720
  incidents: count
20109
20721
  })),
20110
- lastProcessedEventFile: nextState.last_processed_event_file
20722
+ lastProcessedEventFile: finalProcessedEventFile
20111
20723
  });
20112
20724
  return {
20113
20725
  exitCode: 0,
@@ -20223,7 +20835,11 @@ function parseLocalIncident(candidate) {
20223
20835
  }
20224
20836
  const serviceRuntime = candidate["service_runtime"];
20225
20837
  const serviceFramework = candidate["service_framework"];
20226
- const incidentReason = deriveIncidentReasonFromSourceEventTypes(candidate["source_event_types"]);
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"]);
20227
20843
  if (serviceRuntime !== null && typeof serviceRuntime !== "string") {
20228
20844
  throw createReadError(400, "invalid_local_state");
20229
20845
  }
@@ -20472,7 +21088,7 @@ function buildCloudSuggestedActions(status, incidentId, mode = "passive_recent_i
20472
21088
  ];
20473
21089
  }
20474
21090
  return [
20475
- "Run debugbundle login to create ~/.debugbundle/auth.json before verifying cloud traffic.",
21091
+ "Run debugbundle login to choose an auth flow, or use debugbundle login --github, debugbundle login --github-device, or debugbundle login <dbundle_mem_...> to create ~/.debugbundle/auth.json before verifying cloud traffic.",
20476
21092
  "Generate a live cloud request, then re-run debugbundle verify cloud with the correct project and service filters."
20477
21093
  ];
20478
21094
  }
@@ -20529,14 +21145,14 @@ function localFailureStepName(checks) {
20529
21145
  function cloudVerificationRunId(now) {
20530
21146
  return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
20531
21147
  }
20532
- function requestFailure5xxReason() {
21148
+ function requestFailureReason() {
20533
21149
  const incidentReason = deriveIncidentReasonFromSignal({
20534
21150
  event_type: "request_event",
20535
21151
  event_class: "incident_signal",
20536
21152
  response_status: 503
20537
21153
  });
20538
21154
  if (incidentReason === null) {
20539
- throw new Error("request_failure_5xx_reason_unavailable");
21155
+ throw new Error("request_failure_reason_unavailable");
20540
21156
  }
20541
21157
  return incidentReason;
20542
21158
  }
@@ -20811,7 +21427,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
20811
21427
  const verification = {
20812
21428
  mode: "active_5xx",
20813
21429
  bundle_status: "unknown",
20814
- classification_reason: requestFailure5xxReason()
21430
+ classification_reason: requestFailureReason()
20815
21431
  };
20816
21432
  const errors = [];
20817
21433
  let exitCode = 0;
@@ -20863,7 +21479,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
20863
21479
  if (candidate !== void 0) {
20864
21480
  incidentId = candidate.incident_id;
20865
21481
  verification.incident_id = candidate.incident_id;
20866
- verification.classification_reason = candidate.incident_reason ?? requestFailure5xxReason();
21482
+ verification.classification_reason = candidate.incident_reason ?? requestFailureReason();
20867
21483
  break;
20868
21484
  }
20869
21485
  if (attempt < pollAttempts) {
@@ -21359,7 +21975,8 @@ function createAlertMcpTools(api) {
21359
21975
  bearerToken: String(input["bearerToken"]),
21360
21976
  projectId: String(input["projectId"]),
21361
21977
  channel: String(input["channel"]),
21362
- conditionType: String(input["conditionType"])
21978
+ conditionType: String(input["conditionType"]),
21979
+ config: input["config"]
21363
21980
  };
21364
21981
  if (typeof input["serviceId"] === "string") {
21365
21982
  requestInput.serviceId = input["serviceId"];
@@ -21367,9 +21984,6 @@ function createAlertMcpTools(api) {
21367
21984
  if (typeof input["severityMin"] === "string") {
21368
21985
  requestInput.severityMin = input["severityMin"];
21369
21986
  }
21370
- if (typeof input["config"] === "object" && input["config"] !== null) {
21371
- requestInput.config = input["config"];
21372
- }
21373
21987
  if (typeof input["isEnabled"] === "boolean") {
21374
21988
  requestInput.isEnabled = input["isEnabled"];
21375
21989
  }
@@ -22642,8 +23256,71 @@ function createSetupMcpTools(commands) {
22642
23256
  };
22643
23257
  }
22644
23258
 
22645
- // src/token-tools.ts
23259
+ // src/slack-tools.ts
22646
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) {
22647
23324
  if (error instanceof TokenManagementApiError) {
22648
23325
  throw new Error(`mcp_tool_error:${error.code}`);
22649
23326
  }
@@ -22664,7 +23341,7 @@ function createTokenMcpTools(api) {
22664
23341
  tokens: await api.listProjectTokens(requestInput)
22665
23342
  };
22666
23343
  } catch (error) {
22667
- mapMcpError12(error);
23344
+ mapMcpError13(error);
22668
23345
  }
22669
23346
  },
22670
23347
  async create_project_token(input) {
@@ -22677,7 +23354,7 @@ function createTokenMcpTools(api) {
22677
23354
  })
22678
23355
  };
22679
23356
  } catch (error) {
22680
- mapMcpError12(error);
23357
+ mapMcpError13(error);
22681
23358
  }
22682
23359
  },
22683
23360
  async revoke_project_token(input) {
@@ -22690,7 +23367,7 @@ function createTokenMcpTools(api) {
22690
23367
  })
22691
23368
  };
22692
23369
  } catch (error) {
22693
- mapMcpError12(error);
23370
+ mapMcpError13(error);
22694
23371
  }
22695
23372
  },
22696
23373
  async list_member_tokens(input) {
@@ -22705,7 +23382,7 @@ function createTokenMcpTools(api) {
22705
23382
  tokens: await api.listMemberTokens(requestInput)
22706
23383
  };
22707
23384
  } catch (error) {
22708
- mapMcpError12(error);
23385
+ mapMcpError13(error);
22709
23386
  }
22710
23387
  },
22711
23388
  async create_member_token(input) {
@@ -22717,7 +23394,7 @@ function createTokenMcpTools(api) {
22717
23394
  })
22718
23395
  };
22719
23396
  } catch (error) {
22720
- mapMcpError12(error);
23397
+ mapMcpError13(error);
22721
23398
  }
22722
23399
  },
22723
23400
  async revoke_member_token(input) {
@@ -22729,14 +23406,14 @@ function createTokenMcpTools(api) {
22729
23406
  })
22730
23407
  };
22731
23408
  } catch (error) {
22732
- mapMcpError12(error);
23409
+ mapMcpError13(error);
22733
23410
  }
22734
23411
  }
22735
23412
  };
22736
23413
  }
22737
23414
 
22738
23415
  // src/webhook-tools.ts
22739
- function mapMcpError13(error) {
23416
+ function mapMcpError14(error) {
22740
23417
  if (error instanceof WebhookApiError) {
22741
23418
  throw new Error(`mcp_tool_error:${error.code}`);
22742
23419
  }
@@ -22757,7 +23434,7 @@ function createWebhookMcpTools(api) {
22757
23434
  webhooks: await api.listWebhooks(requestInput)
22758
23435
  };
22759
23436
  } catch (error) {
22760
- mapMcpError13(error);
23437
+ mapMcpError14(error);
22761
23438
  }
22762
23439
  },
22763
23440
  async create_webhook(input) {
@@ -22778,7 +23455,7 @@ function createWebhookMcpTools(api) {
22778
23455
  webhook: await api.createWebhook(requestInput)
22779
23456
  };
22780
23457
  } catch (error) {
22781
- mapMcpError13(error);
23458
+ mapMcpError14(error);
22782
23459
  }
22783
23460
  },
22784
23461
  async update_webhook(input) {
@@ -22803,7 +23480,7 @@ function createWebhookMcpTools(api) {
22803
23480
  webhook: await api.updateWebhook(requestInput)
22804
23481
  };
22805
23482
  } catch (error) {
22806
- mapMcpError13(error);
23483
+ mapMcpError14(error);
22807
23484
  }
22808
23485
  },
22809
23486
  async delete_webhook(input) {
@@ -22815,7 +23492,7 @@ function createWebhookMcpTools(api) {
22815
23492
  })
22816
23493
  };
22817
23494
  } catch (error) {
22818
- mapMcpError13(error);
23495
+ mapMcpError14(error);
22819
23496
  }
22820
23497
  },
22821
23498
  async test_webhook(input) {
@@ -22831,7 +23508,7 @@ function createWebhookMcpTools(api) {
22831
23508
  delivery: await api.testWebhook(requestInput)
22832
23509
  };
22833
23510
  } catch (error) {
22834
- mapMcpError13(error);
23511
+ mapMcpError14(error);
22835
23512
  }
22836
23513
  },
22837
23514
  async list_webhook_deliveries(input) {
@@ -22847,7 +23524,7 @@ function createWebhookMcpTools(api) {
22847
23524
  deliveries: await api.listWebhookDeliveries(requestInput)
22848
23525
  };
22849
23526
  } catch (error) {
22850
- mapMcpError13(error);
23527
+ mapMcpError14(error);
22851
23528
  }
22852
23529
  },
22853
23530
  async retry_webhook_delivery(input) {
@@ -22858,14 +23535,14 @@ function createWebhookMcpTools(api) {
22858
23535
  deliveryId: String(input["deliveryId"])
22859
23536
  });
22860
23537
  } catch (error) {
22861
- mapMcpError13(error);
23538
+ mapMcpError14(error);
22862
23539
  }
22863
23540
  }
22864
23541
  };
22865
23542
  }
22866
23543
 
22867
23544
  // src/weekly-report-tools.ts
22868
- function mapMcpError14(error) {
23545
+ function mapMcpError15(error) {
22869
23546
  if (error instanceof WeeklyReportApiError) {
22870
23547
  throw new Error(`mcp_tool_error:${error.code}`);
22871
23548
  }
@@ -22883,7 +23560,7 @@ function createWeeklyReportMcpTools(api) {
22883
23560
  })
22884
23561
  };
22885
23562
  } catch (error) {
22886
- mapMcpError14(error);
23563
+ mapMcpError15(error);
22887
23564
  }
22888
23565
  },
22889
23566
  async create_weekly_report_channel(input) {
@@ -22899,7 +23576,7 @@ function createWeeklyReportMcpTools(api) {
22899
23576
  })
22900
23577
  };
22901
23578
  } catch (error) {
22902
- mapMcpError14(error);
23579
+ mapMcpError15(error);
22903
23580
  }
22904
23581
  },
22905
23582
  async update_weekly_report_channel(input) {
@@ -22914,7 +23591,7 @@ function createWeeklyReportMcpTools(api) {
22914
23591
  })
22915
23592
  };
22916
23593
  } catch (error) {
22917
- mapMcpError14(error);
23594
+ mapMcpError15(error);
22918
23595
  }
22919
23596
  },
22920
23597
  async delete_weekly_report_channel(input) {
@@ -22926,7 +23603,7 @@ function createWeeklyReportMcpTools(api) {
22926
23603
  })
22927
23604
  };
22928
23605
  } catch (error) {
22929
- mapMcpError14(error);
23606
+ mapMcpError15(error);
22930
23607
  }
22931
23608
  }
22932
23609
  };
@@ -22977,6 +23654,7 @@ async function createDefaultMcpTools(input = {}) {
22977
23654
  ...createServicesMcpTools(retrievalApi),
22978
23655
  ...createTokenMcpTools(createTokenManagementApi(httpClient)),
22979
23656
  ...createWebhookMcpTools(createWebhookApi(httpClient)),
23657
+ ...createSlackMcpTools(createSlackApi(httpClient)),
22980
23658
  ...createWeeklyReportMcpTools(createWeeklyReportApi(httpClient)),
22981
23659
  ...createAlertMcpTools(createAlertApi(httpClient)),
22982
23660
  ...createProjectMcpTools(createProjectManagementApi(httpClient)),
@@ -24661,6 +25339,45 @@ var MCP_TOOL_CATALOG = [
24661
25339
  deliveryId: external_exports.string()
24662
25340
  })
24663
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
+ },
24664
25381
  {
24665
25382
  name: "list_weekly_report_channels",
24666
25383
  group: "weekly_reports",
@@ -24726,7 +25443,7 @@ var MCP_TOOL_CATALOG = [
24726
25443
  channel: external_exports.string(),
24727
25444
  conditionType: external_exports.string(),
24728
25445
  severityMin: external_exports.string().optional(),
24729
- config: jsonObjectSchema.optional(),
25446
+ config: jsonObjectSchema,
24730
25447
  isEnabled: external_exports.boolean().optional()
24731
25448
  })
24732
25449
  },
@@ -25030,7 +25747,7 @@ function createMcpServer(input) {
25030
25747
  },
25031
25748
  serverInfo: {
25032
25749
  name: "@debugbundle/mcp",
25033
- version: "0.1.1"
25750
+ version: "0.1.2"
25034
25751
  }
25035
25752
  }
25036
25753
  };