@debugbundle/mcp 1.4.0 → 1.5.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
@@ -16484,6 +16484,113 @@ function createWeeklyReportApi(client) {
16484
16484
  var import_promises2 = require("node:fs/promises");
16485
16485
  var import_node_path2 = require("node:path");
16486
16486
 
16487
+ // ../../packages/shared-types/src/tier-capabilities.ts
16488
+ var TIER_CAPABILITIES = {
16489
+ free: {
16490
+ remote_probes: false,
16491
+ github_automation: false,
16492
+ slack_integration: false,
16493
+ cloud_improvement_bundles: false,
16494
+ shared_dashboards: false,
16495
+ member_invites: false,
16496
+ included_capacity_units: 1,
16497
+ max_members: 1,
16498
+ ingestion_rate_per_min: 1e3,
16499
+ retrieval_rate_per_min: 100,
16500
+ bundle_retention_days: 7,
16501
+ raw_event_retention_days: 7,
16502
+ // Allowance buckets (account-level pool, not per capacity unit)
16503
+ monthly_bundle_requests: 100,
16504
+ monthly_raw_ingested_events: 750,
16505
+ retained_bundle_cap: 50,
16506
+ monthly_remote_activations: 0,
16507
+ monthly_alert_deliveries: 25,
16508
+ monthly_webhook_deliveries: 100,
16509
+ availability_checks_per_project: 1,
16510
+ availability_check_min_interval_seconds: 300
16511
+ },
16512
+ solo: {
16513
+ remote_probes: true,
16514
+ github_automation: true,
16515
+ slack_integration: false,
16516
+ cloud_improvement_bundles: true,
16517
+ shared_dashboards: false,
16518
+ member_invites: false,
16519
+ included_capacity_units: 3,
16520
+ max_members: 1,
16521
+ ingestion_rate_per_min: 5e3,
16522
+ retrieval_rate_per_min: 300,
16523
+ bundle_retention_days: 30,
16524
+ raw_event_retention_days: 14,
16525
+ // Per-unit allowance (multiply by included and purchased capacity units)
16526
+ monthly_bundle_requests: 250,
16527
+ monthly_raw_ingested_events: 3500,
16528
+ retained_bundle_cap: 150,
16529
+ monthly_remote_activations: 25,
16530
+ monthly_alert_deliveries: 75,
16531
+ monthly_webhook_deliveries: 250,
16532
+ availability_checks_per_project: 5,
16533
+ availability_check_min_interval_seconds: 60
16534
+ },
16535
+ team: {
16536
+ remote_probes: true,
16537
+ github_automation: true,
16538
+ slack_integration: true,
16539
+ cloud_improvement_bundles: true,
16540
+ shared_dashboards: true,
16541
+ member_invites: true,
16542
+ included_capacity_units: 15,
16543
+ max_members: 1e3,
16544
+ ingestion_rate_per_min: 1e4,
16545
+ retrieval_rate_per_min: 500,
16546
+ bundle_retention_days: 90,
16547
+ raw_event_retention_days: 30,
16548
+ // Per-unit allowance (multiply by included and purchased capacity units)
16549
+ monthly_bundle_requests: 1e3,
16550
+ monthly_raw_ingested_events: 1e4,
16551
+ retained_bundle_cap: 400,
16552
+ monthly_remote_activations: 50,
16553
+ monthly_alert_deliveries: 300,
16554
+ monthly_webhook_deliveries: 1e3,
16555
+ availability_checks_per_project: 25,
16556
+ availability_check_min_interval_seconds: 30
16557
+ }
16558
+ };
16559
+ var SELFHOST_CAPABILITIES = {
16560
+ remote_probes: true,
16561
+ github_automation: true,
16562
+ slack_integration: true,
16563
+ cloud_improvement_bundles: true,
16564
+ shared_dashboards: true,
16565
+ member_invites: true,
16566
+ included_capacity_units: 1e6,
16567
+ max_members: 1e3,
16568
+ ingestion_rate_per_min: 1e6,
16569
+ retrieval_rate_per_min: 1e5,
16570
+ bundle_retention_days: 36500,
16571
+ raw_event_retention_days: 36500,
16572
+ monthly_bundle_requests: 1e9,
16573
+ monthly_raw_ingested_events: 1e9,
16574
+ retained_bundle_cap: 1e6,
16575
+ monthly_remote_activations: 1e6,
16576
+ monthly_alert_deliveries: 1e6,
16577
+ monthly_webhook_deliveries: 1e6,
16578
+ availability_checks_per_project: 1e6,
16579
+ availability_check_min_interval_seconds: 30
16580
+ };
16581
+ function isSelfHostMode() {
16582
+ return typeof process !== "undefined" && process.env["SELFHOST_MODE"] === "true";
16583
+ }
16584
+ function getTierCapabilities(plan) {
16585
+ if (isSelfHostMode()) {
16586
+ return SELFHOST_CAPABILITIES;
16587
+ }
16588
+ if (plan !== void 0 && plan in TIER_CAPABILITIES) {
16589
+ return TIER_CAPABILITIES[plan];
16590
+ }
16591
+ return TIER_CAPABILITIES.free;
16592
+ }
16593
+
16487
16594
  // ../../packages/shared-types/src/capture-policy.ts
16488
16595
  var EventClassValues = [
16489
16596
  "incident_signal",
@@ -16729,6 +16836,7 @@ function isRouteOnlyExternalProbe(normalizedRoute) {
16729
16836
  "/__debug__/render_panel",
16730
16837
  "/actuator",
16731
16838
  "/autodiscover/autodiscover.json",
16839
+ "/containers/json",
16732
16840
  "/developmentserver/metadatauploader",
16733
16841
  "/cpanel",
16734
16842
  "/favicon.ico",
@@ -19048,6 +19156,189 @@ function createProbeApi(httpClient) {
19048
19156
  };
19049
19157
  }
19050
19158
 
19159
+ // ../cli/src/health-check-commands.ts
19160
+ var HealthCheckApiError = class extends Error {
19161
+ status;
19162
+ code;
19163
+ constructor(status, code) {
19164
+ super(`health_check_api_error: ${status}:${code}`);
19165
+ this.name = "HealthCheckApiError";
19166
+ this.status = status;
19167
+ this.code = code;
19168
+ }
19169
+ };
19170
+ function toApiError6(status, body) {
19171
+ if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
19172
+ return new HealthCheckApiError(status, body.error);
19173
+ }
19174
+ return new HealthCheckApiError(status, "unknown_error");
19175
+ }
19176
+ function buildCreateRequestBody(input) {
19177
+ const body = {
19178
+ name: input.name,
19179
+ url: input.url,
19180
+ method: input.method,
19181
+ expected_status_min: input.expectedStatusMin,
19182
+ expected_status_max: input.expectedStatusMax,
19183
+ timeout_ms: input.timeoutMs,
19184
+ interval_seconds: input.intervalSeconds,
19185
+ failure_threshold: input.failureThreshold,
19186
+ recovery_threshold: input.recoveryThreshold,
19187
+ enabled: input.enabled
19188
+ };
19189
+ if (input.environment !== void 0) {
19190
+ body["environment"] = input.environment;
19191
+ }
19192
+ if (input.serviceName !== void 0) {
19193
+ body["service_name"] = input.serviceName;
19194
+ }
19195
+ return body;
19196
+ }
19197
+ function buildUpdateRequestBody(input) {
19198
+ const body = {};
19199
+ if (input.name !== void 0) {
19200
+ body["name"] = input.name;
19201
+ }
19202
+ if (input.url !== void 0) {
19203
+ body["url"] = input.url;
19204
+ }
19205
+ if (input.method !== void 0) {
19206
+ body["method"] = input.method;
19207
+ }
19208
+ if (input.expectedStatusMin !== void 0) {
19209
+ body["expected_status_min"] = input.expectedStatusMin;
19210
+ }
19211
+ if (input.expectedStatusMax !== void 0) {
19212
+ body["expected_status_max"] = input.expectedStatusMax;
19213
+ }
19214
+ if (input.timeoutMs !== void 0) {
19215
+ body["timeout_ms"] = input.timeoutMs;
19216
+ }
19217
+ if (input.intervalSeconds !== void 0) {
19218
+ body["interval_seconds"] = input.intervalSeconds;
19219
+ }
19220
+ if (input.failureThreshold !== void 0) {
19221
+ body["failure_threshold"] = input.failureThreshold;
19222
+ }
19223
+ if (input.recoveryThreshold !== void 0) {
19224
+ body["recovery_threshold"] = input.recoveryThreshold;
19225
+ }
19226
+ if (input.environment !== void 0) {
19227
+ body["environment"] = input.environment;
19228
+ }
19229
+ if (input.serviceName !== void 0) {
19230
+ body["service_name"] = input.serviceName;
19231
+ }
19232
+ if (input.enabled !== void 0) {
19233
+ body["enabled"] = input.enabled;
19234
+ }
19235
+ return body;
19236
+ }
19237
+ function createHealthCheckApi(httpClient) {
19238
+ return {
19239
+ async listHealthChecks(input) {
19240
+ const limit = input.limit ?? 100;
19241
+ const response = await httpClient.request({
19242
+ method: "GET",
19243
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks?limit=${encodeURIComponent(String(limit))}`,
19244
+ bearerToken: input.bearerToken
19245
+ });
19246
+ if (response.status !== 200) {
19247
+ throw toApiError6(response.status, response.body);
19248
+ }
19249
+ return response.body;
19250
+ },
19251
+ async getHealthCheck(input) {
19252
+ const response = await httpClient.request({
19253
+ method: "GET",
19254
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/${encodeURIComponent(input.checkId)}`,
19255
+ bearerToken: input.bearerToken
19256
+ });
19257
+ if (response.status !== 200) {
19258
+ throw toApiError6(response.status, response.body);
19259
+ }
19260
+ return response.body;
19261
+ },
19262
+ async createHealthCheck(input) {
19263
+ const response = await httpClient.request({
19264
+ method: "POST",
19265
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks`,
19266
+ bearerToken: input.bearerToken,
19267
+ body: buildCreateRequestBody(input)
19268
+ });
19269
+ if (response.status !== 201) {
19270
+ throw toApiError6(response.status, response.body);
19271
+ }
19272
+ return response.body;
19273
+ },
19274
+ async updateHealthCheck(input) {
19275
+ const response = await httpClient.request({
19276
+ method: "PATCH",
19277
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/${encodeURIComponent(input.checkId)}`,
19278
+ bearerToken: input.bearerToken,
19279
+ body: buildUpdateRequestBody(input)
19280
+ });
19281
+ if (response.status !== 200) {
19282
+ throw toApiError6(response.status, response.body);
19283
+ }
19284
+ return response.body;
19285
+ },
19286
+ async deleteHealthCheck(input) {
19287
+ const response = await httpClient.request({
19288
+ method: "DELETE",
19289
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/${encodeURIComponent(input.checkId)}`,
19290
+ bearerToken: input.bearerToken
19291
+ });
19292
+ if (response.status !== 200) {
19293
+ throw toApiError6(response.status, response.body);
19294
+ }
19295
+ return response.body;
19296
+ },
19297
+ async testHealthCheck(input) {
19298
+ const response = await httpClient.request({
19299
+ method: "POST",
19300
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/test`,
19301
+ bearerToken: input.bearerToken,
19302
+ body: {
19303
+ url: input.url,
19304
+ method: input.method,
19305
+ expected_status_min: input.expectedStatusMin,
19306
+ expected_status_max: input.expectedStatusMax,
19307
+ timeout_ms: input.timeoutMs
19308
+ }
19309
+ });
19310
+ if (response.status !== 200) {
19311
+ throw toApiError6(response.status, response.body);
19312
+ }
19313
+ return response.body;
19314
+ },
19315
+ async listHealthCheckResults(input) {
19316
+ const limit = input.limit ?? 20;
19317
+ const response = await httpClient.request({
19318
+ method: "GET",
19319
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/${encodeURIComponent(input.checkId)}/results?limit=${encodeURIComponent(String(limit))}`,
19320
+ bearerToken: input.bearerToken
19321
+ });
19322
+ if (response.status !== 200) {
19323
+ throw toApiError6(response.status, response.body);
19324
+ }
19325
+ return response.body;
19326
+ },
19327
+ async listHealthCheckDailyRollups(input) {
19328
+ const limit = input.limit ?? 30;
19329
+ const response = await httpClient.request({
19330
+ method: "GET",
19331
+ path: `/v1/projects/${encodeURIComponent(input.projectId)}/availability-checks/${encodeURIComponent(input.checkId)}/daily-rollups?limit=${encodeURIComponent(String(limit))}`,
19332
+ bearerToken: input.bearerToken
19333
+ });
19334
+ if (response.status !== 200) {
19335
+ throw toApiError6(response.status, response.body);
19336
+ }
19337
+ return response.body;
19338
+ }
19339
+ };
19340
+ }
19341
+
19051
19342
  // ../cli/src/doctor-command.ts
19052
19343
  var import_promises4 = require("node:fs/promises");
19053
19344
  var import_node_path4 = require("node:path");
@@ -20102,7 +20393,7 @@ async function doctorCommand(input, dependencies = {}) {
20102
20393
  }
20103
20394
 
20104
20395
  // ../cli/src/verify-command.ts
20105
- var import_node_crypto6 = require("node:crypto");
20396
+ var import_node_crypto7 = require("node:crypto");
20106
20397
  var import_promises7 = require("node:fs/promises");
20107
20398
  var import_node_path9 = require("node:path");
20108
20399
 
@@ -20508,6 +20799,16 @@ var DEFAULT_SESSION_LIFETIME_MS = 1e3 * 60 * 60 * 24 * 7;
20508
20799
  var DEFAULT_EMAIL_AUTH_CODE_LIFETIME_MS = 1e3 * 60 * 10;
20509
20800
  var DEFAULT_GITHUB_OAUTH_STATE_LIFETIME_MS = 1e3 * 60 * 10;
20510
20801
 
20802
+ // ../../packages/storage/src/availability-check-store-helpers.ts
20803
+ var TIER_CAPABILITIES_SQL = {
20804
+ free_limit: getTierCapabilities("free").availability_checks_per_project,
20805
+ solo_limit: getTierCapabilities("solo").availability_checks_per_project,
20806
+ team_limit: getTierCapabilities("team").availability_checks_per_project,
20807
+ free_interval: getTierCapabilities("free").availability_check_min_interval_seconds,
20808
+ solo_interval: getTierCapabilities("solo").availability_check_min_interval_seconds,
20809
+ team_interval: getTierCapabilities("team").availability_check_min_interval_seconds
20810
+ };
20811
+
20511
20812
  // ../../packages/storage/src/auth-rate-limiter.ts
20512
20813
  var import_ioredis = __toESM(require_built3(), 1);
20513
20814
 
@@ -20525,8 +20826,131 @@ var import_ioredis3 = __toESM(require_built3(), 1);
20525
20826
  var import_ioredis4 = __toESM(require_built3(), 1);
20526
20827
  var DEFAULT_PROCESSING_TIMEOUT_MS = 5 * 60 * 1e3;
20527
20828
 
20528
- // ../../packages/storage/src/schema-migrations.ts
20529
- var import_node_crypto3 = require("node:crypto");
20829
+ // ../../packages/storage/src/availability-check-bootstrap-statements.ts
20830
+ var AVAILABILITY_CHECK_BOOTSTRAP_STATEMENTS = [
20831
+ `
20832
+ CREATE TABLE availability_checks (
20833
+ id uuid PRIMARY KEY,
20834
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
20835
+ created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
20836
+ name text NOT NULL,
20837
+ url text NOT NULL,
20838
+ method text NOT NULL CHECK (method IN ('GET', 'HEAD')),
20839
+ expected_status_min integer NOT NULL DEFAULT 200 CHECK (expected_status_min BETWEEN 100 AND 599),
20840
+ expected_status_max integer NOT NULL DEFAULT 399 CHECK (expected_status_max BETWEEN 100 AND 599),
20841
+ timeout_ms integer NOT NULL DEFAULT 5000 CHECK (timeout_ms BETWEEN 500 AND 5000),
20842
+ interval_seconds integer NOT NULL CHECK (interval_seconds >= 30),
20843
+ failure_threshold integer NOT NULL DEFAULT 3 CHECK (failure_threshold BETWEEN 1 AND 10),
20844
+ recovery_threshold integer NOT NULL DEFAULT 2 CHECK (recovery_threshold BETWEEN 1 AND 10),
20845
+ environment text NOT NULL DEFAULT 'production',
20846
+ service_name text,
20847
+ enabled boolean NOT NULL DEFAULT true,
20848
+ status text NOT NULL DEFAULT 'unknown' CHECK (status IN ('unknown', 'passing', 'failing')),
20849
+ consecutive_failures integer NOT NULL DEFAULT 0,
20850
+ consecutive_successes integer NOT NULL DEFAULT 0,
20851
+ linked_incident_id uuid REFERENCES incidents(id) ON DELETE SET NULL,
20852
+ last_checked_at timestamptz,
20853
+ next_check_at timestamptz,
20854
+ claimed_at timestamptz,
20855
+ last_result_status text CHECK (
20856
+ last_result_status IS NULL OR last_result_status IN (
20857
+ 'success',
20858
+ 'http_status_mismatch',
20859
+ 'timeout',
20860
+ 'dns_error',
20861
+ 'tls_error',
20862
+ 'connection_error',
20863
+ 'redirect_blocked',
20864
+ 'security_blocked',
20865
+ 'internal_error'
20866
+ )
20867
+ ),
20868
+ last_result_http_status integer,
20869
+ last_result_error_kind text,
20870
+ last_result_error_message text,
20871
+ last_result_duration_ms integer,
20872
+ deleted_at timestamptz,
20873
+ created_at timestamptz NOT NULL DEFAULT now(),
20874
+ updated_at timestamptz NOT NULL DEFAULT now()
20875
+ )
20876
+ `,
20877
+ `
20878
+ CREATE INDEX availability_checks_project_created_idx
20879
+ ON availability_checks (project_id, created_at DESC)
20880
+ `,
20881
+ `
20882
+ CREATE INDEX availability_checks_due_idx
20883
+ ON availability_checks (next_check_at, project_id)
20884
+ `,
20885
+ `
20886
+ CREATE INDEX availability_checks_claimed_idx
20887
+ ON availability_checks (claimed_at)
20888
+ `,
20889
+ `
20890
+ CREATE TABLE availability_check_results (
20891
+ id uuid PRIMARY KEY,
20892
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
20893
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
20894
+ started_at timestamptz NOT NULL,
20895
+ completed_at timestamptz NOT NULL,
20896
+ duration_ms integer NOT NULL,
20897
+ status text NOT NULL CHECK (
20898
+ status IN (
20899
+ 'success',
20900
+ 'http_status_mismatch',
20901
+ 'timeout',
20902
+ 'dns_error',
20903
+ 'tls_error',
20904
+ 'connection_error',
20905
+ 'redirect_blocked',
20906
+ 'security_blocked',
20907
+ 'internal_error'
20908
+ )
20909
+ ),
20910
+ http_status integer,
20911
+ error_kind text,
20912
+ error_message text,
20913
+ redirect_count integer NOT NULL DEFAULT 0,
20914
+ checked_url_host text NOT NULL,
20915
+ checked_url_path text NOT NULL,
20916
+ final_url text NOT NULL,
20917
+ created_at timestamptz NOT NULL DEFAULT now()
20918
+ )
20919
+ `,
20920
+ `
20921
+ CREATE INDEX availability_check_results_check_started_idx
20922
+ ON availability_check_results (check_id, started_at DESC)
20923
+ `,
20924
+ `
20925
+ CREATE INDEX availability_check_results_project_started_idx
20926
+ ON availability_check_results (project_id, started_at DESC)
20927
+ `,
20928
+ `
20929
+ CREATE TABLE availability_check_daily_rollups (
20930
+ id uuid PRIMARY KEY,
20931
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
20932
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
20933
+ day date NOT NULL,
20934
+ state text NOT NULL CHECK (state IN ('unknown', 'operational', 'degraded', 'down', 'paused')),
20935
+ total_checks integer NOT NULL DEFAULT 0,
20936
+ successful_checks integer NOT NULL DEFAULT 0,
20937
+ failed_checks integer NOT NULL DEFAULT 0,
20938
+ degraded_checks integer NOT NULL DEFAULT 0,
20939
+ avg_duration_ms integer,
20940
+ first_checked_at timestamptz,
20941
+ last_checked_at timestamptz,
20942
+ downtime_seconds integer NOT NULL DEFAULT 0,
20943
+ incident_ids uuid[] NOT NULL DEFAULT '{}'::uuid[],
20944
+ created_at timestamptz NOT NULL DEFAULT now(),
20945
+ updated_at timestamptz NOT NULL DEFAULT now(),
20946
+ UNIQUE (check_id, day)
20947
+ )
20948
+ `,
20949
+ `
20950
+ CREATE INDEX availability_check_daily_rollups_project_day_idx
20951
+ ON availability_check_daily_rollups (project_id, day DESC)
20952
+ `
20953
+ ];
20530
20954
 
20531
20955
  // ../../packages/storage/src/storage-bootstrap-statements.ts
20532
20956
  var STORAGE_BOOTSTRAP_STATEMENTS = [
@@ -20695,6 +21119,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
20695
21119
  user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
20696
21120
  organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
20697
21121
  session_token_hash text UNIQUE NOT NULL,
21122
+ auth_method text CHECK (auth_method IS NULL OR auth_method IN ('email_code', 'github_oauth')),
20698
21123
  created_at timestamptz NOT NULL DEFAULT now(),
20699
21124
  expires_at timestamptz NOT NULL,
20700
21125
  revoked_at timestamptz
@@ -21623,12 +22048,257 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
21623
22048
  `
21624
22049
  ];
21625
22050
 
22051
+ // ../../packages/storage/src/storage-bootstrap-all-statements.ts
22052
+ var STORAGE_BOOTSTRAP_STATEMENTS2 = [
22053
+ ...STORAGE_BOOTSTRAP_STATEMENTS,
22054
+ ...AVAILABILITY_CHECK_BOOTSTRAP_STATEMENTS
22055
+ ];
22056
+
21626
22057
  // ../../packages/storage/src/migrations.ts
21627
- var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS.join(";\n\n");
22058
+ var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS2.join(";\n\n");
21628
22059
 
21629
- // ../../packages/storage/src/schema-migrations.ts
22060
+ // ../../packages/storage/src/availability-check-schema-migrations.ts
22061
+ var import_node_crypto3 = require("node:crypto");
22062
+ function defineAvailabilityCheckStorageSchemaMigration(input) {
22063
+ return {
22064
+ ...input,
22065
+ checksum: (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(input)).digest("hex")
22066
+ };
22067
+ }
22068
+ var AVAILABILITY_CHECK_STORAGE_SCHEMA_MIGRATIONS = [
22069
+ defineAvailabilityCheckStorageSchemaMigration({
22070
+ id: "202606150001_add_availability_checks",
22071
+ description: "Add project-scoped availability checks, result history, and daily rollups.",
22072
+ statements: [
22073
+ `
22074
+ CREATE TABLE IF NOT EXISTS availability_checks (
22075
+ id uuid PRIMARY KEY,
22076
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
22077
+ created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
22078
+ name text NOT NULL,
22079
+ url text NOT NULL,
22080
+ method text NOT NULL,
22081
+ expected_status_min integer NOT NULL DEFAULT 200,
22082
+ expected_status_max integer NOT NULL DEFAULT 399,
22083
+ timeout_ms integer NOT NULL DEFAULT 5000,
22084
+ interval_seconds integer NOT NULL,
22085
+ failure_threshold integer NOT NULL DEFAULT 3,
22086
+ recovery_threshold integer NOT NULL DEFAULT 2,
22087
+ environment text NOT NULL DEFAULT 'production',
22088
+ service_name text,
22089
+ enabled boolean NOT NULL DEFAULT true,
22090
+ status text NOT NULL DEFAULT 'unknown',
22091
+ consecutive_failures integer NOT NULL DEFAULT 0,
22092
+ consecutive_successes integer NOT NULL DEFAULT 0,
22093
+ linked_incident_id uuid REFERENCES incidents(id) ON DELETE SET NULL,
22094
+ last_checked_at timestamptz,
22095
+ next_check_at timestamptz,
22096
+ claimed_at timestamptz,
22097
+ last_result_status text,
22098
+ last_result_http_status integer,
22099
+ last_result_error_kind text,
22100
+ last_result_error_message text,
22101
+ last_result_duration_ms integer,
22102
+ deleted_at timestamptz,
22103
+ created_at timestamptz NOT NULL DEFAULT now(),
22104
+ updated_at timestamptz NOT NULL DEFAULT now()
22105
+ )
22106
+ `,
22107
+ `
22108
+ ALTER TABLE availability_checks
22109
+ DROP CONSTRAINT IF EXISTS availability_checks_method_check
22110
+ `,
22111
+ `
22112
+ ALTER TABLE availability_checks
22113
+ ADD CONSTRAINT availability_checks_method_check
22114
+ CHECK (method IN ('GET', 'HEAD'))
22115
+ `,
22116
+ `
22117
+ ALTER TABLE availability_checks
22118
+ DROP CONSTRAINT IF EXISTS availability_checks_expected_status_min_check
22119
+ `,
22120
+ `
22121
+ ALTER TABLE availability_checks
22122
+ ADD CONSTRAINT availability_checks_expected_status_min_check
22123
+ CHECK (expected_status_min BETWEEN 100 AND 599)
22124
+ `,
22125
+ `
22126
+ ALTER TABLE availability_checks
22127
+ DROP CONSTRAINT IF EXISTS availability_checks_expected_status_max_check
22128
+ `,
22129
+ `
22130
+ ALTER TABLE availability_checks
22131
+ ADD CONSTRAINT availability_checks_expected_status_max_check
22132
+ CHECK (expected_status_max BETWEEN 100 AND 599)
22133
+ `,
22134
+ `
22135
+ ALTER TABLE availability_checks
22136
+ DROP CONSTRAINT IF EXISTS availability_checks_timeout_ms_check
22137
+ `,
22138
+ `
22139
+ ALTER TABLE availability_checks
22140
+ ADD CONSTRAINT availability_checks_timeout_ms_check
22141
+ CHECK (timeout_ms BETWEEN 500 AND 5000)
22142
+ `,
22143
+ `
22144
+ ALTER TABLE availability_checks
22145
+ DROP CONSTRAINT IF EXISTS availability_checks_interval_seconds_check
22146
+ `,
22147
+ `
22148
+ ALTER TABLE availability_checks
22149
+ ADD CONSTRAINT availability_checks_interval_seconds_check
22150
+ CHECK (interval_seconds >= 30)
22151
+ `,
22152
+ `
22153
+ ALTER TABLE availability_checks
22154
+ DROP CONSTRAINT IF EXISTS availability_checks_failure_threshold_check
22155
+ `,
22156
+ `
22157
+ ALTER TABLE availability_checks
22158
+ ADD CONSTRAINT availability_checks_failure_threshold_check
22159
+ CHECK (failure_threshold BETWEEN 1 AND 10)
22160
+ `,
22161
+ `
22162
+ ALTER TABLE availability_checks
22163
+ DROP CONSTRAINT IF EXISTS availability_checks_recovery_threshold_check
22164
+ `,
22165
+ `
22166
+ ALTER TABLE availability_checks
22167
+ ADD CONSTRAINT availability_checks_recovery_threshold_check
22168
+ CHECK (recovery_threshold BETWEEN 1 AND 10)
22169
+ `,
22170
+ `
22171
+ ALTER TABLE availability_checks
22172
+ DROP CONSTRAINT IF EXISTS availability_checks_status_check
22173
+ `,
22174
+ `
22175
+ ALTER TABLE availability_checks
22176
+ ADD CONSTRAINT availability_checks_status_check
22177
+ CHECK (status IN ('unknown', 'passing', 'failing'))
22178
+ `,
22179
+ `
22180
+ ALTER TABLE availability_checks
22181
+ DROP CONSTRAINT IF EXISTS availability_checks_last_result_status_check
22182
+ `,
22183
+ `
22184
+ ALTER TABLE availability_checks
22185
+ ADD CONSTRAINT availability_checks_last_result_status_check
22186
+ CHECK (
22187
+ last_result_status IS NULL OR last_result_status IN (
22188
+ 'success',
22189
+ 'http_status_mismatch',
22190
+ 'timeout',
22191
+ 'dns_error',
22192
+ 'tls_error',
22193
+ 'connection_error',
22194
+ 'redirect_blocked',
22195
+ 'security_blocked',
22196
+ 'internal_error'
22197
+ )
22198
+ )
22199
+ `,
22200
+ `
22201
+ CREATE INDEX IF NOT EXISTS availability_checks_project_created_idx
22202
+ ON availability_checks (project_id, created_at DESC)
22203
+ `,
22204
+ `
22205
+ CREATE INDEX IF NOT EXISTS availability_checks_due_idx
22206
+ ON availability_checks (next_check_at, project_id)
22207
+ `,
22208
+ `
22209
+ CREATE INDEX IF NOT EXISTS availability_checks_claimed_idx
22210
+ ON availability_checks (claimed_at)
22211
+ `,
22212
+ `
22213
+ CREATE TABLE IF NOT EXISTS availability_check_results (
22214
+ id uuid PRIMARY KEY,
22215
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
22216
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
22217
+ started_at timestamptz NOT NULL,
22218
+ completed_at timestamptz NOT NULL,
22219
+ duration_ms integer NOT NULL,
22220
+ status text NOT NULL,
22221
+ http_status integer,
22222
+ error_kind text,
22223
+ error_message text,
22224
+ redirect_count integer NOT NULL DEFAULT 0,
22225
+ checked_url_host text NOT NULL,
22226
+ checked_url_path text NOT NULL,
22227
+ final_url text NOT NULL,
22228
+ created_at timestamptz NOT NULL DEFAULT now()
22229
+ )
22230
+ `,
22231
+ `
22232
+ ALTER TABLE availability_check_results
22233
+ DROP CONSTRAINT IF EXISTS availability_check_results_status_check
22234
+ `,
22235
+ `
22236
+ ALTER TABLE availability_check_results
22237
+ ADD CONSTRAINT availability_check_results_status_check
22238
+ CHECK (
22239
+ status IN (
22240
+ 'success',
22241
+ 'http_status_mismatch',
22242
+ 'timeout',
22243
+ 'dns_error',
22244
+ 'tls_error',
22245
+ 'connection_error',
22246
+ 'redirect_blocked',
22247
+ 'security_blocked',
22248
+ 'internal_error'
22249
+ )
22250
+ )
22251
+ `,
22252
+ `
22253
+ CREATE INDEX IF NOT EXISTS availability_check_results_check_started_idx
22254
+ ON availability_check_results (check_id, started_at DESC)
22255
+ `,
22256
+ `
22257
+ CREATE INDEX IF NOT EXISTS availability_check_results_project_started_idx
22258
+ ON availability_check_results (project_id, started_at DESC)
22259
+ `,
22260
+ `
22261
+ CREATE TABLE IF NOT EXISTS availability_check_daily_rollups (
22262
+ id uuid PRIMARY KEY,
22263
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
22264
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
22265
+ day date NOT NULL,
22266
+ state text NOT NULL,
22267
+ total_checks integer NOT NULL DEFAULT 0,
22268
+ successful_checks integer NOT NULL DEFAULT 0,
22269
+ failed_checks integer NOT NULL DEFAULT 0,
22270
+ degraded_checks integer NOT NULL DEFAULT 0,
22271
+ avg_duration_ms integer,
22272
+ first_checked_at timestamptz,
22273
+ last_checked_at timestamptz,
22274
+ downtime_seconds integer NOT NULL DEFAULT 0,
22275
+ incident_ids uuid[] NOT NULL DEFAULT '{}'::uuid[],
22276
+ created_at timestamptz NOT NULL DEFAULT now(),
22277
+ updated_at timestamptz NOT NULL DEFAULT now(),
22278
+ UNIQUE (check_id, day)
22279
+ )
22280
+ `,
22281
+ `
22282
+ ALTER TABLE availability_check_daily_rollups
22283
+ DROP CONSTRAINT IF EXISTS availability_check_daily_rollups_state_check
22284
+ `,
22285
+ `
22286
+ ALTER TABLE availability_check_daily_rollups
22287
+ ADD CONSTRAINT availability_check_daily_rollups_state_check
22288
+ CHECK (state IN ('unknown', 'operational', 'degraded', 'down', 'paused'))
22289
+ `,
22290
+ `
22291
+ CREATE INDEX IF NOT EXISTS availability_check_daily_rollups_project_day_idx
22292
+ ON availability_check_daily_rollups (project_id, day DESC)
22293
+ `
22294
+ ]
22295
+ })
22296
+ ];
22297
+
22298
+ // ../../packages/storage/src/schema-migrations-catalog.ts
22299
+ var import_node_crypto4 = require("node:crypto");
21630
22300
  function computeMigrationChecksum(input) {
21631
- return (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(input)).digest("hex");
22301
+ return (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(input)).digest("hex");
21632
22302
  }
21633
22303
  function defineStorageSchemaMigration(input) {
21634
22304
  return {
@@ -22457,15 +23127,47 @@ var STORAGE_SCHEMA_MIGRATIONS = [
22457
23127
  ON account_payment_provider_events (provider, provider_event_id)
22458
23128
  `
22459
23129
  ]
23130
+ }),
23131
+ defineStorageSchemaMigration({
23132
+ id: "202606120001_add_session_auth_method",
23133
+ description: "Track the auth method used to create each browser session.",
23134
+ statements: [
23135
+ "ALTER TABLE sessions ADD COLUMN IF NOT EXISTS auth_method text",
23136
+ "ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_auth_method_check",
23137
+ `
23138
+ ALTER TABLE sessions
23139
+ ADD CONSTRAINT sessions_auth_method_check
23140
+ CHECK (auth_method IS NULL OR auth_method IN ('email_code', 'github_oauth'))
23141
+ `
23142
+ ]
23143
+ }),
23144
+ defineStorageSchemaMigration({
23145
+ id: "202606130001_retire_expired_project_invites",
23146
+ description: "Retire already-expired project invites so re-inviting the same email is unblocked.",
23147
+ statements: [
23148
+ `
23149
+ UPDATE project_invites
23150
+ SET canceled_at = expires_at
23151
+ WHERE accepted_at IS NULL
23152
+ AND canceled_at IS NULL
23153
+ AND expires_at <= now()
23154
+ `
23155
+ ]
22460
23156
  })
22461
23157
  ];
22462
23158
 
23159
+ // ../../packages/storage/src/schema-migrations.ts
23160
+ var STORAGE_SCHEMA_MIGRATIONS2 = [
23161
+ ...STORAGE_SCHEMA_MIGRATIONS,
23162
+ ...AVAILABILITY_CHECK_STORAGE_SCHEMA_MIGRATIONS
23163
+ ];
23164
+
22463
23165
  // ../cli/src/ingest-command.ts
22464
- var import_node_crypto5 = require("node:crypto");
23166
+ var import_node_crypto6 = require("node:crypto");
22465
23167
  var import_node_path7 = require("node:path");
22466
23168
 
22467
23169
  // ../cli/src/process-command.ts
22468
- var import_node_crypto4 = require("node:crypto");
23170
+ var import_node_crypto5 = require("node:crypto");
22469
23171
  var import_promises5 = require("node:fs/promises");
22470
23172
  var import_node_path6 = require("node:path");
22471
23173
 
@@ -23651,7 +24353,7 @@ function mergeAggregateGroup(aggregates) {
23651
24353
  });
23652
24354
  }
23653
24355
  function hashIdentifier(parts, prefix, length) {
23654
- const digest = (0, import_node_crypto4.createHash)("sha256").update(parts.join("\0")).digest("hex");
24356
+ const digest = (0, import_node_crypto5.createHash)("sha256").update(parts.join("\0")).digest("hex");
23655
24357
  return `${prefix}_${digest.slice(0, length)}`;
23656
24358
  }
23657
24359
  function deriveIncidentId(projectId, serviceName, environment, incidentFingerprint) {
@@ -23685,7 +24387,7 @@ function stableJson3(value) {
23685
24387
  return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson3(record[key])}`).join(",")}}`;
23686
24388
  }
23687
24389
  function buildRequestAnomalyFingerprint(input) {
23688
- return (0, import_node_crypto4.createHash)("sha256").update(
24390
+ return (0, import_node_crypto5.createHash)("sha256").update(
23689
24391
  stableJson3({
23690
24392
  kind: "request_status_anomaly",
23691
24393
  project_id: input.projectId,
@@ -24316,7 +25018,7 @@ function buildEventFileName(events, filePath) {
24316
25018
  const candidate = Date.parse(event.occurred_at);
24317
25019
  return Number.isFinite(candidate) && candidate > latest ? candidate : latest;
24318
25020
  }, 0);
24319
- const digest = (0, import_node_crypto5.createHash)("sha256").update([filePath, ...events.map((event) => event.event_id)].join("\0")).digest("hex").slice(0, 8);
25021
+ const digest = (0, import_node_crypto6.createHash)("sha256").update([filePath, ...events.map((event) => event.event_id)].join("\0")).digest("hex").slice(0, 8);
24320
25022
  return `${lastOccurredAt}-${digest}-${slugify(events[0]?.service.name ?? (0, import_node_path7.basename)(filePath))}.events.json`;
24321
25023
  }
24322
25024
  async function readProfile(rootDirectory, readFile) {
@@ -24725,7 +25427,7 @@ function cloudVerificationRunId(now) {
24725
25427
  return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
24726
25428
  }
24727
25429
  function defaultCloudVerificationSuffix() {
24728
- return (0, import_node_crypto6.randomUUID)().replace(/-/g, "").slice(0, 12);
25430
+ return (0, import_node_crypto7.randomUUID)().replace(/-/g, "").slice(0, 12);
24729
25431
  }
24730
25432
  function normalizeCloudVerificationSuffix(suffix) {
24731
25433
  const normalized = suffix.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 12);
@@ -26509,8 +27211,176 @@ function createProbeMcpTools(api) {
26509
27211
  };
26510
27212
  }
26511
27213
 
26512
- // src/project-tools.ts
27214
+ // src/health-check-tools.ts
26513
27215
  function mapMcpError11(error) {
27216
+ if (error instanceof HealthCheckApiError) {
27217
+ throw new Error(`mcp_tool_error:${error.code}`);
27218
+ }
27219
+ throw new Error("mcp_tool_error:unknown_error");
27220
+ }
27221
+ function createHealthCheckMcpTools(api) {
27222
+ return {
27223
+ async list_health_checks(input) {
27224
+ try {
27225
+ const requestInput = {
27226
+ bearerToken: String(input["bearerToken"]),
27227
+ projectId: String(input["projectId"])
27228
+ };
27229
+ if (typeof input["limit"] === "number") {
27230
+ requestInput.limit = input["limit"];
27231
+ }
27232
+ return await api.listHealthChecks(requestInput);
27233
+ } catch (error) {
27234
+ mapMcpError11(error);
27235
+ }
27236
+ },
27237
+ async get_health_check(input) {
27238
+ try {
27239
+ return await api.getHealthCheck({
27240
+ bearerToken: String(input["bearerToken"]),
27241
+ projectId: String(input["projectId"]),
27242
+ checkId: String(input["checkId"])
27243
+ });
27244
+ } catch (error) {
27245
+ mapMcpError11(error);
27246
+ }
27247
+ },
27248
+ async create_health_check(input) {
27249
+ try {
27250
+ const requestInput = {
27251
+ bearerToken: String(input["bearerToken"]),
27252
+ projectId: String(input["projectId"]),
27253
+ name: String(input["name"]),
27254
+ url: String(input["url"]),
27255
+ method: input["method"] === "HEAD" ? "HEAD" : "GET",
27256
+ expectedStatusMin: typeof input["expectedStatusMin"] === "number" ? input["expectedStatusMin"] : 200,
27257
+ expectedStatusMax: typeof input["expectedStatusMax"] === "number" ? input["expectedStatusMax"] : 399,
27258
+ timeoutMs: typeof input["timeoutMs"] === "number" ? input["timeoutMs"] : 5e3,
27259
+ intervalSeconds: Number(input["intervalSeconds"]),
27260
+ failureThreshold: typeof input["failureThreshold"] === "number" ? input["failureThreshold"] : 3,
27261
+ recoveryThreshold: typeof input["recoveryThreshold"] === "number" ? input["recoveryThreshold"] : 2,
27262
+ enabled: typeof input["enabled"] === "boolean" ? input["enabled"] : true
27263
+ };
27264
+ if (typeof input["environment"] === "string") {
27265
+ requestInput.environment = input["environment"];
27266
+ }
27267
+ if (typeof input["serviceName"] === "string" || input["serviceName"] === null) {
27268
+ requestInput.serviceName = input["serviceName"];
27269
+ }
27270
+ return await api.createHealthCheck(requestInput);
27271
+ } catch (error) {
27272
+ mapMcpError11(error);
27273
+ }
27274
+ },
27275
+ async update_health_check(input) {
27276
+ try {
27277
+ const requestInput = {
27278
+ bearerToken: String(input["bearerToken"]),
27279
+ projectId: String(input["projectId"]),
27280
+ checkId: String(input["checkId"])
27281
+ };
27282
+ if (typeof input["name"] === "string") {
27283
+ requestInput.name = input["name"];
27284
+ }
27285
+ if (typeof input["url"] === "string") {
27286
+ requestInput.url = input["url"];
27287
+ }
27288
+ if (input["method"] === "GET" || input["method"] === "HEAD") {
27289
+ requestInput.method = input["method"];
27290
+ }
27291
+ if (typeof input["expectedStatusMin"] === "number") {
27292
+ requestInput.expectedStatusMin = input["expectedStatusMin"];
27293
+ }
27294
+ if (typeof input["expectedStatusMax"] === "number") {
27295
+ requestInput.expectedStatusMax = input["expectedStatusMax"];
27296
+ }
27297
+ if (typeof input["timeoutMs"] === "number") {
27298
+ requestInput.timeoutMs = input["timeoutMs"];
27299
+ }
27300
+ if (typeof input["intervalSeconds"] === "number") {
27301
+ requestInput.intervalSeconds = input["intervalSeconds"];
27302
+ }
27303
+ if (typeof input["failureThreshold"] === "number") {
27304
+ requestInput.failureThreshold = input["failureThreshold"];
27305
+ }
27306
+ if (typeof input["recoveryThreshold"] === "number") {
27307
+ requestInput.recoveryThreshold = input["recoveryThreshold"];
27308
+ }
27309
+ if (typeof input["environment"] === "string") {
27310
+ requestInput.environment = input["environment"];
27311
+ }
27312
+ if (typeof input["serviceName"] === "string" || input["serviceName"] === null) {
27313
+ requestInput.serviceName = input["serviceName"];
27314
+ }
27315
+ if (typeof input["enabled"] === "boolean") {
27316
+ requestInput.enabled = input["enabled"];
27317
+ }
27318
+ return await api.updateHealthCheck(requestInput);
27319
+ } catch (error) {
27320
+ mapMcpError11(error);
27321
+ }
27322
+ },
27323
+ async delete_health_check(input) {
27324
+ try {
27325
+ return await api.deleteHealthCheck({
27326
+ bearerToken: String(input["bearerToken"]),
27327
+ projectId: String(input["projectId"]),
27328
+ checkId: String(input["checkId"])
27329
+ });
27330
+ } catch (error) {
27331
+ mapMcpError11(error);
27332
+ }
27333
+ },
27334
+ async test_health_check(input) {
27335
+ try {
27336
+ return await api.testHealthCheck({
27337
+ bearerToken: String(input["bearerToken"]),
27338
+ projectId: String(input["projectId"]),
27339
+ url: String(input["url"]),
27340
+ method: input["method"] === "HEAD" ? "HEAD" : "GET",
27341
+ expectedStatusMin: typeof input["expectedStatusMin"] === "number" ? input["expectedStatusMin"] : 200,
27342
+ expectedStatusMax: typeof input["expectedStatusMax"] === "number" ? input["expectedStatusMax"] : 399,
27343
+ timeoutMs: typeof input["timeoutMs"] === "number" ? input["timeoutMs"] : 5e3
27344
+ });
27345
+ } catch (error) {
27346
+ mapMcpError11(error);
27347
+ }
27348
+ },
27349
+ async list_health_check_results(input) {
27350
+ try {
27351
+ const requestInput = {
27352
+ bearerToken: String(input["bearerToken"]),
27353
+ projectId: String(input["projectId"]),
27354
+ checkId: String(input["checkId"])
27355
+ };
27356
+ if (typeof input["limit"] === "number") {
27357
+ requestInput.limit = input["limit"];
27358
+ }
27359
+ return await api.listHealthCheckResults(requestInput);
27360
+ } catch (error) {
27361
+ mapMcpError11(error);
27362
+ }
27363
+ },
27364
+ async list_health_check_daily_rollups(input) {
27365
+ try {
27366
+ const requestInput = {
27367
+ bearerToken: String(input["bearerToken"]),
27368
+ projectId: String(input["projectId"]),
27369
+ checkId: String(input["checkId"])
27370
+ };
27371
+ if (typeof input["limit"] === "number") {
27372
+ requestInput.limit = input["limit"];
27373
+ }
27374
+ return await api.listHealthCheckDailyRollups(requestInput);
27375
+ } catch (error) {
27376
+ mapMcpError11(error);
27377
+ }
27378
+ }
27379
+ };
27380
+ }
27381
+
27382
+ // src/project-tools.ts
27383
+ function mapMcpError12(error) {
26514
27384
  if (error instanceof ProjectManagementApiError) {
26515
27385
  throw new Error(`mcp_tool_error:${error.code}`);
26516
27386
  }
@@ -26528,7 +27398,7 @@ function createProjectMcpTools(api) {
26528
27398
  }
26529
27399
  return { projects: await api.listProjects(requestInput) };
26530
27400
  } catch (error) {
26531
- mapMcpError11(error);
27401
+ mapMcpError12(error);
26532
27402
  }
26533
27403
  },
26534
27404
  async create_project(input) {
@@ -26543,7 +27413,7 @@ function createProjectMcpTools(api) {
26543
27413
  }
26544
27414
  return { project: await api.createProject(requestInput) };
26545
27415
  } catch (error) {
26546
- mapMcpError11(error);
27416
+ mapMcpError12(error);
26547
27417
  }
26548
27418
  },
26549
27419
  async update_project(input) {
@@ -26563,7 +27433,7 @@ function createProjectMcpTools(api) {
26563
27433
  }
26564
27434
  return { project: await api.updateProject(requestInput) };
26565
27435
  } catch (error) {
26566
- mapMcpError11(error);
27436
+ mapMcpError12(error);
26567
27437
  }
26568
27438
  },
26569
27439
  async delete_project(input) {
@@ -26575,7 +27445,7 @@ function createProjectMcpTools(api) {
26575
27445
  })
26576
27446
  };
26577
27447
  } catch (error) {
26578
- mapMcpError11(error);
27448
+ mapMcpError12(error);
26579
27449
  }
26580
27450
  }
26581
27451
  };
@@ -26782,7 +27652,7 @@ async function persistCloudArtifact(directoryPath, fileName, payload, dependenci
26782
27652
  }
26783
27653
 
26784
27654
  // src/retrieval-tools.ts
26785
- function mapMcpError12(error) {
27655
+ function mapMcpError13(error) {
26786
27656
  if (error instanceof RetrievalApiError) {
26787
27657
  throw new Error(`mcp_tool_error:${error.code}`);
26788
27658
  }
@@ -26972,7 +27842,7 @@ function createRetrievalMcpTools(api) {
26972
27842
  incidents: incidents.incidents.map((incident) => attachSourceToRecord(incident, "cloud"))
26973
27843
  };
26974
27844
  } catch (error) {
26975
- mapMcpError12(error);
27845
+ mapMcpError13(error);
26976
27846
  }
26977
27847
  },
26978
27848
  async get_incident(input) {
@@ -27007,7 +27877,7 @@ function createRetrievalMcpTools(api) {
27007
27877
  )
27008
27878
  };
27009
27879
  } catch (error) {
27010
- mapMcpError12(error);
27880
+ mapMcpError13(error);
27011
27881
  }
27012
27882
  },
27013
27883
  async get_incident_context(input) {
@@ -27036,7 +27906,7 @@ function createRetrievalMcpTools(api) {
27036
27906
  "cloud"
27037
27907
  );
27038
27908
  } catch (error) {
27039
- mapMcpError12(error);
27909
+ mapMcpError13(error);
27040
27910
  }
27041
27911
  },
27042
27912
  async resolve_incident(input) {
@@ -27081,7 +27951,7 @@ function createRetrievalMcpTools(api) {
27081
27951
  })()
27082
27952
  };
27083
27953
  } catch (error) {
27084
- mapMcpError12(error);
27954
+ mapMcpError13(error);
27085
27955
  }
27086
27956
  },
27087
27957
  async resolve_incidents(input) {
@@ -27142,7 +28012,7 @@ function createRetrievalMcpTools(api) {
27142
28012
  incidents: incidentIds.map((incidentId) => localIncidents.get(incidentId))
27143
28013
  };
27144
28014
  } catch (error) {
27145
- mapMcpError12(error);
28015
+ mapMcpError13(error);
27146
28016
  }
27147
28017
  },
27148
28018
  async reopen_incident(input) {
@@ -27187,7 +28057,7 @@ function createRetrievalMcpTools(api) {
27187
28057
  })()
27188
28058
  };
27189
28059
  } catch (error) {
27190
- mapMcpError12(error);
28060
+ mapMcpError13(error);
27191
28061
  }
27192
28062
  },
27193
28063
  async reopen_incidents(input) {
@@ -27248,7 +28118,7 @@ function createRetrievalMcpTools(api) {
27248
28118
  incidents: incidentIds.map((incidentId) => localIncidents.get(incidentId))
27249
28119
  };
27250
28120
  } catch (error) {
27251
- mapMcpError12(error);
28121
+ mapMcpError13(error);
27252
28122
  }
27253
28123
  },
27254
28124
  async get_bundle(input) {
@@ -27279,7 +28149,7 @@ function createRetrievalMcpTools(api) {
27279
28149
  }
27280
28150
  );
27281
28151
  } catch (error) {
27282
- mapMcpError12(error);
28152
+ mapMcpError13(error);
27283
28153
  }
27284
28154
  },
27285
28155
  async get_logs(input) {
@@ -27299,7 +28169,7 @@ function createRetrievalMcpTools(api) {
27299
28169
  }
27300
28170
  return await api.getLogs(requestInput);
27301
28171
  } catch (error) {
27302
- mapMcpError12(error);
28172
+ mapMcpError13(error);
27303
28173
  }
27304
28174
  },
27305
28175
  async get_reproduction(input) {
@@ -27330,14 +28200,14 @@ function createRetrievalMcpTools(api) {
27330
28200
  }
27331
28201
  );
27332
28202
  } catch (error) {
27333
- mapMcpError12(error);
28203
+ mapMcpError13(error);
27334
28204
  }
27335
28205
  }
27336
28206
  };
27337
28207
  }
27338
28208
 
27339
28209
  // src/services-tools.ts
27340
- function mapMcpError13(error) {
28210
+ function mapMcpError14(error) {
27341
28211
  if (error instanceof RetrievalApiError) {
27342
28212
  throw new Error(`mcp_tool_error:${error.code}`);
27343
28213
  }
@@ -27358,14 +28228,14 @@ function createServicesMcpTools(api) {
27358
28228
  services: await api.listServices(requestInput)
27359
28229
  };
27360
28230
  } catch (error) {
27361
- mapMcpError13(error);
28231
+ mapMcpError14(error);
27362
28232
  }
27363
28233
  }
27364
28234
  };
27365
28235
  }
27366
28236
 
27367
28237
  // src/setup-tools.ts
27368
- function mapMcpError14() {
28238
+ function mapMcpError15() {
27369
28239
  throw new Error("mcp_tool_error:unknown_error");
27370
28240
  }
27371
28241
  function parseJsonOutput2(output) {
@@ -27380,7 +28250,7 @@ async function runJsonCommand2(command) {
27380
28250
  const result = await command();
27381
28251
  return parseJsonOutput2(result.output);
27382
28252
  } catch {
27383
- mapMcpError14();
28253
+ mapMcpError15();
27384
28254
  }
27385
28255
  }
27386
28256
  function createSetupMcpTools(commands) {
@@ -27439,7 +28309,7 @@ function createSetupMcpTools(commands) {
27439
28309
  }
27440
28310
 
27441
28311
  // src/slack-tools.ts
27442
- function mapMcpError15(error) {
28312
+ function mapMcpError16(error) {
27443
28313
  if (error instanceof SlackApiError) {
27444
28314
  throw new Error(`mcp_tool_error:${error.code}`);
27445
28315
  }
@@ -27456,7 +28326,7 @@ function createSlackMcpTools(api) {
27456
28326
  })
27457
28327
  };
27458
28328
  } catch (error) {
27459
- mapMcpError15(error);
28329
+ mapMcpError16(error);
27460
28330
  }
27461
28331
  },
27462
28332
  async get_slack_connect_url(input) {
@@ -27469,7 +28339,7 @@ function createSlackMcpTools(api) {
27469
28339
  })
27470
28340
  };
27471
28341
  } catch (error) {
27472
- mapMcpError15(error);
28342
+ mapMcpError16(error);
27473
28343
  }
27474
28344
  },
27475
28345
  async test_slack_destination(input) {
@@ -27482,7 +28352,7 @@ function createSlackMcpTools(api) {
27482
28352
  })
27483
28353
  };
27484
28354
  } catch (error) {
27485
- mapMcpError15(error);
28355
+ mapMcpError16(error);
27486
28356
  }
27487
28357
  },
27488
28358
  async delete_slack_destination(input) {
@@ -27495,14 +28365,14 @@ function createSlackMcpTools(api) {
27495
28365
  })
27496
28366
  };
27497
28367
  } catch (error) {
27498
- mapMcpError15(error);
28368
+ mapMcpError16(error);
27499
28369
  }
27500
28370
  }
27501
28371
  };
27502
28372
  }
27503
28373
 
27504
28374
  // src/token-tools.ts
27505
- function mapMcpError16(error) {
28375
+ function mapMcpError17(error) {
27506
28376
  if (error instanceof TokenManagementApiError) {
27507
28377
  throw new Error(`mcp_tool_error:${error.code}`);
27508
28378
  }
@@ -27523,7 +28393,7 @@ function createTokenMcpTools(api) {
27523
28393
  tokens: await api.listProjectTokens(requestInput)
27524
28394
  };
27525
28395
  } catch (error) {
27526
- mapMcpError16(error);
28396
+ mapMcpError17(error);
27527
28397
  }
27528
28398
  },
27529
28399
  async create_project_token(input) {
@@ -27538,7 +28408,7 @@ function createTokenMcpTools(api) {
27538
28408
  })
27539
28409
  };
27540
28410
  } catch (error) {
27541
- mapMcpError16(error);
28411
+ mapMcpError17(error);
27542
28412
  }
27543
28413
  },
27544
28414
  async revoke_project_token(input) {
@@ -27551,7 +28421,7 @@ function createTokenMcpTools(api) {
27551
28421
  })
27552
28422
  };
27553
28423
  } catch (error) {
27554
- mapMcpError16(error);
28424
+ mapMcpError17(error);
27555
28425
  }
27556
28426
  },
27557
28427
  async list_member_tokens(input) {
@@ -27566,7 +28436,7 @@ function createTokenMcpTools(api) {
27566
28436
  tokens: await api.listMemberTokens(requestInput)
27567
28437
  };
27568
28438
  } catch (error) {
27569
- mapMcpError16(error);
28439
+ mapMcpError17(error);
27570
28440
  }
27571
28441
  },
27572
28442
  async create_member_token(input) {
@@ -27578,7 +28448,7 @@ function createTokenMcpTools(api) {
27578
28448
  })
27579
28449
  };
27580
28450
  } catch (error) {
27581
- mapMcpError16(error);
28451
+ mapMcpError17(error);
27582
28452
  }
27583
28453
  },
27584
28454
  async revoke_member_token(input) {
@@ -27590,14 +28460,14 @@ function createTokenMcpTools(api) {
27590
28460
  })
27591
28461
  };
27592
28462
  } catch (error) {
27593
- mapMcpError16(error);
28463
+ mapMcpError17(error);
27594
28464
  }
27595
28465
  }
27596
28466
  };
27597
28467
  }
27598
28468
 
27599
28469
  // src/webhook-tools.ts
27600
- function mapMcpError17(error) {
28470
+ function mapMcpError18(error) {
27601
28471
  if (error instanceof WebhookApiError) {
27602
28472
  throw new Error(`mcp_tool_error:${error.code}`);
27603
28473
  }
@@ -27618,7 +28488,7 @@ function createWebhookMcpTools(api) {
27618
28488
  webhooks: await api.listWebhooks(requestInput)
27619
28489
  };
27620
28490
  } catch (error) {
27621
- mapMcpError17(error);
28491
+ mapMcpError18(error);
27622
28492
  }
27623
28493
  },
27624
28494
  async create_webhook(input) {
@@ -27639,7 +28509,7 @@ function createWebhookMcpTools(api) {
27639
28509
  webhook: await api.createWebhook(requestInput)
27640
28510
  };
27641
28511
  } catch (error) {
27642
- mapMcpError17(error);
28512
+ mapMcpError18(error);
27643
28513
  }
27644
28514
  },
27645
28515
  async update_webhook(input) {
@@ -27665,7 +28535,7 @@ function createWebhookMcpTools(api) {
27665
28535
  webhook: await api.updateWebhook(requestInput)
27666
28536
  };
27667
28537
  } catch (error) {
27668
- mapMcpError17(error);
28538
+ mapMcpError18(error);
27669
28539
  }
27670
28540
  },
27671
28541
  async delete_webhook(input) {
@@ -27678,7 +28548,7 @@ function createWebhookMcpTools(api) {
27678
28548
  })
27679
28549
  };
27680
28550
  } catch (error) {
27681
- mapMcpError17(error);
28551
+ mapMcpError18(error);
27682
28552
  }
27683
28553
  },
27684
28554
  async test_webhook(input) {
@@ -27695,7 +28565,7 @@ function createWebhookMcpTools(api) {
27695
28565
  delivery: await api.testWebhook(requestInput)
27696
28566
  };
27697
28567
  } catch (error) {
27698
- mapMcpError17(error);
28568
+ mapMcpError18(error);
27699
28569
  }
27700
28570
  },
27701
28571
  async list_webhook_deliveries(input) {
@@ -27712,7 +28582,7 @@ function createWebhookMcpTools(api) {
27712
28582
  deliveries: await api.listWebhookDeliveries(requestInput)
27713
28583
  };
27714
28584
  } catch (error) {
27715
- mapMcpError17(error);
28585
+ mapMcpError18(error);
27716
28586
  }
27717
28587
  },
27718
28588
  async retry_webhook_delivery(input) {
@@ -27724,14 +28594,14 @@ function createWebhookMcpTools(api) {
27724
28594
  deliveryId: String(input["deliveryId"])
27725
28595
  });
27726
28596
  } catch (error) {
27727
- mapMcpError17(error);
28597
+ mapMcpError18(error);
27728
28598
  }
27729
28599
  }
27730
28600
  };
27731
28601
  }
27732
28602
 
27733
28603
  // src/weekly-report-tools.ts
27734
- function mapMcpError18(error) {
28604
+ function mapMcpError19(error) {
27735
28605
  if (error instanceof WeeklyReportApiError) {
27736
28606
  throw new Error(`mcp_tool_error:${error.code}`);
27737
28607
  }
@@ -27749,7 +28619,7 @@ function createWeeklyReportMcpTools(api) {
27749
28619
  })
27750
28620
  };
27751
28621
  } catch (error) {
27752
- mapMcpError18(error);
28622
+ mapMcpError19(error);
27753
28623
  }
27754
28624
  },
27755
28625
  async create_weekly_report_channel(input) {
@@ -27765,7 +28635,7 @@ function createWeeklyReportMcpTools(api) {
27765
28635
  })
27766
28636
  };
27767
28637
  } catch (error) {
27768
- mapMcpError18(error);
28638
+ mapMcpError19(error);
27769
28639
  }
27770
28640
  },
27771
28641
  async update_weekly_report_channel(input) {
@@ -27780,7 +28650,7 @@ function createWeeklyReportMcpTools(api) {
27780
28650
  })
27781
28651
  };
27782
28652
  } catch (error) {
27783
- mapMcpError18(error);
28653
+ mapMcpError19(error);
27784
28654
  }
27785
28655
  },
27786
28656
  async delete_weekly_report_channel(input) {
@@ -27792,7 +28662,7 @@ function createWeeklyReportMcpTools(api) {
27792
28662
  })
27793
28663
  };
27794
28664
  } catch (error) {
27795
- mapMcpError18(error);
28665
+ mapMcpError19(error);
27796
28666
  }
27797
28667
  }
27798
28668
  };
@@ -27861,6 +28731,7 @@ async function createDefaultMcpTools(input = {}) {
27861
28731
  ...createCapturePolicyMcpTools(createCapturePolicyApi(httpClient)),
27862
28732
  ...createImprovementSettingsMcpTools(createImprovementSettingsApi(httpClient)),
27863
28733
  ...createProbeMcpTools(createProbeApi(httpClient)),
28734
+ ...createHealthCheckMcpTools(createHealthCheckApi(httpClient)),
27864
28735
  ...createBillingMcpTools(createBillingApi(httpClient)),
27865
28736
  ...createMemberMcpTools(createMemberApi(httpClient)),
27866
28737
  ...createGitHubMcpTools(createGitHubManagementApi(httpClient))
@@ -29160,7 +30031,7 @@ var zodToJsonSchema = (schema, options) => {
29160
30031
  var package_default = {
29161
30032
  name: "@debugbundle/mcp",
29162
30033
  mcpName: "com.debugbundle/mcp",
29163
- version: "1.4.0",
30034
+ version: "1.5.0",
29164
30035
  private: false,
29165
30036
  description: "Model Context Protocol server for DebugBundle",
29166
30037
  license: "AGPL-3.0-only",
@@ -29196,6 +30067,156 @@ var package_default = {
29196
30067
  }
29197
30068
  };
29198
30069
 
30070
+ // src/health-check-tool-catalog.ts
30071
+ var HEALTH_CHECK_MCP_TOOL_CATALOG = [
30072
+ {
30073
+ name: "list_health_checks",
30074
+ group: "health_checks",
30075
+ description: "List hosted health checks for a project.",
30076
+ inputSchema: external_exports.object({
30077
+ bearerToken: external_exports.string(),
30078
+ projectId: external_exports.string(),
30079
+ limit: external_exports.number().optional()
30080
+ })
30081
+ },
30082
+ {
30083
+ name: "get_health_check",
30084
+ group: "health_checks",
30085
+ description: "Get one hosted health check by id.",
30086
+ inputSchema: external_exports.object({
30087
+ bearerToken: external_exports.string(),
30088
+ projectId: external_exports.string(),
30089
+ checkId: external_exports.string()
30090
+ })
30091
+ },
30092
+ {
30093
+ name: "create_health_check",
30094
+ group: "health_checks",
30095
+ description: "Create a hosted health check for a project.",
30096
+ inputSchema: external_exports.object({
30097
+ bearerToken: external_exports.string(),
30098
+ projectId: external_exports.string(),
30099
+ name: external_exports.string(),
30100
+ url: external_exports.string(),
30101
+ method: external_exports.enum(["GET", "HEAD"]).optional(),
30102
+ expectedStatusMin: external_exports.number().optional(),
30103
+ expectedStatusMax: external_exports.number().optional(),
30104
+ timeoutMs: external_exports.number().optional(),
30105
+ intervalSeconds: external_exports.number(),
30106
+ failureThreshold: external_exports.number().optional(),
30107
+ recoveryThreshold: external_exports.number().optional(),
30108
+ environment: external_exports.string().optional(),
30109
+ serviceName: external_exports.string().nullable().optional(),
30110
+ enabled: external_exports.boolean().optional()
30111
+ })
30112
+ },
30113
+ {
30114
+ name: "update_health_check",
30115
+ group: "health_checks",
30116
+ description: "Update a hosted health check.",
30117
+ inputSchema: external_exports.object({
30118
+ bearerToken: external_exports.string(),
30119
+ projectId: external_exports.string(),
30120
+ checkId: external_exports.string(),
30121
+ name: external_exports.string().optional(),
30122
+ url: external_exports.string().optional(),
30123
+ method: external_exports.enum(["GET", "HEAD"]).optional(),
30124
+ expectedStatusMin: external_exports.number().optional(),
30125
+ expectedStatusMax: external_exports.number().optional(),
30126
+ timeoutMs: external_exports.number().optional(),
30127
+ intervalSeconds: external_exports.number().optional(),
30128
+ failureThreshold: external_exports.number().optional(),
30129
+ recoveryThreshold: external_exports.number().optional(),
30130
+ environment: external_exports.string().optional(),
30131
+ serviceName: external_exports.string().nullable().optional(),
30132
+ enabled: external_exports.boolean().optional()
30133
+ })
30134
+ },
30135
+ {
30136
+ name: "delete_health_check",
30137
+ group: "health_checks",
30138
+ description: "Delete a hosted health check.",
30139
+ inputSchema: external_exports.object({
30140
+ bearerToken: external_exports.string(),
30141
+ projectId: external_exports.string(),
30142
+ checkId: external_exports.string()
30143
+ })
30144
+ },
30145
+ {
30146
+ name: "test_health_check",
30147
+ group: "health_checks",
30148
+ description: "Run a side-effect-free test for a hosted health-check target.",
30149
+ inputSchema: external_exports.object({
30150
+ bearerToken: external_exports.string(),
30151
+ projectId: external_exports.string(),
30152
+ url: external_exports.string(),
30153
+ method: external_exports.enum(["GET", "HEAD"]).optional(),
30154
+ expectedStatusMin: external_exports.number().optional(),
30155
+ expectedStatusMax: external_exports.number().optional(),
30156
+ timeoutMs: external_exports.number().optional()
30157
+ })
30158
+ },
30159
+ {
30160
+ name: "list_health_check_results",
30161
+ group: "health_checks",
30162
+ description: "List recent execution results for one hosted health check.",
30163
+ inputSchema: external_exports.object({
30164
+ bearerToken: external_exports.string(),
30165
+ projectId: external_exports.string(),
30166
+ checkId: external_exports.string(),
30167
+ limit: external_exports.number().optional()
30168
+ })
30169
+ },
30170
+ {
30171
+ name: "list_health_check_daily_rollups",
30172
+ group: "health_checks",
30173
+ description: "List retained per-day history for one hosted health check.",
30174
+ inputSchema: external_exports.object({
30175
+ bearerToken: external_exports.string(),
30176
+ projectId: external_exports.string(),
30177
+ checkId: external_exports.string(),
30178
+ limit: external_exports.number().optional()
30179
+ })
30180
+ }
30181
+ ];
30182
+
30183
+ // src/probe-tool-catalog.ts
30184
+ var PROBE_MCP_TOOL_CATALOG = [
30185
+ {
30186
+ name: "activate_probe",
30187
+ group: "probes",
30188
+ description: "Activate a remote probe on a project.",
30189
+ inputSchema: external_exports.object({
30190
+ bearerToken: external_exports.string(),
30191
+ projectId: external_exports.string(),
30192
+ labelPattern: external_exports.string(),
30193
+ service: external_exports.string().optional(),
30194
+ environment: external_exports.string().optional(),
30195
+ ttlSeconds: external_exports.number().optional(),
30196
+ triggerTtlSeconds: external_exports.number().optional()
30197
+ })
30198
+ },
30199
+ {
30200
+ name: "list_active_probes",
30201
+ group: "probes",
30202
+ description: "List active probe activations for a project.",
30203
+ inputSchema: external_exports.object({
30204
+ bearerToken: external_exports.string(),
30205
+ projectId: external_exports.string()
30206
+ })
30207
+ },
30208
+ {
30209
+ name: "deactivate_probe",
30210
+ group: "probes",
30211
+ description: "Deactivate a probe activation.",
30212
+ inputSchema: external_exports.object({
30213
+ bearerToken: external_exports.string(),
30214
+ projectId: external_exports.string(),
30215
+ activationId: external_exports.string()
30216
+ })
30217
+ }
30218
+ ];
30219
+
29199
30220
  // src/tool-catalog.ts
29200
30221
  var jsonObjectSchema = external_exports.record(external_exports.unknown());
29201
30222
  var optionalBearerTokenSchema = external_exports.string().optional();
@@ -29953,39 +30974,8 @@ var MCP_TOOL_CATALOG = [
29953
30974
  })
29954
30975
  })
29955
30976
  },
29956
- {
29957
- name: "activate_probe",
29958
- group: "probes",
29959
- description: "Activate a remote probe on a project.",
29960
- inputSchema: external_exports.object({
29961
- bearerToken: external_exports.string(),
29962
- projectId: external_exports.string(),
29963
- labelPattern: external_exports.string(),
29964
- service: external_exports.string().optional(),
29965
- environment: external_exports.string().optional(),
29966
- ttlSeconds: external_exports.number().optional(),
29967
- triggerTtlSeconds: external_exports.number().optional()
29968
- })
29969
- },
29970
- {
29971
- name: "list_active_probes",
29972
- group: "probes",
29973
- description: "List active probe activations for a project.",
29974
- inputSchema: external_exports.object({
29975
- bearerToken: external_exports.string(),
29976
- projectId: external_exports.string()
29977
- })
29978
- },
29979
- {
29980
- name: "deactivate_probe",
29981
- group: "probes",
29982
- description: "Deactivate a probe activation.",
29983
- inputSchema: external_exports.object({
29984
- bearerToken: external_exports.string(),
29985
- projectId: external_exports.string(),
29986
- activationId: external_exports.string()
29987
- })
29988
- },
30977
+ ...PROBE_MCP_TOOL_CATALOG,
30978
+ ...HEALTH_CHECK_MCP_TOOL_CATALOG,
29989
30979
  {
29990
30980
  name: "get_billing_summary",
29991
30981
  group: "billing",