@debugbundle/cli 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.
Files changed (2) hide show
  1. package/dist/main.cjs +1408 -126
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -14462,6 +14462,113 @@ var coerce = {
14462
14462
  };
14463
14463
  var NEVER = INVALID;
14464
14464
 
14465
+ // ../../packages/shared-types/src/tier-capabilities.ts
14466
+ var TIER_CAPABILITIES = {
14467
+ free: {
14468
+ remote_probes: false,
14469
+ github_automation: false,
14470
+ slack_integration: false,
14471
+ cloud_improvement_bundles: false,
14472
+ shared_dashboards: false,
14473
+ member_invites: false,
14474
+ included_capacity_units: 1,
14475
+ max_members: 1,
14476
+ ingestion_rate_per_min: 1e3,
14477
+ retrieval_rate_per_min: 100,
14478
+ bundle_retention_days: 7,
14479
+ raw_event_retention_days: 7,
14480
+ // Allowance buckets (account-level pool, not per capacity unit)
14481
+ monthly_bundle_requests: 100,
14482
+ monthly_raw_ingested_events: 750,
14483
+ retained_bundle_cap: 50,
14484
+ monthly_remote_activations: 0,
14485
+ monthly_alert_deliveries: 25,
14486
+ monthly_webhook_deliveries: 100,
14487
+ availability_checks_per_project: 1,
14488
+ availability_check_min_interval_seconds: 300
14489
+ },
14490
+ solo: {
14491
+ remote_probes: true,
14492
+ github_automation: true,
14493
+ slack_integration: false,
14494
+ cloud_improvement_bundles: true,
14495
+ shared_dashboards: false,
14496
+ member_invites: false,
14497
+ included_capacity_units: 3,
14498
+ max_members: 1,
14499
+ ingestion_rate_per_min: 5e3,
14500
+ retrieval_rate_per_min: 300,
14501
+ bundle_retention_days: 30,
14502
+ raw_event_retention_days: 14,
14503
+ // Per-unit allowance (multiply by included and purchased capacity units)
14504
+ monthly_bundle_requests: 250,
14505
+ monthly_raw_ingested_events: 3500,
14506
+ retained_bundle_cap: 150,
14507
+ monthly_remote_activations: 25,
14508
+ monthly_alert_deliveries: 75,
14509
+ monthly_webhook_deliveries: 250,
14510
+ availability_checks_per_project: 5,
14511
+ availability_check_min_interval_seconds: 60
14512
+ },
14513
+ team: {
14514
+ remote_probes: true,
14515
+ github_automation: true,
14516
+ slack_integration: true,
14517
+ cloud_improvement_bundles: true,
14518
+ shared_dashboards: true,
14519
+ member_invites: true,
14520
+ included_capacity_units: 15,
14521
+ max_members: 1e3,
14522
+ ingestion_rate_per_min: 1e4,
14523
+ retrieval_rate_per_min: 500,
14524
+ bundle_retention_days: 90,
14525
+ raw_event_retention_days: 30,
14526
+ // Per-unit allowance (multiply by included and purchased capacity units)
14527
+ monthly_bundle_requests: 1e3,
14528
+ monthly_raw_ingested_events: 1e4,
14529
+ retained_bundle_cap: 400,
14530
+ monthly_remote_activations: 50,
14531
+ monthly_alert_deliveries: 300,
14532
+ monthly_webhook_deliveries: 1e3,
14533
+ availability_checks_per_project: 25,
14534
+ availability_check_min_interval_seconds: 30
14535
+ }
14536
+ };
14537
+ var SELFHOST_CAPABILITIES = {
14538
+ remote_probes: true,
14539
+ github_automation: true,
14540
+ slack_integration: true,
14541
+ cloud_improvement_bundles: true,
14542
+ shared_dashboards: true,
14543
+ member_invites: true,
14544
+ included_capacity_units: 1e6,
14545
+ max_members: 1e3,
14546
+ ingestion_rate_per_min: 1e6,
14547
+ retrieval_rate_per_min: 1e5,
14548
+ bundle_retention_days: 36500,
14549
+ raw_event_retention_days: 36500,
14550
+ monthly_bundle_requests: 1e9,
14551
+ monthly_raw_ingested_events: 1e9,
14552
+ retained_bundle_cap: 1e6,
14553
+ monthly_remote_activations: 1e6,
14554
+ monthly_alert_deliveries: 1e6,
14555
+ monthly_webhook_deliveries: 1e6,
14556
+ availability_checks_per_project: 1e6,
14557
+ availability_check_min_interval_seconds: 30
14558
+ };
14559
+ function isSelfHostMode() {
14560
+ return typeof process !== "undefined" && process.env["SELFHOST_MODE"] === "true";
14561
+ }
14562
+ function getTierCapabilities(plan) {
14563
+ if (isSelfHostMode()) {
14564
+ return SELFHOST_CAPABILITIES;
14565
+ }
14566
+ if (plan !== void 0 && plan in TIER_CAPABILITIES) {
14567
+ return TIER_CAPABILITIES[plan];
14568
+ }
14569
+ return TIER_CAPABILITIES.free;
14570
+ }
14571
+
14465
14572
  // ../../packages/shared-types/src/capture-policy.ts
