@debugbundle/mcp 1.5.2 → 1.6.0

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 CHANGED
@@ -15938,6 +15938,8 @@ var CaptureRuleSuggestionSchema = external_exports.object({
15938
15938
  confidence: CaptureRuleSuggestionConfidenceSchema,
15939
15939
  reason: external_exports.string().min(1).max(500),
15940
15940
  requires_confirmation: external_exports.boolean(),
15941
+ created_rule_id: external_exports.string().min(1).max(120).nullable().default(null),
15942
+ created_rule_enabled: external_exports.boolean().nullable().default(null),
15941
15943
  rule: CaptureRuleCreateSchema
15942
15944
  });
15943
15945
  var CaptureRuleSuggestionsResponseSchema = external_exports.object({
@@ -16031,11 +16033,16 @@ var ServiceSchema = external_exports.object({
16031
16033
  environment: external_exports.string().min(1)
16032
16034
  });
16033
16035
  var CorrelationSchema = external_exports.object({
16034
- request_id: external_exports.string().nullable(),
16035
- trace_id: external_exports.string().nullable(),
16036
- session_id: external_exports.string().nullable(),
16037
- user_id_hash: external_exports.string().nullable()
16038
- }).strict();
16036
+ request_id: external_exports.string().nullable().optional(),
16037
+ trace_id: external_exports.string().nullable().optional(),
16038
+ session_id: external_exports.string().nullable().optional(),
16039
+ user_id_hash: external_exports.string().nullable().optional()
16040
+ }).strict().transform((value) => ({
16041
+ request_id: value.request_id ?? null,
16042
+ trace_id: value.trace_id ?? null,
16043
+ session_id: value.session_id ?? null,
16044
+ user_id_hash: value.user_id_hash ?? null
16045
+ }));
16039
16046
  var InlineProbeDataItemSchema = external_exports.object({
16040
16047
  label: external_exports.string().min(1),
16041
16048
  data: external_exports.record(external_exports.string(), external_exports.unknown()),
@@ -16215,7 +16222,8 @@ var EnvelopeBaseSchema = external_exports.object({
16215
16222
  sdk_version: external_exports.string().min(1),
16216
16223
  service: ServiceSchema,
16217
16224
  occurred_at: external_exports.string().datetime(),
16218
- correlation: CorrelationSchema.optional()
16225
+ correlation: CorrelationSchema.optional(),
16226
+ context: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16219
16227
  }).strict();
16220
16228
  var EventEnvelopeSchema = external_exports.discriminatedUnion("event_type", [
16221
16229
  EnvelopeBaseSchema.extend({ event_type: external_exports.literal("backend_exception"), payload: BackendExceptionPayloadSchema }),
@@ -16244,6 +16252,7 @@ function createEventEnvelope(input) {
16244
16252
  session_id: null,
16245
16253
  user_id_hash: null
16246
16254
  },
16255
+ context: input.context,
16247
16256
  payload: input.payload
16248
16257
  };
16249
16258
  return EventEnvelopeSchema.parse(candidate);
@@ -17022,6 +17031,9 @@ function createRetrievalApi(client) {
17022
17031
  if (input.firstSeenAfter !== void 0) {
17023
17032
  query.set("first_seen_after", input.firstSeenAfter);
17024
17033
  }
17034
+ if (input.attentionAfter !== void 0) {
17035
+ query.set("attention_after", input.attentionAfter);
17036
+ }
17025
17037
  if (input.cursor !== void 0) {
17026
17038
  query.set("cursor", input.cursor);
17027
17039
  }
@@ -19075,7 +19087,7 @@ function createCaptureRuleApi(httpClient) {
19075
19087
  bearerToken: input.bearerToken,
19076
19088
  body: input.create
19077
19089
  });
19078
- if (response.status !== 201) {
19090
+ if (response.status !== 200 && response.status !== 201) {
19079
19091
  throw toApiError(response.status, response.body, "Failed to create capture rule from suggestion.");
19080
19092
  }
19081
19093
  const parsed = CaptureRuleResponseSchema.safeParse(response.body);
@@ -19680,6 +19692,167 @@ function redact(payload, options) {
19680
19692
 
19681
19693
  // ../../packages/event-normalizer/src/index.ts
19682
19694
  var FINGERPRINT_VERSION = "v1";
19695
+ var PAYLOAD_ALLOWED_KEYS = {
19696
+ backend_exception: /* @__PURE__ */ new Set(["name", "message", "stack", "handled", "request", "response", "runtime", "probe_data"]),
19697
+ request_event: /* @__PURE__ */ new Set([
19698
+ "method",
19699
+ "path",
19700
+ "query",
19701
+ "headers",
19702
+ "body",
19703
+ "response_status",
19704
+ "duration_ms",
19705
+ "route_template",
19706
+ "response_headers",
19707
+ "response_body"
19708
+ ]),
19709
+ log_event: /* @__PURE__ */ new Set(["level", "message", "attributes"]),
19710
+ frontend_breadcrumb: /* @__PURE__ */ new Set(["breadcrumb_type", "route", "data"]),
19711
+ frontend_exception: /* @__PURE__ */ new Set([
19712
+ "name",
19713
+ "message",
19714
+ "stack",
19715
+ "route",
19716
+ "browser",
19717
+ "breadcrumbs",
19718
+ "device",
19719
+ "browser_event",
19720
+ "rejection_reason",
19721
+ "dom_context",
19722
+ "probe_data"
19723
+ ]),
19724
+ deploy_metadata: /* @__PURE__ */ new Set(["commit_sha", "version", "branch", "environment", "deployed_at"]),
19725
+ error_suppressed: /* @__PURE__ */ new Set(["fingerprint", "suppressed_count", "window_seconds", "first_seen", "last_seen"]),
19726
+ probe_event: /* @__PURE__ */ new Set(["label", "data", "activation_id", "probe_label_pattern"])
19727
+ };
19728
+ function isRecord(candidate) {
19729
+ return typeof candidate === "object" && candidate !== null && !Array.isArray(candidate);
19730
+ }
19731
+ function cloneRecord(candidate) {
19732
+ return { ...candidate };
19733
+ }
19734
+ function readString(candidate) {
19735
+ if (typeof candidate === "string") {
19736
+ return candidate;
19737
+ }
19738
+ if (typeof candidate === "number" || typeof candidate === "boolean") {
19739
+ return String(candidate);
19740
+ }
19741
+ return null;
19742
+ }
19743
+ function readNonNegativeNumber(candidate, fallback) {
19744
+ if (typeof candidate === "number" && Number.isFinite(candidate) && candidate >= 0) {
19745
+ return candidate;
19746
+ }
19747
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
19748
+ const parsed = Number(candidate);
19749
+ if (Number.isFinite(parsed) && parsed >= 0) {
19750
+ return parsed;
19751
+ }
19752
+ }
19753
+ return fallback;
19754
+ }
19755
+ function normalizeMap(candidate) {
19756
+ return isRecord(candidate) ? cloneRecord(candidate) : {};
19757
+ }
19758
+ function mergeContext(baseContext, incomingContext) {
19759
+ if (!isRecord(incomingContext)) {
19760
+ return baseContext;
19761
+ }
19762
+ return {
19763
+ ...baseContext,
19764
+ ...incomingContext
19765
+ };
19766
+ }
19767
+ function normalizeCorrelation(candidate) {
19768
+ if (!isRecord(candidate)) {
19769
+ return void 0;
19770
+ }
19771
+ return {
19772
+ request_id: readString(candidate["request_id"]),
19773
+ trace_id: readString(candidate["trace_id"]),
19774
+ session_id: readString(candidate["session_id"]),
19775
+ user_id_hash: readString(candidate["user_id_hash"])
19776
+ };
19777
+ }
19778
+ function normalizeBackendExceptionPayload(payload) {
19779
+ const request = normalizeMap(payload["request"]);
19780
+ payload["request"] = {
19781
+ method: readString(request["method"]) ?? "UNKNOWN",
19782
+ path: readString(request["path"]) ?? "/",
19783
+ query: normalizeMap(request["query"]),
19784
+ headers: normalizeMap(request["headers"]),
19785
+ ..."body" in request ? { body: request["body"] ?? null } : {}
19786
+ };
19787
+ const response = normalizeMap(payload["response"]);
19788
+ payload["response"] = {
19789
+ status_code: readNonNegativeNumber(response["status_code"], 0),
19790
+ ..."headers" in response ? { headers: normalizeMap(response["headers"]) } : {},
19791
+ ..."body" in response ? { body: response["body"] } : {}
19792
+ };
19793
+ }
19794
+ function normalizeRequestEventPayload(payload) {
19795
+ payload["query"] = normalizeMap(payload["query"]);
19796
+ payload["headers"] = normalizeMap(payload["headers"]);
19797
+ payload["response_status"] = readNonNegativeNumber(payload["response_status"], 0);
19798
+ payload["duration_ms"] = readNonNegativeNumber(payload["duration_ms"], 0);
19799
+ }
19800
+ function normalizePayloadExtras(input) {
19801
+ const allowedKeys = PAYLOAD_ALLOWED_KEYS[input.eventType];
19802
+ if (allowedKeys === void 0) {
19803
+ return input.context;
19804
+ }
19805
+ let context = input.context;
19806
+ for (const key of Object.keys(input.payload)) {
19807
+ if (allowedKeys.has(key)) {
19808
+ continue;
19809
+ }
19810
+ context = mergeContext(context, { [key]: input.payload[key] });
19811
+ delete input.payload[key];
19812
+ }
19813
+ return context;
19814
+ }
19815
+ function normalizeCompatibleEventCandidate(candidate) {
19816
+ if (!isRecord(candidate)) {
19817
+ return candidate;
19818
+ }
19819
+ const event = cloneRecord(candidate);
19820
+ const eventType = typeof event["event_type"] === "string" ? event["event_type"] : "";
19821
+ let context = normalizeMap(event["context"]);
19822
+ if (typeof event["sdk_language"] === "string") {
19823
+ context = mergeContext(context, { sdk_language: event["sdk_language"] });
19824
+ delete event["sdk_language"];
19825
+ }
19826
+ const correlation = normalizeCorrelation(event["correlation"]);
19827
+ if (correlation !== void 0) {
19828
+ event["correlation"] = correlation;
19829
+ }
19830
+ if (isRecord(event["payload"])) {
19831
+ const payload = cloneRecord(event["payload"]);
19832
+ context = mergeContext(context, payload["context"]);
19833
+ delete payload["context"];
19834
+ if (eventType === "backend_exception") {
19835
+ normalizeBackendExceptionPayload(payload);
19836
+ }
19837
+ if (eventType === "request_event") {
19838
+ const attributes = isRecord(payload["attributes"]) ? payload["attributes"] : null;
19839
+ if (typeof payload["route_template"] !== "string" && typeof attributes?.["route_template"] === "string") {
19840
+ payload["route_template"] = attributes["route_template"];
19841
+ }
19842
+ context = mergeContext(context, attributes);
19843
+ delete payload["attributes"];
19844
+ normalizeRequestEventPayload(payload);
19845
+ }
19846
+ context = normalizePayloadExtras({ eventType, payload, context });
19847
+ event["payload"] = payload;
19848
+ }
19849
+ if (Object.keys(context).length > 0) {
19850
+ event["context"] = context;
19851
+ } else {
19852
+ delete event["context"];
19853
+ }
19854
+ return event;
19855
+ }
19683
19856
  function inferMatchedFields(event) {
19684
19857
  const matchedFields = ["environment", "normalized_message"];
19685
19858
  if (event.error_type !== null) {
@@ -19924,7 +20097,7 @@ function stableJson(value) {
19924
20097
  return `{${pairs.join(",")}}`;
19925
20098
  }
19926
20099
  function validateEvent(candidate) {
19927
- return EventEnvelopeSchema.safeParse(candidate);
20100
+ return EventEnvelopeSchema.safeParse(normalizeCompatibleEventCandidate(candidate));
19928
20101
  }
19929
20102
  function normalizeEvent(event) {
19930
20103
  const redactedPayload = redact(event.payload).redacted;
@@ -20743,10 +20916,10 @@ var ACCOUNT_METRIC_KEYS = [
20743
20916
  var AccountMetricKeySchema = external_exports.enum(ACCOUNT_METRIC_KEYS);
20744
20917
 
20745
20918
  // ../../packages/storage/src/incident-context.ts
20746
- function isRecord(value) {
20919
+ function isRecord2(value) {
20747
20920
  return typeof value === "object" && value !== null && !Array.isArray(value);
20748
20921
  }
20749
- function readString(value) {
20922
+ function readString2(value) {
20750
20923
  return typeof value === "string" ? value : null;
20751
20924
  }
20752
20925
  function readNumber(value) {
@@ -20759,32 +20932,32 @@ function readStringArray(value) {
20759
20932
  return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
20760
20933
  }
20761
20934
  function buildPrimarySignal(incident, incidentReason, bundleBody) {
20762
- const bundle = isRecord(bundleBody) ? bundleBody : {};
20763
- const summary = isRecord(bundle["summary"]) ? bundle["summary"] : {};
20764
- const signal = isRecord(bundle["signal"]) ? bundle["signal"] : {};
20765
- const context = isRecord(bundle["context"]) ? bundle["context"] : {};
20766
- const errorContext = isRecord(context["error"]) ? context["error"] : {};
20767
- const requestContext = isRecord(context["request"]) ? context["request"] : {};
20768
- const responseContext = isRecord(context["response"]) ? context["response"] : {};
20769
- const firstApplicationFrame = isRecord(summary["first_application_frame"]) ? summary["first_application_frame"] : null;
20935
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
20936
+ const summary = isRecord2(bundle["summary"]) ? bundle["summary"] : {};
20937
+ const signal = isRecord2(bundle["signal"]) ? bundle["signal"] : {};
20938
+ const context = isRecord2(bundle["context"]) ? bundle["context"] : {};
20939
+ const errorContext = isRecord2(context["error"]) ? context["error"] : {};
20940
+ const requestContext = isRecord2(context["request"]) ? context["request"] : {};
20941
+ const responseContext = isRecord2(context["response"]) ? context["response"] : {};
20942
+ const firstApplicationFrame = isRecord2(summary["first_application_frame"]) ? summary["first_application_frame"] : null;
20770
20943
  return {
20771
20944
  kind: incidentReason?.kind ?? null,
20772
- event_type: incidentReason?.event_type ?? readString(summary["primary_signal"]),
20945
+ event_type: incidentReason?.event_type ?? readString2(summary["primary_signal"]),
20773
20946
  event_class: incidentReason?.event_class ?? null,
20774
20947
  description: incidentReason?.description ?? `Primary signal for incident ${incident.incident_id}`,
20775
- severity: readString(signal["severity"]) ?? incident.severity,
20948
+ severity: readString2(signal["severity"]) ?? incident.severity,
20776
20949
  service_name: incident.service_name,
20777
20950
  environment: incident.environment,
20778
- error_type: readString(summary["error_type"]) ?? readString(errorContext["name"]),
20779
- error_message: readString(summary["error_message"]) ?? readString(errorContext["message"]),
20780
- request_method: readString(requestContext["method"]),
20781
- request_path: readString(requestContext["path"]),
20782
- route_template: readString(requestContext["route_template"]),
20951
+ error_type: readString2(summary["error_type"]) ?? readString2(errorContext["name"]),
20952
+ error_message: readString2(summary["error_message"]) ?? readString2(errorContext["message"]),
20953
+ request_method: readString2(requestContext["method"]),
20954
+ request_path: readString2(requestContext["path"]),
20955
+ route_template: readString2(requestContext["route_template"]),
20783
20956
  response_status: readNumber(responseContext["status_code"]),
20784
20957
  first_application_frame: firstApplicationFrame === null ? null : {
20785
- file: readString(firstApplicationFrame["file"]),
20958
+ file: readString2(firstApplicationFrame["file"]),
20786
20959
  line: readNumber(firstApplicationFrame["line"]),
20787
- function: readString(firstApplicationFrame["function"])
20960
+ function: readString2(firstApplicationFrame["function"])
20788
20961
  }
20789
20962
  };
20790
20963
  }
@@ -20796,9 +20969,9 @@ function buildLogsRecord(bundleBody, logsInput) {
20796
20969
  next_cursor: logsInput.next_cursor
20797
20970
  };
20798
20971
  }
20799
- const bundle = isRecord(bundleBody) ? bundleBody : {};
20800
- const context = isRecord(bundle["context"]) ? bundle["context"] : {};
20801
- const logsContext = isRecord(context["logs"]) ? context["logs"] : {};
20972
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
20973
+ const context = isRecord2(bundle["context"]) ? bundle["context"] : {};
20974
+ const logsContext = isRecord2(context["logs"]) ? context["logs"] : {};
20802
20975
  const items = Array.isArray(logsContext["items"]) ? logsContext["items"] : [];
20803
20976
  if (items.length > 0) {
20804
20977
  return {
@@ -20814,53 +20987,53 @@ function buildLogsRecord(bundleBody, logsInput) {
20814
20987
  };
20815
20988
  }
20816
20989
  function buildDeployRecord(incident, bundleBody) {
20817
- const bundle = isRecord(bundleBody) ? bundleBody : {};
20818
- const context = isRecord(bundle["context"]) ? bundle["context"] : {};
20819
- const deployContext = isRecord(context["deploy"]) ? context["deploy"] : {};
20990
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
20991
+ const context = isRecord2(bundle["context"]) ? bundle["context"] : {};
20992
+ const deployContext = isRecord2(context["deploy"]) ? context["deploy"] : {};
20820
20993
  return {
20821
20994
  latest_deployment_id: incident.latest_deployment_id ?? null,
20822
- commit_sha: readString(deployContext["commit_sha"]),
20823
- deploy_version: readString(deployContext["deploy_version"]),
20824
- branch: readString(deployContext["branch"]),
20825
- deployed_at: readString(deployContext["deployed_at"]),
20995
+ commit_sha: readString2(deployContext["commit_sha"]),
20996
+ deploy_version: readString2(deployContext["deploy_version"]),
20997
+ branch: readString2(deployContext["branch"]),
20998
+ deployed_at: readString2(deployContext["deployed_at"]),
20826
20999
  regression_window: readBoolean(deployContext["regression_window"])
20827
21000
  };
20828
21001
  }
20829
21002
  function buildRedactionRecord(bundleBody) {
20830
- const bundle = isRecord(bundleBody) ? bundleBody : {};
20831
- const redaction = isRecord(bundle["redaction"]) ? bundle["redaction"] : null;
21003
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
21004
+ const redaction = isRecord2(bundle["redaction"]) ? bundle["redaction"] : null;
20832
21005
  if (redaction === null) {
20833
21006
  return null;
20834
21007
  }
20835
21008
  return {
20836
21009
  redacted: readBoolean(redaction["redacted"]) ?? false,
20837
21010
  fields: readStringArray(redaction["fields"]),
20838
- notes: readString(redaction["notes"])
21011
+ notes: readString2(redaction["notes"])
20839
21012
  };
20840
21013
  }
20841
21014
  function buildBrowserSignalRecord(bundleBody) {
20842
- const bundle = isRecord(bundleBody) ? bundleBody : {};
20843
- const context = isRecord(bundle["context"]) ? bundle["context"] : {};
20844
- const frontend = isRecord(context["frontend"]) ? context["frontend"] : {};
21015
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
21016
+ const context = isRecord2(bundle["context"]) ? bundle["context"] : {};
21017
+ const frontend = isRecord2(context["frontend"]) ? context["frontend"] : {};
20845
21018
  const exceptions = Array.isArray(frontend["exceptions"]) ? frontend["exceptions"] : [];
20846
21019
  let exception;
20847
21020
  for (let index = exceptions.length - 1; index >= 0; index -= 1) {
20848
21021
  const candidate = exceptions[index];
20849
- if (isRecord(candidate) && isRecord(candidate["browser_event"])) {
21022
+ if (isRecord2(candidate) && isRecord2(candidate["browser_event"])) {
20850
21023
  exception = candidate;
20851
21024
  break;
20852
21025
  }
20853
21026
  }
20854
- const browserEvent = isRecord(exception) && isRecord(exception["browser_event"]) ? exception["browser_event"] : null;
20855
- const device = isRecord(context["device"]) ? context["device"] : {};
20856
- const client = classifyCaptureRuleClientFromUserAgent(readString(device["user_agent"]) ?? void 0);
21027
+ const browserEvent = isRecord2(exception) && isRecord2(exception["browser_event"]) ? exception["browser_event"] : null;
21028
+ const device = isRecord2(context["device"]) ? context["device"] : {};
21029
+ const client = classifyCaptureRuleClientFromUserAgent(readString2(device["user_agent"]) ?? void 0);
20857
21030
  if (browserEvent === null && client.client_kind === "unknown") {
20858
21031
  return null;
20859
21032
  }
20860
21033
  return {
20861
- browser_event_kind: readString(browserEvent?.["kind"]),
21034
+ browser_event_kind: readString2(browserEvent?.["kind"]),
20862
21035
  browser_event_opaque: readBoolean(browserEvent?.["opaque"]),
20863
- browser_event_message: readString(browserEvent?.["message"]),
21036
+ browser_event_message: readString2(browserEvent?.["message"]),
20864
21037
  client_kind: client.client_kind,
20865
21038
  bot_family: client.bot_family ?? null
20866
21039
  };
@@ -23577,6 +23750,26 @@ function selectPrimarySignalEnvelope(envelopes, sourceEventId) {
23577
23750
  (envelope) => envelope.event_type === "backend_exception" || envelope.event_type === "frontend_exception" || envelope.event_type === "request_event"
23578
23751
  ) ?? null;
23579
23752
  }
23753
+ function deriveBundleSdk(envelopes, sourceEventId) {
23754
+ const sourceEnvelope = envelopes.find((envelope) => envelope.event_id === sourceEventId);
23755
+ if (sourceEnvelope !== void 0) {
23756
+ return {
23757
+ name: sourceEnvelope.sdk_name,
23758
+ version: sourceEnvelope.sdk_version
23759
+ };
23760
+ }
23761
+ const latestCapturedEnvelope = selectLatestEnvelope(envelopes, (envelope) => envelope.event_type !== "probe_event");
23762
+ if (latestCapturedEnvelope !== null) {
23763
+ return {
23764
+ name: latestCapturedEnvelope.sdk_name,
23765
+ version: latestCapturedEnvelope.sdk_version
23766
+ };
23767
+ }
23768
+ return {
23769
+ name: "unknown",
23770
+ version: "unknown"
23771
+ };
23772
+ }
23580
23773
  function mapSignalType(eventType) {
23581
23774
  if (eventType === "request_event") {
23582
23775
  return "request_failure";
@@ -24194,6 +24387,7 @@ function buildBundle(input) {
24194
24387
  const firstSeenAt = new Date(input.incident.first_seen_at).toISOString();
24195
24388
  const lastSeenAt = new Date(input.incident.last_seen_at).toISOString();
24196
24389
  const capturedAt = primarySignalEnvelope !== null ? toIsoTimestamp(primarySignalEnvelope.occurred_at) : toIsoTimestamp(input.bundleMetadata.source_occurred_at);
24390
+ const bundleSdk = deriveBundleSdk(sourceEnvelopes, input.bundleMetadata.source_event_id);
24197
24391
  const serviceRuntime = input.incident.service_runtime ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.runtime ?? null;
24198
24392
  const serviceFramework = input.incident.service_framework ?? selectLatestEnvelope(sourceEnvelopes, (envelope) => envelope.event_type !== "probe_event")?.service.framework ?? null;
24199
24393
  const customerVisible = frontendContext !== null;
@@ -24212,10 +24406,7 @@ function buildBundle(input) {
24212
24406
  bundle_id: `bnd_${input.incident.incident_id}`,
24213
24407
  bundle_type: "failure",
24214
24408
  captured_at: capturedAt,
24215
- sdk: {
24216
- name: "debugbundle-worker",
24217
- version: "0.1.0"
24218
- },
24409
+ sdk: bundleSdk,
24219
24410
  project: {
24220
24411
  id: input.incident.project_id,
24221
24412
  slug: input.incident.project_id,
@@ -24588,7 +24779,7 @@ function buildReproduction(bundle) {
24588
24779
 
24589
24780
  // ../cli/src/cli-fs-helpers.ts
24590
24781
  var import_node_path5 = require("node:path");
24591
- function isRecord2(value) {
24782
+ function isRecord3(value) {
24592
24783
  return typeof value === "object" && value !== null;
24593
24784
  }
24594
24785
  function isMissingPathError(error) {
@@ -24886,14 +25077,14 @@ async function pathExists4(path, stat) {
24886
25077
  await stat(path);
24887
25078
  return true;
24888
25079
  } catch (error) {
24889
- if (isRecord2(error) && error["code"] === "ENOENT") {
25080
+ if (isRecord3(error) && error["code"] === "ENOENT") {
24890
25081
  return false;
24891
25082
  }
24892
25083
  throw error;
24893
25084
  }
24894
25085
  }
24895
25086
  function parseIncidentState(candidate) {
24896
- if (!isRecord2(candidate)) {
25087
+ if (!isRecord3(candidate)) {
24897
25088
  return null;
24898
25089
  }
24899
25090
  if (candidate["source"] !== "local" || candidate["status"] !== "open" && candidate["status"] !== "resolved") {
@@ -25005,7 +25196,7 @@ function parseIncidentState(candidate) {
25005
25196
  }
25006
25197
  function parseState(rawState) {
25007
25198
  const parsed = JSON.parse(rawState);
25008
- if (!isRecord2(parsed) || parsed["version"] !== 1) {
25199
+ if (!isRecord3(parsed) || parsed["version"] !== 1) {
25009
25200
  return null;
25010
25201
  }
25011
25202
  const lastProcessedEventFile = parsed["last_processed_event_file"];
@@ -25013,7 +25204,7 @@ function parseState(rawState) {
25013
25204
  return null;
25014
25205
  }
25015
25206
  const incidents = parsed["incidents"];
25016
- if (!isRecord2(incidents)) {
25207
+ if (!isRecord3(incidents)) {
25017
25208
  return null;
25018
25209
  }
25019
25210
  const parsedIncidents = {};
@@ -25400,14 +25591,14 @@ async function readJsonFile(path, dependencies) {
25400
25591
  try {
25401
25592
  return JSON.parse(await readFile(path, "utf8"));
25402
25593
  } catch (error) {
25403
- if (isRecord2(error) && error["code"] === "ENOENT") {
25594
+ if (isRecord3(error) && error["code"] === "ENOENT") {
25404
25595
  throw error;
25405
25596
  }
25406
25597
  throw createReadError(400, "invalid_local_json");
25407
25598
  }
25408
25599
  }
25409
25600
  function parseLocalConnection(candidate) {
25410
- if (!isRecord2(candidate) || candidate["mode"] !== "local-only" && candidate["mode"] !== "connected") {
25601
+ if (!isRecord3(candidate) || candidate["mode"] !== "local-only" && candidate["mode"] !== "connected") {
25411
25602
  throw createReadError(400, "invalid_local_connection_config");
25412
25603
  }
25413
25604
  return {
@@ -25415,7 +25606,7 @@ function parseLocalConnection(candidate) {
25415
25606
  };
25416
25607
  }
25417
25608
  function parseLocalIncident(candidate) {
25418
- if (!isRecord2(candidate)) {
25609
+ if (!isRecord3(candidate)) {
25419
25610
  throw createReadError(400, "invalid_local_state");
25420
25611
  }
25421
25612
  const requiredStringFields = [
@@ -25447,9 +25638,13 @@ function parseLocalIncident(candidate) {
25447
25638
  throw createReadError(400, "invalid_local_state");
25448
25639
  }
25449
25640
  const resolvedAt = candidate["resolved_at"];
25641
+ const regressedAt = candidate["regressed_at"];
25450
25642
  if (resolvedAt !== void 0 && resolvedAt !== null && typeof resolvedAt !== "string") {
25451
25643
  throw createReadError(400, "invalid_local_state");
25452
25644
  }
25645
+ if (regressedAt !== void 0 && regressedAt !== null && typeof regressedAt !== "string") {
25646
+ throw createReadError(400, "invalid_local_state");
25647
+ }
25453
25648
  if (typeof candidate["occurrence_count"] !== "number" || typeof candidate["generation_number"] !== "number") {
25454
25649
  throw createReadError(400, "invalid_local_state");
25455
25650
  }
@@ -25484,6 +25679,7 @@ function parseLocalIncident(candidate) {
25484
25679
  severity: candidate["severity"],
25485
25680
  status: candidate["status"],
25486
25681
  ...resolvedAt === void 0 ? {} : { resolved_at: resolvedAt },
25682
+ ...regressedAt === void 0 ? {} : { regressed_at: regressedAt },
25487
25683
  first_seen_at: candidate["first_seen_at"],
25488
25684
  last_seen_at: candidate["last_seen_at"],
25489
25685
  occurrence_count: candidate["occurrence_count"],
@@ -25498,7 +25694,7 @@ function parseLocalIncident(candidate) {
25498
25694
  };
25499
25695
  }
25500
25696
  function parseLocalState(candidate) {
25501
- if (!isRecord2(candidate) || candidate["version"] !== 1 || !isRecord2(candidate["incidents"])) {
25697
+ if (!isRecord3(candidate) || candidate["version"] !== 1 || !isRecord3(candidate["incidents"])) {
25502
25698
  throw createReadError(400, "invalid_local_state");
25503
25699
  }
25504
25700
  const incidents = Object.fromEntries(
@@ -25535,7 +25731,7 @@ async function readLocalConnectionConfig(dependencies) {
25535
25731
  try {
25536
25732
  return parseLocalConnection(await readJsonFile((0, import_node_path8.join)(rootDirectory, CONNECTION_FILE_PATH2), dependencies));
25537
25733
  } catch (error) {
25538
- if (isRecord2(error) && error["code"] === "ENOENT") {
25734
+ if (isRecord3(error) && error["code"] === "ENOENT") {
25539
25735
  return null;
25540
25736
  }
25541
25737
  throw error;
@@ -25546,7 +25742,7 @@ async function readLocalState(dependencies) {
25546
25742
  try {
25547
25743
  return parseLocalState(await readJsonFile(getStateFilePath(rootDirectory), dependencies));
25548
25744
  } catch (error) {
25549
- if (isRecord2(error) && error["code"] === "ENOENT") {
25745
+ if (isRecord3(error) && error["code"] === "ENOENT") {
25550
25746
  return {
25551
25747
  version: 1,
25552
25748
  last_processed_event_file: null,
@@ -25589,7 +25785,12 @@ async function listLocalIncidents(input, dependencies) {
25589
25785
  return incident.status === "open";
25590
25786
  }
25591
25787
  return incident.status === input.status;
25592
- }).filter((incident) => input.severity === void 0 ? true : incident.severity === input.severity).filter((incident) => input.firstSeenAfter === void 0 ? true : incident.first_seen_at >= input.firstSeenAfter).sort(sortIncidentsDescending);
25788
+ }).filter((incident) => input.severity === void 0 ? true : incident.severity === input.severity).filter((incident) => input.firstSeenAfter === void 0 ? true : incident.first_seen_at >= input.firstSeenAfter).filter((incident) => {
25789
+ if (input.attentionAfter === void 0) {
25790
+ return true;
25791
+ }
25792
+ return incident.first_seen_at >= input.attentionAfter || incident.regressed_at != null && incident.regressed_at >= input.attentionAfter;
25793
+ }).sort(sortIncidentsDescending);
25593
25794
  const startIndex = input.cursor === void 0 ? 0 : incidents.findIndex((incident) => buildCursor(incident) === input.cursor) + 1;
25594
25795
  const pagedIncidents = input.limit === void 0 ? incidents.slice(startIndex) : incidents.slice(startIndex, startIndex + input.limit);
25595
25796
  const hasMore = input.limit !== void 0 && startIndex + input.limit < incidents.length;
@@ -25611,7 +25812,7 @@ async function getLocalBundle(input, dependencies) {
25611
25812
  try {
25612
25813
  return await readJsonFile(resolveWorkspacePath(rootDirectory, incident.bundle_path), dependencies);
25613
25814
  } catch (error) {
25614
- if (isRecord2(error) && error["code"] === "ENOENT") {
25815
+ if (isRecord3(error) && error["code"] === "ENOENT") {
25615
25816
  throw createReadError(404, "bundle_not_found");
25616
25817
  }
25617
25818
  if (error instanceof RetrievalApiError && error.code === "invalid_local_json") {
@@ -25626,7 +25827,7 @@ async function getLocalReproduction(input, dependencies) {
25626
25827
  try {
25627
25828
  return await readJsonFile(resolveWorkspacePath(rootDirectory, incident.reproduction_path), dependencies);
25628
25829
  } catch (error) {
25629
- if (isRecord2(error) && error["code"] === "ENOENT") {
25830
+ if (isRecord3(error) && error["code"] === "ENOENT") {
25630
25831
  throw createReadError(404, "reproduction_not_found");
25631
25832
  }
25632
25833
  if (error instanceof RetrievalApiError && error.code === "invalid_local_json") {
@@ -27312,7 +27513,7 @@ function requireBearerToken(input) {
27312
27513
  }
27313
27514
  return bearerToken;
27314
27515
  }
27315
- function readString2(input, key) {
27516
+ function readString3(input, key) {
27316
27517
  const value = input[key];
27317
27518
  return typeof value === "string" ? value : "";
27318
27519
  }
@@ -27339,7 +27540,7 @@ function createImprovementMcpTools(api) {
27339
27540
  try {
27340
27541
  return await api.getImprovement({
27341
27542
  bearerToken: requireBearerToken(input),
27342
- improvementId: readString2(input, "improvementId")
27543
+ improvementId: readString3(input, "improvementId")
27343
27544
  });
27344
27545
  } catch (error) {
27345
27546
  mapMcpError7(error);
@@ -27349,8 +27550,8 @@ function createImprovementMcpTools(api) {
27349
27550
  try {
27350
27551
  return await api.getImprovementBundle({
27351
27552
  bearerToken: requireBearerToken(input),
27352
- projectId: readString2(input, "projectId"),
27353
- improvementId: readString2(input, "improvementId")
27553
+ projectId: readString3(input, "projectId"),
27554
+ improvementId: readString3(input, "improvementId")
27354
27555
  });
27355
27556
  } catch (error) {
27356
27557
  mapMcpError7(error);
@@ -27360,7 +27561,7 @@ function createImprovementMcpTools(api) {
27360
27561
  try {
27361
27562
  return await api.resolveImprovement({
27362
27563
  bearerToken: requireBearerToken(input),
27363
- improvementId: readString2(input, "improvementId")
27564
+ improvementId: readString3(input, "improvementId")
27364
27565
  });
27365
27566
  } catch (error) {
27366
27567
  mapMcpError7(error);
@@ -27370,7 +27571,7 @@ function createImprovementMcpTools(api) {
27370
27571
  try {
27371
27572
  return await api.reopenImprovement({
27372
27573
  bearerToken: requireBearerToken(input),
27373
- improvementId: readString2(input, "improvementId")
27574
+ improvementId: readString3(input, "improvementId")
27374
27575
  });
27375
27576
  } catch (error) {
27376
27577
  mapMcpError7(error);
@@ -27380,8 +27581,8 @@ function createImprovementMcpTools(api) {
27380
27581
  try {
27381
27582
  return await api.snoozeImprovement({
27382
27583
  bearerToken: requireBearerToken(input),
27383
- improvementId: readString2(input, "improvementId"),
27384
- snoozedUntil: readString2(input, "snoozedUntil")
27584
+ improvementId: readString3(input, "improvementId"),
27585
+ snoozedUntil: readString3(input, "snoozedUntil")
27385
27586
  });
27386
27587
  } catch (error) {
27387
27588
  mapMcpError7(error);
@@ -27991,7 +28192,7 @@ async function updateCachedArtifactStatus(filePath, input, dependencies) {
27991
28192
  `, "utf8");
27992
28193
  }
27993
28194
  function applyIncidentStatusToPayload(payload, incidentId, incident) {
27994
- if (!isRecord2(payload)) {
28195
+ if (!isRecord3(payload)) {
27995
28196
  return payload;
27996
28197
  }
27997
28198
  const nextPayload = { ...payload };
@@ -28002,7 +28203,7 @@ function applyIncidentStatusToPayload(payload, incidentId, incident) {
28002
28203
  if (matchesIncident && (Object.hasOwn(payload, "resolved_at") || incident.resolved_at !== void 0)) {
28003
28204
  nextPayload["resolved_at"] = incident.resolved_at ?? null;
28004
28205
  }
28005
- if (isRecord2(payload["incident"])) {
28206
+ if (isRecord3(payload["incident"])) {
28006
28207
  nextPayload["incident"] = applyIncidentStatusToPayload(payload["incident"], incidentId, incident);
28007
28208
  }
28008
28209
  return nextPayload;
@@ -28084,6 +28285,9 @@ function readIncidentListFilters(input) {
28084
28285
  if (typeof input["firstSeenAfter"] === "string") {
28085
28286
  requestInput.firstSeenAfter = input["firstSeenAfter"];
28086
28287
  }
28288
+ if (typeof input["attentionAfter"] === "string") {
28289
+ requestInput.attentionAfter = input["attentionAfter"];
28290
+ }
28087
28291
  if (typeof input["cursor"] === "string") {
28088
28292
  requestInput.cursor = input["cursor"];
28089
28293
  }
@@ -28105,6 +28309,7 @@ async function listAllCloudIncidents(input, api) {
28105
28309
  ...filters.status === void 0 ? {} : { status: filters.status },
28106
28310
  ...filters.severity === void 0 ? {} : { severity: filters.severity },
28107
28311
  ...filters.firstSeenAfter === void 0 ? {} : { firstSeenAfter: filters.firstSeenAfter },
28312
+ ...filters.attentionAfter === void 0 ? {} : { attentionAfter: filters.attentionAfter },
28108
28313
  ...cursor === void 0 ? {} : { cursor }
28109
28314
  });
28110
28315
  incidents.push(...response.incidents.map((incident) => attachSourceToRecord(incident, "cloud")));
@@ -28167,7 +28372,8 @@ function createRetrievalMcpTools(api) {
28167
28372
  ...incidentFilters.service === void 0 ? {} : { service: incidentFilters.service },
28168
28373
  ...incidentFilters.status === void 0 ? {} : { status: incidentFilters.status },
28169
28374
  ...incidentFilters.severity === void 0 ? {} : { severity: incidentFilters.severity },
28170
- ...incidentFilters.firstSeenAfter === void 0 ? {} : { firstSeenAfter: incidentFilters.firstSeenAfter }
28375
+ ...incidentFilters.firstSeenAfter === void 0 ? {} : { firstSeenAfter: incidentFilters.firstSeenAfter },
28376
+ ...incidentFilters.attentionAfter === void 0 ? {} : { attentionAfter: incidentFilters.attentionAfter }
28171
28377
  });
28172
28378
  const cloudIncidents = await listAllCloudIncidents(input, {
28173
28379
  listIncidents: (requestInput2) => api.listIncidents(requestInput2)
@@ -28201,6 +28407,9 @@ function createRetrievalMcpTools(api) {
28201
28407
  if (incidentFilters.firstSeenAfter !== void 0) {
28202
28408
  requestInput.firstSeenAfter = incidentFilters.firstSeenAfter;
28203
28409
  }
28410
+ if (incidentFilters.attentionAfter !== void 0) {
28411
+ requestInput.attentionAfter = incidentFilters.attentionAfter;
28412
+ }
28204
28413
  if (incidentFilters.cursor !== void 0) {
28205
28414
  requestInput.cursor = incidentFilters.cursor;
28206
28415
  }
@@ -30402,7 +30611,7 @@ var zodToJsonSchema = (schema, options) => {
30402
30611
  var package_default = {
30403
30612
  name: "@debugbundle/mcp",
30404
30613
  mcpName: "com.debugbundle/mcp",
30405
- version: "1.5.2",
30614
+ version: "1.6.0",
30406
30615
  private: false,
30407
30616
  description: "Model Context Protocol server for DebugBundle",
30408
30617
  license: "AGPL-3.0-only",
@@ -30607,6 +30816,7 @@ var listIncidentsInputSchema = external_exports.object({
30607
30816
  status: external_exports.string().optional(),
30608
30817
  severity: external_exports.string().optional(),
30609
30818
  firstSeenAfter: external_exports.string().optional(),
30819
+ attentionAfter: external_exports.string().optional(),
30610
30820
  cursor: external_exports.string().optional(),
30611
30821
  limit: external_exports.number().optional()
30612
30822
  });
@@ -31476,7 +31686,7 @@ var MCP_TOOL_NAMES = MCP_TOOL_CATALOG.map((tool) => tool.name);
31476
31686
 
31477
31687
  // src/server.ts
31478
31688
  var MCP_SERVER_VERSION = package_default.version;
31479
- function isRecord3(value) {
31689
+ function isRecord4(value) {
31480
31690
  return typeof value === "object" && value !== null && !Array.isArray(value);
31481
31691
  }
31482
31692
  function readRequestId(id) {
@@ -31496,13 +31706,13 @@ function buildError(id, code, message) {
31496
31706
  };
31497
31707
  }
31498
31708
  function parseToolCallParams(params) {
31499
- if (!isRecord3(params) || typeof params["name"] !== "string") {
31709
+ if (!isRecord4(params) || typeof params["name"] !== "string") {
31500
31710
  return null;
31501
31711
  }
31502
31712
  const rawArguments = params["arguments"];
31503
31713
  return {
31504
31714
  name: params["name"],
31505
- arguments: isRecord3(rawArguments) ? rawArguments : {}
31715
+ arguments: isRecord4(rawArguments) ? rawArguments : {}
31506
31716
  };
31507
31717
  }
31508
31718
  function toToolResponse(payload) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@debugbundle/mcp",
3
3
  "mcpName": "com.debugbundle/mcp",
4
- "version": "1.5.2",
4
+ "version": "1.6.0",
5
5
  "private": false,
6
6
  "description": "Model Context Protocol server for DebugBundle",
7
7
  "license": "AGPL-3.0-only",
package/server.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "source": "github",
9
9
  "subfolder": "apps/mcp"
10
10
  },
11
- "version": "1.5.2",
11
+ "version": "1.6.0",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "registryBaseUrl": "https://registry.npmjs.org",
16
16
  "identifier": "@debugbundle/mcp",
17
- "version": "1.5.2",
17
+ "version": "1.6.0",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  },