@debugbundle/mcp 1.11.0 → 1.12.1

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/README.md CHANGED
@@ -42,7 +42,7 @@ Use `npx -y @debugbundle/mcp` in clients that require noninteractive package exe
42
42
  | Claude Desktop local MCP | local MCP server config | uses local machine auth/config |
43
43
  | Claude Code plugin | `/plugin marketplace add debugbundle/debugbundle` | installs bundled MCP config and DebugBundle skill |
44
44
  | Codex developer plugin | `codex plugin add debugbundle-codex@debugbundle` | repository marketplace; local MCP and workflow skill |
45
- | Codex direct MCP | `codex mcp add debugbundle -- npx -y @debugbundle/mcp@1.11.0 --local-auth` | app, CLI, and IDE on the same host |
45
+ | Codex direct MCP | `codex mcp add debugbundle -- npx -y @debugbundle/mcp@1.12.1 --local-auth` | app, CLI, and IDE on the same host |
46
46
  | Cursor | MCP config with `npx @debugbundle/mcp` | stdio transport |
47
47
  | VS Code / GitHub MCP Registry | `com.debugbundle/mcp` | official registry metadata |
48
48
  | OpenClaw / ClawHub | DebugBundle skill plus MCP config | use the published skill for workflow guidance |
package/dist/main.cjs CHANGED
@@ -10041,7 +10041,7 @@ var require_agent = __commonJS({
10041
10041
  function defaultFactory(origin, opts) {
10042
10042
  return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts);
10043
10043
  }
10044
- var Agent2 = class extends DispatcherBase {
10044
+ var Agent3 = class extends DispatcherBase {
10045
10045
  constructor({ factory = defaultFactory, maxOrigins = Infinity, connect, ...options } = {}) {
10046
10046
  if (typeof factory !== "function") {
10047
10047
  throw new InvalidArgumentError("factory must be a function.");
@@ -10155,7 +10155,7 @@ var require_agent = __commonJS({
10155
10155
  return allClientStats;
10156
10156
  }
10157
10157
  };
10158
- module2.exports = Agent2;
10158
+ module2.exports = Agent3;
10159
10159
  }
10160
10160
  });
10161
10161
 
@@ -10946,7 +10946,7 @@ var require_proxy_agent = __commonJS({
10946
10946
  "../../node_modules/.pnpm/undici@8.5.0/node_modules/undici/lib/dispatcher/proxy-agent.js"(exports2, module2) {
10947
10947
  "use strict";
10948
10948
  var { kProxy, kClose, kDestroy, kDispatch } = require_symbols();
10949
- var Agent2 = require_agent();
10949
+ var Agent3 = require_agent();
10950
10950
  var Pool = require_pool();
10951
10951
  var DispatcherBase = require_dispatcher_base();
10952
10952
  var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors();
@@ -11082,7 +11082,7 @@ var require_proxy_agent = __commonJS({
11082
11082
  } else {
11083
11083
  this[kClient] = clientFactory(url, { connect });
11084
11084
  }
11085
- this[kAgent] = new Agent2({
11085
+ this[kAgent] = new Agent3({
11086
11086
  ...opts,
11087
11087
  factory,
11088
11088
  connect: async (opts2, callback) => {
@@ -11221,7 +11221,7 @@ var require_env_http_proxy_agent = __commonJS({
11221
11221
  var DispatcherBase = require_dispatcher_base();
11222
11222
  var { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = require_symbols();
11223
11223
  var ProxyAgent = require_proxy_agent();
11224
- var Agent2 = require_agent();
11224
+ var Agent3 = require_agent();
11225
11225
  var DEFAULT_PORTS = {
11226
11226
  "http:": 80,
11227
11227
  "https:": 443
@@ -11234,7 +11234,7 @@ var require_env_http_proxy_agent = __commonJS({
11234
11234
  super();
11235
11235
  this.#opts = opts;
11236
11236
  const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts;
11237
- this[kNoProxyAgent] = new Agent2(agentOpts);
11237
+ this[kNoProxyAgent] = new Agent3(agentOpts);
11238
11238
  const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY;
11239
11239
  if (HTTP_PROXY) {
11240
11240
  this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY });
@@ -13993,7 +13993,7 @@ var require_mock_agent = __commonJS({
13993
13993
  "../../node_modules/.pnpm/undici@8.5.0/node_modules/undici/lib/mock/mock-agent.js"(exports2, module2) {
13994
13994
  "use strict";
13995
13995
  var { kClients } = require_symbols();
13996
- var Agent2 = require_agent();
13996
+ var Agent3 = require_agent();
13997
13997
  var {
13998
13998
  kAgent,
13999
13999
  kMockAgentSet,
@@ -14031,7 +14031,7 @@ var require_mock_agent = __commonJS({
14031
14031
  if (opts?.agent && typeof opts.agent.dispatch !== "function") {
14032
14032
  throw new InvalidArgumentError("Argument opts.agent must implement Agent");
14033
14033
  }
14034
- const agent = opts?.agent ? opts.agent : new Agent2(opts);
14034
+ const agent = opts?.agent ? opts.agent : new Agent3(opts);
14035
14035
  this[kAgent] = agent;
14036
14036
  this[kClients] = agent[kClients];
14037
14037
  this[kOptions] = mockOptions;
@@ -14653,7 +14653,7 @@ var require_snapshot_recorder = __commonJS({
14653
14653
  var require_snapshot_agent = __commonJS({
14654
14654
  "../../node_modules/.pnpm/undici@8.5.0/node_modules/undici/lib/mock/snapshot-agent.js"(exports2, module2) {
14655
14655
  "use strict";
14656
- var Agent2 = require_agent();
14656
+ var Agent3 = require_agent();
14657
14657
  var MockAgent = require_mock_agent();
14658
14658
  var { SnapshotRecorder } = require_snapshot_recorder();
14659
14659
  var { InvalidArgumentError, UndiciError } = require_errors();
@@ -14706,7 +14706,7 @@ var require_snapshot_agent = __commonJS({
14706
14706
  });
14707
14707
  this[kSnapshotLoaded] = false;
14708
14708
  if (this[kSnapshotMode] === "record" || this[kSnapshotMode] === "update" || this[kSnapshotMode] === "playback" && opts.excludeUrls && opts.excludeUrls.length > 0) {
14709
- this[kRealAgent] = new Agent2(opts);
14709
+ this[kRealAgent] = new Agent3(opts);
14710
14710
  }
14711
14711
  if ((this[kSnapshotMode] === "playback" || this[kSnapshotMode] === "update") && this[kSnapshotPath]) {
14712
14712
  this.loadSnapshots().catch(() => {
@@ -14955,10 +14955,10 @@ var require_global2 = __commonJS({
14955
14955
  var globalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.2");
14956
14956
  var legacyGlobalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
14957
14957
  var { InvalidArgumentError } = require_errors();
14958
- var Agent2 = require_agent();
14958
+ var Agent3 = require_agent();
14959
14959
  var Dispatcher1Wrapper = require_dispatcher1_wrapper();
14960
14960
  if (getGlobalDispatcher() === void 0) {
14961
- setGlobalDispatcher(new Agent2());
14961
+ setGlobalDispatcher(new Agent3());
14962
14962
  }
14963
14963
  function setGlobalDispatcher(agent) {
14964
14964
  if (!agent || typeof agent.dispatch !== "function") {
@@ -15431,8 +15431,8 @@ var require_dump = __commonJS({
15431
15431
  var require_dns = __commonJS({
15432
15432
  "../../node_modules/.pnpm/undici@8.5.0/node_modules/undici/lib/interceptor/dns.js"(exports2, module2) {
15433
15433
  "use strict";
15434
- var { isIP: isIP2 } = require("node:net");
15435
- var { lookup } = require("node:dns");
15434
+ var { isIP: isIP3 } = require("node:net");
15435
+ var { lookup: lookup2 } = require("node:dns");
15436
15436
  var DecoratorHandler = require_decorator_handler();
15437
15437
  var { InvalidArgumentError, InformationalError } = require_errors();
15438
15438
  var maxInt = Math.pow(2, 31) - 1;
@@ -15622,7 +15622,7 @@ var require_dns = __commonJS({
15622
15622
  }
15623
15623
  }
15624
15624
  #defaultLookup(origin, opts, cb) {
15625
- lookup(
15625
+ lookup2(
15626
15626
  origin.hostname,
15627
15627
  {
15628
15628
  all: true,
@@ -15840,7 +15840,7 @@ var require_dns = __commonJS({
15840
15840
  return dispatch(origDispatchOpts, handler7);
15841
15841
  }
15842
15842
  const origin = origDispatchOpts.origin.constructor === URL ? origDispatchOpts.origin : new URL(origDispatchOpts.origin);
15843
- if (isIP2(origin.hostname) !== 0) {
15843
+ if (isIP3(origin.hostname) !== 0) {
15844
15844
  return dispatch(origDispatchOpts, handler7);
15845
15845
  }
15846
15846
  instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => {
@@ -25618,7 +25618,7 @@ var require_undici = __commonJS({
25618
25618
  var Pool = require_pool();
25619
25619
  var BalancedPool = require_balanced_pool();
25620
25620
  var RoundRobinPool = require_round_robin_pool();
25621
- var Agent2 = require_agent();
25621
+ var Agent3 = require_agent();
25622
25622
  var Dispatcher1Wrapper = require_dispatcher1_wrapper();
25623
25623
  var ProxyAgent = require_proxy_agent();
25624
25624
  var Socks5ProxyAgent = require_socks5_proxy_agent();
@@ -25646,7 +25646,7 @@ var require_undici = __commonJS({
25646
25646
  module2.exports.Pool = Pool;
25647
25647
  module2.exports.BalancedPool = BalancedPool;
25648
25648
  module2.exports.RoundRobinPool = RoundRobinPool;
25649
- module2.exports.Agent = Agent2;
25649
+ module2.exports.Agent = Agent3;
25650
25650
  module2.exports.Dispatcher1Wrapper = Dispatcher1Wrapper;
25651
25651
  module2.exports.ProxyAgent = ProxyAgent;
25652
25652
  module2.exports.Socks5ProxyAgent = Socks5ProxyAgent;
@@ -29507,7 +29507,7 @@ var require_fast_uri = __commonJS({
29507
29507
  query: void 0,
29508
29508
  fragment: void 0
29509
29509
  };
29510
- let isIP2 = false;
29510
+ let isIP3 = false;
29511
29511
  if (options.reference === "suffix") {
29512
29512
  if (options.scheme) {
29513
29513
  uri = options.scheme + ":" + uri;
@@ -29532,9 +29532,9 @@ var require_fast_uri = __commonJS({
29532
29532
  if (ipv4result === false) {
29533
29533
  const ipv6result = normalizeIPv6(parsed.host);
29534
29534
  parsed.host = ipv6result.host.toLowerCase();
29535
- isIP2 = ipv6result.isIPV6;
29535
+ isIP3 = ipv6result.isIPV6;
29536
29536
  } else {
29537
- isIP2 = true;
29537
+ isIP3 = true;
29538
29538
  }
29539
29539
  }
29540
29540
  if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) {
@@ -29551,7 +29551,7 @@ var require_fast_uri = __commonJS({
29551
29551
  }
29552
29552
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
29553
29553
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
29554
- if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP2 === false && nonSimpleDomain(parsed.host)) {
29554
+ if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP3 === false && nonSimpleDomain(parsed.host)) {
29555
29555
  try {
29556
29556
  parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
29557
29557
  } catch (e) {
@@ -42498,7 +42498,7 @@ var require_mime_types = __commonJS({
42498
42498
  exports2.contentType = contentType;
42499
42499
  exports2.extension = extension;
42500
42500
  exports2.extensions = /* @__PURE__ */ Object.create(null);
42501
- exports2.lookup = lookup;
42501
+ exports2.lookup = lookup2;
42502
42502
  exports2.types = /* @__PURE__ */ Object.create(null);
42503
42503
  populateMaps(exports2.extensions, exports2.types);
42504
42504
  function charset(type) {
@@ -42540,7 +42540,7 @@ var require_mime_types = __commonJS({
42540
42540
  }
42541
42541
  return exts[0];
42542
42542
  }
42543
- function lookup(path) {
42543
+ function lookup2(path) {
42544
42544
  if (!path || typeof path !== "string") {
42545
42545
  return false;
42546
42546
  }
@@ -52293,7 +52293,7 @@ var require_mime_types2 = __commonJS({
52293
52293
  exports2.contentType = contentType;
52294
52294
  exports2.extension = extension;
52295
52295
  exports2.extensions = /* @__PURE__ */ Object.create(null);
52296
- exports2.lookup = lookup;
52296
+ exports2.lookup = lookup2;
52297
52297
  exports2.types = /* @__PURE__ */ Object.create(null);
52298
52298
  exports2._extensionConflicts = [];
52299
52299
  populateMaps(exports2.extensions, exports2.types);
@@ -52336,7 +52336,7 @@ var require_mime_types2 = __commonJS({
52336
52336
  }
52337
52337
  return exts[0];
52338
52338
  }
52339
- function lookup(path) {
52339
+ function lookup2(path) {
52340
52340
  if (!path || typeof path !== "string") {
52341
52341
  return false;
52342
52342
  }
@@ -59524,7 +59524,7 @@ var require_redis_errors = __commonJS({
59524
59524
  // ../../node_modules/.pnpm/cluster-key-slot@1.1.2/node_modules/cluster-key-slot/lib/index.js
59525
59525
  var require_lib2 = __commonJS({
59526
59526
  "../../node_modules/.pnpm/cluster-key-slot@1.1.2/node_modules/cluster-key-slot/lib/index.js"(exports2, module2) {
59527
- var lookup = [
59527
+ var lookup2 = [
59528
59528
  0,
59529
59529
  4129,
59530
59530
  8258,
@@ -59824,11 +59824,11 @@ var require_lib2 = __commonJS({
59824
59824
  start = i;
59825
59825
  }
59826
59826
  } else if (char !== 125) {
59827
- resultHash = lookup[(char ^ resultHash >> 8) & 255] ^ resultHash << 8;
59827
+ resultHash = lookup2[(char ^ resultHash >> 8) & 255] ^ resultHash << 8;
59828
59828
  } else if (i - 1 !== start) {
59829
59829
  return resultHash & 16383;
59830
59830
  }
59831
- result = lookup[(char ^ result >> 8) & 255] ^ result << 8;
59831
+ result = lookup2[(char ^ result >> 8) & 255] ^ result << 8;
59832
59832
  }
59833
59833
  return result & 16383;
59834
59834
  };
@@ -70211,16 +70211,43 @@ var AlertSchema = external_exports.object({
70211
70211
  severity_lifecycle_scope: AlertSeverityLifecycleScopeSchema.nullable().optional().default(null),
70212
70212
  cooldown_seconds: external_exports.number().int().min(0),
70213
70213
  config: external_exports.record(external_exports.string(), external_exports.unknown()),
70214
+ signing_secret: external_exports.string().optional(),
70214
70215
  is_enabled: external_exports.boolean(),
70215
70216
  created_at: external_exports.string(),
70216
70217
  updated_at: external_exports.string()
70217
70218
  }).strict();
70218
70219
  var AlertListResponseSchema = external_exports.object({
70219
- alerts: external_exports.array(AlertSchema)
70220
+ alerts: external_exports.array(AlertSchema.omit({ signing_secret: true }).strict())
70220
70221
  }).strict();
70221
70222
  var AlertResponseSchema = external_exports.object({
70222
70223
  alert: AlertSchema
70223
70224
  }).strict();
70225
+ var AlertGroupSummarySchema = external_exports.object({
70226
+ group_id: external_exports.string().uuid(),
70227
+ kind: external_exports.enum(["direct", "email_digest"]),
70228
+ project_id: external_exports.string().uuid(),
70229
+ alert_id: external_exports.string().uuid().nullable(),
70230
+ root_incident_id: external_exports.string().uuid().nullable(),
70231
+ channel: AlertChannelSchema,
70232
+ status: external_exports.enum(["pending", "delivered", "failed"]),
70233
+ member_count: external_exports.number().int().min(0),
70234
+ created_at: external_exports.string(),
70235
+ delivered_at: external_exports.string().nullable()
70236
+ }).strict();
70237
+ var AlertGroupMemberSchema = external_exports.object({
70238
+ incident_id: external_exports.string().uuid(),
70239
+ condition_type: external_exports.string(),
70240
+ created_at: external_exports.string()
70241
+ }).strict();
70242
+ var AlertGroupListResponseSchema = external_exports.object({
70243
+ groups: external_exports.array(AlertGroupSummarySchema),
70244
+ next_cursor: external_exports.string().nullable()
70245
+ }).strict();
70246
+ var AlertGroupResponseSchema = external_exports.object({
70247
+ group: AlertGroupSummarySchema,
70248
+ members: external_exports.array(AlertGroupMemberSchema),
70249
+ next_cursor: external_exports.string().nullable()
70250
+ }).strict();
70224
70251
  var ApiErrorResponseSchema = external_exports.object({
70225
70252
  error: external_exports.string()
70226
70253
  }).strict();
@@ -70283,6 +70310,28 @@ function createAlertApi(client) {
70283
70310
  })
70284
70311
  );
70285
70312
  },
70313
+ async listAlertGroups(input2) {
70314
+ const response = await client.request({
70315
+ method: "GET",
70316
+ path: `/v1/alert-groups${buildQuery({ project_id: input2.projectId, limit: input2.limit, cursor: input2.cursor })}`,
70317
+ bearerToken: input2.bearerToken
70318
+ });
70319
+ if (response.status < 200 || response.status >= 300) parseApiError(response.status, response.body);
70320
+ const parsed = AlertGroupListResponseSchema.safeParse(response.body);
70321
+ if (!parsed.success) throw new AlertApiError(response.status, "invalid_response_shape");
70322
+ return parsed.data;
70323
+ },
70324
+ async getAlertGroup(input2) {
70325
+ const response = await client.request({
70326
+ method: "GET",
70327
+ path: `/v1/alert-groups/${input2.kind}/${encodeURIComponent(input2.groupId)}${buildQuery({ project_id: input2.projectId, limit: input2.limit, cursor: input2.cursor })}`,
70328
+ bearerToken: input2.bearerToken
70329
+ });
70330
+ if (response.status < 200 || response.status >= 300) parseApiError(response.status, response.body);
70331
+ const parsed = AlertGroupResponseSchema.safeParse(response.body);
70332
+ if (!parsed.success) throw new AlertApiError(response.status, "invalid_response_shape");
70333
+ return parsed.data;
70334
+ },
70286
70335
  async createAlert(input2) {
70287
70336
  const body = {
70288
70337
  project_id: input2.projectId,
@@ -70290,6 +70339,9 @@ function createAlertApi(client) {
70290
70339
  condition_type: input2.conditionType,
70291
70340
  config: input2.config
70292
70341
  };
70342
+ if (input2.channel === "webhook") {
70343
+ body.signing = "hmac_sha256_v1";
70344
+ }
70293
70345
  if (input2.serviceId !== void 0) {
70294
70346
  body.service_id = input2.serviceId;
70295
70347
  }
@@ -70337,6 +70389,9 @@ function createAlertApi(client) {
70337
70389
  if (input2.config !== void 0) {
70338
70390
  body.config = input2.config;
70339
70391
  }
70392
+ if (input2.rotateSigningSecret === true) {
70393
+ body.rotate_signing_secret = true;
70394
+ }
70340
70395
  if (input2.isEnabled !== void 0) {
70341
70396
  body.is_enabled = input2.isEnabled;
70342
70397
  }
@@ -75332,6 +75387,7 @@ function buildCliReference() {
75332
75387
  "## Notifications",
75333
75388
  "",
75334
75389
  "- `debugbundle alert list --project-id <id> [--limit <n>] [--auth-file <path>] [--json]`",
75390
+ "- `debugbundle alert groups --project-id <id> [--limit <n>] [--cursor <cursor>] [--auth-file <path>] [--json]` lists safe alert delivery and email digest groups; `debugbundle alert group <direct|email_digest> <group-id> --project-id <id> [--cursor <cursor>] --json` pages their incident IDs.",
75335
75391
  "- `debugbundle alert create --project-id <id> --channel <channel> --condition <condition> [--service-id <id>] [--severity-min <level>] [--cooldown <seconds>] --config-json <json> [--is-enabled <true|false>] [--auth-file <path>] [--json]`",
75336
75392
  "- `debugbundle alert update <alert-id> --project-id <id> [--service-id <id|null>] [--channel <channel>] [--condition <condition>] [--severity-min <level|null>] [--cooldown <seconds>] [--config-json <json|null>] [--is-enabled <true|false>] [--auth-file <path>] [--json]`",
75337
75393
  "- `debugbundle alert delete <alert-id> --project-id <id> [--auth-file <path>] [--json]`",
@@ -75485,7 +75541,7 @@ function buildMcpReference() {
75485
75541
  "",
75486
75542
  "## Notification Tools",
75487
75543
  "",
75488
- "- `list_alerts`, `create_alert`, `update_alert`, `delete_alert` \u2014 manage incident alert rules.",
75544
+ "- `list_alerts`, `create_alert`, `update_alert`, `delete_alert` \u2014 manage incident alert rules. `list_alert_groups` and `get_alert_group` inspect project-scoped delivery groups without raw payloads or destination secrets.",
75489
75545
  "- `list_webhooks`, `create_webhook`, `update_webhook`, `delete_webhook` \u2014 manage signed webhook destinations.",
75490
75546
  "- `test_webhook`, `list_webhook_deliveries` \u2014 validate webhook delivery and inspect delivery history.",
75491
75547
  "",
@@ -85009,6 +85065,34 @@ function createAlertMcpTools(api) {
85009
85065
  mapMcpError(error2);
85010
85066
  }
85011
85067
  },
85068
+ async list_alert_groups(input2) {
85069
+ try {
85070
+ return await api.listAlertGroups({
85071
+ bearerToken: String(input2["bearerToken"]),
85072
+ projectId: String(input2["projectId"]),
85073
+ ...typeof input2["limit"] === "number" ? { limit: input2["limit"] } : {},
85074
+ ...typeof input2["cursor"] === "string" ? { cursor: input2["cursor"] } : {}
85075
+ });
85076
+ } catch (error2) {
85077
+ mapMcpError(error2);
85078
+ }
85079
+ },
85080
+ async get_alert_group(input2) {
85081
+ try {
85082
+ const kind = input2["kind"];
85083
+ if (kind !== "direct" && kind !== "email_digest") throw new Error("invalid_group_kind");
85084
+ return await api.getAlertGroup({
85085
+ bearerToken: String(input2["bearerToken"]),
85086
+ projectId: String(input2["projectId"]),
85087
+ kind,
85088
+ groupId: String(input2["groupId"]),
85089
+ ...typeof input2["limit"] === "number" ? { limit: input2["limit"] } : {},
85090
+ ...typeof input2["cursor"] === "string" ? { cursor: input2["cursor"] } : {}
85091
+ });
85092
+ } catch (error2) {
85093
+ mapMcpError(error2);
85094
+ }
85095
+ },
85012
85096
  async create_alert(input2) {
85013
85097
  try {
85014
85098
  const requestInput = {
@@ -85080,6 +85164,19 @@ function createAlertMcpTools(api) {
85080
85164
  mapMcpError(error2);
85081
85165
  }
85082
85166
  },
85167
+ async rotate_alert_webhook_secret(input2) {
85168
+ try {
85169
+ return { alert: await api.updateAlert({
85170
+ bearerToken: String(input2["bearerToken"]),
85171
+ projectId: String(input2["projectId"]),
85172
+ alertId: String(input2["alertId"]),
85173
+ channel: "webhook",
85174
+ rotateSigningSecret: true
85175
+ }) };
85176
+ } catch (error2) {
85177
+ mapMcpError(error2);
85178
+ }
85179
+ },
85083
85180
  async delete_alert(input2) {
85084
85181
  try {
85085
85182
  return {
@@ -98757,8 +98854,8 @@ function applySSRFProtection(dispatcher2) {
98757
98854
  return dispatcher2;
98758
98855
  }
98759
98856
  function createSSRFProtectedDispatcher() {
98760
- const Agent2 = getAgent();
98761
- return applySSRFProtection(new Agent2());
98857
+ const Agent3 = getAgent();
98858
+ return applySSRFProtection(new Agent3());
98762
98859
  }
98763
98860
  var dispatcher;
98764
98861
  async function fetchRequest(provider, url, options) {
@@ -104494,6 +104591,88 @@ var CLAIM_DUE_AVAILABILITY_CHECKS_QUERY = `
104494
104591
  c.consecutive_successes
104495
104592
  `;
104496
104593
 
104594
+ // ../../packages/storage/src/alert-outbound-guard.ts
104595
+ var import_promises5 = require("node:dns/promises");
104596
+ var import_node_net2 = require("node:net");
104597
+ var import_undici3 = __toESM(require_undici(), 1);
104598
+ var blockedAddresses2 = new import_node_net2.BlockList();
104599
+ for (const [address, prefix] of [
104600
+ ["0.0.0.0", 8],
104601
+ ["10.0.0.0", 8],
104602
+ ["100.64.0.0", 10],
104603
+ ["127.0.0.0", 8],
104604
+ ["169.254.0.0", 16],
104605
+ ["172.16.0.0", 12],
104606
+ ["192.0.0.0", 24],
104607
+ ["192.0.2.0", 24],
104608
+ ["192.88.99.0", 24],
104609
+ ["192.168.0.0", 16],
104610
+ ["198.18.0.0", 15],
104611
+ ["198.51.100.0", 24],
104612
+ ["203.0.113.0", 24],
104613
+ ["224.0.0.0", 4],
104614
+ ["240.0.0.0", 4]
104615
+ ]) blockedAddresses2.addSubnet(address, prefix);
104616
+ for (const [address, prefix] of [
104617
+ ["::", 128],
104618
+ ["::1", 128],
104619
+ ["64:ff9b::", 96],
104620
+ ["100::", 64],
104621
+ ["2001::", 23],
104622
+ ["2001:db8::", 32],
104623
+ ["2002::", 16],
104624
+ ["fc00::", 7],
104625
+ ["fe80::", 10],
104626
+ ["ff00::", 8]
104627
+ ]) blockedAddresses2.addSubnet(address, prefix, "ipv6");
104628
+ function blocked() {
104629
+ return new Error("alert_target_blocked");
104630
+ }
104631
+ function assertPublicAddress(address, family) {
104632
+ if (family !== 4 && family !== 6 || (0, import_node_net2.isIP)(address) !== family || blockedAddresses2.check(address, family === 4 ? "ipv4" : "ipv6")) {
104633
+ throw blocked();
104634
+ }
104635
+ }
104636
+ function assertPublicHostname(hostname2) {
104637
+ const normalized = hostname2.toLowerCase().replace(/\.$/, "");
104638
+ if (!normalized.includes(".") || [".local", ".internal", ".localhost"].some((suffix) => normalized.endsWith(suffix))) {
104639
+ throw blocked();
104640
+ }
104641
+ }
104642
+ async function resolveAlertOutboundAddress(hostname2, resolve4 = import_promises5.lookup) {
104643
+ const literalFamily = (0, import_node_net2.isIP)(hostname2);
104644
+ if (literalFamily) {
104645
+ assertPublicAddress(hostname2, literalFamily);
104646
+ return { address: hostname2, family: literalFamily };
104647
+ }
104648
+ assertPublicHostname(hostname2);
104649
+ let answers;
104650
+ try {
104651
+ answers = await resolve4(hostname2, { all: true, verbatim: true });
104652
+ } catch {
104653
+ throw blocked();
104654
+ }
104655
+ if (answers.length === 0) throw blocked();
104656
+ for (const answer of answers) assertPublicAddress(answer.address, answer.family);
104657
+ const first = answers[0];
104658
+ return { address: first.address, family: first.family };
104659
+ }
104660
+ var outboundAgent = new import_undici3.Agent({
104661
+ connections: 4,
104662
+ maxOrigins: 128,
104663
+ connect: {
104664
+ lookup(hostname2, options, callback) {
104665
+ resolveAlertOutboundAddress(hostname2).then(
104666
+ ({ address, family }) => {
104667
+ if (options.all) callback(null, [{ address, family }]);
104668
+ else callback(null, address, family);
104669
+ },
104670
+ () => callback(blocked(), "")
104671
+ );
104672
+ }
104673
+ }
104674
+ });
104675
+
104497
104676
  // ../../packages/storage/src/auth-rate-limiter.ts
104498
104677
  var import_ioredis = __toESM(require_built3(), 1);
104499
104678
 
@@ -105013,6 +105192,11 @@ function normalizeInstalledJavaEvent(candidate) {
105013
105192
  };
105014
105193
  }
105015
105194
 
105195
+ // ../../packages/event-normalizer/src/java-stderr.ts
105196
+ function isJavaRedirectedStderrLogger(candidate) {
105197
+ return typeof candidate === "string" && candidate.length <= 256 && (candidate === "stderr" || candidate === "org.jboss.stdio" || candidate.startsWith("org.jboss.stdio."));
105198
+ }
105199
+
105016
105200
  // ../../packages/event-normalizer/src/java-timer-message.ts
105017
105201
  var TIMER_DIAGNOSTIC = /^WFLYEJB002(?:0|2):[^\n]*\[id=[^\]\n]*\btimedObjectId=/;
105018
105202
  var JAVA_TIMER_DATE = /\b(previousRun|initialExpiration|nextExpiration)=((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{1,2}\s+\d{2}:\d{2}:\d{2}\s+[A-Za-z][A-Za-z0-9:+-]{0,15}\s+\d{4})\b/g;
@@ -105502,12 +105686,22 @@ function getRequestResponseStatus(payload2) {
105502
105686
  const status = payload2?.["response_status"];
105503
105687
  return typeof status === "number" && Number.isFinite(status) ? status : null;
105504
105688
  }
105505
- function classifyEvent(eventType, logLevel, probeActivationId, payload2, capturePreset = "minimal", immediateClientErrorStatuses = [], immediateClientErrorPathRules = []) {
105689
+ function isJavaStackContinuation(payload2) {
105690
+ const message3 = payload2?.["message"];
105691
+ if (typeof message3 !== "string" || message3.length > 16384 || /[\r\n]/.test(message3)) return false;
105692
+ const attributes = payload2?.["attributes"];
105693
+ if (attributes === null || typeof attributes !== "object" || Array.isArray(attributes)) return false;
105694
+ if (!isJavaRedirectedStderrLogger(attributes["logger"])) return false;
105695
+ if ("throwable" in attributes && attributes.throwable !== null) return false;
105696
+ return /^\s*(?:at\s+[\w.$/]+\([^\r\n]*\)|\.\.\.\s+\d+\s+more|(?:Caused by|Suppressed):\s+[\w.$/]+(?:Exception|Error|Throwable)(?::[^\r\n]*|\s|$))\s*$/.test(message3);
105697
+ }
105698
+ function classifyEvent(eventType, logLevel, probeActivationId, payload2, capturePreset = "minimal", immediateClientErrorStatuses = [], immediateClientErrorPathRules = [], runtime) {
105506
105699
  switch (eventType) {
105507
105700
  case "backend_exception":
105508
105701
  case "frontend_exception":
105509
105702
  return "incident_signal";
105510
105703
  case "log_event":
105704
+ if (runtime === "java" && isJavaStackContinuation(payload2)) return "context_signal";
105511
105705
  if (logLevel !== void 0 && INCIDENT_LOG_LEVELS.has(logLevel)) {
105512
105706
  return "incident_signal";
105513
105707
  }
@@ -107141,6 +107335,8 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
107141
107335
  severity_lifecycle_scope text,
107142
107336
  cooldown_seconds integer NOT NULL DEFAULT 0,
107143
107337
  config jsonb NOT NULL DEFAULT '{}'::jsonb,
107338
+ signing_secret text,
107339
+ webhook_payload_version smallint NOT NULL DEFAULT 0 CHECK (webhook_payload_version IN (0, 1)),
107144
107340
  is_enabled boolean NOT NULL DEFAULT true,
107145
107341
  created_at timestamptz NOT NULL DEFAULT now(),
107146
107342
  updated_at timestamptz NOT NULL DEFAULT now(),
@@ -107187,6 +107383,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
107187
107383
  dedupe_key text NOT NULL,
107188
107384
  notification_key text NOT NULL DEFAULT '',
107189
107385
  coalescing_key text,
107386
+ evaluation_job_id text,
107190
107387
  channel text NOT NULL,
107191
107388
  status text NOT NULL,
107192
107389
  payload jsonb NOT NULL,
@@ -107205,6 +107402,21 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
107205
107402
  CREATE INDEX alert_deliveries_alert_notification_idx
107206
107403
  ON alert_deliveries (alert_id, notification_key, created_at DESC)
107207
107404
  `,
107405
+ `
107406
+ CREATE TABLE alert_delivery_members (
107407
+ id uuid PRIMARY KEY,
107408
+ delivery_id uuid NOT NULL REFERENCES alert_deliveries(id) ON DELETE CASCADE,
107409
+ incident_id uuid NOT NULL,
107410
+ condition_type text NOT NULL,
107411
+ dedupe_key text NOT NULL,
107412
+ created_at timestamptz NOT NULL DEFAULT now(),
107413
+ UNIQUE (delivery_id, incident_id, condition_type, dedupe_key)
107414
+ )
107415
+ `,
107416
+ `
107417
+ CREATE INDEX alert_delivery_members_delivery_created_idx
107418
+ ON alert_delivery_members (delivery_id, created_at ASC, id ASC)
107419
+ `,
107208
107420
  `
107209
107421
  CREATE TABLE alert_email_digests (
107210
107422
  id uuid PRIMARY KEY,
@@ -109699,6 +109911,45 @@ var STORAGE_SCHEMA_MIGRATIONS = [
109699
109911
  id: "202609160001_add_browser_resource_routes",
109700
109912
  description: "Retain sanitized browser resource routes independently of raw event sampling.",
109701
109913
  statements: ["ALTER TABLE incident_events ADD COLUMN IF NOT EXISTS resource_route text"]
109914
+ }),
109915
+ defineStorageSchemaMigration({
109916
+ id: "202609240001_add_alert_delivery_members",
109917
+ description: "Retain incident identities represented by one coherent alert delivery.",
109918
+ statements: [
109919
+ `
109920
+ CREATE TABLE IF NOT EXISTS alert_delivery_members (
109921
+ id uuid PRIMARY KEY,
109922
+ delivery_id uuid NOT NULL REFERENCES alert_deliveries(id) ON DELETE CASCADE,
109923
+ incident_id uuid NOT NULL,
109924
+ condition_type text NOT NULL,
109925
+ dedupe_key text NOT NULL,
109926
+ created_at timestamptz NOT NULL DEFAULT now(),
109927
+ UNIQUE (delivery_id, incident_id, condition_type, dedupe_key)
109928
+ )
109929
+ `,
109930
+ `
109931
+ CREATE INDEX IF NOT EXISTS alert_delivery_members_delivery_created_idx
109932
+ ON alert_delivery_members (delivery_id, created_at ASC, id ASC)
109933
+ `
109934
+ ]
109935
+ }),
109936
+ defineStorageSchemaMigration({
109937
+ id: "202609240002_add_alert_webhook_signing_secret",
109938
+ description: "Store custom alert-webhook signing secrets separately from readable rule config.",
109939
+ statements: ["ALTER TABLE alert_rules ADD COLUMN IF NOT EXISTS signing_secret text"]
109940
+ }),
109941
+ defineStorageSchemaMigration({
109942
+ id: "202609250001_add_alert_evaluation_owner",
109943
+ description: "Bind direct alert retries to the durable evaluation job that created the intent.",
109944
+ statements: ["ALTER TABLE alert_deliveries ADD COLUMN IF NOT EXISTS evaluation_job_id text"]
109945
+ }),
109946
+ defineStorageSchemaMigration({
109947
+ id: "202609250002_version_alert_webhook_payloads",
109948
+ description: "Preserve legacy custom webhook bodies while enforcing signatures for every delivery.",
109949
+ statements: [
109950
+ "ALTER TABLE alert_rules ADD COLUMN IF NOT EXISTS webhook_payload_version smallint NOT NULL DEFAULT 0 CHECK (webhook_payload_version IN (0, 1))",
109951
+ "UPDATE alert_rules SET webhook_payload_version = 1 WHERE channel = 'webhook' AND signing_secret IS NOT NULL"
109952
+ ]
109702
109953
  })
109703
109954
  ];
109704
109955
 
@@ -109713,7 +109964,7 @@ var STORAGE_SCHEMA_MIGRATIONS2 = [
109713
109964
  ].sort((left, right) => left.id.localeCompare(right.id));
109714
109965
 
109715
109966
  // ../cli/src/cloud-artifact-cache.ts
109716
- var import_promises5 = require("node:fs/promises");
109967
+ var import_promises6 = require("node:fs/promises");
109717
109968
  var import_node_path6 = require("node:path");
109718
109969
 
109719
109970
  // ../cli/src/cli-fs-helpers.ts
@@ -109858,9 +110109,9 @@ async function pruneCloudArtifactCache(input2, dependencies) {
109858
110109
  };
109859
110110
  }
109860
110111
  async function pruneExpiredArtifactsInDirectory(directoryPath, now, olderThanMs, dependencies) {
109861
- const readdir = dependencies?.readdir ?? import_promises5.readdir;
109862
- const rm = dependencies?.rm ?? import_promises5.rm;
109863
- const stat = dependencies?.stat ?? import_promises5.stat;
110112
+ const readdir = dependencies?.readdir ?? import_promises6.readdir;
110113
+ const rm = dependencies?.rm ?? import_promises6.rm;
110114
+ const stat = dependencies?.stat ?? import_promises6.stat;
109864
110115
  let fileNames;
109865
110116
  try {
109866
110117
  fileNames = await readdir(directoryPath);
@@ -109902,8 +110153,8 @@ async function pruneExpiredArtifactsInDirectory(directoryPath, now, olderThanMs,
109902
110153
  );
109903
110154
  }
109904
110155
  async function updateCachedArtifactStatus(filePath, input2, dependencies) {
109905
- const readFile = dependencies?.readFile ?? import_promises5.readFile;
109906
- const writeFile = dependencies?.writeFile ?? import_promises5.writeFile;
110156
+ const readFile = dependencies?.readFile ?? import_promises6.readFile;
110157
+ const writeFile = dependencies?.writeFile ?? import_promises6.writeFile;
109907
110158
  let payload2;
109908
110159
  try {
109909
110160
  const raw = await readFile(filePath, "utf8");
@@ -109937,15 +110188,15 @@ function applyIncidentStatusToPayload(payload2, incidentId2, incident) {
109937
110188
  return nextPayload;
109938
110189
  }
109939
110190
  async function persistCloudArtifact(directoryPath, fileName, payload2, dependencies) {
109940
- const mkdir5 = dependencies?.mkdir ?? import_promises5.mkdir;
109941
- const writeFile = dependencies?.writeFile ?? import_promises5.writeFile;
110191
+ const mkdir5 = dependencies?.mkdir ?? import_promises6.mkdir;
110192
+ const writeFile = dependencies?.writeFile ?? import_promises6.writeFile;
109942
110193
  await mkdir5(directoryPath, { recursive: true });
109943
110194
  await writeFile((0, import_node_path6.join)(directoryPath, fileName), `${JSON.stringify(payload2, null, 2)}
109944
110195
  `, "utf8");
109945
110196
  }
109946
110197
 
109947
110198
  // ../cli/src/local-retrieval-store.ts
109948
- var import_promises6 = require("node:fs/promises");
110199
+ var import_promises7 = require("node:fs/promises");
109949
110200
  var import_node_path7 = require("node:path");
109950
110201
  var CONNECTION_FILE_PATH2 = ".debugbundle/local/connection.json";
109951
110202
  var STATE_FILE_PATH = ".debugbundle/local/state.json";
@@ -109958,7 +110209,7 @@ function projectLocalEvidence(value) {
109958
110209
  return projected.value;
109959
110210
  }
109960
110211
  async function readLocalArtifact(path, dependencies) {
109961
- const readFile = dependencies?.readFile ?? import_promises6.readFile;
110212
+ const readFile = dependencies?.readFile ?? import_promises7.readFile;
109962
110213
  const raw = await readFile(path, "utf8");
109963
110214
  if (Buffer.byteLength(raw, "utf8") > MAX_ARTIFACT_BYTES) {
109964
110215
  throw createReadError(503, "privacy_projection_unavailable");
@@ -109977,7 +110228,7 @@ function createReadError(status, code) {
109977
110228
  return new RetrievalApiError(status, code);
109978
110229
  }
109979
110230
  async function readJsonFile(path, dependencies) {
109980
- const readFile = dependencies?.readFile ?? import_promises6.readFile;
110231
+ const readFile = dependencies?.readFile ?? import_promises7.readFile;
109981
110232
  try {
109982
110233
  return JSON.parse(await readFile(path, "utf8"));
109983
110234
  } catch (error2) {
@@ -110147,7 +110398,7 @@ async function readLocalState(dependencies) {
110147
110398
  }
110148
110399
  async function writeLocalState(state, dependencies) {
110149
110400
  const rootDirectory = getWorkspaceRoot2(dependencies);
110150
- const writeFile = dependencies?.writeFile ?? import_promises6.writeFile;
110401
+ const writeFile = dependencies?.writeFile ?? import_promises7.writeFile;
110151
110402
  await writeFile(getStateFilePath(rootDirectory), `${JSON.stringify(state, null, 2)}
110152
110403
  `, "utf8");
110153
110404
  }
@@ -110837,7 +111088,7 @@ function createServicesMcpTools(api) {
110837
111088
 
110838
111089
  // ../../packages/agent-setup/src/files.ts
110839
111090
  var import_node_fs2 = require("node:fs");
110840
- var import_promises7 = require("node:fs/promises");
111091
+ var import_promises8 = require("node:fs/promises");
110841
111092
  var import_node_crypto9 = require("node:crypto");
110842
111093
  var import_node_path8 = require("node:path");
110843
111094
  var digest2 = (text) => (0, import_node_crypto9.createHash)("sha256").update(text).digest("hex");
@@ -110852,7 +111103,7 @@ async function safePath(root, file, allowLeafLink = false) {
110852
111103
  for (let i = 0; i < parts.length; i++) {
110853
111104
  cursor = (0, import_node_path8.join)(cursor, parts[i]);
110854
111105
  try {
110855
- const info2 = await (0, import_promises7.lstat)(cursor);
111106
+ const info2 = await (0, import_promises8.lstat)(cursor);
110856
111107
  if (info2.isSymbolicLink() && !(allowLeafLink && i === parts.length - 1))
110857
111108
  throw new Error(`Unsafe symbolic link: ${file}`);
110858
111109
  if (i < parts.length - 1 && !info2.isDirectory())
@@ -110866,10 +111117,10 @@ async function safePath(root, file, allowLeafLink = false) {
110866
111117
  async function readManaged(root, file) {
110867
111118
  const path = await safePath(root, file);
110868
111119
  try {
110869
- const initial = await (0, import_promises7.lstat)(path);
111120
+ const initial = await (0, import_promises8.lstat)(path);
110870
111121
  if (!initial.isFile() || initial.size > 1024 * 1024)
110871
111122
  throw new Error(`Invalid or oversized managed file: ${file}`);
110872
- const handle = await (0, import_promises7.open)(
111123
+ const handle = await (0, import_promises8.open)(
110873
111124
  path,
110874
111125
  import_node_fs2.constants.O_RDONLY | import_node_fs2.constants.O_NOFOLLOW | import_node_fs2.constants.O_NONBLOCK
110875
111126
  );
@@ -110902,14 +111153,14 @@ async function readManaged(root, file) {
110902
111153
  }
110903
111154
  async function writeManaged(root, file, value, expected) {
110904
111155
  const path = await safePath(root, file);
110905
- await (0, import_promises7.mkdir)((0, import_node_path8.dirname)(path), { recursive: true });
111156
+ await (0, import_promises8.mkdir)((0, import_node_path8.dirname)(path), { recursive: true });
110906
111157
  await safePath(root, file);
110907
- const previousMode = await (0, import_promises7.lstat)(path).then((info2) => info2.mode & 511).catch((error2) => {
111158
+ const previousMode = await (0, import_promises8.lstat)(path).then((info2) => info2.mode & 511).catch((error2) => {
110908
111159
  if (!isMissing(error2)) throw error2;
110909
111160
  return void 0;
110910
111161
  });
110911
111162
  const temporary = `${path}.${(0, import_node_crypto9.randomUUID)()}.tmp`;
110912
- const handle = await (0, import_promises7.open)(
111163
+ const handle = await (0, import_promises8.open)(
110913
111164
  temporary,
110914
111165
  import_node_fs2.constants.O_WRONLY | import_node_fs2.constants.O_CREAT | import_node_fs2.constants.O_EXCL | import_node_fs2.constants.O_NOFOLLOW,
110915
111166
  384
@@ -110921,21 +111172,21 @@ async function writeManaged(root, file, value, expected) {
110921
111172
  if (await readManaged(root, file) !== expected)
110922
111173
  throw new Error(`File changed during setup: ${file}`);
110923
111174
  await safePath(root, file);
110924
- await (0, import_promises7.rename)(temporary, path);
111175
+ await (0, import_promises8.rename)(temporary, path);
110925
111176
  } finally {
110926
111177
  await handle.close();
110927
- await (0, import_promises7.unlink)(temporary).catch((error2) => {
111178
+ await (0, import_promises8.unlink)(temporary).catch((error2) => {
110928
111179
  if (!isMissing(error2)) throw error2;
110929
111180
  });
110930
111181
  }
110931
111182
  }
110932
111183
  async function projectRoot(cwd) {
110933
- const start = await (0, import_promises7.realpath)(cwd);
111184
+ const start = await (0, import_promises8.realpath)(cwd);
110934
111185
  let cursor = start;
110935
111186
  while (true) {
110936
111187
  if (await readManaged(cursor, ".debugbundle/profile.json") !== void 0) return cursor;
110937
111188
  try {
110938
- await (0, import_promises7.lstat)((0, import_node_path8.join)(cursor, ".git"));
111189
+ await (0, import_promises8.lstat)((0, import_node_path8.join)(cursor, ".git"));
110939
111190
  return start;
110940
111191
  } catch (error2) {
110941
111192
  if (!isMissing(error2)) throw error2;
@@ -111001,7 +111252,7 @@ async function pluginHints(root) {
111001
111252
  }
111002
111253
 
111003
111254
  // ../../packages/agent-setup/src/index.ts
111004
- var import_promises10 = require("node:fs/promises");
111255
+ var import_promises11 = require("node:fs/promises");
111005
111256
  var import_node_path11 = require("node:path");
111006
111257
 
111007
111258
  // ../../packages/agent-setup/src/model.ts
@@ -111090,11 +111341,11 @@ async function syncFiles(root, files, hashes2, fix, prefix = CANONICAL, legacyHa
111090
111341
  }
111091
111342
 
111092
111343
  // ../../packages/agent-setup/src/discovery.ts
111093
- var import_promises8 = require("node:fs/promises");
111344
+ var import_promises9 = require("node:fs/promises");
111094
111345
  var import_node_path9 = require("node:path");
111095
111346
  async function entries(root, dir, remaining = { count: 100 }) {
111096
111347
  const result = [];
111097
- for await (const entry of await (0, import_promises8.opendir)(await safePath(root, dir))) {
111348
+ for await (const entry of await (0, import_promises9.opendir)(await safePath(root, dir))) {
111098
111349
  if (--remaining.count < 0 || entry.isSymbolicLink())
111099
111350
  throw new Error("Unowned native discovery entries.");
111100
111351
  const path = `${dir}/${entry.name}`;
@@ -111125,15 +111376,15 @@ async function removeDiscovery(root, files, manifest) {
111125
111376
  if (!manifest.claude) return void 0;
111126
111377
  try {
111127
111378
  const path = await safePath(root, NATIVE, true);
111128
- const info2 = await (0, import_promises8.lstat)(path).catch((error2) => {
111379
+ const info2 = await (0, import_promises9.lstat)(path).catch((error2) => {
111129
111380
  if (!isMissing(error2)) throw error2;
111130
111381
  return void 0;
111131
111382
  });
111132
111383
  if (info2) {
111133
111384
  if (manifest.claude.mode === "link") {
111134
- if (!info2.isSymbolicLink() || await (0, import_promises8.readlink)(path) !== LINK)
111385
+ if (!info2.isSymbolicLink() || await (0, import_promises9.readlink)(path) !== LINK)
111135
111386
  return "claude-code: preserved changed skill link during removal.";
111136
- await (0, import_promises8.unlink)(path);
111387
+ await (0, import_promises9.unlink)(path);
111137
111388
  } else {
111138
111389
  if (!info2.isDirectory())
111139
111390
  return "claude-code: preserved changed skill directory during removal.";
@@ -111150,13 +111401,13 @@ async function removeDiscovery(root, files, manifest) {
111150
111401
  const content = await readManaged(root, file);
111151
111402
  if (content === void 0 || digest2(content) !== manifest.claude.files[file.slice(NATIVE.length + 1)])
111152
111403
  return "claude-code: preserved a skill file changed during removal.";
111153
- await (0, import_promises8.unlink)(await safePath(root, file));
111404
+ await (0, import_promises9.unlink)(await safePath(root, file));
111154
111405
  }
111155
111406
  for (const dir of copyDirectories(files))
111156
- await (0, import_promises8.rmdir)(await safePath(root, dir)).catch((error2) => {
111407
+ await (0, import_promises9.rmdir)(await safePath(root, dir)).catch((error2) => {
111157
111408
  if (!isMissing(error2)) throw error2;
111158
111409
  });
111159
- await (0, import_promises8.rmdir)(path);
111410
+ await (0, import_promises9.rmdir)(path);
111160
111411
  }
111161
111412
  }
111162
111413
  delete manifest.claude;
@@ -111165,10 +111416,10 @@ async function removeDiscovery(root, files, manifest) {
111165
111416
  return "claude-code: cannot safely remove managed discovery; manual review required.";
111166
111417
  }
111167
111418
  }
111168
- async function syncDiscovery(root, files, manifest, fix, writeLink = import_promises8.symlink) {
111419
+ async function syncDiscovery(root, files, manifest, fix, writeLink = import_promises9.symlink) {
111169
111420
  try {
111170
111421
  const path = await safePath(root, NATIVE, true);
111171
- let info2 = await (0, import_promises8.lstat)(path).catch((error2) => {
111422
+ let info2 = await (0, import_promises9.lstat)(path).catch((error2) => {
111172
111423
  if (!isMissing(error2)) throw error2;
111173
111424
  return void 0;
111174
111425
  });
@@ -111178,7 +111429,7 @@ async function syncDiscovery(root, files, manifest, fix, writeLink = import_prom
111178
111429
  message: `claude-code: missing ${NATIVE}; run debugbundle validate --fix.`
111179
111430
  };
111180
111431
  if (!info2 && fix) {
111181
- await (0, import_promises8.mkdir)((0, import_node_path9.dirname)(path), { recursive: true });
111432
+ await (0, import_promises9.mkdir)((0, import_node_path9.dirname)(path), { recursive: true });
111182
111433
  await safePath(root, NATIVE);
111183
111434
  if (manifest.claude?.mode !== "copy") {
111184
111435
  try {
@@ -111190,11 +111441,11 @@ async function syncDiscovery(root, files, manifest, fix, writeLink = import_prom
111190
111441
  manifest.claude = { mode: "copy", files: {} };
111191
111442
  }
111192
111443
  }
111193
- if (manifest.claude?.mode === "copy") await (0, import_promises8.mkdir)(path, { recursive: true });
111194
- info2 = await (0, import_promises8.lstat)(path);
111444
+ if (manifest.claude?.mode === "copy") await (0, import_promises9.mkdir)(path, { recursive: true });
111445
+ info2 = await (0, import_promises9.lstat)(path);
111195
111446
  }
111196
111447
  if (info2?.isSymbolicLink()) {
111197
- if (await (0, import_promises8.readlink)(path) !== LINK || manifest.claude?.mode === "copy")
111448
+ if (await (0, import_promises9.readlink)(path) !== LINK || manifest.claude?.mode === "copy")
111198
111449
  return {
111199
111450
  status: "conflict",
111200
111451
  message: "claude-code: preserved unknown or changed skill link."
@@ -111228,7 +111479,7 @@ async function syncDiscovery(root, files, manifest, fix, writeLink = import_prom
111228
111479
 
111229
111480
  // ../../packages/agent-setup/src/instructions.ts
111230
111481
  var import_node_path10 = require("node:path");
111231
- var import_promises9 = require("node:fs/promises");
111482
+ var import_promises10 = require("node:fs/promises");
111232
111483
  var DEFAULTS2 = {
111233
111484
  codex: "AGENTS.md",
111234
111485
  "claude-code": "CLAUDE.md",
@@ -111237,7 +111488,7 @@ var DEFAULTS2 = {
111237
111488
  };
111238
111489
  async function instructionExists(root, path) {
111239
111490
  try {
111240
- return (await (0, import_promises9.lstat)(await safePath(root, path, true))).size > 0;
111491
+ return (await (0, import_promises10.lstat)(await safePath(root, path, true))).size > 0;
111241
111492
  } catch (error2) {
111242
111493
  if (isMissing(error2)) return false;
111243
111494
  throw error2;
@@ -111252,7 +111503,7 @@ async function instructionPath(root, agent) {
111252
111503
  ".claude/CLAUDE.md"
111253
111504
  ]) {
111254
111505
  try {
111255
- await (0, import_promises9.lstat)(await safePath(root, path, true));
111506
+ await (0, import_promises10.lstat)(await safePath(root, path, true));
111256
111507
  return path;
111257
111508
  } catch (error2) {
111258
111509
  if (!isMissing(error2)) throw error2;
@@ -111267,14 +111518,14 @@ async function instructionPath(root, agent) {
111267
111518
  }
111268
111519
  async function linkedInstructions(root, path) {
111269
111520
  const absolute = await safePath(root, path, true);
111270
- const info2 = await (0, import_promises9.lstat)(absolute).catch((error2) => {
111521
+ const info2 = await (0, import_promises10.lstat)(absolute).catch((error2) => {
111271
111522
  if (!isMissing(error2)) throw error2;
111272
111523
  return void 0;
111273
111524
  });
111274
111525
  if (!info2?.isSymbolicLink()) return void 0;
111275
111526
  const destination = (0, import_node_path10.relative)(
111276
111527
  root,
111277
- (0, import_node_path10.resolve)((0, import_node_path10.dirname)(absolute), await (0, import_promises9.readlink)(absolute))
111528
+ (0, import_node_path10.resolve)((0, import_node_path10.dirname)(absolute), await (0, import_promises10.readlink)(absolute))
111278
111529
  ).replaceAll("\\", "/");
111279
111530
  if (!["AGENTS.md", "AGENTS.override.md", `${CANONICAL}/SKILL.md`].includes(destination))
111280
111531
  return false;
@@ -111389,7 +111640,7 @@ async function removeInstruction(root, agent, manifest, retained = []) {
111389
111640
  return `${agent}: preserved changed instruction spacing during removal.`;
111390
111641
  const end = range.end + owned.suffix.length;
111391
111642
  const next = current.slice(0, prefixStart) + current.slice(end);
111392
- if (owned.created && next === "") await (0, import_promises9.unlink)(await safePath(root, owned.path));
111643
+ if (owned.created && next === "") await (0, import_promises10.unlink)(await safePath(root, owned.path));
111393
111644
  else await writeManaged(root, owned.path, next, current);
111394
111645
  }
111395
111646
  delete manifest.instructions[agent];
@@ -111422,11 +111673,11 @@ async function discoveryOverride(root, agent) {
111422
111673
  async function manageAgentSetup(input2) {
111423
111674
  if (!input2.fix) return manage(input2);
111424
111675
  const lockPath = await safePath(input2.root, ".debugbundle/agent-setup.lock");
111425
- await (0, import_promises10.mkdir)((0, import_node_path11.dirname)(lockPath), { recursive: true });
111676
+ await (0, import_promises11.mkdir)((0, import_node_path11.dirname)(lockPath), { recursive: true });
111426
111677
  await safePath(input2.root, ".debugbundle/agent-setup.lock");
111427
111678
  let lock;
111428
111679
  try {
111429
- lock = await (0, import_promises10.open)(lockPath, "wx", 384);
111680
+ lock = await (0, import_promises11.open)(lockPath, "wx", 384);
111430
111681
  } catch {
111431
111682
  throw new Error(
111432
111683
  "Agent setup is locked or not writable. Wait for the active setup to finish; after a crashed process, remove .debugbundle/agent-setup.lock only after confirming no setup is running."
@@ -111436,7 +111687,7 @@ async function manageAgentSetup(input2) {
111436
111687
  return await manage(input2);
111437
111688
  } finally {
111438
111689
  await lock.close();
111439
- await (0, import_promises10.unlink)(await safePath(input2.root, ".debugbundle/agent-setup.lock"));
111690
+ await (0, import_promises11.unlink)(await safePath(input2.root, ".debugbundle/agent-setup.lock"));
111440
111691
  }
111441
111692
  }
111442
111693
  async function manage(input2) {
@@ -111520,7 +111771,7 @@ var legacy_skill_hashes_default = {
111520
111771
  };
111521
111772
 
111522
111773
  // ../cli/src/agent-setup.ts
111523
- var import_promises11 = require("node:readline/promises");
111774
+ var import_promises12 = require("node:readline/promises");
111524
111775
  var MANAGED_AGENTS_START = "<!-- debugbundle:start -->";
111525
111776
  var MANAGED_AGENTS_END = "<!-- debugbundle:end -->";
111526
111777
  function buildManagedAgentsSection() {
@@ -111589,7 +111840,7 @@ function localScaffoldFailure(error2, json2 = false) {
111589
111840
  }
111590
111841
 
111591
111842
  // ../cli/src/doctor-command.ts
111592
- var import_promises12 = require("node:fs/promises");
111843
+ var import_promises13 = require("node:fs/promises");
111593
111844
  var import_node_path12 = require("node:path");
111594
111845
 
111595
111846
  // ../cli/src/connection-config.ts
@@ -111752,7 +112003,7 @@ function buildPrivacyPreview() {
111752
112003
  "body.otp",
111753
112004
  "context.apiKey"
111754
112005
  ];
111755
- const sampleEventClass = classifyEvent(sampleEvent.event_type, void 0, void 0, sampleEvent.payload);
112006
+ const sampleEventClass = classifyEvent(sampleEvent.event_type, void 0, void 0, sampleEvent.payload, "minimal", [], [], sampleEvent.service.runtime);
111756
112007
  return {
111757
112008
  policy_version: TELEMETRY_PRIVACY_POLICY_VERSION,
111758
112009
  rule_families: ["sensitive_keys", "credential_text", "urls", "private_keys", "payment_cards"],
@@ -112148,13 +112399,13 @@ async function runDoctorCommand(input2, dependencies = {}) {
112148
112399
  const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
112149
112400
  const fetchImpl = dependencies.fetchImpl ?? nodeFetch;
112150
112401
  const readAuthStateImpl = dependencies.readAuthState ?? readCliAuthState;
112151
- const readdir = dependencies.readdir ?? import_promises12.readdir;
112402
+ const readdir = dependencies.readdir ?? import_promises13.readdir;
112152
112403
  const readFile = dependencies.readFile ?? (async (filePath) => {
112153
112404
  const content = await readManaged(rootDirectory, (0, import_node_path12.relative)(rootDirectory, filePath));
112154
112405
  if (content === void 0) throw Object.assign(new Error("Missing local scaffold file."), { code: "ENOENT" });
112155
112406
  return content;
112156
112407
  });
112157
- const stat = dependencies.stat ?? import_promises12.stat;
112408
+ const stat = dependencies.stat ?? import_promises13.stat;
112158
112409
  const rootDirectory = await projectRoot(cwd());
112159
112410
  const currentTime = now();
112160
112411
  const { check: profileCheck, profile, validationErrors } = await loadProfile(rootDirectory, { readFile, stat });
@@ -112321,7 +112572,7 @@ function formatCloudResult(input2, exitCode, checks, errors, incidentId2, verifi
112321
112572
 
112322
112573
  // ../cli/src/verify-command.ts
112323
112574
  var import_node_crypto13 = require("node:crypto");
112324
- var import_promises14 = require("node:fs/promises");
112575
+ var import_promises15 = require("node:fs/promises");
112325
112576
  var import_node_path15 = require("node:path");
112326
112577
 
112327
112578
  // ../../packages/log-parser/src/project-id.ts
@@ -112357,7 +112608,7 @@ var import_node_path14 = require("node:path");
112357
112608
 
112358
112609
  // ../cli/src/process-command.ts
112359
112610
  var import_node_crypto11 = require("node:crypto");
112360
- var import_promises13 = require("node:fs/promises");
112611
+ var import_promises14 = require("node:fs/promises");
112361
112612
  var import_node_path13 = require("node:path");
112362
112613
 
112363
112614
  // ../../packages/shared-types/src/browser-recovery.ts
@@ -113898,7 +114149,10 @@ function classifyEnvelope(envelope, capturePreset) {
113898
114149
  envelope.event_type === "log_event" ? envelope.payload.level : void 0,
113899
114150
  envelope.event_type === "probe_event" ? envelope.payload.activation_id : void 0,
113900
114151
  envelope.payload,
113901
- capturePreset
114152
+ capturePreset,
114153
+ [],
114154
+ [],
114155
+ envelope.service.runtime
113902
114156
  );
113903
114157
  }
113904
114158
  function isIncidentSignalEnvelope(envelope, capturePreset) {
@@ -114216,11 +114470,11 @@ function serializeState(state) {
114216
114470
  }
114217
114471
  async function processCommand(input2, dependencies = {}) {
114218
114472
  const cwd = dependencies.cwd ?? (() => process.cwd());
114219
- const mkdir5 = dependencies.mkdir ?? import_promises13.mkdir;
114220
- const readFile = dependencies.readFile ?? ((filePath) => (0, import_promises13.readFile)(filePath, "utf8"));
114221
- const readdir = dependencies.readdir ?? import_promises13.readdir;
114222
- const stat = dependencies.stat ?? import_promises13.stat;
114223
- const writeFile = dependencies.writeFile ?? ((filePath, content) => (0, import_promises13.writeFile)(filePath, content, "utf8"));
114473
+ const mkdir5 = dependencies.mkdir ?? import_promises14.mkdir;
114474
+ const readFile = dependencies.readFile ?? ((filePath) => (0, import_promises14.readFile)(filePath, "utf8"));
114475
+ const readdir = dependencies.readdir ?? import_promises14.readdir;
114476
+ const stat = dependencies.stat ?? import_promises14.stat;
114477
+ const writeFile = dependencies.writeFile ?? ((filePath, content) => (0, import_promises14.writeFile)(filePath, content, "utf8"));
114224
114478
  const rootDirectory = cwd();
114225
114479
  const eventsDirectoryPath = (0, import_node_path13.join)(rootDirectory, LOCAL_EVENTS_DIRECTORY_PATH);
114226
114480
  const statePath = (0, import_node_path13.join)(rootDirectory, LOCAL_STATE_FILE_PATH);
@@ -114708,14 +114962,14 @@ async function writeVerificationEventBatch(input2, dependencies) {
114708
114962
  async function verifyLocalCommand(input2, dependencies = {}) {
114709
114963
  const cwd = dependencies.cwd ?? (() => process.cwd());
114710
114964
  const mkdir5 = dependencies.mkdir ?? (async (path, options) => {
114711
- await (0, import_promises14.mkdir)(path, options);
114965
+ await (0, import_promises15.mkdir)(path, options);
114712
114966
  });
114713
114967
  const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
114714
114968
  const processLocal = dependencies.processCommand ?? processCommand;
114715
114969
  const readVerifiedLocalState = dependencies.readLocalState ?? readLocalState;
114716
114970
  const readVerifiedLocalBundle = dependencies.getLocalBundle ?? getLocalBundle;
114717
- const rename3 = dependencies.rename ?? (async (sourcePath, destinationPath) => (0, import_promises14.rename)(sourcePath, destinationPath));
114718
- const writeFile = dependencies.writeFile ?? (async (path, content) => (0, import_promises14.writeFile)(path, content, "utf8"));
114971
+ const rename3 = dependencies.rename ?? (async (sourcePath, destinationPath) => (0, import_promises15.rename)(sourcePath, destinationPath));
114972
+ const writeFile = dependencies.writeFile ?? (async (path, content) => (0, import_promises15.writeFile)(path, content, "utf8"));
114719
114973
  const checks = [];
114720
114974
  function finalize(exitCode, errors, incidentId2) {
114721
114975
  return formatResult(input2, exitCode, checks, errors, incidentId2);
@@ -114736,7 +114990,7 @@ async function verifyLocalCommand(input2, dependencies = {}) {
114736
114990
  });
114737
114991
  try {
114738
114992
  const rootDirectory = cwd();
114739
- const profile = await readProfile(rootDirectory, async (path) => (0, import_promises14.readFile)(path, "utf8"));
114993
+ const profile = await readProfile(rootDirectory, async (path) => (0, import_promises15.readFile)(path, "utf8"));
114740
114994
  const projectId2 = buildProjectId(profile);
114741
114995
  const verificationNow = now();
114742
114996
  const runId = verificationNow.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
@@ -115311,7 +115565,7 @@ async function smokeCommand(input2, dependencies = {}) {
115311
115565
  }
115312
115566
 
115313
115567
  // ../cli/src/validate-command.ts
115314
- var import_promises15 = require("node:fs/promises");
115568
+ var import_promises16 = require("node:fs/promises");
115315
115569
  var import_node_path16 = require("node:path");
115316
115570
  var SUGGESTED_ACTIONS2 = [
115317
115571
  "Run debugbundle setup if .debugbundle/profile.json is missing.",
@@ -115426,14 +115680,14 @@ async function fixMissingFile(rootDirectory, filePath, buildContent, dependencie
115426
115680
  async function runValidateCommand(input2, dependencies = {}) {
115427
115681
  const cwd = dependencies.cwd ?? (() => process.cwd());
115428
115682
  const mkdir5 = dependencies.mkdir ?? (async (path, options) => {
115429
- await (0, import_promises15.mkdir)(path, options);
115683
+ await (0, import_promises16.mkdir)(path, options);
115430
115684
  });
115431
115685
  const readFile = dependencies.readFile ?? (async (filePath) => {
115432
115686
  const content = await readManaged(rootDirectory, (0, import_node_path16.relative)(rootDirectory, filePath));
115433
115687
  if (content === void 0) throw Object.assign(new Error("Missing local scaffold file."), { code: "ENOENT" });
115434
115688
  return content;
115435
115689
  });
115436
- const stat = dependencies.stat ?? import_promises15.stat;
115690
+ const stat = dependencies.stat ?? import_promises16.stat;
115437
115691
  const rootDirectory = await projectRoot(cwd());
115438
115692
  for (const file of [PROFILE_FILE_PATH, CONNECTION_FILE_PATH, GITIGNORE_FILE_PATH]) await safePath(rootDirectory, file);
115439
115693
  const profileValidation = await validateProfile(rootDirectory, { readFile, stat });
@@ -116540,6 +116794,30 @@ var MCP_TOOL_CATALOG_OPERATIONS = [
116540
116794
  limit: external_exports.number().optional()
116541
116795
  })
116542
116796
  },
116797
+ {
116798
+ name: "list_alert_groups",
116799
+ group: "alerts",
116800
+ description: "List project-scoped alert delivery and email digest groups with bounded incident counts and no payloads or destination secrets.",
116801
+ inputSchema: external_exports.object({
116802
+ bearerToken: external_exports.string(),
116803
+ projectId: external_exports.string().uuid(),
116804
+ limit: external_exports.number().int().min(1).max(100).optional(),
116805
+ cursor: external_exports.string().max(256).optional()
116806
+ })
116807
+ },
116808
+ {
116809
+ name: "get_alert_group",
116810
+ group: "alerts",
116811
+ description: "Inspect one project-scoped alert group and a paginated page of member incident IDs without raw logs or destination secrets.",
116812
+ inputSchema: external_exports.object({
116813
+ bearerToken: external_exports.string(),
116814
+ projectId: external_exports.string().uuid(),
116815
+ kind: external_exports.enum(["direct", "email_digest"]),
116816
+ groupId: external_exports.string().uuid(),
116817
+ limit: external_exports.number().int().min(1).max(100).optional(),
116818
+ cursor: external_exports.string().max(256).optional()
116819
+ })
116820
+ },
116543
116821
  {
116544
116822
  name: "create_alert",
116545
116823
  group: "alerts",
@@ -116575,6 +116853,16 @@ var MCP_TOOL_CATALOG_OPERATIONS = [
116575
116853
  isEnabled: external_exports.boolean().optional()
116576
116854
  })
116577
116855
  },
116856
+ {
116857
+ name: "rotate_alert_webhook_secret",
116858
+ group: "alerts",
116859
+ description: "Rotate a custom alert-webhook signing secret and reveal the new secret once.",
116860
+ inputSchema: external_exports.object({
116861
+ bearerToken: external_exports.string(),
116862
+ projectId: external_exports.string(),
116863
+ alertId: external_exports.string()
116864
+ })
116865
+ },
116578
116866
  {
116579
116867
  name: "delete_alert",
116580
116868
  group: "alerts",
@@ -117117,7 +117405,7 @@ var import_node_readline = require("node:readline");
117117
117405
  var package_default = {
117118
117406
  name: "@debugbundle/mcp",
117119
117407
  mcpName: "com.debugbundle/mcp",
117120
- version: "1.11.0",
117408
+ version: "1.12.1",
117121
117409
  private: false,
117122
117410
  description: "MCP server for runtime error reporting, incident response, health checks, debug bundles, and product analytics",
117123
117411
  license: "Apache-2.0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@debugbundle/mcp",
3
3
  "mcpName": "com.debugbundle/mcp",
4
- "version": "1.11.0",
4
+ "version": "1.12.1",
5
5
  "private": false,
6
6
  "description": "MCP server for runtime error reporting, incident response, health checks, debug bundles, and product analytics",
7
7
  "license": "Apache-2.0",
package/server.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "source": "github",
9
9
  "subfolder": "apps/mcp"
10
10
  },
11
- "version": "1.11.0",
11
+ "version": "1.12.1",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "registryBaseUrl": "https://registry.npmjs.org",
16
16
  "identifier": "@debugbundle/mcp",
17
- "version": "1.11.0",
17
+ "version": "1.12.1",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  },