react-doctor 0.9.9 → 0.9.10

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 (28) hide show
  1. package/dist/{build-section-divider-rq_KQONI.js → build-section-divider-BBuZ20p0.js} +22 -103
  2. package/dist/{ci-BwCh-hUD.js → ci-Cje97GMB.js} +11 -11
  3. package/dist/cli.js +33 -30
  4. package/dist/{design-CTL1QpZB.js → design-swBQC07N.js} +4 -4
  5. package/dist/{exit-gracefully-C7wgCb-s.js → exit-gracefully-GZXxMj5W.js} +7 -6
  6. package/dist/index.d.ts +9 -1
  7. package/dist/index.js +159 -159
  8. package/dist/{inspect-CGCfCxoM.js → inspect-BQapfOJX.js} +16 -16
  9. package/dist/{install-CdlRGSxJ.js → install-CChowo4Z.js} +8 -8
  10. package/dist/{install-doctor-script-BEIl1lby.js → install-doctor-script-BM5NC98v.js} +4 -4
  11. package/dist/{install-github-workflow-Cun64Fxh.js → install-github-workflow-L48jbG9d.js} +6 -6
  12. package/dist/{install-react-doctor-Bn-dP3rT.js → install-react-doctor-BFp6q3iz.js} +8 -8
  13. package/dist/lsp.js +2122 -327
  14. package/dist/{print-branded-header-C9de_0PE.js → print-branded-header-DQn3TZpV.js} +4 -4
  15. package/dist/{read-object-file-ClOsQUSD.js → read-object-file-BTd_gGow.js} +4 -4
  16. package/dist/{record-metric-b5KUd2XK.js → record-metric-CuPtdZfm.js} +1654 -295
  17. package/dist/{report-error-DU6Bxy9R.js → report-error-DemUcOtc.js} +18 -12
  18. package/dist/{report-workflow-result-CjrL22OD.js → report-workflow-result-W-amAB4Z.js} +5 -5
  19. package/dist/{resolve-scope-pjSIB8ZY.js → resolve-scope-BGBQcbGi.js} +6 -6
  20. package/dist/{rules-Ds2rHd-a.js → rules-BsYE5BBb.js} +6 -6
  21. package/dist/{run-scan-app-D8wBLuwl.js → run-scan-app-CfT3YzbG.js} +10 -10
  22. package/dist/{scan-CHh6DGmw.js → scan-D8DHxJxj.js} +8 -8
  23. package/dist/{should-fail-scan-gate-Bif6gnI9.js → should-fail-scan-gate-B5XfdAMg.js} +114 -192
  24. package/dist/{should-skip-prompts-Q3cS356Z.js → should-skip-prompts-DaBGPwa3.js} +4 -4
  25. package/dist/{unref-stdin-DTLx8HEf.js → unref-stdin-D0Lq28Bk.js} +112 -5
  26. package/dist/{version-BrAILQSv.js → version-CyVLelBf.js} +4 -4
  27. package/dist/{why-DB_XpRpg.js → why-nfPQ3AAq.js} +4 -4
  28. package/package.json +6 -6
