@debugbundle/cli 1.2.0 → 1.3.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 +177 -13
  2. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -14771,7 +14771,7 @@ function isIpLikeHost(value) {
14771
14771
  return /^(?:\d{1,3}\.){3}\d{1,3}$/.test(host) || /^\[[0-9a-f:]+\]$/i.test(host) || host.includes(":") && /^[0-9a-f:]+$/i.test(host);
14772
14772
  }
14773
14773
 
14774
- // ../../packages/shared-types/src/capture-rules.ts
14774
+ // ../../packages/shared-types/src/capture-rule-schemas.ts
14775
14775
  var CAPTURE_RULE_EVENT_TYPES = [
14776
14776
  "backend_exception",
14777
14777
  "request_event",
@@ -14799,6 +14799,7 @@ var CaptureRuleSampleEventClassSchema = external_exports.enum(CaptureRuleSampleE
14799
14799
  var CaptureRuleRuntimeSchema = external_exports.enum(CAPTURE_RULE_RUNTIME_VALUES);
14800
14800
  var CaptureRuleEventTypeSchema = external_exports.enum(CAPTURE_RULE_EVENT_TYPES);
14801
14801
  var BrowserEventKindSchema = external_exports.enum(["window_error", "resource_error"]);
14802
+ var CaptureRuleClientKindSchema = external_exports.enum(["human", "bot", "unknown"]);
14802
14803
  function normalizeOptionalTrimmedString(value) {
14803
14804
  const trimmed = value?.trim();
14804
14805
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
@@ -14876,6 +14877,9 @@ var CaptureRuleMatcherSchema = external_exports.object({
14876
14877
  message_contains: external_exports.string().min(1).max(500).optional(),
14877
14878
  message_equals: external_exports.string().min(1).max(500).optional(),
14878
14879
  browser_event_kind: BrowserEventKindSchema.optional(),
14880
+ browser_event_opaque: external_exports.boolean().optional(),
14881
+ client_kind: CaptureRuleClientKindSchema.optional(),
14882
+ bot_family: external_exports.string().min(1).max(120).optional(),
14879
14883
  resource_url: UrlMatcherSchema.optional(),
14880
14884
  request_url: UrlMatcherSchema.optional(),
14881
14885
  status_codes: external_exports.array(external_exports.number().int().min(100).max(599)).min(1).optional(),
@@ -14890,6 +14894,7 @@ var CaptureRuleMatcherSchema = external_exports.object({
14890
14894
  const errorName = normalizeOptionalTrimmedString(value.error_name);
14891
14895
  const messageContains = normalizeOptionalTrimmedString(value.message_contains);
14892
14896
  const messageEquals = normalizeOptionalTrimmedString(value.message_equals);
14897
+ const botFamily = normalizeOptionalTrimmedString(value.bot_family);
14893
14898
  const statusCodes = normalizeNumberArray(value.status_codes);
14894
14899
  if (eventTypes !== void 0) {
14895
14900
  normalized.event_types = eventTypes;
@@ -14918,6 +14923,15 @@ var CaptureRuleMatcherSchema = external_exports.object({
14918
14923
  if (value.browser_event_kind !== void 0) {
14919
14924
  normalized.browser_event_kind = value.browser_event_kind;
14920
14925
  }
14926
+ if (value.browser_event_opaque !== void 0) {
14927
+ normalized.browser_event_opaque = value.browser_event_opaque;
14928
+ }
14929
+ if (value.client_kind !== void 0) {
14930
+ normalized.client_kind = value.client_kind;
14931
+ }
14932
+ if (botFamily !== void 0) {
14933
+ normalized.bot_family = botFamily;
14934
+ }
14921
14935
  if (value.resource_url !== void 0) {
14922
14936
  normalized.resource_url = value.resource_url;
14923
14937
  }
@@ -14944,6 +14958,9 @@ var CaptureRuleMatcherSchema = external_exports.object({
14944
14958
  "message_contains",
14945
14959
  "message_equals",
14946
14960
  "browser_event_kind",
14961
+ "browser_event_opaque",
14962
+ "client_kind",
14963
+ "bot_family",
14947
14964
  "resource_url",
14948
14965
  "request_url",
14949
14966
  "status_codes",
@@ -15126,6 +15143,8 @@ var CaptureRulesFileSchema = external_exports.object({
15126
15143
  version: external_exports.literal(1),
15127
15144
  rules: external_exports.array(CaptureRuleSchema)
15128
15145
  });
15146
+
15147
+ // ../../packages/shared-types/src/capture-rule-evaluation.ts
15129
15148
  var CaptureRuleEvaluationUrlSchema = external_exports.object({
15130
15149
  host: external_exports.string().min(1).transform((value) => value.toLowerCase()).optional(),
15131
15150
  path: external_exports.string().min(1).transform((value) => value.startsWith("/") ? value : `/${value}`)
@@ -15141,11 +15160,40 @@ var CaptureRuleEvaluationContextSchema = external_exports.object({
15141
15160
  error_name: external_exports.string().min(1).optional(),
15142
15161
  message: external_exports.string().min(1).optional(),
15143
15162
  browser_event_kind: BrowserEventKindSchema.optional(),
15163
+ browser_event_opaque: external_exports.boolean().optional(),
15164
+ client_kind: CaptureRuleClientKindSchema.optional(),
15165
+ bot_family: external_exports.string().min(1).max(120).optional(),
15144
15166
  resource_url: CaptureRuleEvaluationUrlSchema.optional(),
15145
15167
  request_url: CaptureRuleEvaluationUrlSchema.optional(),
15146
15168
  status_code: external_exports.number().int().min(0).max(599).optional(),
15147
15169
  fingerprint: CaptureRuleFingerprintSchema.optional()
15148
15170
  });
15171
+ function classifyCaptureRuleClientFromUserAgent(userAgent) {
15172
+ if (userAgent === null || userAgent === void 0) {
15173
+ return { client_kind: "unknown" };
15174
+ }
15175
+ const lower = userAgent.toLowerCase();
15176
+ const knownBots = [
15177
+ { family: "Googlebot", markers: ["googlebot", "adsbot-google", "google-inspectiontool"] },
15178
+ { family: "Bingbot", markers: ["bingbot", "msnbot"] },
15179
+ { family: "DuckDuckBot", markers: ["duckduckbot"] },
15180
+ { family: "Applebot", markers: ["applebot"] },
15181
+ { family: "YandexBot", markers: ["yandexbot"] },
15182
+ { family: "Baiduspider", markers: ["baiduspider"] },
15183
+ { family: "FacebookBot", markers: ["facebookexternalhit", "facebot"] },
15184
+ { family: "LinkedInBot", markers: ["linkedinbot"] },
15185
+ { family: "TwitterBot", markers: ["twitterbot"] },
15186
+ { family: "Slackbot", markers: ["slackbot"] }
15187
+ ];
15188
+ const knownBot = knownBots.find((entry) => entry.markers.some((marker) => lower.includes(marker)));
15189
+ if (knownBot !== void 0) {
15190
+ return { client_kind: "bot", bot_family: knownBot.family };
15191
+ }
15192
+ if (["bot", "crawler", "spider", "slurp"].some((marker) => lower.includes(marker))) {
15193
+ return { client_kind: "bot", bot_family: "OtherBot" };
15194
+ }
15195
+ return { client_kind: "human" };
15196
+ }
15149
15197
 
15150
15198
  // ../../packages/shared-types/src/capture-rule-suggestions.ts
15151
15199
  var CaptureRuleSuggestionConfidenceSchema = external_exports.enum(["high", "medium", "low"]);
@@ -15355,6 +15403,12 @@ var BrowserExceptionEventSchema = external_exports.object({
15355
15403
  }).strict().optional(),
15356
15404
  opaque: external_exports.boolean()
15357
15405
  }).strict();
15406
+ var FrontendRejectionReasonSchema = external_exports.object({
15407
+ kind: external_exports.enum(["error", "string", "object", "null", "undefined", "unknown"]),
15408
+ name: external_exports.string().min(1).optional(),
15409
+ message: external_exports.string().min(1).optional(),
15410
+ preview: external_exports.string().min(1).optional()
15411
+ }).strict();
15358
15412
  var FrontendExceptionPayloadSchema = external_exports.object({
15359
15413
  name: external_exports.string().min(1),
15360
15414
  message: external_exports.string().min(1),
@@ -15367,6 +15421,7 @@ var FrontendExceptionPayloadSchema = external_exports.object({
15367
15421
  breadcrumbs: external_exports.array(FrontendExceptionBreadcrumbSchema).optional(),
15368
15422
  device: DeviceInfoSchema.nullable().optional(),
15369
15423
  browser_event: BrowserExceptionEventSchema.optional(),
15424
+ rejection_reason: FrontendRejectionReasonSchema.optional(),
15370
15425
  dom_context: external_exports.object({
15371
15426
  mode: external_exports.literal("lightweight"),
15372
15427
  html_excerpt: external_exports.string().min(1)
@@ -15818,7 +15873,7 @@ function buildSkill() {
15818
15873
  "2. Inspect the incident bundle and reproduction artifact before proposing a fix.",
15819
15874
  "3. Run `debugbundle analyze --type improvement --local` after local processing when you need a deterministic change plan.",
15820
15875
  "4. Apply the narrowest fix, then validate it with the repository test workflow from `.debugbundle/profile.json`.",
15821
- "5. When the fix is confirmed, or when the incident was intentionally generated for smoke, verification, or dogfooding, resolve it with `debugbundle resolve <incident-id>` or MCP `resolve_incident` so the open queue stays actionable.",
15876
+ "5. When the fix is confirmed, or when the incident was intentionally generated for smoke, verification, or dogfooding, resolve it with `debugbundle resolve <incident-id> [incident-id ...]` or MCP `resolve_incident` / `resolve_incidents` so the open queue stays actionable.",
15822
15877
  "",
15823
15878
  "## Incident Hygiene",
15824
15879
  "",
@@ -15827,6 +15882,15 @@ function buildSkill() {
15827
15882
  "- Reopen or leave open if the failure is still present, the validation is incomplete, or the incident represents a live unresolved problem.",
15828
15883
  "- If a resolved incident regresses, let the platform move it back to `regressed` through normal incident lifecycle behavior.",
15829
15884
  "",
15885
+ "## Noise Management",
15886
+ "",
15887
+ "When incident evidence shows repeated low-value operational noise rather than a product bug, evaluate whether a scoped capture rule or capture-policy path rule should handle future matches.",
15888
+ "",
15889
+ "- Run `debugbundle capture-rule suggest <incident-id> --json` before creating a manual rule. Apply deterministic suggestions with `debugbundle capture-rule create-from-suggestion <incident-id> --suggestion-id <id>` after confirming the scope is safe.",
15890
+ "- Prefer project capture rules for operational noise because they are centralized, auditable, and enforced by ingestion and processing. Use SDK `beforeSend` only for app-owned local policy such as final redaction or events that must never leave the runtime.",
15891
+ "- Scope frontend noise by structured evidence such as service, environment, `browser_event_kind`, `browser_event_opaque`, `client_kind`, `bot_family`, and message fields. Do not broadly demote generic `Unhandled promise rejection` incidents without bot-scoped or otherwise narrow evidence.",
15892
+ "- For expected or intentionally promoted 4xx responses on known routes, use capture-policy client-error path rules instead of promoting all client errors: `debugbundle capture-policy set --client-error-path-rule <status=/path/*@GET>`.",
15893
+ "",
15830
15894
  "## Profile Validation",
15831
15895
  "",
15832
15896
  "Use this task after setup or whenever architecture changes make the static profile stale.",
@@ -15889,10 +15953,21 @@ function buildCliReference() {
15889
15953
  "- `debugbundle explain <incident-id> [--source <local|cloud>] [--json]`",
15890
15954
  "- `debugbundle bundle <incident-id> [--source <local|cloud>] [--json]`",
15891
15955
  "- `debugbundle reproduce <incident-id> [--source <local|cloud>] [--json]`",
15892
- "- `debugbundle resolve <incident-id> [--source <local|cloud>] [--json]`",
15893
- "- `debugbundle reopen <incident-id> [--source <local|cloud>] [--json]`",
15956
+ "- `debugbundle resolve <incident-id> [incident-id ...] [--source <local|cloud>] [--json]`",
15957
+ "- `debugbundle reopen <incident-id> [incident-id ...] [--source <local|cloud>] [--json]`",
15894
15958
  "- `debugbundle analyze --type improvement --local`",
15895
15959
  "",
15960
+ "## Noise Management",
15961
+ "",
15962
+ "- `debugbundle capture-rule suggest <incident-id> [--auth-file <path>] [--json]`",
15963
+ "- `debugbundle capture-rule create-from-suggestion <incident-id> --suggestion-id <id> [--name <name>] [--expires-at <ISO8601>] [--auth-file <path>] [--json]`",
15964
+ "- `debugbundle capture-rule list --project-id <id> [--auth-file <path>] [--json]`",
15965
+ "- `debugbundle capture-rule create --project-id <id> --name <name> --action <demote|sample|drop> --matcher-json <json> [--auth-file <path>] [--json]`",
15966
+ "- `debugbundle capture-policy get [--project <id>] [--json]`",
15967
+ "- `debugbundle capture-policy set [--project <id>] --client-error-path-rule <404=/path/*@GET,POST> [--json]`",
15968
+ "",
15969
+ "Use capture-rule suggestions for repeated operational noise after inspecting an incident bundle. Use capture-policy client-error path rules for route-scoped 4xx incidents instead of promoting all client errors.",
15970
+ "",
15896
15971
  "## Operational Paths",
15897
15972
  "",
15898
15973
  "- `.debugbundle/profile.json` \u2014 committed project map and agent validation state",
@@ -15923,7 +15998,7 @@ function buildCliReference() {
15923
15998
  "```bash",
15924
15999
  "debugbundle incidents --status open --json \\",
15925
16000
  ` | jq -r '.incidents[] | select(.title | test("smoke test|dogfood|verification|synthetic"; "i")) | .incident_id' \\`,
15926
- " | xargs -n1 debugbundle resolve",
16001
+ " | xargs debugbundle resolve",
15927
16002
  "```",
15928
16003
  ""
15929
16004
  ].join("\n");
@@ -15942,19 +16017,28 @@ function buildMcpReference() {
15942
16017
  "- `get_incident_context` \u2014 fetch deterministic explanation context for triage.",
15943
16018
  "- `get_bundle` \u2014 fetch the full debug bundle before proposing a fix.",
15944
16019
  "- `get_reproduction` \u2014 fetch reproduction guidance before editing code.",
15945
- "- `resolve_incident` / `reopen_incident` \u2014 update lifecycle state after validation.",
16020
+ "- `resolve_incident` / `resolve_incidents` / `reopen_incident` / `reopen_incidents` \u2014 update lifecycle state after validation.",
15946
16021
  "- `analyze` \u2014 run local agent-oriented analysis from local bundles and skill schemas.",
15947
16022
  "",
15948
16023
  "- Prefer bundle retrieval tools before reading raw repository files.",
15949
16024
  "- Use MCP bundle access when the current issue originated in production.",
15950
- "- Resolve fixed or intentionally generated incidents with `resolve_incident` so open incidents stay actionable.",
16025
+ "- Resolve fixed or intentionally generated incidents with `resolve_incident` or `resolve_incidents` so open incidents stay actionable.",
15951
16026
  "- Fall back to local CLI processing when the project is local-only.",
15952
16027
  "",
16028
+ "## Noise and Capture Policy Tools",
16029
+ "",
16030
+ "- `suggest_capture_rules_from_incident` \u2014 generate deterministic capture-rule suggestions from an incident bundle.",
16031
+ "- `create_capture_rule_from_incident_suggestion` \u2014 apply a confirmed suggestion.",
16032
+ "- `list_capture_rules`, `create_capture_rule`, `update_capture_rule`, `delete_capture_rule` \u2014 manage project capture rules.",
16033
+ "- `get_capture_policy`, `update_capture_policy` \u2014 review or update capture policy, including path-scoped client-error incident rules.",
16034
+ "",
16035
+ "Use these tools for repeated low-value operational noise only after inspecting incident evidence. Keep frontend suppression scoped by structured browser and client signals, and use path-scoped capture policy for known 4xx routes.",
16036
+ "",
15953
16037
  "## Smoke-Test Cleanup Recipe",
15954
16038
  "",
15955
16039
  '1. Call `list_incidents` with `status: "open"`.',
15956
16040
  "2. Filter incidents whose titles show they were intentionally generated for smoke, dogfood, verification, or synthetic checks.",
15957
- "3. Call `resolve_incident` for each verified synthetic incident.",
16041
+ "3. Call `resolve_incidents` for verified synthetic incidents, or `resolve_incident` for a single incident.",
15958
16042
  "4. Call `list_incidents` again and confirm the open queue only contains actionable failures.",
15959
16043
  ""
15960
16044
  ].join("\n");
@@ -16074,6 +16158,16 @@ function buildSkillEvals() {
16074
16158
  "Leave unresolved incidents open when the failure is still live or unverified."
16075
16159
  ]
16076
16160
  },
16161
+ {
16162
+ name: "noise_management_guidance",
16163
+ prompt: "The same low-value frontend incident keeps reopening. Confirm the skill tells the agent how to evaluate operational noise without hiding real bugs.",
16164
+ expected_behavior: [
16165
+ "Inspect incident evidence before creating a rule.",
16166
+ "Use capture-rule suggestions for repeated operational noise.",
16167
+ "Keep generic frontend suppression narrow with structured browser or bot signals.",
16168
+ "Use capture-policy path rules for known route-scoped 4xx incidents."
16169
+ ]
16170
+ },
16077
16171
  {
16078
16172
  name: "artifact_path_discovery",
16079
16173
  prompt: "The user reports an unknown local runtime error. Confirm the skill tells the agent which DebugBundle paths and commands to inspect first.",
@@ -17088,6 +17182,33 @@ function buildRedactionRecord(bundleBody) {
17088
17182
  notes: readString(redaction["notes"])
17089
17183
  };
17090
17184
  }
17185
+ function buildBrowserSignalRecord(bundleBody) {
17186
+ const bundle = isRecord2(bundleBody) ? bundleBody : {};
17187
+ const context = isRecord2(bundle["context"]) ? bundle["context"] : {};
17188
+ const frontend = isRecord2(context["frontend"]) ? context["frontend"] : {};
17189
+ const exceptions = Array.isArray(frontend["exceptions"]) ? frontend["exceptions"] : [];
17190
+ let exception;
17191
+ for (let index = exceptions.length - 1; index >= 0; index -= 1) {
17192
+ const candidate = exceptions[index];
17193
+ if (isRecord2(candidate) && isRecord2(candidate["browser_event"])) {
17194
+ exception = candidate;
17195
+ break;
17196
+ }
17197
+ }
17198
+ const browserEvent = isRecord2(exception) && isRecord2(exception["browser_event"]) ? exception["browser_event"] : null;
17199
+ const device = isRecord2(context["device"]) ? context["device"] : {};
17200
+ const client = classifyCaptureRuleClientFromUserAgent(readString(device["user_agent"]) ?? void 0);
17201
+ if (browserEvent === null && client.client_kind === "unknown") {
17202
+ return null;
17203
+ }
17204
+ return {
17205
+ browser_event_kind: readString(browserEvent?.["kind"]),
17206
+ browser_event_opaque: readBoolean(browserEvent?.["opaque"]),
17207
+ browser_event_message: readString(browserEvent?.["message"]),
17208
+ client_kind: client.client_kind,
17209
+ bot_family: client.bot_family ?? null
17210
+ };
17211
+ }
17091
17212
  function buildVisibilityRecord(input2) {
17092
17213
  const routeTarget = input2.primarySignal.route_template ?? input2.primarySignal.request_path;
17093
17214
  const matchedFields = input2.incident.matched_fields.length === 0 ? "none" : input2.incident.matched_fields.join(", ");
@@ -17125,6 +17246,14 @@ function buildSuggestedNextChecks(input2) {
17125
17246
  if (input2.deploy.regression_window === true || input2.incident.status === "regressed") {
17126
17247
  suggestions.push("Compare this incident against the most recent deploy and recent regressions.");
17127
17248
  }
17249
+ if (input2.browserSignal?.browser_event_opaque === true) {
17250
+ suggestions.push("Treat the browser event as opaque; inspect CSP, cross-origin scripts, resource loading, and framework error boundaries before changing application code.");
17251
+ }
17252
+ if (input2.browserSignal?.client_kind === "bot") {
17253
+ suggestions.push(
17254
+ `Review whether ${input2.browserSignal.bot_family ?? "bot"} traffic is operational noise before applying a bot-scoped capture rule.`
17255
+ );
17256
+ }
17128
17257
  if (input2.reproduction.status === "pending") {
17129
17258
  suggestions.push("Recheck reproduction guidance after the reproduction artifact is ready.");
17130
17259
  }
@@ -17145,6 +17274,7 @@ function buildIncidentContextRecord(input2) {
17145
17274
  primarySignal
17146
17275
  });
17147
17276
  const redaction = buildRedactionRecord(bundleBody);
17277
+ const browserSignal = buildBrowserSignalRecord(bundleBody);
17148
17278
  return {
17149
17279
  incident: input2.incident,
17150
17280
  incident_reason: incidentReason,
@@ -17160,13 +17290,15 @@ function buildIncidentContextRecord(input2) {
17160
17290
  },
17161
17291
  visibility,
17162
17292
  redaction,
17293
+ browser_signal: browserSignal,
17163
17294
  suggested_next_checks: buildSuggestedNextChecks({
17164
17295
  incident: input2.incident,
17165
17296
  bundle: input2.bundle,
17166
17297
  reproduction: input2.reproduction,
17167
17298
  logs,
17168
17299
  primarySignal,
17169
- deploy
17300
+ deploy,
17301
+ browserSignal
17170
17302
  })
17171
17303
  };
17172
17304
  }
@@ -32379,18 +32511,44 @@ function mapErrorToExitCode12(error) {
32379
32511
  }
32380
32512
  return 1;
32381
32513
  }
32382
- function formatMatcher(rule) {
32514
+ function formatMatcherFromValue(matcher) {
32383
32515
  const parts = [];
32384
- const matcher = rule.matcher;
32385
32516
  if (matcher.event_types !== void 0) {
32386
32517
  parts.push(`event_types=${matcher.event_types.join(",")}`);
32387
32518
  }
32388
32519
  if (matcher.browser_event_kind !== void 0) {
32389
32520
  parts.push(`browser_event_kind=${matcher.browser_event_kind}`);
32390
32521
  }
32522
+ if (matcher.browser_event_opaque !== void 0) {
32523
+ parts.push(`browser_event_opaque=${String(matcher.browser_event_opaque)}`);
32524
+ }
32525
+ if (matcher.client_kind !== void 0) {
32526
+ parts.push(`client_kind=${matcher.client_kind}`);
32527
+ }
32528
+ if (matcher.bot_family !== void 0) {
32529
+ parts.push(`bot_family=${matcher.bot_family}`);
32530
+ }
32531
+ if (matcher.services !== void 0) {
32532
+ parts.push(`services=${matcher.services.join(",")}`);
32533
+ }
32534
+ if (matcher.environments !== void 0) {
32535
+ parts.push(`environments=${matcher.environments.join(",")}`);
32536
+ }
32537
+ if (matcher.message_equals !== void 0) {
32538
+ parts.push(`message_equals=${JSON.stringify(matcher.message_equals)}`);
32539
+ }
32540
+ if (matcher.message_contains !== void 0) {
32541
+ parts.push(`message_contains=${JSON.stringify(matcher.message_contains)}`);
32542
+ }
32543
+ if (matcher.error_name !== void 0) {
32544
+ parts.push(`error_name=${matcher.error_name}`);
32545
+ }
32391
32546
  if (matcher.resource_url?.host !== void 0) {
32392
32547
  parts.push(`resource_host=${matcher.resource_url.host}`);
32393
32548
  }
32549
+ if (matcher.resource_url?.path_equals !== void 0) {
32550
+ parts.push(`resource_path=${matcher.resource_url.path_equals}`);
32551
+ }
32394
32552
  if (matcher.request_url?.path_equals !== void 0) {
32395
32553
  parts.push(`request_path=${matcher.request_url.path_equals}`);
32396
32554
  }
@@ -32402,6 +32560,9 @@ function formatMatcher(rule) {
32402
32560
  }
32403
32561
  return parts.length > 0 ? parts.join(" ") : "matcher=custom";
32404
32562
  }
32563
+ function formatMatcher(rule) {
32564
+ return formatMatcherFromValue(rule.matcher);
32565
+ }
32405
32566
  function formatRule(rule) {
32406
32567
  const action = rule.action === "sample" ? `${rule.action}:${rule.sample_rate ?? "?"}:${rule.sample_event_class ?? "?"}` : rule.action;
32407
32568
  return [
@@ -32422,7 +32583,10 @@ function formatSuggestionResponse(response) {
32422
32583
  return response.suggestions.map(
32423
32584
  (suggestion) => [
32424
32585
  `${suggestion.suggestion_id} ${suggestion.recommended_action} ${suggestion.confidence} ${suggestion.label}`,
32425
- suggestion.reason
32586
+ suggestion.reason,
32587
+ `matcher: ${formatMatcherFromValue(suggestion.rule.matcher)}`,
32588
+ `requires_confirmation: ${String(suggestion.requires_confirmation)}`,
32589
+ `apply: debugbundle capture-rule create-from-suggestion <incident-id> --suggestion-id ${suggestion.suggestion_id}`
32426
32590
  ].join("\n")
32427
32591
  ).join("\n\n");
32428
32592
  }
@@ -34739,7 +34903,7 @@ async function handleCaptureRuleCommand2(parsedArgv, dependencies) {
34739
34903
  // package.json
34740
34904
  var package_default = {
34741
34905
  name: "@debugbundle/cli",
34742
- version: "1.2.0",
34906
+ version: "1.3.0",
34743
34907
  private: false,
34744
34908
  description: "Command-line interface for DebugBundle",
34745
34909
  license: "AGPL-3.0-only",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@debugbundle/cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "description": "Command-line interface for DebugBundle",
6
6
  "license": "AGPL-3.0-only",