14466
14573
  var EventClassValues = [
14467
14574
  "incident_signal",
@@ -14707,6 +14814,7 @@ function isRouteOnlyExternalProbe(normalizedRoute) {
14707
14814
  "/__debug__/render_panel",
14708
14815
  "/actuator",
14709
14816
  "/autodiscover/autodiscover.json",
14817
+ "/containers/json",
14710
14818
  "/developmentserver/metadatauploader",
14711
14819
  "/cpanel",
14712
14820
  "/favicon.ico",
@@ -17464,6 +17572,16 @@ var DEFAULT_SESSION_LIFETIME_MS = 1e3 * 60 * 60 * 24 * 7;
17464
17572
  var DEFAULT_EMAIL_AUTH_CODE_LIFETIME_MS = 1e3 * 60 * 10;
17465
17573
  var DEFAULT_GITHUB_OAUTH_STATE_LIFETIME_MS = 1e3 * 60 * 10;
17466
17574
 
17575
+ // ../../packages/storage/src/availability-check-store-helpers.ts
17576
+ var TIER_CAPABILITIES_SQL = {
17577
+ free_limit: getTierCapabilities("free").availability_checks_per_project,
17578
+ solo_limit: getTierCapabilities("solo").availability_checks_per_project,
17579
+ team_limit: getTierCapabilities("team").availability_checks_per_project,
17580
+ free_interval: getTierCapabilities("free").availability_check_min_interval_seconds,
17581
+ solo_interval: getTierCapabilities("solo").availability_check_min_interval_seconds,
17582
+ team_interval: getTierCapabilities("team").availability_check_min_interval_seconds
17583
+ };
17584
+
17467
17585
  // ../../packages/storage/src/auth-rate-limiter.ts
17468
17586
  var import_ioredis = __toESM(require_built3(), 1);
17469
17587
 
@@ -17968,8 +18086,131 @@ function classifyEvent(eventType, logLevel, probeActivationId, payload, captureP
17968
18086
  var import_ioredis4 = __toESM(require_built3(), 1);
17969
18087
  var DEFAULT_PROCESSING_TIMEOUT_MS = 5 * 60 * 1e3;
17970
18088
 
17971
- // ../../packages/storage/src/schema-migrations.ts
17972
- var import_node_crypto2 = require("node:crypto");
18089
+ // ../../packages/storage/src/availability-check-bootstrap-statements.ts
18090
+ var AVAILABILITY_CHECK_BOOTSTRAP_STATEMENTS = [
18091
+ `
18092
+ CREATE TABLE availability_checks (
18093
+ id uuid PRIMARY KEY,
18094
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
18095
+ created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
18096
+ name text NOT NULL,
18097
+ url text NOT NULL,
18098
+ method text NOT NULL CHECK (method IN ('GET', 'HEAD')),
18099
+ expected_status_min integer NOT NULL DEFAULT 200 CHECK (expected_status_min BETWEEN 100 AND 599),
18100
+ expected_status_max integer NOT NULL DEFAULT 399 CHECK (expected_status_max BETWEEN 100 AND 599),
18101
+ timeout_ms integer NOT NULL DEFAULT 5000 CHECK (timeout_ms BETWEEN 500 AND 5000),
18102
+ interval_seconds integer NOT NULL CHECK (interval_seconds >= 30),
18103
+ failure_threshold integer NOT NULL DEFAULT 3 CHECK (failure_threshold BETWEEN 1 AND 10),
18104
+ recovery_threshold integer NOT NULL DEFAULT 2 CHECK (recovery_threshold BETWEEN 1 AND 10),
18105
+ environment text NOT NULL DEFAULT 'production',
18106
+ service_name text,
18107
+ enabled boolean NOT NULL DEFAULT true,
18108
+ status text NOT NULL DEFAULT 'unknown' CHECK (status IN ('unknown', 'passing', 'failing')),
18109
+ consecutive_failures integer NOT NULL DEFAULT 0,
18110
+ consecutive_successes integer NOT NULL DEFAULT 0,
18111
+ linked_incident_id uuid REFERENCES incidents(id) ON DELETE SET NULL,
18112
+ last_checked_at timestamptz,
18113
+ next_check_at timestamptz,
18114
+ claimed_at timestamptz,
18115
+ last_result_status text CHECK (
18116
+ last_result_status IS NULL OR last_result_status IN (
18117
+ 'success',
18118
+ 'http_status_mismatch',
18119
+ 'timeout',
18120
+ 'dns_error',
18121
+ 'tls_error',
18122
+ 'connection_error',
18123
+ 'redirect_blocked',
18124
+ 'security_blocked',
18125
+ 'internal_error'
18126
+ )
18127
+ ),
18128
+ last_result_http_status integer,
18129
+ last_result_error_kind text,
18130
+ last_result_error_message text,
18131
+ last_result_duration_ms integer,
18132
+ deleted_at timestamptz,
18133
+ created_at timestamptz NOT NULL DEFAULT now(),
18134
+ updated_at timestamptz NOT NULL DEFAULT now()
18135
+ )
18136
+ `,
18137
+ `
18138
+ CREATE INDEX availability_checks_project_created_idx
18139
+ ON availability_checks (project_id, created_at DESC)
18140
+ `,
18141
+ `
18142
+ CREATE INDEX availability_checks_due_idx
18143
+ ON availability_checks (next_check_at, project_id)
18144
+ `,
18145
+ `
18146
+ CREATE INDEX availability_checks_claimed_idx
18147
+ ON availability_checks (claimed_at)
18148
+ `,
18149
+ `
18150
+ CREATE TABLE availability_check_results (
18151
+ id uuid PRIMARY KEY,
18152
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
18153
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
18154
+ started_at timestamptz NOT NULL,
18155
+ completed_at timestamptz NOT NULL,
18156
+ duration_ms integer NOT NULL,
18157
+ status text NOT NULL CHECK (
18158
+ status IN (
18159
+ 'success',
18160
+ 'http_status_mismatch',
18161
+ 'timeout',
18162
+ 'dns_error',
18163
+ 'tls_error',
18164
+ 'connection_error',
18165
+ 'redirect_blocked',
18166
+ 'security_blocked',
18167
+ 'internal_error'
18168
+ )
18169
+ ),
18170
+ http_status integer,
18171
+ error_kind text,
18172
+ error_message text,
18173
+ redirect_count integer NOT NULL DEFAULT 0,
18174
+ checked_url_host text NOT NULL,
18175
+ checked_url_path text NOT NULL,
18176
+ final_url text NOT NULL,
18177
+ created_at timestamptz NOT NULL DEFAULT now()
18178
+ )
18179
+ `,
18180
+ `
18181
+ CREATE INDEX availability_check_results_check_started_idx
18182
+ ON availability_check_results (check_id, started_at DESC)
18183
+ `,
18184
+ `
18185
+ CREATE INDEX availability_check_results_project_started_idx
18186
+ ON availability_check_results (project_id, started_at DESC)
18187
+ `,
18188
+ `
18189
+ CREATE TABLE availability_check_daily_rollups (
18190
+ id uuid PRIMARY KEY,
18191
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
18192
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
18193
+ day date NOT NULL,
18194
+ state text NOT NULL CHECK (state IN ('unknown', 'operational', 'degraded', 'down', 'paused')),
18195
+ total_checks integer NOT NULL DEFAULT 0,
18196
+ successful_checks integer NOT NULL DEFAULT 0,
18197
+ failed_checks integer NOT NULL DEFAULT 0,
18198
+ degraded_checks integer NOT NULL DEFAULT 0,
18199
+ avg_duration_ms integer,
18200
+ first_checked_at timestamptz,
18201
+ last_checked_at timestamptz,
18202
+ downtime_seconds integer NOT NULL DEFAULT 0,
18203
+ incident_ids uuid[] NOT NULL DEFAULT '{}'::uuid[],
18204
+ created_at timestamptz NOT NULL DEFAULT now(),
18205
+ updated_at timestamptz NOT NULL DEFAULT now(),
18206
+ UNIQUE (check_id, day)
18207
+ )
18208
+ `,
18209
+ `
18210
+ CREATE INDEX availability_check_daily_rollups_project_day_idx
18211
+ ON availability_check_daily_rollups (project_id, day DESC)
18212
+ `
18213
+ ];
17973
18214
 
17974
18215
  // ../../packages/storage/src/storage-bootstrap-statements.ts
17975
18216
  var STORAGE_BOOTSTRAP_STATEMENTS = [
@@ -18138,6 +18379,7 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
18138
18379
  user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
18139
18380
  organization_id uuid NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
18140
18381
  session_token_hash text UNIQUE NOT NULL,
18382
+ auth_method text CHECK (auth_method IS NULL OR auth_method IN ('email_code', 'github_oauth')),
18141
18383
  created_at timestamptz NOT NULL DEFAULT now(),
18142
18384
  expires_at timestamptz NOT NULL,
18143
18385
  revoked_at timestamptz
@@ -19066,12 +19308,257 @@ var STORAGE_BOOTSTRAP_STATEMENTS = [
19066
19308
  `
19067
19309
  ];
19068
19310
 
19311
+ // ../../packages/storage/src/storage-bootstrap-all-statements.ts
19312
+ var STORAGE_BOOTSTRAP_STATEMENTS2 = [
19313
+ ...STORAGE_BOOTSTRAP_STATEMENTS,
19314
+ ...AVAILABILITY_CHECK_BOOTSTRAP_STATEMENTS
19315
+ ];
19316
+
19069
19317
  // ../../packages/storage/src/migrations.ts
19070
- var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS.join(";\n\n");
19318
+ var STORAGE_BOOTSTRAP_SQL = STORAGE_BOOTSTRAP_STATEMENTS2.join(";\n\n");
19071
19319
 
19072
- // ../../packages/storage/src/schema-migrations.ts
19320
+ // ../../packages/storage/src/availability-check-schema-migrations.ts
19321
+ var import_node_crypto2 = require("node:crypto");
19322
+ function defineAvailabilityCheckStorageSchemaMigration(input2) {
19323
+ return {
19324
+ ...input2,
19325
+ checksum: (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(input2)).digest("hex")
19326
+ };
19327
+ }
19328
+ var AVAILABILITY_CHECK_STORAGE_SCHEMA_MIGRATIONS = [
19329
+ defineAvailabilityCheckStorageSchemaMigration({
19330
+ id: "202606150001_add_availability_checks",
19331
+ description: "Add project-scoped availability checks, result history, and daily rollups.",
19332
+ statements: [
19333
+ `
19334
+ CREATE TABLE IF NOT EXISTS availability_checks (
19335
+ id uuid PRIMARY KEY,
19336
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
19337
+ created_by_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
19338
+ name text NOT NULL,
19339
+ url text NOT NULL,
19340
+ method text NOT NULL,
19341
+ expected_status_min integer NOT NULL DEFAULT 200,
19342
+ expected_status_max integer NOT NULL DEFAULT 399,
19343
+ timeout_ms integer NOT NULL DEFAULT 5000,
19344
+ interval_seconds integer NOT NULL,
19345
+ failure_threshold integer NOT NULL DEFAULT 3,
19346
+ recovery_threshold integer NOT NULL DEFAULT 2,
19347
+ environment text NOT NULL DEFAULT 'production',
19348
+ service_name text,
19349
+ enabled boolean NOT NULL DEFAULT true,
19350
+ status text NOT NULL DEFAULT 'unknown',
19351
+ consecutive_failures integer NOT NULL DEFAULT 0,
19352
+ consecutive_successes integer NOT NULL DEFAULT 0,
19353
+ linked_incident_id uuid REFERENCES incidents(id) ON DELETE SET NULL,
19354
+ last_checked_at timestamptz,
19355
+ next_check_at timestamptz,
19356
+ claimed_at timestamptz,
19357
+ last_result_status text,
19358
+ last_result_http_status integer,
19359
+ last_result_error_kind text,
19360
+ last_result_error_message text,
19361
+ last_result_duration_ms integer,
19362
+ deleted_at timestamptz,
19363
+ created_at timestamptz NOT NULL DEFAULT now(),
19364
+ updated_at timestamptz NOT NULL DEFAULT now()
19365
+ )
19366
+ `,
19367
+ `
19368
+ ALTER TABLE availability_checks
19369
+ DROP CONSTRAINT IF EXISTS availability_checks_method_check
19370
+ `,
19371
+ `
19372
+ ALTER TABLE availability_checks
19373
+ ADD CONSTRAINT availability_checks_method_check
19374
+ CHECK (method IN ('GET', 'HEAD'))
19375
+ `,
19376
+ `
19377
+ ALTER TABLE availability_checks
19378
+ DROP CONSTRAINT IF EXISTS availability_checks_expected_status_min_check
19379
+ `,
19380
+ `
19381
+ ALTER TABLE availability_checks
19382
+ ADD CONSTRAINT availability_checks_expected_status_min_check
19383
+ CHECK (expected_status_min BETWEEN 100 AND 599)
19384
+ `,
19385
+ `
19386
+ ALTER TABLE availability_checks
19387
+ DROP CONSTRAINT IF EXISTS availability_checks_expected_status_max_check
19388
+ `,
19389
+ `
19390
+ ALTER TABLE availability_checks
19391
+ ADD CONSTRAINT availability_checks_expected_status_max_check
19392
+ CHECK (expected_status_max BETWEEN 100 AND 599)
19393
+ `,
19394
+ `
19395
+ ALTER TABLE availability_checks
19396
+ DROP CONSTRAINT IF EXISTS availability_checks_timeout_ms_check
19397
+ `,
19398
+ `
19399
+ ALTER TABLE availability_checks
19400
+ ADD CONSTRAINT availability_checks_timeout_ms_check
19401
+ CHECK (timeout_ms BETWEEN 500 AND 5000)
19402
+ `,
19403
+ `
19404
+ ALTER TABLE availability_checks
19405
+ DROP CONSTRAINT IF EXISTS availability_checks_interval_seconds_check
19406
+ `,
19407
+ `
19408
+ ALTER TABLE availability_checks
19409
+ ADD CONSTRAINT availability_checks_interval_seconds_check
19410
+ CHECK (interval_seconds >= 30)
19411
+ `,
19412
+ `
19413
+ ALTER TABLE availability_checks
19414
+ DROP CONSTRAINT IF EXISTS availability_checks_failure_threshold_check
19415
+ `,
19416
+ `
19417
+ ALTER TABLE availability_checks
19418
+ ADD CONSTRAINT availability_checks_failure_threshold_check
19419
+ CHECK (failure_threshold BETWEEN 1 AND 10)
19420
+ `,
19421
+ `
19422
+ ALTER TABLE availability_checks
19423
+ DROP CONSTRAINT IF EXISTS availability_checks_recovery_threshold_check
19424
+ `,
19425
+ `
19426
+ ALTER TABLE availability_checks
19427
+ ADD CONSTRAINT availability_checks_recovery_threshold_check
19428
+ CHECK (recovery_threshold BETWEEN 1 AND 10)
19429
+ `,
19430
+ `
19431
+ ALTER TABLE availability_checks
19432
+ DROP CONSTRAINT IF EXISTS availability_checks_status_check
19433
+ `,
19434
+ `
19435
+ ALTER TABLE availability_checks
19436
+ ADD CONSTRAINT availability_checks_status_check
19437
+ CHECK (status IN ('unknown', 'passing', 'failing'))
19438
+ `,
19439
+ `
19440
+ ALTER TABLE availability_checks
19441
+ DROP CONSTRAINT IF EXISTS availability_checks_last_result_status_check
19442
+ `,
19443
+ `
19444
+ ALTER TABLE availability_checks
19445
+ ADD CONSTRAINT availability_checks_last_result_status_check
19446
+ CHECK (
19447
+ last_result_status IS NULL OR last_result_status IN (
19448
+ 'success',
19449
+ 'http_status_mismatch',
19450
+ 'timeout',
19451
+ 'dns_error',
19452
+ 'tls_error',
19453
+ 'connection_error',
19454
+ 'redirect_blocked',
19455
+ 'security_blocked',
19456
+ 'internal_error'
19457
+ )
19458
+ )
19459
+ `,
19460
+ `
19461
+ CREATE INDEX IF NOT EXISTS availability_checks_project_created_idx
19462
+ ON availability_checks (project_id, created_at DESC)
19463
+ `,
19464
+ `
19465
+ CREATE INDEX IF NOT EXISTS availability_checks_due_idx
19466
+ ON availability_checks (next_check_at, project_id)
19467
+ `,
19468
+ `
19469
+ CREATE INDEX IF NOT EXISTS availability_checks_claimed_idx
19470
+ ON availability_checks (claimed_at)
19471
+ `,
19472
+ `
19473
+ CREATE TABLE IF NOT EXISTS availability_check_results (
19474
+ id uuid PRIMARY KEY,
19475
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
19476
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
19477
+ started_at timestamptz NOT NULL,
19478
+ completed_at timestamptz NOT NULL,
19479
+ duration_ms integer NOT NULL,
19480
+ status text NOT NULL,
19481
+ http_status integer,
19482
+ error_kind text,
19483
+ error_message text,
19484
+ redirect_count integer NOT NULL DEFAULT 0,
19485
+ checked_url_host text NOT NULL,
19486
+ checked_url_path text NOT NULL,
19487
+ final_url text NOT NULL,
19488
+ created_at timestamptz NOT NULL DEFAULT now()
19489
+ )
19490
+ `,
19491
+ `
19492
+ ALTER TABLE availability_check_results
19493
+ DROP CONSTRAINT IF EXISTS availability_check_results_status_check
19494
+ `,
19495
+ `
19496
+ ALTER TABLE availability_check_results
19497
+ ADD CONSTRAINT availability_check_results_status_check
19498
+ CHECK (
19499
+ status IN (
19500
+ 'success',
19501
+ 'http_status_mismatch',
19502
+ 'timeout',
19503
+ 'dns_error',
19504
+ 'tls_error',
19505
+ 'connection_error',
19506
+ 'redirect_blocked',
19507
+ 'security_blocked',
19508
+ 'internal_error'
19509
+ )
19510
+ )
19511
+ `,
19512
+ `
19513
+ CREATE INDEX IF NOT EXISTS availability_check_results_check_started_idx
19514
+ ON availability_check_results (check_id, started_at DESC)
19515
+ `,
19516
+ `
19517
+ CREATE INDEX IF NOT EXISTS availability_check_results_project_started_idx
19518
+ ON availability_check_results (project_id, started_at DESC)
19519
+ `,
19520
+ `
19521
+ CREATE TABLE IF NOT EXISTS availability_check_daily_rollups (
19522
+ id uuid PRIMARY KEY,
19523
+ check_id uuid NOT NULL REFERENCES availability_checks(id) ON DELETE CASCADE,
19524
+ project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
19525
+ day date NOT NULL,
19526
+ state text NOT NULL,
19527
+ total_checks integer NOT NULL DEFAULT 0,
19528
+ successful_checks integer NOT NULL DEFAULT 0,
19529
+ failed_checks integer NOT NULL DEFAULT 0,
19530
+ degraded_checks integer NOT NULL DEFAULT 0,
19531
+ avg_duration_ms integer,
19532
+ first_checked_at timestamptz,
19533
+ last_checked_at timestamptz,
19534
+ downtime_seconds integer NOT NULL DEFAULT 0,
19535
+ incident_ids uuid[] NOT NULL DEFAULT '{}'::uuid[],
19536
+ created_at timestamptz NOT NULL DEFAULT now(),
19537
+ updated_at timestamptz NOT NULL DEFAULT now(),
19538
+ UNIQUE (check_id, day)
19539
+ )
19540
+ `,
19541
+ `
19542
+ ALTER TABLE availability_check_daily_rollups
19543
+ DROP CONSTRAINT IF EXISTS availability_check_daily_rollups_state_check
19544
+ `,
19545
+ `
19546
+ ALTER TABLE availability_check_daily_rollups
19547
+ ADD CONSTRAINT availability_check_daily_rollups_state_check
19548
+ CHECK (state IN ('unknown', 'operational', 'degraded', 'down', 'paused'))
19549
+ `,
19550
+ `
19551
+ CREATE INDEX IF NOT EXISTS availability_check_daily_rollups_project_day_idx
19552
+ ON availability_check_daily_rollups (project_id, day DESC)
19553
+ `
19554
+ ]
19555
+ })
19556
+ ];
19557
+
19558
+ // ../../packages/storage/src/schema-migrations-catalog.ts
19559
+ var import_node_crypto3 = require("node:crypto");
19073
19560
  function computeMigrationChecksum(input2) {
19074
- return (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(input2)).digest("hex");
19561
+ return (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(input2)).digest("hex");
19075
19562
  }
19076
19563
  function defineStorageSchemaMigration(input2) {
19077
19564
  return {
@@ -19900,9 +20387,41 @@ var STORAGE_SCHEMA_MIGRATIONS = [
19900
20387
  ON account_payment_provider_events (provider, provider_event_id)
19901
20388
  `
19902
20389
  ]
20390
+ }),
20391
+ defineStorageSchemaMigration({
20392
+ id: "202606120001_add_session_auth_method",
20393
+ description: "Track the auth method used to create each browser session.",
20394
+ statements: [
20395
+ "ALTER TABLE sessions ADD COLUMN IF NOT EXISTS auth_method text",
20396
+ "ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_auth_method_check",
20397
+ `
20398
+ ALTER TABLE sessions
20399
+ ADD CONSTRAINT sessions_auth_method_check
20400
+ CHECK (auth_method IS NULL OR auth_method IN ('email_code', 'github_oauth'))
20401
+ `
20402
+ ]
20403
+ }),
20404
+ defineStorageSchemaMigration({
20405
+ id: "202606130001_retire_expired_project_invites",
20406
+ description: "Retire already-expired project invites so re-inviting the same email is unblocked.",
20407
+ statements: [
20408
+ `
20409
+ UPDATE project_invites
20410
+ SET canceled_at = expires_at
20411
+ WHERE accepted_at IS NULL
20412
+ AND canceled_at IS NULL
20413
+ AND expires_at <= now()
20414
+ `
20415
+ ]
19903
20416
  })
19904
20417
  ];
19905
20418
 
20419
+ // ../../packages/storage/src/schema-migrations.ts
20420
+ var STORAGE_SCHEMA_MIGRATIONS2 = [
20421
+ ...STORAGE_SCHEMA_MIGRATIONS,
20422
+ ...AVAILABILITY_CHECK_STORAGE_SCHEMA_MIGRATIONS
20423
+ ];
20424
+
19906
20425
  // src/local-retrieval-store.ts
19907
20426
  var CONNECTION_FILE_PATH2 = ".debugbundle/local/connection.json";
19908
20427
  var STATE_FILE_PATH = ".debugbundle/local/state.json";
@@ -23886,12 +24405,12 @@ async function doctorCommand(input2, dependencies = {}) {
23886
24405
  }
23887
24406
 
23888
24407
  // src/ingest-command.ts
23889
- var import_node_crypto5 = require("node:crypto");
24408
+ var import_node_crypto6 = require("node:crypto");
23890
24409
  var import_promises11 = require("node:fs/promises");
23891
24410
  var import_node_path12 = require("node:path");
23892
24411
 
23893
24412
  // ../../packages/log-parser/src/project-id.ts
23894
- var import_node_crypto3 = require("node:crypto");
24413
+ var import_node_crypto4 = require("node:crypto");
23895
24414
  var INGEST_SDK = {
23896
24415
  name: "debugbundle-ingest",
23897
24416
  version: "0.1.0"
@@ -23901,7 +24420,7 @@ function slugify(value) {
23901
24420
  return normalized.length > 0 ? normalized : "application";
23902
24421
  }
23903
24422
  function buildDeterministicUuid(parts) {
23904
- const digest = (0, import_node_crypto3.createHash)("sha256").update(parts.join("\0")).digest();
24423
+ const digest = (0, import_node_crypto4.createHash)("sha256").update(parts.join("\0")).digest();
23905
24424
  const bytes = Uint8Array.from(digest.subarray(0, 16));
23906
24425
  bytes[6] = (bytes[6] ?? 0) & 15 | 80;
23907
24426
  bytes[8] = (bytes[8] ?? 0) & 63 | 128;
@@ -24206,7 +24725,7 @@ function parseLogFile(content, input2) {
24206
24725
  }
24207
24726
 
24208
24727
  // src/process-command.ts
24209
- var import_node_crypto4 = require("node:crypto");
24728
+ var import_node_crypto5 = require("node:crypto");
24210
24729
  var import_promises10 = require("node:fs/promises");
24211
24730
  var import_node_path11 = require("node:path");
24212
24731
 
@@ -25380,7 +25899,7 @@ function mergeAggregateGroup(aggregates) {
25380
25899
  });
25381
25900
  }
25382
25901
  function hashIdentifier(parts, prefix, length) {
25383
- const digest = (0, import_node_crypto4.createHash)("sha256").update(parts.join("\0")).digest("hex");
25902
+ const digest = (0, import_node_crypto5.createHash)("sha256").update(parts.join("\0")).digest("hex");
25384
25903
  return `${prefix}_${digest.slice(0, length)}`;
25385
25904
  }
25386
25905
  function deriveIncidentId(projectId, serviceName, environment, incidentFingerprint) {
@@ -25414,7 +25933,7 @@ function stableJson3(value) {
25414
25933
  return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson3(record[key])}`).join(",")}}`;
25415
25934
  }
25416
25935
  function buildRequestAnomalyFingerprint(input2) {
25417
- return (0, import_node_crypto4.createHash)("sha256").update(
25936
+ return (0, import_node_crypto5.createHash)("sha256").update(
25418
25937
  stableJson3({
25419
25938
  kind: "request_status_anomaly",
25420
25939
  project_id: input2.projectId,
@@ -26048,7 +26567,7 @@ function buildEventFileName(events, filePath) {
26048
26567
  const candidate = Date.parse(event.occurred_at);
26049
26568
  return Number.isFinite(candidate) && candidate > latest ? candidate : latest;
26050
26569
  }, 0);
26051
- const digest = (0, import_node_crypto5.createHash)("sha256").update([filePath, ...events.map((event) => event.event_id)].join("\0")).digest("hex").slice(0, 8);
26570
+ const digest = (0, import_node_crypto6.createHash)("sha256").update([filePath, ...events.map((event) => event.event_id)].join("\0")).digest("hex").slice(0, 8);
26052
26571
  return `${lastOccurredAt}-${digest}-${slugify2(events[0]?.service.name ?? (0, import_node_path12.basename)(filePath))}.events.json`;
26053
26572
  }
26054
26573
  function formatHumanOutput(summary) {
@@ -28596,7 +29115,7 @@ async function listServicesWithAuthCommand(input2, dependencies) {
28596
29115
  }
28597
29116
 
28598
29117
  // src/verify-command.ts
28599
- var import_node_crypto6 = require("node:crypto");
29118
+ var import_node_crypto7 = require("node:crypto");
28600
29119
  var import_promises15 = require("node:fs/promises");
28601
29120
  var import_node_path17 = require("node:path");
28602
29121
  function resolveOverallStatus2(checks) {
@@ -28741,7 +29260,7 @@ function cloudVerificationRunId(now) {
28741
29260
  return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
28742
29261
  }
28743
29262
  function defaultCloudVerificationSuffix() {
28744
- return (0, import_node_crypto6.randomUUID)().replace(/-/g, "").slice(0, 12);
29263
+ return (0, import_node_crypto7.randomUUID)().replace(/-/g, "").slice(0, 12);
28745
29264
  }
28746
29265
  function normalizeCloudVerificationSuffix(suffix) {
28747
29266
  const normalized = suffix.toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 12);
@@ -29633,6 +30152,14 @@ var CLI_USAGE_LINES = [
29633
30152
  " debugbundle probe activate <project-id> --label-pattern <pattern> [--service <name>] [--environment <name>] [--ttl-seconds <n>] [--trigger-ttl-seconds <n>] [--auth-file <path>] [--json]",
29634
30153
  " debugbundle probe list <project-id> [--auth-file <path>] [--json]",
29635
30154
  " debugbundle probe deactivate <project-id> <activation-id> [--auth-file <path>] [--json]",
30155
+ " debugbundle health checks list --project-id <id> [--limit <n>] [--auth-file <path>] [--json]",
30156
+ " debugbundle health checks get <check-id> --project-id <id> [--auth-file <path>] [--json]",
30157
+ " debugbundle health checks create --project-id <id> --name <name> --url <url> --interval-seconds <n> [--method <GET|HEAD>] [--expected-status-min <code>] [--expected-status-max <code>] [--timeout-ms <n>] [--failure-threshold <n>] [--recovery-threshold <n>] [--environment <name>] [--service <name|null>] [--enabled <true|false>] [--auth-file <path>] [--json]",
30158
+ " debugbundle health checks update <check-id> --project-id <id> [--name <name>] [--url <url>] [--method <GET|HEAD>] [--expected-status-min <code>] [--expected-status-max <code>] [--timeout-ms <n>] [--interval-seconds <n>] [--failure-threshold <n>] [--recovery-threshold <n>] [--environment <name>] [--service <name|null>] [--enabled <true|false>] [--auth-file <path>] [--json]",
30159
+ " debugbundle health checks delete <check-id> --project-id <id> [--auth-file <path>] [--json]",
30160
+ " debugbundle health checks test --project-id <id> --url <url> [--method <GET|HEAD>] [--expected-status-min <code>] [--expected-status-max <code>] [--timeout-ms <n>] [--auth-file <path>] [--json]",
30161
+ " debugbundle health checks results <check-id> --project-id <id> [--limit <n>] [--auth-file <path>] [--json]",
30162
+ " debugbundle health checks daily-rollups <check-id> --project-id <id> [--limit <n>] [--auth-file <path>] [--json]",
29636
30163
  " debugbundle project members list --project-id <id> [--auth-file <path>] [--json]",
29637
30164
  " debugbundle project members invites --project-id <id> [--auth-file <path>] [--json]",
29638
30165
  " debugbundle project members invite --project-id <id> --email <email> --role <admin|member> [--auth-file <path>] [--json]",
@@ -32521,58 +33048,25 @@ async function handleTokenCommand(parsedArgv, dependencies) {
32521
33048
  throw new CliInputError("Unknown token command.");
32522
33049
  }
32523
33050
 
32524
- // src/capture-policy-commands.ts
32525
- var CapturePolicyApiError = class extends Error {
33051
+ // src/health-check-commands.ts
33052
+ var HealthCheckApiError = class extends Error {
32526
33053
  status;
32527
- constructor(status, message) {
32528
- super(message);
32529
- this.name = "CapturePolicyApiError";
33054
+ code;
33055
+ constructor(status, code) {
33056
+ super(`health_check_api_error: ${status}:${code}`);
33057
+ this.name = "HealthCheckApiError";
32530
33058
  this.status = status;
33059
+ this.code = code;
32531
33060
  }
32532
33061
  };
32533
- function toApiError3(status, body, fallback) {
33062
+ function toApiError3(status, body) {
32534
33063
  if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
32535
- return new CapturePolicyApiError(status, body.error);
33064
+ return new HealthCheckApiError(status, body.error);
32536
33065
  }
32537
- return new CapturePolicyApiError(status, fallback);
32538
- }
32539
- function createCapturePolicyApi(httpClient) {
32540
- return {
32541
- async getCapturePolicy(input2) {
32542
- const response = await httpClient.request({
32543
- method: "GET",
32544
- path: `/v1/projects/${encodeURIComponent(input2.projectId)}/capture-policy`,
32545
- bearerToken: input2.bearerToken
32546
- });
32547
- if (response.status !== 200) {
32548
- throw toApiError3(response.status, response.body, "Failed to get capture policy.");
32549
- }
32550
- const parsed = CapturePolicyResponseSchema.safeParse(response.body);
32551
- if (!parsed.success) {
32552
- throw new CapturePolicyApiError(500, "Invalid capture policy response.");
32553
- }
32554
- return parsed.data;
32555
- },
32556
- async updateCapturePolicy(input2) {
32557
- const response = await httpClient.request({
32558
- method: "PATCH",
32559
- path: `/v1/projects/${encodeURIComponent(input2.projectId)}/capture-policy`,
32560
- bearerToken: input2.bearerToken,
32561
- body: input2.update
32562
- });
32563
- if (response.status !== 200) {
32564
- throw toApiError3(response.status, response.body, "Failed to update capture policy.");
32565
- }
32566
- const parsed = CapturePolicyResponseSchema.safeParse(response.body);
32567
- if (!parsed.success) {
32568
- throw new CapturePolicyApiError(500, "Invalid capture policy response.");
32569
- }
32570
- return parsed.data;
32571
- }
32572
- };
33066
+ return new HealthCheckApiError(status, "unknown_error");
32573
33067
  }
32574
33068
  function mapErrorToExitCode11(error) {
32575
- if (!(error instanceof CapturePolicyApiError)) {
33069
+ if (!(error instanceof HealthCheckApiError)) {
32576
33070
  return 1;
32577
33071
  }
32578
33072
  if (error.status === 401) {
@@ -32584,31 +33078,816 @@ function mapErrorToExitCode11(error) {
32584
33078
  if (error.status === 400) {
32585
33079
  return 4;
32586
33080
  }
33081
+ if (error.status === 403 || error.status === 409) {
33082
+ return 5;
33083
+ }
33084
+ if (error.status === 429) {
33085
+ return 6;
33086
+ }
32587
33087
  return 1;
32588
33088
  }
32589
- function statusesEqual(left, right) {
32590
- if (left.length !== right.length) {
32591
- return false;
33089
+ function buildCreateRequestBody(input2) {
33090
+ const body = {
33091
+ name: input2.name,
33092
+ url: input2.url,
33093
+ method: input2.method,
33094
+ expected_status_min: input2.expectedStatusMin,
33095
+ expected_status_max: input2.expectedStatusMax,
33096
+ timeout_ms: input2.timeoutMs,
33097
+ interval_seconds: input2.intervalSeconds,
33098
+ failure_threshold: input2.failureThreshold,
33099
+ recovery_threshold: input2.recoveryThreshold,
33100
+ enabled: input2.enabled
33101
+ };
33102
+ if (input2.environment !== void 0) {
33103
+ body["environment"] = input2.environment;
32592
33104
  }
32593
- return left.every((value, index) => value === right[index]);
32594
- }
32595
- function formatStatusList(statuses) {
32596
- return statuses.length === 0 ? "none" : statuses.join(", ");
32597
- }
32598
- function formatClientErrorPathRules(response) {
32599
- const rawOverride = response.overrides.immediate_client_error_path_rules ?? null;
32600
- const rules = rawOverride ?? response.policy.immediate_client_error_path_rules ?? [];
32601
- if (rules.length === 0) {
32602
- return rawOverride === null ? "preset default (none)" : "none (explicit)";
33105
+ if (input2.serviceName !== void 0) {
33106
+ body["service_name"] = input2.serviceName;
32603
33107
  }
32604
- const formatted = rules.map((rule) => {
32605
- const methods = rule.methods.length === 0 ? "" : `@${rule.methods.join(",")}`;
32606
- return `${rule.status_code}=${rule.path_pattern}${methods}`;
32607
- });
32608
- return `${rawOverride === null ? "preset default" : "custom"} (${formatted.join("; ")})`;
33108
+ return body;
32609
33109
  }
32610
- function formatClientErrorIncidents(response) {
32611
- const rawOverride = response.overrides.immediate_client_error_statuses;
33110
+ function buildUpdateRequestBody(input2) {
33111
+ const body = {};
33112
+ if (input2.name !== void 0) {
33113
+ body["name"] = input2.name;
33114
+ }
33115
+ if (input2.url !== void 0) {
33116
+ body["url"] = input2.url;
33117
+ }
33118
+ if (input2.method !== void 0) {
33119
+ body["method"] = input2.method;
33120
+ }
33121
+ if (input2.expectedStatusMin !== void 0) {
33122
+ body["expected_status_min"] = input2.expectedStatusMin;
33123
+ }
33124
+ if (input2.expectedStatusMax !== void 0) {
33125
+ body["expected_status_max"] = input2.expectedStatusMax;
33126
+ }
33127
+ if (input2.timeoutMs !== void 0) {
33128
+ body["timeout_ms"] = input2.timeoutMs;
33129
+ }
33130
+ if (input2.intervalSeconds !== void 0) {
33131
+ body["interval_seconds"] = input2.intervalSeconds;
33132
+ }
33133
+ if (input2.failureThreshold !== void 0) {
33134
+ body["failure_threshold"] = input2.failureThreshold;
33135
+ }
33136
+ if (input2.recoveryThreshold !== void 0) {
33137
+ body["recovery_threshold"] = input2.recoveryThreshold;
33138
+ }
33139
+ if (input2.environment !== void 0) {
33140
+ body["environment"] = input2.environment;
33141
+ }
33142
+ if (input2.serviceName !== void 0) {
33143
+ body["service_name"] = input2.serviceName;
33144
+ }
33145
+ if (input2.enabled !== void 0) {
33146
+ body["enabled"] = input2.enabled;
33147
+ }
33148
+ return body;
33149
+ }
33150
+ function createHealthCheckApi(httpClient) {
33151
+ return {
33152
+ async listHealthChecks(input2) {
33153
+ const limit = input2.limit ?? 100;
33154
+ const response = await httpClient.request({
33155
+ method: "GET",
33156
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks?limit=${encodeURIComponent(String(limit))}`,
33157
+ bearerToken: input2.bearerToken
33158
+ });
33159
+ if (response.status !== 200) {
33160
+ throw toApiError3(response.status, response.body);
33161
+ }
33162
+ return response.body;
33163
+ },
33164
+ async getHealthCheck(input2) {
33165
+ const response = await httpClient.request({
33166
+ method: "GET",
33167
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/${encodeURIComponent(input2.checkId)}`,
33168
+ bearerToken: input2.bearerToken
33169
+ });
33170
+ if (response.status !== 200) {
33171
+ throw toApiError3(response.status, response.body);
33172
+ }
33173
+ return response.body;
33174
+ },
33175
+ async createHealthCheck(input2) {
33176
+ const response = await httpClient.request({
33177
+ method: "POST",
33178
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks`,
33179
+ bearerToken: input2.bearerToken,
33180
+ body: buildCreateRequestBody(input2)
33181
+ });
33182
+ if (response.status !== 201) {
33183
+ throw toApiError3(response.status, response.body);
33184
+ }
33185
+ return response.body;
33186
+ },
33187
+ async updateHealthCheck(input2) {
33188
+ const response = await httpClient.request({
33189
+ method: "PATCH",
33190
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/${encodeURIComponent(input2.checkId)}`,
33191
+ bearerToken: input2.bearerToken,
33192
+ body: buildUpdateRequestBody(input2)
33193
+ });
33194
+ if (response.status !== 200) {
33195
+ throw toApiError3(response.status, response.body);
33196
+ }
33197
+ return response.body;
33198
+ },
33199
+ async deleteHealthCheck(input2) {
33200
+ const response = await httpClient.request({
33201
+ method: "DELETE",
33202
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/${encodeURIComponent(input2.checkId)}`,
33203
+ bearerToken: input2.bearerToken
33204
+ });
33205
+ if (response.status !== 200) {
33206
+ throw toApiError3(response.status, response.body);
33207
+ }
33208
+ return response.body;
33209
+ },
33210
+ async testHealthCheck(input2) {
33211
+ const response = await httpClient.request({
33212
+ method: "POST",
33213
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/test`,
33214
+ bearerToken: input2.bearerToken,
33215
+ body: {
33216
+ url: input2.url,
33217
+ method: input2.method,
33218
+ expected_status_min: input2.expectedStatusMin,
33219
+ expected_status_max: input2.expectedStatusMax,
33220
+ timeout_ms: input2.timeoutMs
33221
+ }
33222
+ });
33223
+ if (response.status !== 200) {
33224
+ throw toApiError3(response.status, response.body);
33225
+ }
33226
+ return response.body;
33227
+ },
33228
+ async listHealthCheckResults(input2) {
33229
+ const limit = input2.limit ?? 20;
33230
+ const response = await httpClient.request({
33231
+ method: "GET",
33232
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/${encodeURIComponent(input2.checkId)}/results?limit=${encodeURIComponent(String(limit))}`,
33233
+ bearerToken: input2.bearerToken
33234
+ });
33235
+ if (response.status !== 200) {
33236
+ throw toApiError3(response.status, response.body);
33237
+ }
33238
+ return response.body;
33239
+ },
33240
+ async listHealthCheckDailyRollups(input2) {
33241
+ const limit = input2.limit ?? 30;
33242
+ const response = await httpClient.request({
33243
+ method: "GET",
33244
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/availability-checks/${encodeURIComponent(input2.checkId)}/daily-rollups?limit=${encodeURIComponent(String(limit))}`,
33245
+ bearerToken: input2.bearerToken
33246
+ });
33247
+ if (response.status !== 200) {
33248
+ throw toApiError3(response.status, response.body);
33249
+ }
33250
+ return response.body;
33251
+ }
33252
+ };
33253
+ }
33254
+ function formatServiceAndEnvironment(check) {
33255
+ return `${check.service_name ?? "availability"}/${check.environment}`;
33256
+ }
33257
+ function formatNullable(value) {
33258
+ return value === null ? "-" : String(value);
33259
+ }
33260
+ function formatCheckSummary(check) {
33261
+ const lastResult = check.last_result_status === null ? "no checks yet" : `${check.last_result_status}${check.last_result_http_status === null ? "" : ` ${check.last_result_http_status}`}`;
33262
+ return [
33263
+ `${check.check_id} ${check.name} [${check.status}]`,
33264
+ `${check.method} ${check.url}`,
33265
+ `interval=${check.interval_seconds}s timeout=${check.timeout_ms}ms expected=${check.expected_status_min}-${check.expected_status_max}`,
33266
+ `service=${formatServiceAndEnvironment(check)} enabled=${check.enabled ? "true" : "false"} last=${lastResult}`
33267
+ ].join("\n");
33268
+ }
33269
+ function formatCheckResultSummary(result) {
33270
+ return [
33271
+ `${result.started_at} ${result.status}`,
33272
+ `http=${formatNullable(result.http_status)} duration=${result.duration_ms}ms redirects=${result.redirect_count}`,
33273
+ `host=${result.checked_url_host} final=${result.final_url}`
33274
+ ].join(" ");
33275
+ }
33276
+ function formatCheckDailyRollupSummary(rollup) {
33277
+ return [
33278
+ `${rollup.day} ${rollup.state}`,
33279
+ `checks=${rollup.total_checks}`,
33280
+ `success=${rollup.successful_checks}`,
33281
+ `failed=${rollup.failed_checks}`,
33282
+ `degraded=${rollup.degraded_checks}`,
33283
+ `avg=${formatNullable(rollup.avg_duration_ms)}ms`,
33284
+ `downtime=${rollup.downtime_seconds}s`
33285
+ ].join(" ");
33286
+ }
33287
+ function formatTestResult(result) {
33288
+ return [
33289
+ `Test result: ${result.result.status}`,
33290
+ `http=${formatNullable(result.result.http_status)}`,
33291
+ `duration=${result.result.duration_ms}ms`,
33292
+ `host=${result.result.checked_url_host}`,
33293
+ `final=${result.result.final_url}`
33294
+ ].join(" ");
33295
+ }
33296
+ async function listHealthChecksCommand(input2, api) {
33297
+ try {
33298
+ const result = await api.listHealthChecks({
33299
+ bearerToken: input2.bearerToken,
33300
+ projectId: input2.projectId,
33301
+ ...input2.limit === void 0 ? {} : { limit: input2.limit }
33302
+ });
33303
+ if (input2.json) {
33304
+ return { exitCode: 0, output: JSON.stringify(result) };
33305
+ }
33306
+ if (result.checks.length === 0) {
33307
+ return {
33308
+ exitCode: 0,
33309
+ output: `No health checks.
33310
+ Plan limits: ${result.limits.max_checks_per_project} checks, minimum interval ${result.limits.min_interval_seconds}s.`
33311
+ };
33312
+ }
33313
+ return {
33314
+ exitCode: 0,
33315
+ output: result.checks.map(formatCheckSummary).join("\n\n")
33316
+ };
33317
+ } catch (error) {
33318
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33319
+ }
33320
+ }
33321
+ async function getHealthCheckCommand(input2, api) {
33322
+ try {
33323
+ const result = await api.getHealthCheck({
33324
+ bearerToken: input2.bearerToken,
33325
+ projectId: input2.projectId,
33326
+ checkId: input2.checkId
33327
+ });
33328
+ if (input2.json) {
33329
+ return { exitCode: 0, output: JSON.stringify(result) };
33330
+ }
33331
+ return {
33332
+ exitCode: 0,
33333
+ output: `${formatCheckSummary(result.check)}
33334
+ limits=${result.limits.max_checks_per_project} min_interval=${result.limits.min_interval_seconds}s`
33335
+ };
33336
+ } catch (error) {
33337
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33338
+ }
33339
+ }
33340
+ async function createHealthCheckCommand(input2, api) {
33341
+ try {
33342
+ const result = await api.createHealthCheck(input2);
33343
+ if (input2.json) {
33344
+ return { exitCode: 0, output: JSON.stringify(result) };
33345
+ }
33346
+ return {
33347
+ exitCode: 0,
33348
+ output: `Health check created: ${result.check.check_id} (${result.check.name})`
33349
+ };
33350
+ } catch (error) {
33351
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33352
+ }
33353
+ }
33354
+ async function updateHealthCheckCommand(input2, api) {
33355
+ try {
33356
+ const result = await api.updateHealthCheck(input2);
33357
+ if (input2.json) {
33358
+ return { exitCode: 0, output: JSON.stringify(result) };
33359
+ }
33360
+ return {
33361
+ exitCode: 0,
33362
+ output: `Health check updated: ${result.check.check_id} (${result.check.name})`
33363
+ };
33364
+ } catch (error) {
33365
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33366
+ }
33367
+ }
33368
+ async function deleteHealthCheckCommand(input2, api) {
33369
+ try {
33370
+ const result = await api.deleteHealthCheck({
33371
+ bearerToken: input2.bearerToken,
33372
+ projectId: input2.projectId,
33373
+ checkId: input2.checkId
33374
+ });
33375
+ if (input2.json) {
33376
+ return { exitCode: 0, output: JSON.stringify(result) };
33377
+ }
33378
+ return {
33379
+ exitCode: 0,
33380
+ output: result.deleted ? "Health check deleted." : "Health check was already deleted."
33381
+ };
33382
+ } catch (error) {
33383
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33384
+ }
33385
+ }
33386
+ async function testHealthCheckCommand(input2, api) {
33387
+ try {
33388
+ const result = await api.testHealthCheck(input2);
33389
+ if (input2.json) {
33390
+ return { exitCode: 0, output: JSON.stringify(result) };
33391
+ }
33392
+ return {
33393
+ exitCode: 0,
33394
+ output: formatTestResult(result)
33395
+ };
33396
+ } catch (error) {
33397
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33398
+ }
33399
+ }
33400
+ async function listHealthCheckResultsCommand(input2, api) {
33401
+ try {
33402
+ const result = await api.listHealthCheckResults({
33403
+ bearerToken: input2.bearerToken,
33404
+ projectId: input2.projectId,
33405
+ checkId: input2.checkId,
33406
+ ...input2.limit === void 0 ? {} : { limit: input2.limit }
33407
+ });
33408
+ if (input2.json) {
33409
+ return { exitCode: 0, output: JSON.stringify(result) };
33410
+ }
33411
+ if (result.results.length === 0) {
33412
+ return { exitCode: 0, output: "No health check results." };
33413
+ }
33414
+ return {
33415
+ exitCode: 0,
33416
+ output: result.results.map(formatCheckResultSummary).join("\n")
33417
+ };
33418
+ } catch (error) {
33419
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33420
+ }
33421
+ }
33422
+ async function listHealthCheckDailyRollupsCommand(input2, api) {
33423
+ try {
33424
+ const result = await api.listHealthCheckDailyRollups({
33425
+ bearerToken: input2.bearerToken,
33426
+ projectId: input2.projectId,
33427
+ checkId: input2.checkId,
33428
+ ...input2.limit === void 0 ? {} : { limit: input2.limit }
33429
+ });
33430
+ if (input2.json) {
33431
+ return { exitCode: 0, output: JSON.stringify(result) };
33432
+ }
33433
+ if (result.rollups.length === 0) {
33434
+ return { exitCode: 0, output: "No health check daily rollups." };
33435
+ }
33436
+ return {
33437
+ exitCode: 0,
33438
+ output: result.rollups.map(formatCheckDailyRollupSummary).join("\n")
33439
+ };
33440
+ } catch (error) {
33441
+ return { exitCode: mapErrorToExitCode11(error), output: error instanceof Error ? error.message : String(error) };
33442
+ }
33443
+ }
33444
+ async function createAuthenticatedHealthCheckApi(input2, dependencies) {
33445
+ const readAuth = dependencies?.readAuthState ?? readCliAuthState;
33446
+ const authStateInput = {};
33447
+ if (input2.authFilePath !== void 0) {
33448
+ authStateInput.authFilePath = input2.authFilePath;
33449
+ }
33450
+ const authState = await readAuth(authStateInput);
33451
+ const createHttpClient = dependencies?.createHttpClient ?? ((clientInput) => createCliHttpClient(clientInput));
33452
+ const httpClient = createHttpClient({ baseUrl: authState.base_url });
33453
+ const createApi = dependencies?.createApi ?? createHealthCheckApi;
33454
+ return { authState, api: createApi(httpClient) };
33455
+ }
33456
+ async function listHealthChecksWithAuthCommand(input2, dependencies) {
33457
+ return runAuthenticatedCliCommand(input2, {
33458
+ createApi: createAuthenticatedHealthCheckApi,
33459
+ dependencies,
33460
+ runCommand: (authState, api) => listHealthChecksCommand(
33461
+ {
33462
+ bearerToken: authState.bearer_token,
33463
+ projectId: input2.projectId,
33464
+ ...input2.limit === void 0 ? {} : { limit: input2.limit },
33465
+ ...input2.json === void 0 ? {} : { json: input2.json }
33466
+ },
33467
+ { listHealthChecks: (requestInput) => api.listHealthChecks(requestInput) }
33468
+ )
33469
+ });
33470
+ }
33471
+ async function getHealthCheckWithAuthCommand(input2, dependencies) {
33472
+ return runAuthenticatedCliCommand(input2, {
33473
+ createApi: createAuthenticatedHealthCheckApi,
33474
+ dependencies,
33475
+ runCommand: (authState, api) => getHealthCheckCommand(
33476
+ {
33477
+ bearerToken: authState.bearer_token,
33478
+ projectId: input2.projectId,
33479
+ checkId: input2.checkId,
33480
+ ...input2.json === void 0 ? {} : { json: input2.json }
33481
+ },
33482
+ { getHealthCheck: (requestInput) => api.getHealthCheck(requestInput) }
33483
+ )
33484
+ });
33485
+ }
33486
+ async function createHealthCheckWithAuthCommand(input2, dependencies) {
33487
+ return runAuthenticatedCliCommand(input2, {
33488
+ createApi: createAuthenticatedHealthCheckApi,
33489
+ dependencies,
33490
+ runCommand: (authState, api) => {
33491
+ const commandInput = {
33492
+ ...input2,
33493
+ bearerToken: authState.bearer_token
33494
+ };
33495
+ return createHealthCheckCommand(commandInput, {
33496
+ createHealthCheck: (requestInput) => api.createHealthCheck(requestInput)
33497
+ });
33498
+ }
33499
+ });
33500
+ }
33501
+ async function updateHealthCheckWithAuthCommand(input2, dependencies) {
33502
+ return runAuthenticatedCliCommand(input2, {
33503
+ createApi: createAuthenticatedHealthCheckApi,
33504
+ dependencies,
33505
+ runCommand: (authState, api) => {
33506
+ const commandInput = {
33507
+ ...input2,
33508
+ bearerToken: authState.bearer_token
33509
+ };
33510
+ return updateHealthCheckCommand(commandInput, {
33511
+ updateHealthCheck: (requestInput) => api.updateHealthCheck(requestInput)
33512
+ });
33513
+ }
33514
+ });
33515
+ }
33516
+ async function deleteHealthCheckWithAuthCommand(input2, dependencies) {
33517
+ return runAuthenticatedCliCommand(input2, {
33518
+ createApi: createAuthenticatedHealthCheckApi,
33519
+ dependencies,
33520
+ runCommand: (authState, api) => deleteHealthCheckCommand(
33521
+ {
33522
+ bearerToken: authState.bearer_token,
33523
+ projectId: input2.projectId,
33524
+ checkId: input2.checkId,
33525
+ ...input2.json === void 0 ? {} : { json: input2.json }
33526
+ },
33527
+ { deleteHealthCheck: (requestInput) => api.deleteHealthCheck(requestInput) }
33528
+ )
33529
+ });
33530
+ }
33531
+ async function testHealthCheckWithAuthCommand(input2, dependencies) {
33532
+ return runAuthenticatedCliCommand(input2, {
33533
+ createApi: createAuthenticatedHealthCheckApi,
33534
+ dependencies,
33535
+ runCommand: (authState, api) => {
33536
+ const commandInput = {
33537
+ ...input2,
33538
+ bearerToken: authState.bearer_token
33539
+ };
33540
+ return testHealthCheckCommand(commandInput, {
33541
+ testHealthCheck: (requestInput) => api.testHealthCheck(requestInput)
33542
+ });
33543
+ }
33544
+ });
33545
+ }
33546
+ async function listHealthCheckResultsWithAuthCommand(input2, dependencies) {
33547
+ return runAuthenticatedCliCommand(input2, {
33548
+ createApi: createAuthenticatedHealthCheckApi,
33549
+ dependencies,
33550
+ runCommand: (authState, api) => listHealthCheckResultsCommand(
33551
+ {
33552
+ bearerToken: authState.bearer_token,
33553
+ projectId: input2.projectId,
33554
+ checkId: input2.checkId,
33555
+ ...input2.limit === void 0 ? {} : { limit: input2.limit },
33556
+ ...input2.json === void 0 ? {} : { json: input2.json }
33557
+ },
33558
+ { listHealthCheckResults: (requestInput) => api.listHealthCheckResults(requestInput) }
33559
+ )
33560
+ });
33561
+ }
33562
+ async function listHealthCheckDailyRollupsWithAuthCommand(input2, dependencies) {
33563
+ return runAuthenticatedCliCommand(input2, {
33564
+ createApi: createAuthenticatedHealthCheckApi,
33565
+ dependencies,
33566
+ runCommand: (authState, api) => listHealthCheckDailyRollupsCommand(
33567
+ {
33568
+ bearerToken: authState.bearer_token,
33569
+ projectId: input2.projectId,
33570
+ checkId: input2.checkId,
33571
+ ...input2.limit === void 0 ? {} : { limit: input2.limit },
33572
+ ...input2.json === void 0 ? {} : { json: input2.json }
33573
+ },
33574
+ { listHealthCheckDailyRollups: (requestInput) => api.listHealthCheckDailyRollups(requestInput) }
33575
+ )
33576
+ });
33577
+ }
33578
+
33579
+ // src/management-health-command-handlers.ts
33580
+ function readOptionalServiceName(parsedArgv) {
33581
+ const service = readStringOption(parsedArgv, "service");
33582
+ if (service === void 0) {
33583
+ return void 0;
33584
+ }
33585
+ return service === "null" ? null : service;
33586
+ }
33587
+ function readRequiredProjectId(parsedArgv) {
33588
+ const projectId = readStringOption(parsedArgv, "project-id");
33589
+ if (projectId === void 0) {
33590
+ throw new CliInputError("Missing required option --project-id.");
33591
+ }
33592
+ return projectId;
33593
+ }
33594
+ function readRequiredUrl(parsedArgv) {
33595
+ const url = readStringOption(parsedArgv, "url");
33596
+ if (url === void 0) {
33597
+ throw new CliInputError("Missing required option --url.");
33598
+ }
33599
+ return url;
33600
+ }
33601
+ function readRequiredName(parsedArgv) {
33602
+ const name = readStringOption(parsedArgv, "name");
33603
+ if (name === void 0) {
33604
+ throw new CliInputError("Missing required option --name.");
33605
+ }
33606
+ return name;
33607
+ }
33608
+ async function handleHealthCommand(parsedArgv, dependencies) {
33609
+ const resource = requirePositional(parsedArgv, 1, "resource");
33610
+ if (resource !== "checks") {
33611
+ throw new CliInputError("Unknown health command.");
33612
+ }
33613
+ const action = requirePositional(parsedArgv, 2, "action");
33614
+ if (action === "list") {
33615
+ expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id", "limit"]);
33616
+ ensureNoExtraPositionals(parsedArgv, 3);
33617
+ const limit = readLimitOption(parsedArgv);
33618
+ return await (dependencies.listHealthChecksCommand ?? listHealthChecksWithAuthCommand)(
33619
+ appendCommonAuthOptions(parsedArgv, {
33620
+ projectId: readRequiredProjectId(parsedArgv),
33621
+ ...limit === void 0 ? {} : { limit }
33622
+ })
33623
+ );
33624
+ }
33625
+ if (action === "get") {
33626
+ expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id"]);
33627
+ ensureNoExtraPositionals(parsedArgv, 4);
33628
+ return await (dependencies.getHealthCheckCommand ?? getHealthCheckWithAuthCommand)(
33629
+ appendCommonAuthOptions(parsedArgv, {
33630
+ projectId: readRequiredProjectId(parsedArgv),
33631
+ checkId: requirePositional(parsedArgv, 3, "check-id")
33632
+ })
33633
+ );
33634
+ }
33635
+ if (action === "create") {
33636
+ expectNoUnknownOptions(parsedArgv, [
33637
+ "auth-file",
33638
+ "json",
33639
+ "project-id",
33640
+ "name",
33641
+ "url",
33642
+ "method",
33643
+ "expected-status-min",
33644
+ "expected-status-max",
33645
+ "timeout-ms",
33646
+ "interval-seconds",
33647
+ "failure-threshold",
33648
+ "recovery-threshold",
33649
+ "environment",
33650
+ "service",
33651
+ "enabled"
33652
+ ]);
33653
+ ensureNoExtraPositionals(parsedArgv, 3);
33654
+ const intervalSeconds = readIntegerOption(parsedArgv, "interval-seconds");
33655
+ if (intervalSeconds === void 0) {
33656
+ throw new CliInputError("Missing required option --interval-seconds.");
33657
+ }
33658
+ const method = readStringOption(parsedArgv, "method") ?? "GET";
33659
+ if (method !== "GET" && method !== "HEAD") {
33660
+ throw new CliInputError("Invalid value for --method.");
33661
+ }
33662
+ const enabled = readBooleanStringOption(parsedArgv, "enabled") ?? true;
33663
+ const environment = readStringOption(parsedArgv, "environment");
33664
+ const serviceName = readOptionalServiceName(parsedArgv);
33665
+ return await (dependencies.createHealthCheckCommand ?? createHealthCheckWithAuthCommand)(
33666
+ appendCommonAuthOptions(parsedArgv, {
33667
+ projectId: readRequiredProjectId(parsedArgv),
33668
+ name: readRequiredName(parsedArgv),
33669
+ url: readRequiredUrl(parsedArgv),
33670
+ method,
33671
+ expectedStatusMin: readIntegerOption(parsedArgv, "expected-status-min") ?? 200,
33672
+ expectedStatusMax: readIntegerOption(parsedArgv, "expected-status-max") ?? 399,
33673
+ timeoutMs: readIntegerOption(parsedArgv, "timeout-ms") ?? 5e3,
33674
+ intervalSeconds,
33675
+ failureThreshold: readIntegerOption(parsedArgv, "failure-threshold") ?? 3,
33676
+ recoveryThreshold: readIntegerOption(parsedArgv, "recovery-threshold") ?? 2,
33677
+ ...environment === void 0 ? {} : { environment },
33678
+ ...serviceName === void 0 ? {} : { serviceName },
33679
+ enabled
33680
+ })
33681
+ );
33682
+ }
33683
+ if (action === "update") {
33684
+ expectNoUnknownOptions(parsedArgv, [
33685
+ "auth-file",
33686
+ "json",
33687
+ "project-id",
33688
+ "name",
33689
+ "url",
33690
+ "method",
33691
+ "expected-status-min",
33692
+ "expected-status-max",
33693
+ "timeout-ms",
33694
+ "interval-seconds",
33695
+ "failure-threshold",
33696
+ "recovery-threshold",
33697
+ "environment",
33698
+ "service",
33699
+ "enabled"
33700
+ ]);
33701
+ ensureNoExtraPositionals(parsedArgv, 4);
33702
+ const method = readStringOption(parsedArgv, "method");
33703
+ if (method !== void 0 && method !== "GET" && method !== "HEAD") {
33704
+ throw new CliInputError("Invalid value for --method.");
33705
+ }
33706
+ const input2 = appendCommonAuthOptions(parsedArgv, {
33707
+ projectId: readRequiredProjectId(parsedArgv),
33708
+ checkId: requirePositional(parsedArgv, 3, "check-id")
33709
+ });
33710
+ const name = readStringOption(parsedArgv, "name");
33711
+ const url = readStringOption(parsedArgv, "url");
33712
+ const expectedStatusMin = readIntegerOption(parsedArgv, "expected-status-min");
33713
+ const expectedStatusMax = readIntegerOption(parsedArgv, "expected-status-max");
33714
+ const timeoutMs = readIntegerOption(parsedArgv, "timeout-ms");
33715
+ const intervalSeconds = readIntegerOption(parsedArgv, "interval-seconds");
33716
+ const failureThreshold = readIntegerOption(parsedArgv, "failure-threshold");
33717
+ const recoveryThreshold = readIntegerOption(parsedArgv, "recovery-threshold");
33718
+ const environment = readStringOption(parsedArgv, "environment");
33719
+ const serviceName = readOptionalServiceName(parsedArgv);
33720
+ const enabled = readBooleanStringOption(parsedArgv, "enabled");
33721
+ if (name !== void 0) input2.name = name;
33722
+ if (url !== void 0) input2.url = url;
33723
+ if (method !== void 0) input2.method = method;
33724
+ if (expectedStatusMin !== void 0) input2.expectedStatusMin = expectedStatusMin;
33725
+ if (expectedStatusMax !== void 0) input2.expectedStatusMax = expectedStatusMax;
33726
+ if (timeoutMs !== void 0) input2.timeoutMs = timeoutMs;
33727
+ if (intervalSeconds !== void 0) input2.intervalSeconds = intervalSeconds;
33728
+ if (failureThreshold !== void 0) input2.failureThreshold = failureThreshold;
33729
+ if (recoveryThreshold !== void 0) input2.recoveryThreshold = recoveryThreshold;
33730
+ if (environment !== void 0) input2.environment = environment;
33731
+ if (serviceName !== void 0) input2.serviceName = serviceName;
33732
+ if (enabled !== void 0) input2.enabled = enabled;
33733
+ const hasChanges = name !== void 0 || url !== void 0 || method !== void 0 || expectedStatusMin !== void 0 || expectedStatusMax !== void 0 || timeoutMs !== void 0 || intervalSeconds !== void 0 || failureThreshold !== void 0 || recoveryThreshold !== void 0 || environment !== void 0 || serviceName !== void 0 || enabled !== void 0;
33734
+ if (!hasChanges) {
33735
+ throw new CliInputError("At least one health-check field must be provided.");
33736
+ }
33737
+ return await (dependencies.updateHealthCheckCommand ?? updateHealthCheckWithAuthCommand)(input2);
33738
+ }
33739
+ if (action === "delete") {
33740
+ expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id"]);
33741
+ ensureNoExtraPositionals(parsedArgv, 4);
33742
+ return await (dependencies.deleteHealthCheckCommand ?? deleteHealthCheckWithAuthCommand)(
33743
+ appendCommonAuthOptions(parsedArgv, {
33744
+ projectId: readRequiredProjectId(parsedArgv),
33745
+ checkId: requirePositional(parsedArgv, 3, "check-id")
33746
+ })
33747
+ );
33748
+ }
33749
+ if (action === "test") {
33750
+ expectNoUnknownOptions(parsedArgv, [
33751
+ "auth-file",
33752
+ "json",
33753
+ "project-id",
33754
+ "url",
33755
+ "method",
33756
+ "expected-status-min",
33757
+ "expected-status-max",
33758
+ "timeout-ms"
33759
+ ]);
33760
+ ensureNoExtraPositionals(parsedArgv, 3);
33761
+ const method = readStringOption(parsedArgv, "method") ?? "GET";
33762
+ if (method !== "GET" && method !== "HEAD") {
33763
+ throw new CliInputError("Invalid value for --method.");
33764
+ }
33765
+ return await (dependencies.testHealthCheckCommand ?? testHealthCheckWithAuthCommand)(
33766
+ appendCommonAuthOptions(parsedArgv, {
33767
+ projectId: readRequiredProjectId(parsedArgv),
33768
+ url: readRequiredUrl(parsedArgv),
33769
+ method,
33770
+ expectedStatusMin: readIntegerOption(parsedArgv, "expected-status-min") ?? 200,
33771
+ expectedStatusMax: readIntegerOption(parsedArgv, "expected-status-max") ?? 399,
33772
+ timeoutMs: readIntegerOption(parsedArgv, "timeout-ms") ?? 5e3
33773
+ })
33774
+ );
33775
+ }
33776
+ if (action === "results") {
33777
+ expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id", "limit"]);
33778
+ ensureNoExtraPositionals(parsedArgv, 4);
33779
+ const limit = readLimitOption(parsedArgv);
33780
+ return await (dependencies.listHealthCheckResultsCommand ?? listHealthCheckResultsWithAuthCommand)(
33781
+ appendCommonAuthOptions(parsedArgv, {
33782
+ projectId: readRequiredProjectId(parsedArgv),
33783
+ checkId: requirePositional(parsedArgv, 3, "check-id"),
33784
+ ...limit === void 0 ? {} : { limit }
33785
+ })
33786
+ );
33787
+ }
33788
+ if (action === "daily-rollups") {
33789
+ expectNoUnknownOptions(parsedArgv, ["auth-file", "json", "project-id", "limit"]);
33790
+ ensureNoExtraPositionals(parsedArgv, 4);
33791
+ const limit = readLimitOption(parsedArgv);
33792
+ return await (dependencies.listHealthCheckDailyRollupsCommand ?? listHealthCheckDailyRollupsWithAuthCommand)(
33793
+ appendCommonAuthOptions(parsedArgv, {
33794
+ projectId: readRequiredProjectId(parsedArgv),
33795
+ checkId: requirePositional(parsedArgv, 3, "check-id"),
33796
+ ...limit === void 0 ? {} : { limit }
33797
+ })
33798
+ );
33799
+ }
33800
+ throw new CliInputError("Unknown health checks command.");
33801
+ }
33802
+
33803
+ // src/capture-policy-commands.ts
33804
+ var CapturePolicyApiError = class extends Error {
33805
+ status;
33806
+ constructor(status, message) {
33807
+ super(message);
33808
+ this.name = "CapturePolicyApiError";
33809
+ this.status = status;
33810
+ }
33811
+ };
33812
+ function toApiError4(status, body, fallback) {
33813
+ if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
33814
+ return new CapturePolicyApiError(status, body.error);
33815
+ }
33816
+ return new CapturePolicyApiError(status, fallback);
33817
+ }
33818
+ function createCapturePolicyApi(httpClient) {
33819
+ return {
33820
+ async getCapturePolicy(input2) {
33821
+ const response = await httpClient.request({
33822
+ method: "GET",
33823
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/capture-policy`,
33824
+ bearerToken: input2.bearerToken
33825
+ });
33826
+ if (response.status !== 200) {
33827
+ throw toApiError4(response.status, response.body, "Failed to get capture policy.");
33828
+ }
33829
+ const parsed = CapturePolicyResponseSchema.safeParse(response.body);
33830
+ if (!parsed.success) {
33831
+ throw new CapturePolicyApiError(500, "Invalid capture policy response.");
33832
+ }
33833
+ return parsed.data;
33834
+ },
33835
+ async updateCapturePolicy(input2) {
33836
+ const response = await httpClient.request({
33837
+ method: "PATCH",
33838
+ path: `/v1/projects/${encodeURIComponent(input2.projectId)}/capture-policy`,
33839
+ bearerToken: input2.bearerToken,
33840
+ body: input2.update
33841
+ });
33842
+ if (response.status !== 200) {
33843
+ throw toApiError4(response.status, response.body, "Failed to update capture policy.");
33844
+ }
33845
+ const parsed = CapturePolicyResponseSchema.safeParse(response.body);
33846
+ if (!parsed.success) {
33847
+ throw new CapturePolicyApiError(500, "Invalid capture policy response.");
33848
+ }
33849
+ return parsed.data;
33850
+ }
33851
+ };
33852
+ }
33853
+ function mapErrorToExitCode12(error) {
33854
+ if (!(error instanceof CapturePolicyApiError)) {
33855
+ return 1;
33856
+ }
33857
+ if (error.status === 401) {
33858
+ return 2;
33859
+ }
33860
+ if (error.status === 404) {
33861
+ return 3;
33862
+ }
33863
+ if (error.status === 400) {
33864
+ return 4;
33865
+ }
33866
+ return 1;
33867
+ }
33868
+ function statusesEqual(left, right) {
33869
+ if (left.length !== right.length) {
33870
+ return false;
33871
+ }
33872
+ return left.every((value, index) => value === right[index]);
33873
+ }
33874
+ function formatStatusList(statuses) {
33875
+ return statuses.length === 0 ? "none" : statuses.join(", ");
33876
+ }
33877
+ function formatClientErrorPathRules(response) {
33878
+ const rawOverride = response.overrides.immediate_client_error_path_rules ?? null;
33879
+ const rules = rawOverride ?? response.policy.immediate_client_error_path_rules ?? [];
33880
+ if (rules.length === 0) {
33881
+ return rawOverride === null ? "preset default (none)" : "none (explicit)";
33882
+ }
33883
+ const formatted = rules.map((rule) => {
33884
+ const methods = rule.methods.length === 0 ? "" : `@${rule.methods.join(",")}`;
33885
+ return `${rule.status_code}=${rule.path_pattern}${methods}`;
33886
+ });
33887
+ return `${rawOverride === null ? "preset default" : "custom"} (${formatted.join("; ")})`;
33888
+ }
33889
+ function formatClientErrorIncidents(response) {
33890
+ const rawOverride = response.overrides.immediate_client_error_statuses;
32612
33891
  if (rawOverride === null) {
32613
33892
  return `preset default (${formatStatusList(response.policy.immediate_client_error_statuses)})`;
32614
33893
  }
@@ -32644,7 +33923,7 @@ async function getCapturePolicyCommand(input2, api) {
32644
33923
  };
32645
33924
  } catch (error) {
32646
33925
  return {
32647
- exitCode: mapErrorToExitCode11(error),
33926
+ exitCode: mapErrorToExitCode12(error),
32648
33927
  output: error instanceof Error ? error.message : String(error)
32649
33928
  };
32650
33929
  }
@@ -32670,7 +33949,7 @@ ${formatPolicy(response)}`
32670
33949
  };
32671
33950
  } catch (error) {
32672
33951
  return {
32673
- exitCode: mapErrorToExitCode11(error),
33952
+ exitCode: mapErrorToExitCode12(error),
32674
33953
  output: error instanceof Error ? error.message : String(error)
32675
33954
  };
32676
33955
  }
@@ -32743,7 +34022,7 @@ var CaptureRuleApiError = class extends Error {
32743
34022
  this.status = status;
32744
34023
  }
32745
34024
  };
32746
- function toApiError4(status, body, fallback) {
34025
+ function toApiError5(status, body, fallback) {
32747
34026
  if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
32748
34027
  return new CaptureRuleApiError(status, body.error);
32749
34028
  }
@@ -32758,7 +34037,7 @@ function createCaptureRuleApi(httpClient) {
32758
34037
  bearerToken: input2.bearerToken
32759
34038
  });
32760
34039
  if (response.status !== 200) {
32761
- throw toApiError4(response.status, response.body, "Failed to list capture rules.");
34040
+ throw toApiError5(response.status, response.body, "Failed to list capture rules.");
32762
34041
  }
32763
34042
  const parsed = CaptureRulesResponseSchema.safeParse(response.body);
32764
34043
  if (!parsed.success) {
@@ -32774,7 +34053,7 @@ function createCaptureRuleApi(httpClient) {
32774
34053
  body: input2.create
32775
34054
  });
32776
34055
  if (response.status !== 201) {
32777
- throw toApiError4(response.status, response.body, "Failed to create capture rule.");
34056
+ throw toApiError5(response.status, response.body, "Failed to create capture rule.");
32778
34057
  }
32779
34058
  const parsed = CaptureRuleResponseSchema.safeParse(response.body);
32780
34059
  if (!parsed.success) {
@@ -32789,7 +34068,7 @@ function createCaptureRuleApi(httpClient) {
32789
34068
  bearerToken: input2.bearerToken
32790
34069
  });
32791
34070
  if (response.status !== 200) {
32792
- throw toApiError4(response.status, response.body, "Failed to suggest capture rules.");
34071
+ throw toApiError5(response.status, response.body, "Failed to suggest capture rules.");
32793
34072
  }
32794
34073
  const parsed = CaptureRuleSuggestionsResponseSchema.safeParse(response.body);
32795
34074
  if (!parsed.success) {
@@ -32805,7 +34084,7 @@ function createCaptureRuleApi(httpClient) {
32805
34084
  body: input2.create
32806
34085
  });
32807
34086
  if (response.status !== 201) {
32808
- throw toApiError4(response.status, response.body, "Failed to create capture rule from suggestion.");
34087
+ throw toApiError5(response.status, response.body, "Failed to create capture rule from suggestion.");
32809
34088
  }
32810
34089
  const parsed = CaptureRuleResponseSchema.safeParse(response.body);
32811
34090
  if (!parsed.success) {
@@ -32821,7 +34100,7 @@ function createCaptureRuleApi(httpClient) {
32821
34100
  body: input2.update
32822
34101
  });
32823
34102
  if (response.status !== 200) {
32824
- throw toApiError4(response.status, response.body, "Failed to update capture rule.");
34103
+ throw toApiError5(response.status, response.body, "Failed to update capture rule.");
32825
34104
  }
32826
34105
  const parsed = CaptureRuleResponseSchema.safeParse(response.body);
32827
34106
  if (!parsed.success) {
@@ -32836,7 +34115,7 @@ function createCaptureRuleApi(httpClient) {
32836
34115
  bearerToken: input2.bearerToken
32837
34116
  });
32838
34117
  if (response.status !== 200) {
32839
- throw toApiError4(response.status, response.body, "Failed to delete capture rule.");
34118
+ throw toApiError5(response.status, response.body, "Failed to delete capture rule.");
32840
34119
  }
32841
34120
  if (typeof response.body !== "object" || response.body === null || !("success" in response.body) || response.body.success !== true) {
32842
34121
  throw new CaptureRuleApiError(500, "Invalid capture rule delete response.");
@@ -32845,7 +34124,7 @@ function createCaptureRuleApi(httpClient) {
32845
34124
  }
32846
34125
  };
32847
34126
  }
32848
- function mapErrorToExitCode12(error) {
34127
+ function mapErrorToExitCode13(error) {
32849
34128
  if (!(error instanceof CaptureRuleApiError)) {
32850
34129
  return 1;
32851
34130
  }
@@ -32969,7 +34248,7 @@ async function listCaptureRulesCommand(input2, api) {
32969
34248
  };
32970
34249
  } catch (error) {
32971
34250
  return {
32972
- exitCode: mapErrorToExitCode12(error),
34251
+ exitCode: mapErrorToExitCode13(error),
32973
34252
  output: error instanceof Error ? error.message : String(error)
32974
34253
  };
32975
34254
  }
@@ -32995,7 +34274,7 @@ ${formatRule(response.rule)}`
32995
34274
  };
32996
34275
  } catch (error) {
32997
34276
  return {
32998
- exitCode: mapErrorToExitCode12(error),
34277
+ exitCode: mapErrorToExitCode13(error),
32999
34278
  output: error instanceof Error ? error.message : String(error)
33000
34279
  };
33001
34280
  }
@@ -33012,7 +34291,7 @@ async function suggestCaptureRulesFromIncidentCommand(input2, api) {
33012
34291
  };
33013
34292
  } catch (error) {
33014
34293
  return {
33015
- exitCode: mapErrorToExitCode12(error),
34294
+ exitCode: mapErrorToExitCode13(error),
33016
34295
  output: error instanceof Error ? error.message : String(error)
33017
34296
  };
33018
34297
  }
@@ -33038,7 +34317,7 @@ ${formatRule(response.rule)}`
33038
34317
  };
33039
34318
  } catch (error) {
33040
34319
  return {
33041
- exitCode: mapErrorToExitCode12(error),
34320
+ exitCode: mapErrorToExitCode13(error),
33042
34321
  output: error instanceof Error ? error.message : String(error)
33043
34322
  };
33044
34323
  }
@@ -33065,7 +34344,7 @@ ${formatRule(response.rule)}`
33065
34344
  };
33066
34345
  } catch (error) {
33067
34346
  return {
33068
- exitCode: mapErrorToExitCode12(error),
34347
+ exitCode: mapErrorToExitCode13(error),
33069
34348
  output: error instanceof Error ? error.message : String(error)
33070
34349
  };
33071
34350
  }
@@ -33083,7 +34362,7 @@ async function deleteCaptureRuleCommand(input2, api) {
33083
34362
  };
33084
34363
  } catch (error) {
33085
34364
  return {
33086
- exitCode: mapErrorToExitCode12(error),
34365
+ exitCode: mapErrorToExitCode13(error),
33087
34366
  output: error instanceof Error ? error.message : String(error)
33088
34367
  };
33089
34368
  }
@@ -33210,7 +34489,7 @@ var ProbeApiError = class extends Error {
33210
34489
  this.code = code;
33211
34490
  }
33212
34491
  };
33213
- function toApiError5(status, body) {
34492
+ function toApiError6(status, body) {
33214
34493
  if (typeof body === "object" && body !== null && "error" in body && typeof body.error === "string") {
33215
34494
  return new ProbeApiError(status, body.error);
33216
34495
  }
@@ -33241,7 +34520,7 @@ function createProbeApi(httpClient) {
33241
34520
  body
33242
34521
  });
33243
34522
  if (response.status !== 201) {
33244
- throw toApiError5(response.status, response.body);
34523
+ throw toApiError6(response.status, response.body);
33245
34524
  }
33246
34525
  return response.body;
33247
34526
  },
@@ -33252,7 +34531,7 @@ function createProbeApi(httpClient) {
33252
34531
  bearerToken: input2.bearerToken
33253
34532
  });
33254
34533
  if (response.status !== 200) {
33255
- throw toApiError5(response.status, response.body);
34534
+ throw toApiError6(response.status, response.body);
33256
34535
  }
33257
34536
  return response.body;
33258
34537
  },
@@ -33264,13 +34543,13 @@ function createProbeApi(httpClient) {
33264
34543
  body: { activation_id: input2.activationId }
33265
34544
  });
33266
34545
  if (response.status !== 200) {
33267
- throw toApiError5(response.status, response.body);
34546
+ throw toApiError6(response.status, response.body);
33268
34547
  }
33269
34548
  return response.body;
33270
34549
  }
33271
34550
  };
33272
34551
  }
33273
- function mapErrorToExitCode13(error) {
34552
+ function mapErrorToExitCode14(error) {
33274
34553
  if (!(error instanceof ProbeApiError)) {
33275
34554
  return 1;
33276
34555
  }
@@ -33323,7 +34602,7 @@ async function activateProbeCommand(input2, api) {
33323
34602
  Trigger token: ${result.trigger_token}`
33324
34603
  };
33325
34604
  } catch (error) {
33326
- return { exitCode: mapErrorToExitCode13(error), output: error instanceof Error ? error.message : String(error) };
34605
+ return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
33327
34606
  }
33328
34607
  }
33329
34608
  async function listActiveProbesCommand(input2, api) {
@@ -33343,7 +34622,7 @@ async function listActiveProbesCommand(input2, api) {
33343
34622
  output: result.activations.map((a) => `${a.activation_id} ${a.label_pattern} (${a.service}/${a.environment}) expires ${a.expires_at}`).join("\n")
33344
34623
  };
33345
34624
  } catch (error) {
33346
- return { exitCode: mapErrorToExitCode13(error), output: error instanceof Error ? error.message : String(error) };
34625
+ return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
33347
34626
  }
33348
34627
  }
33349
34628
  async function deactivateProbeCommand(input2, api) {
@@ -33361,7 +34640,7 @@ async function deactivateProbeCommand(input2, api) {
33361
34640
  output: result.deactivated ? "Probe deactivated." : "Probe was already inactive."
33362
34641
  };
33363
34642
  } catch (error) {
33364
- return { exitCode: mapErrorToExitCode13(error), output: error instanceof Error ? error.message : String(error) };
34643
+ return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
33365
34644
  }
33366
34645
  }
33367
34646
  async function createAuthenticatedProbeApi(input2, dependencies) {
@@ -33796,7 +35075,7 @@ function handleMemberCommand(parsedArgv, dependencies) {
33796
35075
  }
33797
35076
 
33798
35077
  // src/alert-commands.ts
33799
- function mapErrorToExitCode14(error) {
35078
+ function mapErrorToExitCode15(error) {
33800
35079
  if (!(error instanceof AlertApiError)) {
33801
35080
  return 1;
33802
35081
  }
@@ -33834,7 +35113,7 @@ async function listAlertsCommand(input2, api) {
33834
35113
  output: input2.json ? JSON.stringify({ alerts }) : formatAlertTable(alerts)
33835
35114
  };
33836
35115
  } catch (error) {
33837
- return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
35116
+ return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
33838
35117
  }
33839
35118
  }
33840
35119
  async function listAlertsWithAuthCommand(input2, dependencies) {
@@ -33885,7 +35164,7 @@ async function createAlertCommand(input2, api) {
33885
35164
  output: input2.json ? JSON.stringify({ alert }) : `Alert created: ${alert.alert_id}`
33886
35165
  };
33887
35166
  } catch (error) {
33888
- return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
35167
+ return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
33889
35168
  }
33890
35169
  }
33891
35170
  async function createAlertWithAuthCommand(input2, dependencies) {
@@ -33955,7 +35234,7 @@ async function updateAlertCommand(input2, api) {
33955
35234
  output: input2.json ? JSON.stringify({ alert }) : `Alert updated: ${alert.alert_id}`
33956
35235
  };
33957
35236
  } catch (error) {
33958
- return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
35237
+ return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
33959
35238
  }
33960
35239
  }
33961
35240
  async function updateAlertWithAuthCommand(input2, dependencies) {
@@ -34010,7 +35289,7 @@ async function deleteAlertCommand(input2, api) {
34010
35289
  output: input2.json ? JSON.stringify({ alert }) : `Alert deleted: ${alert.alert_id}`
34011
35290
  };
34012
35291
  } catch (error) {
34013
- return { exitCode: mapErrorToExitCode14(error), output: error instanceof Error ? error.message : String(error) };
35292
+ return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
34014
35293
  }
34015
35294
  }
34016
35295
  async function deleteAlertWithAuthCommand(input2, dependencies) {
@@ -34034,7 +35313,7 @@ async function deleteAlertWithAuthCommand(input2, dependencies) {
34034
35313
  }
34035
35314
 
34036
35315
  // src/slack-commands.ts
34037
- function mapErrorToExitCode15(error) {
35316
+ function mapErrorToExitCode16(error) {
34038
35317
  if (!(error instanceof SlackApiError)) {
34039
35318
  return 1;
34040
35319
  }
@@ -34070,7 +35349,7 @@ async function listSlackDestinationsCommand(input2, api) {
34070
35349
  output: input2.json ? JSON.stringify({ destinations }) : formatSlackDestinationTable(destinations)
34071
35350
  };
34072
35351
  } catch (error) {
34073
- return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
35352
+ return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
34074
35353
  }
34075
35354
  }
34076
35355
  async function listSlackDestinationsWithAuthCommand(input2, dependencies) {
@@ -34099,7 +35378,7 @@ async function getSlackConnectUrlCommand(input2, api) {
34099
35378
  output: input2.json ? JSON.stringify({ install_url: installUrl }) : installUrl
34100
35379
  };
34101
35380
  } catch (error) {
34102
- return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
35381
+ return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
34103
35382
  }
34104
35383
  }
34105
35384
  async function getSlackConnectUrlWithAuthCommand(input2, dependencies) {
@@ -34129,7 +35408,7 @@ async function testSlackDestinationCommand(input2, api) {
34129
35408
  output: input2.json ? JSON.stringify({ delivery }) : `Slack test message delivered for destination: ${input2.destinationId}`
34130
35409
  };
34131
35410
  } catch (error) {
34132
- return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
35411
+ return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
34133
35412
  }
34134
35413
  }
34135
35414
  async function testSlackDestinationWithAuthCommand(input2, dependencies) {
@@ -34159,7 +35438,7 @@ async function deleteSlackDestinationCommand(input2, api) {
34159
35438
  output: input2.json ? JSON.stringify({ destination: deleted }) : `Slack destination deleted: ${deleted.slack_destination_id}`
34160
35439
  };
34161
35440
  } catch (error) {
34162
- return { exitCode: mapErrorToExitCode15(error), output: error instanceof Error ? error.message : String(error) };
35441
+ return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
34163
35442
  }
34164
35443
  }
34165
35444
  async function deleteSlackDestinationWithAuthCommand(input2, dependencies) {
@@ -34179,7 +35458,7 @@ async function deleteSlackDestinationWithAuthCommand(input2, dependencies) {
34179
35458
  }
34180
35459
 
34181
35460
  // src/webhook-commands.ts
34182
- function mapErrorToExitCode16(error) {
35461
+ function mapErrorToExitCode17(error) {
34183
35462
  if (!(error instanceof WebhookApiError)) {
34184
35463
  return 1;
34185
35464
  }
@@ -34224,7 +35503,7 @@ async function listWebhooksCommand(input2, api) {
34224
35503
  output: input2.json ? JSON.stringify({ webhooks }) : formatWebhookTable(webhooks)
34225
35504
  };
34226
35505
  } catch (error) {
34227
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35506
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34228
35507
  }
34229
35508
  }
34230
35509
  async function listWebhooksWithAuthCommand(input2, dependencies) {
@@ -34272,7 +35551,7 @@ async function createWebhookCommand(input2, api) {
34272
35551
  Signing secret: ${webhook.signing_secret}`
34273
35552
  };
34274
35553
  } catch (error) {
34275
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35554
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34276
35555
  }
34277
35556
  }
34278
35557
  async function createWebhookWithAuthCommand(input2, dependencies) {
@@ -34326,7 +35605,7 @@ async function updateWebhookCommand(input2, api) {
34326
35605
  output: input2.json ? JSON.stringify({ webhook }) : `Webhook updated: ${webhook.webhook_id}`
34327
35606
  };
34328
35607
  } catch (error) {
34329
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35608
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34330
35609
  }
34331
35610
  }
34332
35611
  async function updateWebhookWithAuthCommand(input2, dependencies) {
@@ -34372,7 +35651,7 @@ async function deleteWebhookCommand(input2, api) {
34372
35651
  output: input2.json ? JSON.stringify({ webhook }) : `Webhook deleted: ${webhook.webhook_id}`
34373
35652
  };
34374
35653
  } catch (error) {
34375
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35654
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34376
35655
  }
34377
35656
  }
34378
35657
  async function deleteWebhookWithAuthCommand(input2, dependencies) {
@@ -34410,7 +35689,7 @@ async function testWebhookCommand(input2, api) {
34410
35689
  output: input2.json ? JSON.stringify({ delivery }) : `Webhook test queued: ${delivery.delivery_id} | ${delivery.event_type} | attempts=${delivery.attempt_count}`
34411
35690
  };
34412
35691
  } catch (error) {
34413
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35692
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34414
35693
  }
34415
35694
  }
34416
35695
  async function testWebhookWithAuthCommand(input2, dependencies) {
@@ -34451,7 +35730,7 @@ async function listWebhookDeliveriesCommand(input2, api) {
34451
35730
  output: input2.json ? JSON.stringify({ deliveries }) : formatWebhookDeliveriesTable(deliveries)
34452
35731
  };
34453
35732
  } catch (error) {
34454
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35733
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34455
35734
  }
34456
35735
  }
34457
35736
  async function listWebhookDeliveriesWithAuthCommand(input2, dependencies) {
@@ -34489,7 +35768,7 @@ async function retryWebhookDeliveryCommand(input2, api) {
34489
35768
  output: input2.json ? JSON.stringify(result) : `Delivery retried: ${result.delivery_id} | ${result.event_type}`
34490
35769
  };
34491
35770
  } catch (error) {
34492
- return { exitCode: mapErrorToExitCode16(error), output: error instanceof Error ? error.message : String(error) };
35771
+ return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
34493
35772
  }
34494
35773
  }
34495
35774
  async function retryWebhookDeliveryWithAuthCommand(input2, dependencies) {
@@ -34514,7 +35793,7 @@ async function retryWebhookDeliveryWithAuthCommand(input2, dependencies) {
34514
35793
  }
34515
35794
 
34516
35795
  // src/weekly-report-commands.ts
34517
- function mapErrorToExitCode17(error) {
35796
+ function mapErrorToExitCode18(error) {
34518
35797
  if (!(error instanceof WeeklyReportApiError)) {
34519
35798
  return 1;
34520
35799
  }
@@ -34549,7 +35828,7 @@ async function listWeeklyReportChannelsCommand(input2, api) {
34549
35828
  output: input2.json ? JSON.stringify({ channels }) : formatWeeklyReportChannelTable(channels)
34550
35829
  };
34551
35830
  } catch (error) {
34552
- return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
35831
+ return { exitCode: mapErrorToExitCode18(error), output: error instanceof Error ? error.message : String(error) };
34553
35832
  }
34554
35833
  }
34555
35834
  async function listWeeklyReportChannelsWithAuthCommand(input2, dependencies) {
@@ -34582,7 +35861,7 @@ async function createWeeklyReportChannelCommand(input2, api) {
34582
35861
  output: input2.json ? JSON.stringify({ channel }) : `Weekly report channel created: ${channel.channel_id}`
34583
35862
  };
34584
35863
  } catch (error) {
34585
- return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
35864
+ return { exitCode: mapErrorToExitCode18(error), output: error instanceof Error ? error.message : String(error) };
34586
35865
  }
34587
35866
  }
34588
35867
  async function createWeeklyReportChannelWithAuthCommand(input2, dependencies) {
@@ -34617,7 +35896,7 @@ async function updateWeeklyReportChannelCommand(input2, api) {
34617
35896
  output: input2.json ? JSON.stringify({ channel }) : `Weekly report channel updated: ${channel.channel_id}`
34618
35897
  };
34619
35898
  } catch (error) {
34620
- return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
35899
+ return { exitCode: mapErrorToExitCode18(error), output: error instanceof Error ? error.message : String(error) };
34621
35900
  }
34622
35901
  }
34623
35902
  async function updateWeeklyReportChannelWithAuthCommand(input2, dependencies) {
@@ -34648,7 +35927,7 @@ async function deleteWeeklyReportChannelCommand(input2, api) {
34648
35927
  output: input2.json ? JSON.stringify({ channel: deleted }) : `Weekly report channel deleted: ${deleted.channel_id}`
34649
35928
  };
34650
35929
  } catch (error) {
34651
- return { exitCode: mapErrorToExitCode17(error), output: error instanceof Error ? error.message : String(error) };
35930
+ return { exitCode: mapErrorToExitCode18(error), output: error instanceof Error ? error.message : String(error) };
34652
35931
  }
34653
35932
  }
34654
35933
  async function deleteWeeklyReportChannelWithAuthCommand(input2, dependencies) {
@@ -35258,7 +36537,7 @@ async function handleCaptureRuleCommand2(parsedArgv, dependencies) {
35258
36537
  // package.json
35259
36538
  var package_default = {
35260
36539
  name: "@debugbundle/cli",
35261
- version: "1.4.0",
36540
+ version: "1.5.0",
35262
36541
  private: false,
35263
36542
  description: "Command-line interface for DebugBundle",
35264
36543
  license: "AGPL-3.0-only",
@@ -35736,6 +37015,9 @@ ${formatUsage()}`
35736
37015
  if (command === "probe") {
35737
37016
  return await handleProbeCommand(parsedArgv, dependencies);
35738
37017
  }
37018
+ if (command === "health") {
37019
+ return await handleHealthCommand(parsedArgv, dependencies);
37020
+ }
35739
37021
  if (command === "member") {
35740
37022
  return await handleMemberCommand(parsedArgv, dependencies);
35741
37023
  }