@@ -1,12 +1,12 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c4293bd1-fbc8-59a4-8a5f-0fc1e2e1624c")}catch(e){}}();
3
- import { $ as Files, $n as withTracer, $t as hashFileContents, An as summarizeDiagnostics, B as isCiOrCodingAgentEnvironment, Bn as Diagnostic, Bt as filterSourceFiles, Cn as resolveReactDoctorCacheDir, Ct as SupplyChain, Dn as runInspect, Dt as buildSkippedChecks, En as restoreLegacyThrow, Et as buildRuleDocsUrl, Fn as Console, Ft as createOxlintSpawnSlots, Gn as promise, Hn as gen, In as error, J as Config, Jn as runPromise, Kn as provide, L as ACTION_INPUT_ENVIRONMENT_VARIABLES, Lt as discoverReactSubprojects, Mt as computeConfigFingerprint, N as CliInputError, Nt as computeDiagnosticDelta, Ot as calculateScore, P as isNonInteractiveEnvironment, Pn as yieldToEventLoop, Pt as createNodeReadFileLinesSync, Q as ENTERPRISE_CONTACT_URL, R as detectRunnerOs, Rn as log, Rt as filterDiagnosticsForSurface, Sn as resolveLintBatchOrdering, Tn as resolveScanTarget, Un as map, Vn as decodeUnknownSync, W as CI_URL, Wn as orElseSucceed, Xn as sync, Xt as groupBy, Y as DIAGNOSTIC_CATEGORY_BUCKETS, Yn as runSync, Z as DeadCode, Zn as try_, Zt as hasPublishedFixRecipe, _n as mergeReactDoctorConfigs, _t as SHARE_BASE_URL, a as buildSentryProjectContext, ar as externalSpan, bt as Score, cn as isReactDoctorError, ct as MILLISECONDS_PER_SECOND, dn as layerOtlp, dt as OxlintConcurrency, en as highlighter, er as mergeAll, fn as listSourceFiles, ft as OxlintSpawnSlots, g as BASELINE_FILES_TEMP_DIR_PREFIX, gn as materializeSourceTree, gt as Reporter, h as makeNoopConsole, hn as mapWithConcurrency, ht as Project, i as buildSentryScope, in as isMonorepoRoot, ir as ParentSpan, it as JSX_FILE_PATTERN, jt as collectSourceFileCountsByDirectory, kt as canonicalizeUserRuleKey, l as isJsonModeActive, lt as NodeResolver, m as VERSION, mt as Progress, n as recordDistribution, nr as succeed, nt as Git, o as setSentryProjectInfo, or as make, ot as LintPartialFailures, pn as listWorkspacePackages, pt as PerFileLintCacheEnabled, qn as provideService, qt as getDiagnosticRuleIdentity, r as toSpanAttributes, rn as isFile, rr as isSuccess, rt as HTML_FILE_PATTERN, s as getRunId, sr as isSome, st as Linter, t as recordCount, tn as isDirectory, tt as GIT_SHOW_MAX_BUFFER_BYTES, un as isScanComplete, ut as OXLINT_NODE_REQUIREMENT, w as SCAN_RESULT_CACHE_FILENAME, wn as resolveScanConcurrency, wt as atomicWriteJson, x as NANOSECONDS_PER_SECOND, xn as resolveGithubActionsScoreMetadata, xt as SidecarLintCacheEnabled, y as METRIC, z as isCiEnvironment, zn as warn, zt as filterPathsOutsideDirectories } from "./record-metric-b5KUd2XK.js";
4
- import { n as buildFooterLinkLines, o as isSentryTracingEnabled, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-rq_KQONI.js";
5
- import { a as setActiveRunTrace, i as recordRunTraceId } from "./unref-stdin-DTLx8HEf.js";
6
- import { D as getPackageJsonPath, L as cliLogger, O as isRecord, P as runGit, a as installReactDoctorScriptStep, c as spinner, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-BEIl1lby.js";
7
- import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-Cun64Fxh.js";
8
- import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-pjSIB8ZY.js";
9
- import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-CjrL22OD.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="64dd164d-d176-539f-b7f8-b4217a0009df")}catch(e){}}();
3
+ import { $n as orElseSucceed, An as resolveReactDoctorCacheDir, Bt as computeConfigFingerprint, Cn as mapWithConcurrency, Ct as SHARE_BASE_URL, Dt as SidecarLintCacheEnabled, E as NANOSECONDS_PER_MILLISECOND, Et as Score, Ft as buildSkippedChecks, G as isCiOrCodingAgentEnvironment, Gn as log, Gt as discoverReactSubprojects, H as ACTION_INPUT_ENVIRONMENT_VARIABLES, Hn as Console, Ht as createNodeReadFileLinesSync, It as calculateScore, Jn as decodeUnknownSync, Jt as filterSourceFiles, Kn as warn, Kt as filterDiagnosticsForSurface, Ln as summarizeDiagnostics, Lt as canonicalizeUserRuleKey, Mn as resolveScanTarget, Mt as atomicWriteJson, Nn as restoreLegacyThrow, On as resolveGithubActionsScoreMetadata, Pn as runInspect, Pt as buildRuleDocsUrl, Qn as map, R as CliInputError, St as Reporter, Tn as mergeReactDoctorConfigs, U as detectRunnerOs, Un as error, Ut as createOxlintSpawnSlots, Vn as yieldToEventLoop, Vt as computeDiagnosticDelta, W as isCiEnvironment, X as CI_URL, Xn as gen, Zn as makeSpan, _ as makeNoopConsole, _r as ParentSpan, _t as OxlintConcurrency, an as hasPublishedFixRecipe, ar as runSync, at as Files, bn as listSourceFiles, bt as Progress, c as setSentryProjectInfo, cn as highlighter, ct as Git, d as isJsonModeActive, dn as isFile, er as promise, et as Config, fn as isMonorepoRoot, fr as succeed, ft as LintPartialFailures, g as VERSION, gn as isReactDoctorError, gr as void_, gt as OXLINT_NODE_REQUIREMENT, hr as fail, ht as NodeResolver, in as groupBy, ir as runPromise, it as ENTERPRISE_CONTACT_URL, jn as resolveScanConcurrency, k as SCAN_RESULT_CACHE_FILENAME, kn as resolveLintBatchOrdering, kt as SupplyChain, l as getRunId, ln as isDirectory, lt as HTML_FILE_PATTERN, mt as MILLISECONDS_PER_SECOND, n as recordDistribution, nr as provideContext, o as buildSentryScope, or as sync, pt as Linter, qn as Diagnostic, qt as filterPathsOutsideDirectories, r as toSpanAttributes, rr as provideService, rt as DeadCode, s as buildSentryProjectContext, sn as hashFileContents, sr as try_, st as GIT_SHOW_MAX_BUFFER_BYTES, t as recordCount, tn as getDiagnosticRuleIdentity, tr as provide, tt as DIAGNOSTIC_CATEGORY_BUCKETS, ur as mergeAll, ut as JSX_FILE_PATTERN, vn as isScanComplete, vt as OxlintSpawnSlots, w as METRIC, wn as materializeSourceTree, x as BASELINE_FILES_TEMP_DIR_PREFIX, xn as listWorkspacePackages, xt as Project, yt as PerFileLintCacheEnabled, z as isNonInteractiveEnvironment, zt as collectSourceFileCountsByDirectory } from "./record-metric-CuPtdZfm.js";
4
+ import { a as setActiveRunTrace, i as recordRunTraceId, o as getTelemetryContext } from "./unref-stdin-D0Lq28Bk.js";
5
+ import { n as buildFooterLinkLines, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-BBuZ20p0.js";
6
+ import { D as getPackageJsonPath, L as cliLogger, O as isRecord, P as runGit, a as installReactDoctorScriptStep, c as spinner, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-BM5NC98v.js";
7
+ import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-L48jbG9d.js";
8
+ import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-BGBQcbGi.js";
9
+ import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-W-amAB4Z.js";
10
10
  import { createRequire } from "node:module";
11
11
  import { spawn } from "node:child_process";
12
12
  import * as path$1 from "node:path";
@@ -16,132 +16,30 @@ import fs, { mkdtempSync, rmSync } from "node:fs";
16
16
  import crypto, { randomUUID } from "node:crypto";
17
17
  import ts from "typescript";
18
18
  import { tmpdir } from "node:os";
19
- import * as Sentry from "@sentry/node";
20
19
  import { performance } from "node:perf_hooks";
21
20
  import { codeFrameColumns } from "@babel/code-frame";
22
- //#region src/cli/utils/sentry-tracer.ts
23
- const toHrTime = (epochNanoseconds) => [Number(epochNanoseconds / NANOSECONDS_PER_SECOND), Number(epochNanoseconds % NANOSECONDS_PER_SECOND)];
24
- const SPAN_KIND_TO_OTEL = {
25
- internal: 0,
26
- server: 1,
27
- client: 2,
28
- producer: 3,
29
- consumer: 4
30
- };
31
- const toSentryAttributeValue = (value) => {
32
- if (value === null || value === void 0) return void 0;
33
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
34
- return String(value);
35
- };
36
- const normalizeAttributes = (attributes) => {
37
- const normalized = {};
38
- if (!attributes) return normalized;
39
- for (const [key, value] of Object.entries(attributes)) normalized[key] = toSentryAttributeValue(value);
40
- return normalized;
41
- };
42
- const isSentryBackedSpan = (span) => span._tag === "Span" && "sentrySpan" in span;
43
- const spanContextFor = (span) => isSentryBackedSpan(span) ? span.sentrySpan.spanContext() : {
44
- traceId: span.traceId,
45
- spanId: span.spanId,
46
- traceFlags: span.sampled ? 1 : 0
47
- };
48
- /**
49
- * Builds an Effect {@link Tracer.Tracer} that materializes every Effect span
50
- * (`Effect.withSpan(...)` / `Effect.fn("Service.method")`) as a child Sentry
51
- * span, producing one unified per-run trace in Sentry. The CLI already
52
- * instruments `runInspect` and each core service method, so this bridge lights
53
- * all of that up in Sentry for free.
54
- *
55
- * `rootSpan` is the active per-run transaction; Effect spans without an Effect
56
- * parent attach to it, so nesting is correct even if async-context propagation
57
- * is interrupted by Effect's fiber scheduler. Provided to a program via
58
- * `Effect.withTracer(...)`.
59
- */
60
- const makeSentryTracer = (rootSpan, startInactiveSpan = Sentry.startInactiveSpan) => make({ span: (options) => {
61
- const parentSpan = isSome(options.parent) && isSentryBackedSpan(options.parent.value) ? options.parent.value.sentrySpan : rootSpan;
62
- const sentrySpan = startInactiveSpan({
63
- name: options.name,
64
- startTime: toHrTime(options.startTime),
65
- parentSpan,
66
- kind: SPAN_KIND_TO_OTEL[options.kind]
67
- });
68
- const { traceId, spanId } = sentrySpan.spanContext();
69
- const attributes = /* @__PURE__ */ new Map();
70
- let status = {
71
- _tag: "Started",
72
- startTime: options.startTime
73
- };
74
- return {
75
- _tag: "Span",
76
- sentrySpan,
77
- name: options.name,
78
- spanId,
79
- traceId,
80
- parent: options.parent,
81
- annotations: options.annotations,
82
- links: options.links,
83
- sampled: options.sampled,
84
- kind: options.kind,
85
- get status() {
86
- return status;
87
- },
88
- get attributes() {
89
- return attributes;
90
- },
91
- end: (endTime, exit) => {
92
- status = {
93
- _tag: "Ended",
94
- startTime: options.startTime,
95
- endTime,
96
- exit
97
- };
98
- sentrySpan.setStatus({ code: isSuccess(exit) ? 1 : 2 });
99
- sentrySpan.end(toHrTime(endTime));
100
- },
101
- attribute: (key, value) => {
102
- attributes.set(key, value);
103
- sentrySpan.setAttribute(key, toSentryAttributeValue(value));
104
- },
105
- event: (name, startTime, eventAttributes) => {
106
- sentrySpan.addEvent(name, normalizeAttributes(eventAttributes), toHrTime(startTime));
107
- },
108
- addLinks: (links) => {
109
- for (const link of links) sentrySpan.addLink({
110
- context: spanContextFor(link.span),
111
- attributes: normalizeAttributes(link.attributes)
112
- });
113
- }
114
- };
115
- } });
116
- //#endregion
117
21
  //#region src/cli/utils/apply-observability.ts
118
- const isOtlpExportConfigured = () => Boolean(process.env.REACT_DOCTOR_OTLP_ENDPOINT) && Boolean(process.env.REACT_DOCTOR_OTLP_AUTH_HEADER);
119
- const externalSpanFrom = (sentrySpan) => {
120
- const { traceId, spanId, traceFlags } = sentrySpan.spanContext();
121
- return externalSpan({
122
- traceId,
123
- spanId,
124
- sampled: (traceFlags & 1) === 1
125
- });
126
- };
127
22
  /**
128
- * Installs the tracing backend for the inspect program. Effect's tracer is a
129
- * single reference, so the backends are mutually exclusive — we pick by
130
- * precedence:
23
+ * Installs the tracing backend for the inspect program.
24
+ *
25
+ * Both the run root span and this program draw their tracer from the same
26
+ * shared telemetry context, so the scan's spans (`runInspect`, every
27
+ * `Service.method`) nest under the run span natively — no cross-backend
28
+ * `ExternalSpan` stitching, and one exporter with one flush.
29
+ *
30
+ * The backend itself is chosen inside `layerObservability`: a user-configured
31
+ * `REACT_DOCTOR_OTLP_*` endpoint wins over first-party Axiom, since Effect has a
32
+ * single `Tracer` reference and someone who pointed React Doctor at their own
33
+ * collector meant it.
131
34
  *
132
- * 1. **User OTLP backend** (`REACT_DOCTOR_OTLP_*` set) wins; we additionally
133
- * parent the Effect trace under the active Sentry trace via an
134
- * `ExternalSpan` so a trace exported to the user's backend shares its
135
- * `trace_id` with the corresponding Sentry trace.
136
- * 2. **Sentry tracing active** (and no user OTLP): route Effect's existing
137
- * span instrumentation straight into Sentry as one unified per-run trace.
138
- * 3. **Neither**: provide the (no-op) OTLP layer, leaving Effect's native
139
- * in-memory tracer — identical to the prior default behavior.
35
+ * A pass-through when telemetry is off, leaving Effect's native in-memory
36
+ * tracer — identical to the prior default behavior.
140
37
  */
141
- const applyObservability = (program, rootSentrySpan) => {
142
- if (isOtlpExportConfigured()) return (rootSentrySpan ? program.pipe(provideService(ParentSpan, externalSpanFrom(rootSentrySpan))) : program).pipe(provide(layerOtlp));
143
- if (rootSentrySpan) return program.pipe(withTracer(makeSentryTracer(rootSentrySpan)));
144
- return program.pipe(provide(layerOtlp));
38
+ const applyObservability = (program, rootSpan) => {
39
+ const telemetryContext = getTelemetryContext();
40
+ if (telemetryContext === null) return program;
41
+ const withBackend = program.pipe(provideContext(telemetryContext));
42
+ return rootSpan === void 0 ? withBackend : withBackend.pipe(provideService(ParentSpan, rootSpan));
145
43
  };
146
44
  //#endregion
147
45
  //#region src/cli/utils/build-runtime-layers.ts
@@ -201,81 +99,105 @@ const buildRuntimeLayers = (input) => {
201
99
  return input.oxlintSpawnSlots === void 0 ? layersWithConcurrency : mergeAll(layersWithConcurrency, succeed(OxlintSpawnSlots, input.oxlintSpawnSlots));
202
100
  };
203
101
  //#endregion
204
- //#region src/cli/utils/with-sentry-run-span.ts
102
+ //#region src/cli/utils/with-run-span.ts
103
+ /**
104
+ * Ends the run span without letting a telemetry failure change the run's
105
+ * outcome — the invariant every other emit site here already holds.
106
+ *
107
+ * The failure path is the reason this matters most: a throw from `end` there
108
+ * would replace the user's original scan error, so a project-config mistake
109
+ * could surface as an exporter stack trace, be reclassified as a crash, and get
110
+ * reported as one.
111
+ */
112
+ const endSpanSafely = (span, exit) => {
113
+ try {
114
+ span.end(BigInt(Date.now()) * NANOSECONDS_PER_MILLISECOND, exit);
115
+ } catch {}
116
+ };
205
117
  /**
206
- * Clears the module-level run-scoped Sentry state — the current scanned project
207
- * and the active run trace. `inspect()` calls this at the start of every run and
208
- * again after a clean one, so a prior or just-finished scan can't attach its
209
- * project tags / trace to a later run or to a non-scan error (e.g.
118
+ * Clears the module-level run-scoped telemetry state — the current scanned
119
+ * project and the active run trace. `inspect()` calls this at the start of every
120
+ * run and again after a clean one, so a prior or just-finished scan can't attach
121
+ * its project tags / trace to a later run or to a non-scan error (e.g.
210
122
  * inspectAction's post-loop finalize/handoff steps). A thrown scan error skips
211
123
  * the post-run reset, leaving the state for the command catch to attribute and
212
124
  * link the crash. Concurrent batch members (`concurrentScan`) never touch this
213
- * state — they neither write nor reset it. Safe to call when Sentry is off (the
214
- * refs are read only when an event is built).
125
+ * state — they neither write nor reset it. Safe to call when telemetry is off
126
+ * (the refs are read only when an event is built).
215
127
  */
216
128
  const resetSentryRunState = () => {
217
129
  setSentryProjectInfo(null);
218
130
  setActiveRunTrace(null);
219
131
  };
220
132
  /**
221
- * Runs an inspect invocation inside a Sentry root span (transaction) so each
222
- * `react-doctor` run is a first-class trace with timing and the run snapshot as
223
- * attributes. The span is handed to `run` so the Effect→Sentry tracer bridge
224
- * can parent its spans under it.
133
+ * Runs an inspect invocation inside a root span so each `react-doctor` run is a
134
+ * first-class trace with timing and the run snapshot as attributes. The span is
135
+ * handed to `run` so the scan's Effect spans parent under it and so the wide
136
+ * event can be stamped onto it once the outcome is known.
225
137
  *
226
- * A no-op pass-through when Sentry performance tracing is off (Sentry disabled,
227
- * `--no-score`, tests, or `SENTRY_TRACES_SAMPLE_RATE=0`) — `run` receives
228
- * `undefined` and no transaction is created, so there's no added exit latency.
138
+ * A no-op pass-through when telemetry is off (`--no-telemetry`, tests, or an
139
+ * unconfigured build) — `run` receives `undefined` and no span is created, so
140
+ * there's no added exit latency.
141
+ *
142
+ * The span is created against the shared telemetry context rather than a
143
+ * freshly-provided layer, so it lives in the same tracer as the scan program's
144
+ * spans; see `telemetry-runtime.ts` for why that matters. It is started and
145
+ * ended manually because the body it wraps is a promise-returning imperative
146
+ * function, not an Effect — the same shape the Sentry inactive span had.
229
147
  *
230
148
  * While the span runs, its trace context is recorded as the active run trace so
231
149
  * `reportErrorToSentry` can attach a crash thrown during the scan back to this
232
- * transaction's trace (errors surface in the command catch, after the span has
233
- * ended). `inspect()` owns clearing it (and the scanned project): it resets the
234
- * state right after a clean run and at the start of the next one, so the trace
235
- * is never attached to a non-scan error; on a thrown error the state is left in
236
- * place for the command catch, then the process exits.
150
+ * trace (errors surface in the command catch, after the span has ended).
237
151
  *
238
- * A `concurrentScan` (one member of the CLI's multi-project pool) still gets
239
- * its own root span, but skips recording the active run trace — the module-
240
- * level handle has single-scan semantics, and overlapping writers would link a
241
- * crash to an arbitrary sibling's trace.
152
+ * A `concurrentScan` (one member of the CLI's multi-project pool) still gets its
153
+ * own root span, but skips recording the active run trace — the module-level
154
+ * handle has single-scan semantics, and overlapping writers would link a crash
155
+ * to an arbitrary sibling's trace.
242
156
  */
243
- const withSentryRunSpan = (run, options = {}) => {
244
- if (!isSentryTracingEnabled()) return run(void 0);
157
+ const withRunSpan = async (run, options = {}) => {
158
+ const telemetryContext = getTelemetryContext();
159
+ if (telemetryContext === null) return run(void 0);
245
160
  const { tags } = buildSentryScope();
246
161
  const command = typeof tags.command === "string" ? tags.command : "inspect";
247
- return Sentry.startSpan({
248
- name: `react-doctor ${command}`,
249
- op: "cli.inspect",
250
- attributes: toSpanAttributes(tags)
251
- }, (rootSpan) => {
252
- const spanContext = rootSpan.spanContext();
253
- recordRunTraceId(spanContext.traceId);
254
- if (options.concurrentScan !== true) setActiveRunTrace({
255
- traceId: spanContext.traceId,
256
- spanId: spanContext.spanId,
257
- sampled: (spanContext.traceFlags & 1) === 1
258
- });
259
- return run(rootSpan);
162
+ let rootSpan;
163
+ try {
164
+ rootSpan = runSync(makeSpan(`react-doctor ${command}`, { attributes: toSpanAttributes(tags) }).pipe(provideContext(telemetryContext)));
165
+ } catch {
166
+ return run(void 0);
167
+ }
168
+ recordRunTraceId(rootSpan.traceId);
169
+ if (options.concurrentScan !== true) setActiveRunTrace({
170
+ traceId: rootSpan.traceId,
171
+ spanId: rootSpan.spanId,
172
+ sampled: rootSpan.sampled
260
173
  });
174
+ try {
175
+ const result = await run(rootSpan);
176
+ endSpanSafely(rootSpan, void_);
177
+ return result;
178
+ } catch (error) {
179
+ endSpanSafely(rootSpan, fail(error));
180
+ throw error;
181
+ }
261
182
  };
262
183
  /**
263
- * Records the scanned project (discovered in the `beforeLint` hook) for Sentry:
264
- * remembers it for the lazy error-capture path (`buildSentryScope` folds it into
265
- * exception events) and, when tracing is live, sets it as attributes on the
266
- * run's root span so the transaction/trace carries the project shape too.
267
- * Always cheap — the span attribute set is skipped when `rootSpan` is absent
268
- * (tracing off), and storing the info is a plain assignment.
184
+ * Records the scanned project (discovered in the `beforeLint` hook): remembers
185
+ * it for the lazy Sentry error-capture path (`buildSentryScope` folds it into
186
+ * exception events) and for per-emit metric attributes, and sets it on the run's
187
+ * root span so the trace carries the project shape too. Always cheap — the span
188
+ * attributes are skipped when `rootSpan` is absent (telemetry off), and storing
189
+ * the info is a plain assignment.
269
190
  *
270
- * A `concurrentScan` only sets the span attributes: the module-level project
271
- * ref has single-scan semantics, and overlapping writers would stamp events
272
- * and metrics with an arbitrary sibling's project. Wide events keep full
273
- * attribution (they ride the span); per-emit metrics simply omit the project
274
- * shape during a concurrent batch (absent, never wrong).
191
+ * A `concurrentScan` only sets the span attributes: the module-level project ref
192
+ * has single-scan semantics, and overlapping writers would stamp events and
193
+ * metrics with an arbitrary sibling's project. Wide events keep full attribution
194
+ * (they ride the span); per-emit metrics simply omit the project shape during a
195
+ * concurrent batch (absent, never wrong).
275
196
  */
276
197
  const recordSentryProjectContext = (projectInfo, rootSpan, options = {}) => {
277
198
  if (options.concurrentScan !== true) setSentryProjectInfo(projectInfo);
278
- rootSpan?.setAttributes(toSpanAttributes(buildSentryProjectContext(projectInfo).tags));
199
+ if (rootSpan === void 0) return;
200
+ for (const [key, value] of Object.entries(toSpanAttributes(buildSentryProjectContext(projectInfo).tags))) rootSpan.attribute(key, value);
279
201
  };
280
202
  //#endregion
281
203
  //#region src/cli/utils/diagnostic-grouping.ts
@@ -1187,7 +1109,7 @@ const buildRunEventAttributes = (input) => toSpanAttributes({
1187
1109
  const recordRunEvent = (rootSpan, input) => {
1188
1110
  if (!rootSpan) return;
1189
1111
  try {
1190
- rootSpan.setAttributes(buildRunEventAttributes(input));
1112
+ for (const [key, value] of Object.entries(buildRunEventAttributes(input))) rootSpan.attribute(key, value);
1191
1113
  } catch {}
1192
1114
  };
1193
1115
  //#endregion
@@ -1738,7 +1660,7 @@ const renderAndRecordScan = async (input) => {
1738
1660
  userConfig: input.payload.userConfig,
1739
1661
  suppressedRuleCounts: input.payload.suppressedRuleCounts ?? []
1740
1662
  });
1741
- recordRunEvent(input.rootSentrySpan, {
1663
+ recordRunEvent(input.rootSpan, {
1742
1664
  ...buildRunEventConfig(input.options, input.payload.userConfig, resolvedWorkerCount),
1743
1665
  result,
1744
1666
  mode: input.scanMode,
@@ -2298,7 +2220,7 @@ const createScanResultCacheLifecycle = (input) => {
2298
2220
  return {
2299
2221
  replay: () => {
2300
2222
  if (cachedPayload === null) return null;
2301
- recordSentryProjectContext(cachedPayload.project, input.rootSentrySpan, { concurrentScan: input.options.concurrentScan });
2223
+ recordSentryProjectContext(cachedPayload.project, input.rootSpan, { concurrentScan: input.options.concurrentScan });
2302
2224
  recordCount(METRIC.projectDetected, 1);
2303
2225
  const isDiffMode = input.options.includePaths.length > 0;
2304
2226
  const baselineDegraded = Boolean(input.options.baseline) && isDiffMode && cachedPayload.baselineDelta === void 0;
@@ -2306,7 +2228,7 @@ const createScanResultCacheLifecycle = (input) => {
2306
2228
  payload: cachedPayload,
2307
2229
  options: input.options,
2308
2230
  startTime: input.startTime,
2309
- rootSentrySpan: input.rootSentrySpan,
2231
+ rootSpan: input.rootSpan,
2310
2232
  scanMode: cachedPayload.baselineDelta ? "baseline" : isDiffMode ? "diff" : "full",
2311
2233
  baselineDegraded,
2312
2234
  wholeRepoCacheHit: true
@@ -2318,7 +2240,7 @@ const createScanResultCacheLifecycle = (input) => {
2318
2240
  payload: completion.payload,
2319
2241
  options: input.options,
2320
2242
  startTime: input.startTime,
2321
- rootSentrySpan: input.rootSentrySpan,
2243
+ rootSpan: input.rootSpan,
2322
2244
  scanMode: completion.scanMode,
2323
2245
  baselineDegraded: completion.baselineDegraded,
2324
2246
  wholeRepoCacheHit: false,
@@ -2355,11 +2277,11 @@ const inspectWithOxlintRuntime = async (directory, inputOptions, oxlintRuntime)
2355
2277
  const wasSpinnerSilent = isSpinnerSilent();
2356
2278
  if (ownsSpinnerSilence) setSpinnerSilent(true);
2357
2279
  try {
2358
- const result = await withSentryRunSpan(async (rootSentrySpan) => {
2280
+ const result = await withRunSpan(async (rootSpan) => {
2359
2281
  try {
2360
- return await runInspectWithRuntime(scanDirectory, options, userConfig, hasConfigOverride, configSourceDirectory, startTime, deadlineEpochMs, rootSentrySpan, oxlintRuntime);
2282
+ return await runInspectWithRuntime(scanDirectory, options, userConfig, hasConfigOverride, configSourceDirectory, startTime, deadlineEpochMs, rootSpan, oxlintRuntime);
2361
2283
  } catch (error) {
2362
- recordRunEvent(rootSentrySpan, {
2284
+ recordRunEvent(rootSpan, {
2363
2285
  ...buildRunEventConfig(options, userConfig),
2364
2286
  mode: options.includePaths.length > 0 ? "diff" : "full",
2365
2287
  error
@@ -2393,7 +2315,7 @@ const createInvocationInspect = (requestedOxlintConcurrency) => {
2393
2315
  };
2394
2316
  };
2395
2317
  const inspect = async (directory, inputOptions = {}) => createInvocationInspect(inputOptions.concurrency)(directory, inputOptions);
2396
- const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOverride, configSourceDirectory, startTime, deadlineEpochMs, rootSentrySpan, oxlintRuntime) => {
2318
+ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOverride, configSourceDirectory, startTime, deadlineEpochMs, rootSpan, oxlintRuntime) => {
2397
2319
  const isDiffMode = options.includePaths.length > 0;
2398
2320
  const resolvedNodeBinaryPath = await resolveOxlintNode(options.lint, options.scoreOnly || options.silent);
2399
2321
  const lintBindingMissing = options.lint && !resolvedNodeBinaryPath;
@@ -2407,7 +2329,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
2407
2329
  resolvedNodeBinaryPath,
2408
2330
  invocationState: oxlintRuntime.scanResultCacheInvocationState,
2409
2331
  startTime,
2410
- rootSentrySpan
2332
+ rootSpan
2411
2333
  });
2412
2334
  const cachedResult = scanResultCacheLifecycle.replay();
2413
2335
  if (cachedResult !== null) return cachedResult;
@@ -2451,10 +2373,10 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
2451
2373
  excludedProjectDirectories: options.excludedProjectDirectories,
2452
2374
  retainExcludedProjectDeadCodeDiagnostics: options.retainExcludedProjectDeadCodeDiagnostics
2453
2375
  }, { beforeLint: (projectInfo) => sync(() => {
2454
- recordSentryProjectContext(projectInfo, rootSentrySpan, { concurrentScan: options.concurrentScan });
2376
+ recordSentryProjectContext(projectInfo, rootSpan, { concurrentScan: options.concurrentScan });
2455
2377
  recordCount(METRIC.projectDetected, 1);
2456
2378
  }) });
2457
- const output = await runPromise(restoreLegacyThrow(applyObservability(options.silent ? program.pipe(provide(layers), provideService(Console, silentConsole)) : program.pipe(provide(layers)), rootSentrySpan)), { signal: oxlintRuntime.abortSignal });
2379
+ const output = await runPromise(restoreLegacyThrow(applyObservability(options.silent ? program.pipe(provide(layers), provideService(Console, silentConsole)) : program.pipe(provide(layers)), rootSpan)), { signal: oxlintRuntime.abortSignal });
2458
2380
  const didLintFail = lintBindingMissing || output.didLintFail;
2459
2381
  const lintFailureReason = lintBindingMissing ? `oxlint native binding not found for Node ${process.version}; expected one matching ${OXLINT_NODE_REQUIREMENT}` : output.lintFailureReason;
2460
2382
  if (!options.scoreOnly && !options.uiLayers && !lintBindingMissing && output.didLintFail && lintFailureReason !== null) if (output.lintFailureReasonKind === "native-binding-missing") runSync(log(highlighter.gray(` Upgrade to Node ${OXLINT_NODE_REQUIREMENT} or run: npx -p oxlint@latest react-doctor@latest`)));
@@ -3071,5 +2993,5 @@ const shouldFailScanGate = (input) => {
3071
2993
  //#endregion
3072
2994
  export { resolveMergeBaseRef as A, buildEmptyReportMessage as B, copyToClipboard as C, deduplicateProjectScans as D, collectProjectSourceFileCounts as E, printDiagnosticsDump as F, formatLearnMoreLine as G, buildRulePriorityMap as H, formatDiagnosticSite as I, hasIncompleteScoreAnalysis as L, pluralize as M, formatElapsedTime as N, createInvocationInspect as O, printFooter as P, filterDiagnosticsByCategories as R, CLI_AGENT_BINARIES as S, buildHandoffPayload as T, buildSortedRuleGroups as U, hasLintHardFailure as V, formatFixRecipeLine as W, resolveCliInspectOptions as _, projectManifestChanged as a, setUpGitHubActions as b, selectProjects as c, resolveProjectChangedLineRanges as d, resolveProjectDiffIncludePaths as f, resolveWorkspaceDeadCodeOwner as g, retryMissingProjectScores as h, validateModeFlags as i, printHeadlessReport as j, inspect as k, buildCodeFrame as l, resolveProjectRelativeDirectory as m, formatSkippedProjectsMessage as n, partitionProjectScanOutcomes as o, resolveProjectSourceFilePaths as p, validateIncludeUntrackedScope as r, discoverWorkspacePackages as s, shouldFailScanGate as t, resolveProjectScan as u, filterScansForSurface as v, launchCliAgent as w, detectLaunchableAgents as x, countUniqueScannedFiles as y, buildNoScoreMessage as z };
3073
2995
 
3074
- //# sourceMappingURL=should-fail-scan-gate-Bif6gnI9.js.map
3075
- //# debugId=c4293bd1-fbc8-59a4-8a5f-0fc1e2e1624c
2996
+ //# sourceMappingURL=should-fail-scan-gate-B5XfdAMg.js.map
2997
+ //# debugId=64dd164d-d176-539f-b7f8-b4217a0009df
@@ -1,10 +1,10 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c3bf0df5-99dc-53b4-833b-a4de60a0f821")}catch(e){}}();
3
- import { P as isNonInteractiveEnvironment } from "./record-metric-b5KUd2XK.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b49fd4c3-3be0-52f6-9e01-f9bef8d28fc1")}catch(e){}}();
3
+ import { z as isNonInteractiveEnvironment } from "./record-metric-CuPtdZfm.js";
4
4
  //#region src/cli/utils/should-skip-prompts.ts
5
5
  const shouldSkipPrompts = (input = {}) => Boolean(input.yes) || Boolean(input.json) || isNonInteractiveEnvironment() || !process.stdin.isTTY;
6
6
  //#endregion
7
7
  export { shouldSkipPrompts as t };
8
8
 
9
- //# sourceMappingURL=should-skip-prompts-Q3cS356Z.js.map
10
- //# debugId=c3bf0df5-99dc-53b4-833b-a4de60a0f821
9
+ //# sourceMappingURL=should-skip-prompts-DaBGPwa3.js.map
10
+ //# debugId=b49fd4c3-3be0-52f6-9e01-f9bef8d28fc1
@@ -1,6 +1,6 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="42719bad-9cd7-5a1f-ad59-9a375ea67f01")}catch(e){}}();
3
- import { N as CliInputError, cn as isReactDoctorError, nn as isErrnoException, sn as isProjectDiscoveryError, vn as messageFromUnknown } from "./record-metric-b5KUd2XK.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c98da11e-f692-57c2-842b-457b988f926b")}catch(e){}}();
3
+ import { En as messageFromUnknown, R as CliInputError, Yn as make, ar as runSync, g as VERSION, gn as isReactDoctorError, gr as void_, hn as isProjectDiscoveryError, i as isTelemetryEnabled, ir as runPromise, lr as buildWithScope, mr as makeUnsafe, pr as close, un as isErrnoException, yn as layerObservability } from "./record-metric-CuPtdZfm.js";
4
4
  //#region src/cli/utils/is-environment-error.ts
5
5
  const ENVIRONMENT_ERROR_CODES = new Set([
6
6
  "EACCES",
@@ -96,6 +96,113 @@ const formatEnvironmentError = (error) => {
96
96
  */
97
97
  const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
98
98
  //#endregion
99
+ //#region src/cli/utils/resolve-axiom-telemetry-options.ts
100
+ /**
101
+ * Resolves the credentials for first-party Axiom export, or `null` when this
102
+ * process must not emit telemetry.
103
+ *
104
+ * Core deliberately does not read these itself — keeping the token on the CLI
105
+ * side is what makes `@react-doctor/api` silent by construction rather than by a
106
+ * runtime guard.
107
+ *
108
+ * Returning `null` for an empty token means an unconfigured build (or a
109
+ * contributor's checkout without the token baked in) simply doesn't export,
110
+ * instead of sending unauthenticated requests to Axiom on every run.
111
+ *
112
+ * The overrides are `REACT_DOCTOR_`-prefixed rather than the bare `AXIOM_TOKEN`
113
+ * / `AXIOM_DATASET` names Axiom's own tooling uses. Those are common in the
114
+ * environment of anyone who already runs Axiom, and reading them here would
115
+ * silently redirect React Doctor's telemetry into an unrelated account — or
116
+ * fail against a dataset that isn't shaped for it — without the user ever
117
+ * asking for that.
118
+ */
119
+ const resolveAxiomTelemetryOptions = () => {
120
+ if (!isTelemetryEnabled()) return null;
121
+ const token = process.env.REACT_DOCTOR_AXIOM_TOKEN || "xaat-31b59107-855d-4917-8fab-6dc29fb459ce";
122
+ if (!token) return null;
123
+ return {
124
+ token: make(token),
125
+ domain: process.env.REACT_DOCTOR_AXIOM_DOMAIN || "https://api.axiom.co",
126
+ tracesDataset: process.env.REACT_DOCTOR_AXIOM_DATASET || "react-doctor",
127
+ metricsDataset: process.env.REACT_DOCTOR_AXIOM_METRICS_DATASET || "react-doctor-metrics",
128
+ serviceVersion: VERSION
129
+ };
130
+ };
131
+ //#endregion
132
+ //#region src/cli/utils/telemetry-runtime.ts
133
+ const isUserOtlpConfigured = () => Boolean(process.env.REACT_DOCTOR_OTLP_ENDPOINT) && Boolean(process.env.REACT_DOCTOR_OTLP_AUTH_HEADER);
134
+ let telemetryScope = null;
135
+ let telemetryContext = null;
136
+ let isBuilt = false;
137
+ let pendingShutdown = null;
138
+ /**
139
+ * Builds the telemetry layer once and hands back its context.
140
+ *
141
+ * The CLI is an imperative shell around several separate `Effect.runPromise`
142
+ * calls — the scan program, the renderer, and the run root span all run
143
+ * independently. Providing a fresh layer to each would create a separate set of
144
+ * OTLP exporters per program: each holds its own span buffer and its own
145
+ * shutdown flush, so exit latency would multiply, the root span would land in a
146
+ * different export than its children, and — because Effect tracks
147
+ * delta-temporality state per exporter instance — every counter would be
148
+ * re-reported in full by each new metrics exporter.
149
+ *
150
+ * Building into a long-lived scope instead means one tracer and one metrics
151
+ * exporter shared by all of them: child spans nest under the run span natively,
152
+ * with no `ExternalSpan` stitching, and one flush at exit ships both signals.
153
+ *
154
+ * Returns `null` when telemetry is disabled or unconfigured, which is what keeps
155
+ * `--no-telemetry` and unconfigured builds from opening a scope at all.
156
+ *
157
+ * `exportIntervalMs` lets a long-running process (the language server) ship
158
+ * telemetry periodically instead of only at shutdown.
159
+ */
160
+ const getTelemetryContext = (overrides = {}) => {
161
+ if (isBuilt) return telemetryContext;
162
+ isBuilt = true;
163
+ if (!isTelemetryEnabled()) return null;
164
+ const options = resolveAxiomTelemetryOptions();
165
+ if (options === null && !isUserOtlpConfigured()) return null;
166
+ try {
167
+ const scope = makeUnsafe();
168
+ telemetryContext = runSync(buildWithScope(layerObservability(options === null ? null : {
169
+ ...options,
170
+ ...overrides
171
+ }), scope));
172
+ telemetryScope = scope;
173
+ } catch {
174
+ telemetryContext = null;
175
+ telemetryScope = null;
176
+ }
177
+ return telemetryContext;
178
+ };
179
+ /**
180
+ * Closes the telemetry scope, which is what ships buffered spans and metrics.
181
+ *
182
+ * Both exporters flush during scope finalization, bounded by
183
+ * `TELEMETRY_SHUTDOWN_TIMEOUT_MS`. Because the scope is built once and shared,
184
+ * there is exactly one of each exporter per process — which is what keeps
185
+ * metrics honest: Effect tracks delta-temporality state on the exporter
186
+ * instance, so a second one would start with no previous snapshot and re-report
187
+ * every counter's full value, doubling every metric.
188
+ *
189
+ * Memoized for the same reason: several exit paths can fire (a `--debug` user
190
+ * error flushes, then the top-level catch flushes again), and repeat callers
191
+ * must await the original shutdown rather than start a second one.
192
+ *
193
+ * Swallows failures so telemetry can never mask the user's result.
194
+ */
195
+ const shutdownTelemetry = async () => {
196
+ if (pendingShutdown !== null) return pendingShutdown;
197
+ getTelemetryContext();
198
+ const scope = telemetryScope;
199
+ if (scope === null) return;
200
+ telemetryScope = null;
201
+ telemetryContext = null;
202
+ pendingShutdown = runPromise(close(scope, void_)).catch(() => {});
203
+ return pendingShutdown;
204
+ };
205
+ //#endregion
99
206
  //#region src/cli/utils/active-run-trace.ts
100
207
  let activeRunTrace = null;
101
208
  const setActiveRunTrace = (trace) => {
@@ -114,7 +221,7 @@ const unrefStdin = () => {
114
221
  process.stdin.unref?.();
115
222
  };
116
223
  //#endregion
117
- export { setActiveRunTrace as a, isEnvironmentError as c, recordRunTraceId as i, getActiveRunTrace as n, isExpectedUserError as o, getLastRunTraceId as r, formatEnvironmentError as s, unrefStdin as t };
224
+ export { setActiveRunTrace as a, isExpectedUserError as c, recordRunTraceId as i, formatEnvironmentError as l, getActiveRunTrace as n, getTelemetryContext as o, getLastRunTraceId as r, shutdownTelemetry as s, unrefStdin as t, isEnvironmentError as u };
118
225
 
119
- //# sourceMappingURL=unref-stdin-DTLx8HEf.js.map
120
- //# debugId=42719bad-9cd7-5a1f-ad59-9a375ea67f01
226
+ //# sourceMappingURL=unref-stdin-D0Lq28Bk.js.map
227
+ //# debugId=c98da11e-f692-57c2-842b-457b988f926b
@@ -1,6 +1,6 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0a1824b7-507b-51ce-b1ff-2df461594ab9")}catch(e){}}();
3
- import { m as VERSION, t as recordCount, y as METRIC } from "./record-metric-b5KUd2XK.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="10cef2d6-6244-5897-b951-7d7d9bdbf476")}catch(e){}}();
3
+ import { g as VERSION, t as recordCount, w as METRIC } from "./record-metric-CuPtdZfm.js";
4
4
  //#region src/cli/commands/version.ts
5
5
  /**
6
6
  * oclif-style version line. 12-factor CLI Apps (#3, "What version am I
@@ -17,5 +17,5 @@ const versionAction = () => {
17
17
  //#endregion
18
18
  export { versionAction };
19
19
 
20
- //# sourceMappingURL=version-BrAILQSv.js.map
21
- //# debugId=0a1824b7-507b-51ce-b1ff-2df461594ab9
20
+ //# sourceMappingURL=version-CyVLelBf.js.map
21
+ //# debugId=10cef2d6-6244-5897-b951-7d7d9bdbf476
@@ -1,6 +1,6 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5bfd30e1-2aa9-5ce3-9146-943cbecf3f6b")}catch(e){}}();
3
- import { t as inspectAction } from "./inspect-CGCfCxoM.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="79c662d0-5f1b-5d94-b632-bd6ea77829b7")}catch(e){}}();
3
+ import { t as inspectAction } from "./inspect-BQapfOJX.js";
4
4
  //#region src/cli/commands/why.ts
5
5
  /**
6
6
  * `why <file:line>` — explains why a rule fired (or why a suppression didn't
@@ -17,5 +17,5 @@ const whyAction = async (location, options) => {
17
17
  //#endregion
18
18
  export { whyAction };
19
19
 
20
- //# sourceMappingURL=why-DB_XpRpg.js.map
21
- //# debugId=5bfd30e1-2aa9-5ce3-9146-943cbecf3f6b
20
+ //# sourceMappingURL=why-nfPQ3AAq.js.map
21
+ //# debugId=79c662d0-5f1b-5d94-b632-bd6ea77829b7