react-doctor 0.9.2-dev.b31fd85 → 0.9.2-dev.c126684

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
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]="3ced4c14-18cb-5b0c-811c-3448b5c2f139")}catch(e){}}();
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]="bb982094-8280-5afe-b061-eb103665c55c")}catch(e){}}();
3
3
  import { createRequire } from "node:module";
4
4
  import * as NodeChildProcess from "node:child_process";
5
5
  import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
@@ -13,13 +13,14 @@ import * as Crypto from "node:crypto";
13
13
  import crypto, { createHash, randomUUID } from "node:crypto";
14
14
  import { ResolverFactory } from "oxc-resolver";
15
15
  import ts from "typescript";
16
+ import * as NodeUrl from "node:url";
17
+ import { fileURLToPath, pathToFileURL } from "node:url";
16
18
  import * as OS from "node:os";
17
19
  import os, { tmpdir } from "node:os";
18
20
  import { parseJSON5 } from "confbox";
19
- import * as NodeUrl from "node:url";
20
- import { fileURLToPath, pathToFileURL } from "node:url";
21
21
  import { createJiti } from "jiti";
22
22
  import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
23
+ import { convertToTSX } from "@astrojs/compiler/sync";
23
24
  import { gzipSync } from "node:zlib";
24
25
  import * as Sentry from "@sentry/node";
25
26
  import { performance as performance$1 } from "node:perf_hooks";
@@ -13342,7 +13343,7 @@ const Number$4 = globalThis.Number;
13342
13343
  * @category constructors
13343
13344
  * @since 2.0.0
13344
13345
  */
13345
- const parse = (s) => {
13346
+ const parse$1 = (s) => {
13346
13347
  if (s === "NaN") return some(NaN);
13347
13348
  if (s === "Infinity") return some(Infinity);
13348
13349
  if (s === "-Infinity") return some(-Infinity);
@@ -17405,12 +17406,12 @@ TaggedError("EncodingError");
17405
17406
  //#endregion
17406
17407
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/internal/schema/annotations.js
17407
17408
  /** @internal */
17408
- function resolve(ast) {
17409
+ function resolve$1(ast) {
17409
17410
  return ast.checks ? ast.checks[ast.checks.length - 1].annotations : ast.annotations;
17410
17411
  }
17411
17412
  /** @internal */
17412
17413
  function resolveAt(key) {
17413
- return (ast) => resolve(ast)?.[key];
17414
+ return (ast) => resolve$1(ast)?.[key];
17414
17415
  }
17415
17416
  /** @internal */
17416
17417
  const resolveIdentifier = /* @__PURE__ */ resolveAt("identifier");
@@ -21162,7 +21163,7 @@ function asSync(parser) {
21162
21163
  }
21163
21164
  const recur$1 = /* @__PURE__ */ memoize((ast) => {
21164
21165
  let parser;
21165
- const astOptions = resolve(ast)?.["parseOptions"];
21166
+ const astOptions = resolve$1(ast)?.["parseOptions"];
21166
21167
  if (!ast.context && !ast.encoding && !ast.checks) return (ou, options) => {
21167
21168
  parser ??= ast.getParser(recur$1);
21168
21169
  if (astOptions) options = {
@@ -60767,7 +60768,7 @@ var UrlParamsError = class extends TaggedError("UrlParamsError") {};
60767
60768
  * @category converting
60768
60769
  * @since 4.0.0
60769
60770
  */
60770
- const makeUrl = (url, params, hash) => {
60771
+ const makeUrl$1 = (url, params, hash) => {
60771
60772
  try {
60772
60773
  const urlInstance = new URL(url, baseUrl());
60773
60774
  for (let i = 0; i < params.params.length; i++) {
@@ -61401,7 +61402,7 @@ const Proto$2 = {
61401
61402
  const make$10 = (f) => makeWith$1((effect) => flatMap$2(effect, (request) => withFiber((fiber) => {
61402
61403
  const scopedController = scopedRequests.get(request);
61403
61404
  const controller = scopedController ?? new AbortController();
61404
- const urlResult = makeUrl(request.url, request.urlParams, getOrUndefined(request.hash));
61405
+ const urlResult = makeUrl$1(request.url, request.urlParams, getOrUndefined(request.hash));
61405
61406
  if (isFailure(urlResult)) return fail$4(new HttpClientError({ reason: new InvalidUrlError({
61406
61407
  request,
61407
61408
  cause: urlResult.failure
@@ -61840,7 +61841,7 @@ const layer$8 = (loggers, options) => effect(CurrentLoggers, withFiber$1(fnUntra
61840
61841
  * @since 4.0.0
61841
61842
  */
61842
61843
  const policy = /* @__PURE__ */ forever$1.pipe(passthrough$2, /* @__PURE__ */ addDelay((error) => {
61843
- if (isHttpClientError(error) && error.reason._tag === "StatusCodeError" && error.reason.response.status === 429) return succeed$2(seconds(fromUndefinedOr(error.reason.response.headers["retry-after"]).pipe(flatMap$5(parse), getOrElse$1(() => 5))));
61844
+ if (isHttpClientError(error) && error.reason._tag === "StatusCodeError" && error.reason.response.status === 429) return succeed$2(seconds(fromUndefinedOr(error.reason.response.headers["retry-after"]).pipe(flatMap$5(parse$1), getOrElse$1(() => 5))));
61844
61845
  return succeed$2(seconds(1));
61845
61846
  }));
61846
61847
  /**
@@ -64549,6 +64550,428 @@ const layer$1 = /* @__PURE__ */ succeed$3(Path$1)({
64549
64550
  toFileUrl
64550
64551
  });
64551
64552
  //#endregion
64553
+ //#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
64554
+ var comma = ",".charCodeAt(0);
64555
+ ";".charCodeAt(0);
64556
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
64557
+ var intToChar = new Uint8Array(64);
64558
+ var charToInt = new Uint8Array(128);
64559
+ for (let i = 0; i < chars.length; i++) {
64560
+ const c = chars.charCodeAt(i);
64561
+ intToChar[i] = c;
64562
+ charToInt[c] = i;
64563
+ }
64564
+ function decodeInteger(reader, relative) {
64565
+ let value = 0;
64566
+ let shift = 0;
64567
+ let integer = 0;
64568
+ do {
64569
+ integer = charToInt[reader.next()];
64570
+ value |= (integer & 31) << shift;
64571
+ shift += 5;
64572
+ } while (integer & 32);
64573
+ const shouldNegate = value & 1;
64574
+ value >>>= 1;
64575
+ if (shouldNegate) value = -2147483648 | -value;
64576
+ return relative + value;
64577
+ }
64578
+ function hasMoreVlq(reader, max) {
64579
+ if (reader.pos >= max) return false;
64580
+ return reader.peek() !== comma;
64581
+ }
64582
+ var StringReader = class {
64583
+ constructor(buffer) {
64584
+ this.pos = 0;
64585
+ this.buffer = buffer;
64586
+ }
64587
+ next() {
64588
+ return this.buffer.charCodeAt(this.pos++);
64589
+ }
64590
+ peek() {
64591
+ return this.buffer.charCodeAt(this.pos);
64592
+ }
64593
+ indexOf(char) {
64594
+ const { buffer, pos } = this;
64595
+ const idx = buffer.indexOf(char, pos);
64596
+ return idx === -1 ? buffer.length : idx;
64597
+ }
64598
+ };
64599
+ function decode(mappings) {
64600
+ const { length } = mappings;
64601
+ const reader = new StringReader(mappings);
64602
+ const decoded = [];
64603
+ let genColumn = 0;
64604
+ let sourcesIndex = 0;
64605
+ let sourceLine = 0;
64606
+ let sourceColumn = 0;
64607
+ let namesIndex = 0;
64608
+ do {
64609
+ const semi = reader.indexOf(";");
64610
+ const line = [];
64611
+ let sorted = true;
64612
+ let lastCol = 0;
64613
+ genColumn = 0;
64614
+ while (reader.pos < semi) {
64615
+ let seg;
64616
+ genColumn = decodeInteger(reader, genColumn);
64617
+ if (genColumn < lastCol) sorted = false;
64618
+ lastCol = genColumn;
64619
+ if (hasMoreVlq(reader, semi)) {
64620
+ sourcesIndex = decodeInteger(reader, sourcesIndex);
64621
+ sourceLine = decodeInteger(reader, sourceLine);
64622
+ sourceColumn = decodeInteger(reader, sourceColumn);
64623
+ if (hasMoreVlq(reader, semi)) {
64624
+ namesIndex = decodeInteger(reader, namesIndex);
64625
+ seg = [
64626
+ genColumn,
64627
+ sourcesIndex,
64628
+ sourceLine,
64629
+ sourceColumn,
64630
+ namesIndex
64631
+ ];
64632
+ } else seg = [
64633
+ genColumn,
64634
+ sourcesIndex,
64635
+ sourceLine,
64636
+ sourceColumn
64637
+ ];
64638
+ } else seg = [genColumn];
64639
+ line.push(seg);
64640
+ reader.pos++;
64641
+ }
64642
+ if (!sorted) sort(line);
64643
+ decoded.push(line);
64644
+ reader.pos = semi + 1;
64645
+ } while (reader.pos <= length);
64646
+ return decoded;
64647
+ }
64648
+ function sort(line) {
64649
+ line.sort(sortComparator$1);
64650
+ }
64651
+ function sortComparator$1(a, b) {
64652
+ return a[0] - b[0];
64653
+ }
64654
+ //#endregion
64655
+ //#region ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
64656
+ const schemeRegex = /^[\w+.-]+:\/\//;
64657
+ /**
64658
+ * Matches the parts of a URL:
64659
+ * 1. Scheme, including ":", guaranteed.
64660
+ * 2. User/password, including "@", optional.
64661
+ * 3. Host, guaranteed.
64662
+ * 4. Port, including ":", optional.
64663
+ * 5. Path, including "/", optional.
64664
+ * 6. Query, including "?", optional.
64665
+ * 7. Hash, including "#", optional.
64666
+ */
64667
+ const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
64668
+ /**
64669
+ * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
64670
+ * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
64671
+ *
64672
+ * 1. Host, optional.
64673
+ * 2. Path, which may include "/", guaranteed.
64674
+ * 3. Query, including "?", optional.
64675
+ * 4. Hash, including "#", optional.
64676
+ */
64677
+ const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
64678
+ function isAbsoluteUrl(input) {
64679
+ return schemeRegex.test(input);
64680
+ }
64681
+ function isSchemeRelativeUrl(input) {
64682
+ return input.startsWith("//");
64683
+ }
64684
+ function isAbsolutePath(input) {
64685
+ return input.startsWith("/");
64686
+ }
64687
+ function isFileUrl(input) {
64688
+ return input.startsWith("file:");
64689
+ }
64690
+ function isRelative(input) {
64691
+ return /^[.?#]/.test(input);
64692
+ }
64693
+ function parseAbsoluteUrl(input) {
64694
+ const match = urlRegex.exec(input);
64695
+ return makeUrl(match[1], match[2] || "", match[3], match[4] || "", match[5] || "/", match[6] || "", match[7] || "");
64696
+ }
64697
+ function parseFileUrl(input) {
64698
+ const match = fileRegex.exec(input);
64699
+ const path = match[2];
64700
+ return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path) ? path : "/" + path, match[3] || "", match[4] || "");
64701
+ }
64702
+ function makeUrl(scheme, user, host, port, path, query, hash) {
64703
+ return {
64704
+ scheme,
64705
+ user,
64706
+ host,
64707
+ port,
64708
+ path,
64709
+ query,
64710
+ hash,
64711
+ type: 7
64712
+ };
64713
+ }
64714
+ function parseUrl(input) {
64715
+ if (isSchemeRelativeUrl(input)) {
64716
+ const url = parseAbsoluteUrl("http:" + input);
64717
+ url.scheme = "";
64718
+ url.type = 6;
64719
+ return url;
64720
+ }
64721
+ if (isAbsolutePath(input)) {
64722
+ const url = parseAbsoluteUrl("http://foo.com" + input);
64723
+ url.scheme = "";
64724
+ url.host = "";
64725
+ url.type = 5;
64726
+ return url;
64727
+ }
64728
+ if (isFileUrl(input)) return parseFileUrl(input);
64729
+ if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);
64730
+ const url = parseAbsoluteUrl("http://foo.com/" + input);
64731
+ url.scheme = "";
64732
+ url.host = "";
64733
+ url.type = input ? input.startsWith("?") ? 3 : input.startsWith("#") ? 2 : 4 : 1;
64734
+ return url;
64735
+ }
64736
+ function stripPathFilename(path) {
64737
+ if (path.endsWith("/..")) return path;
64738
+ const index = path.lastIndexOf("/");
64739
+ return path.slice(0, index + 1);
64740
+ }
64741
+ function mergePaths(url, base) {
64742
+ normalizePath(base, base.type);
64743
+ if (url.path === "/") url.path = base.path;
64744
+ else url.path = stripPathFilename(base.path) + url.path;
64745
+ }
64746
+ /**
64747
+ * The path can have empty directories "//", unneeded parents "foo/..", or current directory
64748
+ * "foo/.". We need to normalize to a standard representation.
64749
+ */
64750
+ function normalizePath(url, type) {
64751
+ const rel = type <= 4;
64752
+ const pieces = url.path.split("/");
64753
+ let pointer = 1;
64754
+ let positive = 0;
64755
+ let addTrailingSlash = false;
64756
+ for (let i = 1; i < pieces.length; i++) {
64757
+ const piece = pieces[i];
64758
+ if (!piece) {
64759
+ addTrailingSlash = true;
64760
+ continue;
64761
+ }
64762
+ addTrailingSlash = false;
64763
+ if (piece === ".") continue;
64764
+ if (piece === "..") {
64765
+ if (positive) {
64766
+ addTrailingSlash = true;
64767
+ positive--;
64768
+ pointer--;
64769
+ } else if (rel) pieces[pointer++] = piece;
64770
+ continue;
64771
+ }
64772
+ pieces[pointer++] = piece;
64773
+ positive++;
64774
+ }
64775
+ let path = "";
64776
+ for (let i = 1; i < pointer; i++) path += "/" + pieces[i];
64777
+ if (!path || addTrailingSlash && !path.endsWith("/..")) path += "/";
64778
+ url.path = path;
64779
+ }
64780
+ /**
64781
+ * Attempts to resolve `input` URL/path relative to `base`.
64782
+ */
64783
+ function resolve(input, base) {
64784
+ if (!input && !base) return "";
64785
+ const url = parseUrl(input);
64786
+ let inputType = url.type;
64787
+ if (base && inputType !== 7) {
64788
+ const baseUrl = parseUrl(base);
64789
+ const baseType = baseUrl.type;
64790
+ switch (inputType) {
64791
+ case 1: url.hash = baseUrl.hash;
64792
+ case 2: url.query = baseUrl.query;
64793
+ case 3:
64794
+ case 4: mergePaths(url, baseUrl);
64795
+ case 5:
64796
+ url.user = baseUrl.user;
64797
+ url.host = baseUrl.host;
64798
+ url.port = baseUrl.port;
64799
+ case 6: url.scheme = baseUrl.scheme;
64800
+ }
64801
+ if (baseType > inputType) inputType = baseType;
64802
+ }
64803
+ normalizePath(url, inputType);
64804
+ const queryHash = url.query + url.hash;
64805
+ switch (inputType) {
64806
+ case 2:
64807
+ case 3: return queryHash;
64808
+ case 4: {
64809
+ const path = url.path.slice(1);
64810
+ if (!path) return queryHash || ".";
64811
+ if (isRelative(base || input) && !isRelative(path)) return "./" + path + queryHash;
64812
+ return path + queryHash;
64813
+ }
64814
+ case 5: return url.path + queryHash;
64815
+ default: return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
64816
+ }
64817
+ }
64818
+ //#endregion
64819
+ //#region ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
64820
+ function stripFilename(path) {
64821
+ if (!path) return "";
64822
+ const index = path.lastIndexOf("/");
64823
+ return path.slice(0, index + 1);
64824
+ }
64825
+ function resolver(mapUrl, sourceRoot) {
64826
+ const from = stripFilename(mapUrl);
64827
+ const prefix = sourceRoot ? sourceRoot + "/" : "";
64828
+ return (source) => resolve(prefix + (source || ""), from);
64829
+ }
64830
+ var COLUMN = 0;
64831
+ var SOURCES_INDEX = 1;
64832
+ var SOURCE_LINE = 2;
64833
+ var SOURCE_COLUMN = 3;
64834
+ var NAMES_INDEX = 4;
64835
+ function maybeSort(mappings, owned) {
64836
+ const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
64837
+ if (unsortedIndex === mappings.length) return mappings;
64838
+ if (!owned) mappings = mappings.slice();
64839
+ for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) mappings[i] = sortSegments(mappings[i], owned);
64840
+ return mappings;
64841
+ }
64842
+ function nextUnsortedSegmentLine(mappings, start) {
64843
+ for (let i = start; i < mappings.length; i++) if (!isSorted(mappings[i])) return i;
64844
+ return mappings.length;
64845
+ }
64846
+ function isSorted(line) {
64847
+ for (let j = 1; j < line.length; j++) if (line[j][COLUMN] < line[j - 1][COLUMN]) return false;
64848
+ return true;
64849
+ }
64850
+ function sortSegments(line, owned) {
64851
+ if (!owned) line = line.slice();
64852
+ return line.sort(sortComparator);
64853
+ }
64854
+ function sortComparator(a, b) {
64855
+ return a[COLUMN] - b[COLUMN];
64856
+ }
64857
+ var found = false;
64858
+ function binarySearch(haystack, needle, low, high) {
64859
+ while (low <= high) {
64860
+ const mid = low + (high - low >> 1);
64861
+ const cmp = haystack[mid][COLUMN] - needle;
64862
+ if (cmp === 0) {
64863
+ found = true;
64864
+ return mid;
64865
+ }
64866
+ if (cmp < 0) low = mid + 1;
64867
+ else high = mid - 1;
64868
+ }
64869
+ found = false;
64870
+ return low - 1;
64871
+ }
64872
+ function upperBound(haystack, needle, index) {
64873
+ for (let i = index + 1; i < haystack.length; index = i++) if (haystack[i][COLUMN] !== needle) break;
64874
+ return index;
64875
+ }
64876
+ function lowerBound(haystack, needle, index) {
64877
+ for (let i = index - 1; i >= 0; index = i--) if (haystack[i][COLUMN] !== needle) break;
64878
+ return index;
64879
+ }
64880
+ function memoizedState() {
64881
+ return {
64882
+ lastKey: -1,
64883
+ lastNeedle: -1,
64884
+ lastIndex: -1
64885
+ };
64886
+ }
64887
+ function memoizedBinarySearch(haystack, needle, state, key) {
64888
+ const { lastKey, lastNeedle, lastIndex } = state;
64889
+ let low = 0;
64890
+ let high = haystack.length - 1;
64891
+ if (key === lastKey) {
64892
+ if (needle === lastNeedle) {
64893
+ found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
64894
+ return lastIndex;
64895
+ }
64896
+ if (needle >= lastNeedle) low = lastIndex === -1 ? 0 : lastIndex;
64897
+ else high = lastIndex;
64898
+ }
64899
+ state.lastKey = key;
64900
+ state.lastNeedle = needle;
64901
+ return state.lastIndex = binarySearch(haystack, needle, low, high);
64902
+ }
64903
+ function parse(map) {
64904
+ return typeof map === "string" ? JSON.parse(map) : map;
64905
+ }
64906
+ var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
64907
+ var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
64908
+ var TraceMap = class {
64909
+ constructor(map, mapUrl) {
64910
+ const isString = typeof map === "string";
64911
+ if (!isString && map._decodedMemo) return map;
64912
+ const parsed = parse(map);
64913
+ const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
64914
+ this.version = version;
64915
+ this.file = file;
64916
+ this.names = names || [];
64917
+ this.sourceRoot = sourceRoot;
64918
+ this.sources = sources;
64919
+ this.sourcesContent = sourcesContent;
64920
+ this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
64921
+ const resolve = resolver(mapUrl, sourceRoot);
64922
+ this.resolvedSources = sources.map(resolve);
64923
+ const { mappings } = parsed;
64924
+ if (typeof mappings === "string") {
64925
+ this._encoded = mappings;
64926
+ this._decoded = void 0;
64927
+ } else if (Array.isArray(mappings)) {
64928
+ this._encoded = void 0;
64929
+ this._decoded = maybeSort(mappings, isString);
64930
+ } else if (parsed.sections) throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`);
64931
+ else throw new Error(`invalid source map: ${JSON.stringify(parsed)}`);
64932
+ this._decodedMemo = memoizedState();
64933
+ this._bySources = void 0;
64934
+ this._bySourceMemos = void 0;
64935
+ }
64936
+ };
64937
+ function cast(map) {
64938
+ return map;
64939
+ }
64940
+ function decodedMappings(map) {
64941
+ var _a;
64942
+ return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded));
64943
+ }
64944
+ function originalPositionFor(map, needle) {
64945
+ let { line, column, bias } = needle;
64946
+ line--;
64947
+ if (line < 0) throw new Error(LINE_GTR_ZERO);
64948
+ if (column < 0) throw new Error(COL_GTR_EQ_ZERO);
64949
+ const decoded = decodedMappings(map);
64950
+ if (line >= decoded.length) return OMapping(null, null, null, null);
64951
+ const segments = decoded[line];
64952
+ const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || 1);
64953
+ if (index === -1) return OMapping(null, null, null, null);
64954
+ const segment = segments[index];
64955
+ if (segment.length === 1) return OMapping(null, null, null, null);
64956
+ const { names, resolvedSources } = map;
64957
+ return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
64958
+ }
64959
+ function OMapping(source, line, column, name) {
64960
+ return {
64961
+ source,
64962
+ line,
64963
+ column,
64964
+ name
64965
+ };
64966
+ }
64967
+ function traceSegmentInternal(segments, memo, line, column, bias) {
64968
+ let index = memoizedBinarySearch(segments, column, memo, line);
64969
+ if (found) index = (bias === -1 ? upperBound : lowerBound)(segments, column, index);
64970
+ else if (bias === -1) index++;
64971
+ if (index === -1 || index === segments.length) return -1;
64972
+ return index;
64973
+ }
64974
+ //#endregion
64552
64975
  //#region ../core/dist/index.js
64553
64976
  var __create = Object.create;
64554
64977
  var __defProp = Object.defineProperty;
@@ -64618,7 +65041,7 @@ var AmbiguousProjectError = class extends Error {
64618
65041
  };
64619
65042
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
64620
65043
  const HTML_FILE_PATTERN = /\.html$/i;
64621
- const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
65044
+ const SOURCE_FILE_PATTERN = /\.(?:astro|tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
64622
65045
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
64623
65046
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
64624
65047
  const MINIFIED_SNIFF_BYTES = 65536;
@@ -65375,6 +65798,7 @@ const FRAMEWORK_PACKAGES = {
65375
65798
  "@tanstack/react-start": "tanstack-start",
65376
65799
  "@remix-run/react": "remix",
65377
65800
  gatsby: "gatsby",
65801
+ astro: "astro",
65378
65802
  vite: "vite",
65379
65803
  "react-scripts": "cra",
65380
65804
  expo: "expo",
@@ -65596,10 +66020,16 @@ const getTopLevelBinding = (sourceFile, bindingName) => {
65596
66020
  }
65597
66021
  return null;
65598
66022
  };
65599
- const getFunctionLocalBindings = (functionNode, argumentsList) => {
66023
+ const getFunctionLocalBindings = (functionNode, argumentsList, argumentAnalysis, functionAnalysis) => {
65600
66024
  const localBindings = /* @__PURE__ */ new Map();
65601
66025
  functionNode.parameters.forEach((parameter, parameterIndex) => {
65602
- if (ts.isIdentifier(parameter.name)) localBindings.set(parameter.name.text, argumentsList[parameterIndex] ?? parameter.initializer ?? null);
66026
+ if (ts.isIdentifier(parameter.name)) {
66027
+ const argument = argumentsList[parameterIndex];
66028
+ localBindings.set(parameter.name.text, {
66029
+ expression: argument ?? parameter.initializer ?? null,
66030
+ analysis: argument ? argumentAnalysis : functionAnalysis
66031
+ });
66032
+ }
65603
66033
  });
65604
66034
  return localBindings;
65605
66035
  };
@@ -65735,8 +66165,8 @@ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /*
65735
66165
  };
65736
66166
  if (ts.isIdentifier(unwrappedExpression)) {
65737
66167
  if (analysis.localBindings.has(unwrappedExpression.text)) {
65738
- const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
65739
- return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
66168
+ const localReference = analysis.localBindings.get(unwrappedExpression.text);
66169
+ return localReference?.expression ? getStaticConfigValueState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
65740
66170
  }
65741
66171
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
65742
66172
  return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
@@ -65778,8 +66208,8 @@ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /*
65778
66208
  const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
65779
66209
  if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
65780
66210
  if (analysis.localBindings.has(unwrappedExpression.text)) {
65781
- const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
65782
- return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
66211
+ const localReference = analysis.localBindings.get(unwrappedExpression.text);
66212
+ return localReference?.expression ? getReactCompilerFlagState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
65783
66213
  }
65784
66214
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
65785
66215
  return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
@@ -65802,8 +66232,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
65802
66232
  visitedExpressions.add(resolvedExpression);
65803
66233
  if (ts.isIdentifier(resolvedExpression)) {
65804
66234
  if (analysis.localBindings.has(resolvedExpression.text)) {
65805
- const localInitializer = analysis.localBindings.get(resolvedExpression.text);
65806
- return localInitializer ? getSelectedObjectProperty(localInitializer, propertyName, analysis, visitedExpressions) : null;
66235
+ const localReference = analysis.localBindings.get(resolvedExpression.text);
66236
+ return localReference?.expression ? getSelectedObjectProperty(localReference.expression, propertyName, localReference.analysis, visitedExpressions) : null;
65807
66237
  }
65808
66238
  const scopedBinding = getScopedConfigBinding(resolvedExpression);
65809
66239
  if (scopedBinding.wasFound) return scopedBinding.initializer ? getSelectedObjectProperty(scopedBinding.initializer, propertyName, analysis, visitedExpressions) : null;
@@ -65812,9 +66242,18 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
65812
66242
  }
65813
66243
  if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
65814
66244
  for (const property of [...resolvedExpression.properties].reverse()) {
65815
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
65816
- if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
65817
- if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
66245
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return {
66246
+ node: property.initializer,
66247
+ analysis
66248
+ };
66249
+ if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return {
66250
+ node: property,
66251
+ analysis
66252
+ };
66253
+ if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return {
66254
+ node: property.name,
66255
+ analysis
66256
+ };
65818
66257
  if (ts.isSpreadAssignment(property)) {
65819
66258
  const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
65820
66259
  if (spreadProperty) return spreadProperty;
@@ -65827,8 +66266,8 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
65827
66266
  while (ts.isParenthesizedExpression(resolvedExpression) || ts.isAsExpression(resolvedExpression) || ts.isTypeAssertionExpression(resolvedExpression) || ts.isSatisfiesExpression(resolvedExpression) || ts.isNonNullExpression(resolvedExpression)) resolvedExpression = resolvedExpression.expression;
65828
66267
  if (ts.isIdentifier(resolvedExpression)) {
65829
66268
  if (analysis.localBindings.has(resolvedExpression.text)) {
65830
- const localInitializer = analysis.localBindings.get(resolvedExpression.text);
65831
- return localInitializer ? configExpressionMayDefineProperty(localInitializer, propertyName, analysis) : true;
66269
+ const localReference = analysis.localBindings.get(resolvedExpression.text);
66270
+ return localReference?.expression ? configExpressionMayDefineProperty(localReference.expression, propertyName, localReference.analysis) : true;
65832
66271
  }
65833
66272
  const scopedBinding = getScopedConfigBinding(resolvedExpression);
65834
66273
  if (scopedBinding.wasFound) return scopedBinding.initializer ? configExpressionMayDefineProperty(scopedBinding.initializer, propertyName, analysis) : true;
@@ -65912,15 +66351,15 @@ const getReExportedConfigModules = (sourceFile, exportName) => {
65912
66351
  }
65913
66352
  return bindings;
65914
66353
  };
65915
- const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
66354
+ const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
65916
66355
  if (!isFile(filePath) || importDepth > 4) return false;
65917
66356
  const moduleVisitKey = `${filePath}:${exportName}:${allowCompilerTransform}`;
65918
66357
  if (visitedModules.has(moduleVisitKey)) return false;
65919
66358
  const nextVisitedModules = new Set(visitedModules);
65920
66359
  nextVisitedModules.add(moduleVisitKey);
65921
- return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList);
66360
+ return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList, argumentAnalysis);
65922
66361
  };
65923
- const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
66362
+ const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
65924
66363
  const analysis = {
65925
66364
  filePath,
65926
66365
  sourceFile,
@@ -65930,14 +66369,27 @@ const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCo
65930
66369
  localBindings: /* @__PURE__ */ new Map(),
65931
66370
  activeFunctions: /* @__PURE__ */ new Set()
65932
66371
  };
66372
+ const resolvedArgumentAnalysis = argumentAnalysis ?? analysis;
65933
66373
  const exportedConfigNodes = getExportedConfigNodes(sourceFile, exportName);
65934
- return exportedConfigNodes.some((node) => ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) ? analyzeConfigFunction(node, analysis, allowCompilerTransform, argumentsList) : analyzeConfigNode(node, analysis, allowCompilerTransform)) || getReExportedConfigModules(sourceFile, exportName).some((binding) => {
66374
+ return exportedConfigNodes.some((node) => {
66375
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) return analyzeConfigFunction(node, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
66376
+ if (argumentsList.length > 0 && ts.isIdentifier(node)) {
66377
+ const topLevelBinding = getTopLevelBinding(sourceFile, node.text);
66378
+ if (topLevelBinding && ts.isFunctionLike(topLevelBinding)) return analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
66379
+ const importBinding = getImportBinding(sourceFile, node.text);
66380
+ if (importBinding) {
66381
+ const importedFilePath = resolveImportedConfigFile(filePath, importBinding.moduleSpecifier);
66382
+ return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, importBinding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
66383
+ }
66384
+ }
66385
+ return analyzeConfigNode(node, analysis, allowCompilerTransform);
66386
+ }) || getReExportedConfigModules(sourceFile, exportName).some((binding) => {
65935
66387
  if (exportedConfigNodes.length > 0 && binding.isNamespace) return false;
65936
66388
  const importedFilePath = resolveImportedConfigFile(filePath, binding.moduleSpecifier);
65937
- return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList));
66389
+ return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
65938
66390
  });
65939
66391
  };
65940
- const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = []) => {
66392
+ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = [], argumentAnalysis = analysis) => {
65941
66393
  if (!functionNode.body) return false;
65942
66394
  if (analysis.activeFunctions.has(functionNode.pos)) return false;
65943
66395
  const activeFunctions = new Set(analysis.activeFunctions);
@@ -65945,7 +66397,7 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
65945
66397
  const functionAnalysis = {
65946
66398
  ...analysis,
65947
66399
  visitedNodes: /* @__PURE__ */ new Set(),
65948
- localBindings: getFunctionLocalBindings(functionNode, argumentsList),
66400
+ localBindings: getFunctionLocalBindings(functionNode, argumentsList, argumentAnalysis, analysis),
65949
66401
  activeFunctions
65950
66402
  };
65951
66403
  if (!ts.isBlock(functionNode.body)) return analyzeConfigNode(functionNode.body, functionAnalysis, allowCompilerTransform);
@@ -65964,7 +66416,7 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
65964
66416
  const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
65965
66417
  const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
65966
66418
  if (!importedFilePath) return null;
65967
- return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
66419
+ return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList, analysis);
65968
66420
  };
65969
66421
  const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
65970
66422
  const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
@@ -65978,8 +66430,8 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
65978
66430
  if (assignedPlugins.wasFound) overriddenPropertyNames.add("plugins");
65979
66431
  if (assignedPresets.wasFound) overriddenPropertyNames.add("presets");
65980
66432
  if (analysis.localBindings.has(identifier.text)) {
65981
- const localInitializer = analysis.localBindings.get(identifier.text);
65982
- return Boolean(localInitializer && analyzeConfigNode(localInitializer, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
66433
+ const localReference = analysis.localBindings.get(identifier.text);
66434
+ return Boolean(localReference?.expression && analyzeConfigNode(localReference.expression, localReference.analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
65983
66435
  }
65984
66436
  const scopedBinding = getScopedConfigBinding(identifier);
65985
66437
  if (scopedBinding.wasFound) return Boolean(scopedBinding.initializer && analyzeConfigNode(scopedBinding.initializer, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
@@ -66045,7 +66497,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
66045
66497
  }
66046
66498
  const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
66047
66499
  if (selectedProperty === null) return null;
66048
- return ts.isFunctionLike(selectedProperty) ? analyzeConfigFunction(selectedProperty, analysis, allowCompilerTransform, callExpression.arguments) : analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
66500
+ return ts.isFunctionLike(selectedProperty.node) ? analyzeConfigFunction(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform, callExpression.arguments, analysis) : analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
66049
66501
  };
66050
66502
  const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTransformCollection = false, excludedPropertyNames) => {
66051
66503
  const excludedPropertiesVisitKey = excludedPropertyNames ? [...excludedPropertyNames].sort().join(",") : "";
@@ -66145,7 +66597,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
66145
66597
  if (ts.isIdentifier(node.expression)) {
66146
66598
  if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
66147
66599
  const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
66148
- return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
66600
+ return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
66149
66601
  }
66150
66602
  const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
66151
66603
  if (importBinding?.isNamespace) {
@@ -66159,7 +66611,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
66159
66611
  return false;
66160
66612
  }
66161
66613
  const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
66162
- if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
66614
+ if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
66163
66615
  return false;
66164
66616
  }
66165
66617
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
@@ -66168,7 +66620,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
66168
66620
  if (ts.isIdentifier(node.expression)) {
66169
66621
  if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
66170
66622
  const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
66171
- return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
66623
+ return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
66172
66624
  }
66173
66625
  const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
66174
66626
  if (importBinding?.isNamespace) {
@@ -66181,7 +66633,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
66181
66633
  }));
66182
66634
  }
66183
66635
  const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
66184
- if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
66636
+ if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
66185
66637
  return false;
66186
66638
  }
66187
66639
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
@@ -68558,6 +69010,7 @@ const classifyPackageRole = (filename) => {
68558
69010
  * Resolves the absolute path to read for a diagnostic's `filePath`,
68559
69011
  * accounting for the various shapes oxlint emits:
68560
69012
  *
69013
+ * - `file://` URL — decode to an absolute filesystem path.
68561
69014
  * - Absolute POSIX (`/abs/path/file.tsx`) — pass through.
68562
69015
  * - Absolute Windows (`C:/...` or `C:\...`) — pass through.
68563
69016
  * - `./relative` or bare relative — join against `rootDirectory`.
@@ -68567,6 +69020,7 @@ const classifyPackageRole = (filename) => {
68567
69020
  * use one canonical resolution path.
68568
69021
  */
68569
69022
  const resolveCandidateReadPath = (rootDirectory, filePath) => {
69023
+ if (filePath.startsWith("file://")) return fileURLToPath(filePath);
68570
69024
  const normalizedFile = filePath.replace(/\\/g, "/");
68571
69025
  if (normalizedFile.startsWith("/") || /^[a-zA-Z]:\//.test(normalizedFile) || /^[a-zA-Z]:\\/.test(filePath)) return filePath;
68572
69026
  return `${rootDirectory.replace(/\\/g, "/").replace(/\/$/, "")}/${normalizedFile.replace(/^\.\//, "")}`;
@@ -72875,7 +73329,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
72875
73329
  if (argvLengthChars > spawnArgsLengthCap) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${spawnArgsLengthCap})`);
72876
73330
  const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
72877
73331
  cwd: input.directory,
72878
- env: input.env,
73332
+ env: input.command === "git" ? {
73333
+ ...input.env,
73334
+ GIT_DIR: void 0
73335
+ } : input.env,
72879
73336
  extendEnv: true
72880
73337
  }));
72881
73338
  const maxStdoutBytes = input.maxStdoutBytes;
@@ -73148,7 +73605,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
73148
73605
  "--diff-filter=ACMR",
73149
73606
  "--relative"
73150
73607
  ]).pipe(map$3((result) => {
73151
- if (result.status !== 0) return [];
73608
+ if (result.status !== 0) return null;
73152
73609
  return splitNullSeparated(result.stdout);
73153
73610
  })),
73154
73611
  showStagedContent: (directory, relativePath, options) => runCommand({
@@ -74236,6 +74693,50 @@ const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
74236
74693
  while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
74237
74694
  return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
74238
74695
  };
74696
+ const utf8OffsetFromSourcePosition = (sourceBuffer, lineNumber, zeroBasedColumn) => {
74697
+ if (lineNumber < 1 || zeroBasedColumn < 0) return null;
74698
+ const sourceLines = sourceBuffer.toString("utf8").split("\n");
74699
+ const sourceLine = sourceLines[lineNumber - 1];
74700
+ if (sourceLine === void 0 || zeroBasedColumn > sourceLine.length) return null;
74701
+ const precedingLines = sourceLines.slice(0, lineNumber - 1).join("\n");
74702
+ return (lineNumber === 1 ? 0 : Buffer.byteLength(precedingLines) + Buffer.byteLength("\n")) + Buffer.byteLength(sourceLine.slice(0, zeroBasedColumn));
74703
+ };
74704
+ const mapPreparedSourceSpan = (span, preparedSourceMap) => {
74705
+ const generatedLine = lineOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset);
74706
+ const generatedColumn = columnOfUtf8Offset(preparedSourceMap.generatedBuffer, span.offset) - 1;
74707
+ const originalStart = originalPositionFor(preparedSourceMap.traceMap, {
74708
+ line: generatedLine,
74709
+ column: generatedColumn
74710
+ });
74711
+ if (originalStart.source === null || originalStart.line === null || originalStart.column === null) return null;
74712
+ const originalOffset = utf8OffsetFromSourcePosition(preparedSourceMap.sourceBuffer, originalStart.line, originalStart.column);
74713
+ if (originalOffset === null) return null;
74714
+ const generatedSpan = preparedSourceMap.generatedBuffer.subarray(span.offset, span.offset + span.length);
74715
+ return {
74716
+ offset: originalOffset,
74717
+ length: preparedSourceMap.sourceBuffer.subarray(originalOffset, originalOffset + generatedSpan.length).equals(generatedSpan) ? generatedSpan.length : 0,
74718
+ line: originalStart.line,
74719
+ column: originalStart.column + 1
74720
+ };
74721
+ };
74722
+ const mapPreparedSourceLabels = (labels, preparedSourceMap) => {
74723
+ const primaryLabel = labels[0];
74724
+ if (primaryLabel === void 0) return null;
74725
+ const primarySpan = mapPreparedSourceSpan(primaryLabel.span, preparedSourceMap);
74726
+ if (primarySpan === null) return null;
74727
+ const mappedLabels = [{
74728
+ ...primaryLabel,
74729
+ span: primarySpan
74730
+ }];
74731
+ for (const relatedLabel of labels.slice(1)) {
74732
+ const relatedSpan = mapPreparedSourceSpan(relatedLabel.span, preparedSourceMap);
74733
+ if (relatedSpan !== null) mappedLabels.push({
74734
+ ...relatedLabel,
74735
+ span: relatedSpan
74736
+ });
74737
+ }
74738
+ return mappedLabels;
74739
+ };
74239
74740
  const REDACTED_PLACEHOLDER = "<redacted>";
74240
74741
  const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
74241
74742
  const KNOWN_SECRET_RULES = [
@@ -74980,7 +75481,7 @@ const isOxlintOutput = (value) => isRecord$1(value) && Array.isArray(value.diagn
74980
75481
  * to the first `{`. Raises `OxlintOutputUnparseable` when the
74981
75482
  * stdout isn't valid JSON or doesn't carry a `diagnostics` array.
74982
75483
  */
74983
- const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
75484
+ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath) => {
74984
75485
  if (!stdout) return [];
74985
75486
  const jsonStart = stdout.indexOf("{");
74986
75487
  const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
@@ -74998,6 +75499,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath)
74998
75499
  const sourceLinesCache = /* @__PURE__ */ new Map();
74999
75500
  const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
75000
75501
  const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
75502
+ const resolvePreparedSourceMap = (filename) => sourceMapByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
75001
75503
  const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
75002
75504
  const readSourceBuffer = (filename) => {
75003
75505
  const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
@@ -75029,7 +75531,19 @@ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath)
75029
75531
  minifiedFileCache.set(absolutePath, minified);
75030
75532
  return minified;
75031
75533
  };
75032
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
75534
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.flatMap((diagnostic) => {
75535
+ const preparedSourceMap = resolvePreparedSourceMap(diagnostic.filename);
75536
+ if (preparedSourceMap === void 0) return [diagnostic];
75537
+ const { plugin, rule } = parseRuleCode(diagnostic.code);
75538
+ if (plugin !== "react-doctor" || !reactDoctorPlugin.rules[rule]?.tags?.includes("design")) return [];
75539
+ const labels = mapPreparedSourceLabels(diagnostic.labels, preparedSourceMap);
75540
+ const sourceFilename = resolveMappedSourceFilename(diagnostic.filename);
75541
+ return labels === null || sourceFilename === void 0 ? [] : [{
75542
+ ...diagnostic,
75543
+ filename: sourceFilename,
75544
+ labels
75545
+ }];
75546
+ }).filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
75033
75547
  const { plugin, rule } = parseRuleCode(diagnostic.code);
75034
75548
  const primaryLabel = diagnostic.labels[0];
75035
75549
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
@@ -75247,7 +75761,7 @@ const isParallelismRelatedSpawnError = (error) => {
75247
75761
  * loop with a slimmer config in that case.
75248
75762
  */
75249
75763
  const spawnLintBatches = async (input) => {
75250
- const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
75764
+ const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, sourceMapByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
75251
75765
  const resolveSourcePath = (filePath) => {
75252
75766
  const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
75253
75767
  return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
@@ -75271,7 +75785,7 @@ const spawnLintBatches = async (input) => {
75271
75785
  }
75272
75786
  const batchArgs = [...baseArgs, ...batch];
75273
75787
  try {
75274
- return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
75788
+ return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath, sourceMapByLintPath);
75275
75789
  } catch (error) {
75276
75790
  if (!isSplittableReactDoctorError(error)) throw error;
75277
75791
  if (isPastDeadline()) {
@@ -75710,20 +76224,47 @@ const prepareHtmlScriptSource = (sourceBuffer) => {
75710
76224
  lintBuffer: maskedBuffer ?? sourceBuffer
75711
76225
  };
75712
76226
  };
75713
- const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
76227
+ const ASTRO_FILE_PATTERN = /\.astro$/;
76228
+ const prepareLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
75714
76229
  const lintFiles = [];
75715
76230
  const sourcePathByLintPath = /* @__PURE__ */ new Map();
76231
+ const sourceMapByLintPath = /* @__PURE__ */ new Map();
75716
76232
  const sizeByLintPath = /* @__PURE__ */ new Map();
75717
76233
  const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
76234
+ const astroSourcesDirectory = Path.join(temporaryDirectory, "astro-sources");
75718
76235
  let htmlFileIndex = 0;
76236
+ let astroFileIndex = 0;
75719
76237
  let hasThreeModuleImport = false;
75720
76238
  for (const candidateFile of candidateFiles) {
75721
- if (!HTML_FILE_PATTERN.test(candidateFile)) {
76239
+ if (!HTML_FILE_PATTERN.test(candidateFile) && !ASTRO_FILE_PATTERN.test(candidateFile)) {
75722
76240
  lintFiles.push(candidateFile);
75723
76241
  continue;
75724
76242
  }
75725
76243
  const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
75726
76244
  const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
76245
+ if (ASTRO_FILE_PATTERN.test(candidateFile)) {
76246
+ const compilerSourcePath = absoluteSourcePath.replaceAll("\\", "/");
76247
+ const convertedSource = convertToTSX(sourceBuffer.toString("utf8"), {
76248
+ filename: compilerSourcePath,
76249
+ sourcemap: "external",
76250
+ includeScripts: true
76251
+ });
76252
+ if (astroFileIndex === 0) NFS.mkdirSync(astroSourcesDirectory, { recursive: true });
76253
+ const lintPath = Path.join(astroSourcesDirectory, `${astroFileIndex}.tsx`);
76254
+ const generatedBuffer = Buffer.from(convertedSource.code);
76255
+ NFS.writeFileSync(lintPath, generatedBuffer);
76256
+ lintFiles.push(candidateFile);
76257
+ lintFiles.push(lintPath);
76258
+ sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
76259
+ sourceMapByLintPath.set(Path.resolve(lintPath), {
76260
+ traceMap: new TraceMap(JSON.stringify(convertedSource.map)),
76261
+ generatedBuffer,
76262
+ sourceBuffer
76263
+ });
76264
+ sizeByLintPath.set(lintPath, sourceBuffer.length);
76265
+ astroFileIndex++;
76266
+ continue;
76267
+ }
75727
76268
  const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
75728
76269
  if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
75729
76270
  const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
@@ -75737,6 +76278,7 @@ const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFile
75737
76278
  return {
75738
76279
  lintFiles,
75739
76280
  sourcePathByLintPath,
76281
+ sourceMapByLintPath,
75740
76282
  sizeByLintPath,
75741
76283
  hasThreeModuleImport
75742
76284
  };
@@ -75955,10 +76497,10 @@ const runOxlint = async (options) => {
75955
76497
  rootDirectory,
75956
76498
  candidateFiles
75957
76499
  });
75958
- const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
75959
- const lintFiles = preparedHtmlSources.lintFiles;
75960
- const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
75961
- const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
76500
+ const preparedLintSources = prepareLintSources(rootDirectory, configDirectory, candidateFiles);
76501
+ const lintFiles = preparedLintSources.lintFiles;
76502
+ const hasPreparedFiles = preparedLintSources.sourcePathByLintPath.size > 0;
76503
+ const lintProject = !project.hasThree && preparedLintSources.hasThreeModuleImport ? {
75962
76504
  ...project,
75963
76505
  hasThree: true
75964
76506
  } : project;
@@ -75980,7 +76522,7 @@ const runOxlint = async (options) => {
75980
76522
  sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
75981
76523
  });
75982
76524
  const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
75983
- if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
76525
+ if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedLintSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
75984
76526
  const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
75985
76527
  baseArgs: passBaseArgs,
75986
76528
  files: passFiles,
@@ -76010,7 +76552,8 @@ const runOxlint = async (options) => {
76010
76552
  rootDirectory,
76011
76553
  nodeBinaryPath,
76012
76554
  project: lintProject,
76013
- sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
76555
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
76556
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
76014
76557
  onPartialFailure: reportPartialFailure,
76015
76558
  onAnalyzedFiles: (filePaths) => {
76016
76559
  analyzedFiles = filePaths;
@@ -76045,7 +76588,7 @@ const runOxlint = async (options) => {
76045
76588
  };
76046
76589
  }
76047
76590
  };
76048
- if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
76591
+ if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasPreparedFiles) {
76049
76592
  const rulesetHash = computeRulesetHash({
76050
76593
  config: buildConfig({
76051
76594
  extendsPaths: [],
@@ -76211,7 +76754,8 @@ const runOxlint = async (options) => {
76211
76754
  rootDirectory,
76212
76755
  nodeBinaryPath,
76213
76756
  project: lintProject,
76214
- sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
76757
+ sourcePathByLintPath: preparedLintSources.sourcePathByLintPath,
76758
+ sourceMapByLintPath: preparedLintSources.sourceMapByLintPath,
76215
76759
  onPartialFailure,
76216
76760
  onAnalyzedFiles: (filePaths) => {
76217
76761
  analyzedFiles = filePaths;
@@ -77571,10 +78115,14 @@ const materializeSourceTree = (input) => gen(function* () {
77571
78115
  materializedFiles.push(relativePath);
77572
78116
  }
77573
78117
  yield* sync(() => {
77574
- for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
77575
- const sourcePath = path.join(input.directory, configFilename);
77576
- const targetPath = path.join(resolvedTempDirectory, configFilename);
77577
- if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) fs.cpSync(sourcePath, targetPath);
78118
+ for (const subdirectory of ["", ...input.configSubdirectories ?? []]) for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
78119
+ const sourcePath = path.join(input.directory, subdirectory, configFilename);
78120
+ const targetPath = path.resolve(resolvedTempDirectory, subdirectory, configFilename);
78121
+ if (!isPathInsideDirectory(targetPath, resolvedTempDirectory)) continue;
78122
+ if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
78123
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
78124
+ fs.cpSync(sourcePath, targetPath);
78125
+ }
77578
78126
  }
77579
78127
  });
77580
78128
  return {
@@ -77607,15 +78155,17 @@ var StagedFiles = class StagedFiles extends Service()("react-doctor/StagedFiles"
77607
78155
  static layerNode = effect(StagedFiles, gen(function* () {
77608
78156
  const git = yield* Git;
77609
78157
  return StagedFiles.of({
77610
- discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
77611
- materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
78158
+ discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries === null ? null : entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
78159
+ materialize: ({ directory, stagedFiles, tempDirectory, configSubdirectories }) => materializeSourceTree({
77612
78160
  directory,
77613
78161
  files: stagedFiles,
77614
78162
  tempDirectory,
78163
+ configSubdirectories,
77615
78164
  readContent: (relativePath) => git.showStagedContent(directory, relativePath, { maxBufferBytes: GIT_SHOW_MAX_BUFFER_BYTES })
77616
78165
  }).pipe(map$3((tree) => ({
77617
78166
  tempDirectory: tree.tempDirectory,
77618
78167
  stagedFiles: tree.materializedFiles,
78168
+ unmaterializedFiles: tree.unmaterializedFiles,
77619
78169
  cleanup: tree.cleanup
77620
78170
  })), withSpan("StagedFiles.materialize"))
77621
78171
  });
@@ -77630,6 +78180,7 @@ var StagedFiles = class StagedFiles extends Service()("react-doctor/StagedFiles"
77630
78180
  materialize: ({ tempDirectory }) => succeed$2({
77631
78181
  tempDirectory,
77632
78182
  stagedFiles: snapshot.materializedFiles ?? snapshot.sourceFiles ?? [],
78183
+ unmaterializedFiles: [],
77633
78184
  cleanup: () => {}
77634
78185
  })
77635
78186
  }));
@@ -78339,6 +78890,7 @@ const METRIC = {
78339
78890
  cliError: "cli.error",
78340
78891
  cliEnvironmentError: "cli.env_error",
78341
78892
  stagedSnapshotDivergence: "staged.snapshot_divergence",
78893
+ stagedPerProject: "staged.per_project",
78342
78894
  projectDetected: "project.detected",
78343
78895
  projectPathSelected: "project.path_selected",
78344
78896
  projectConfigSelected: "project.config_selected",
@@ -78424,7 +78976,7 @@ const makeNoopConsole = () => ({
78424
78976
  });
78425
78977
  //#endregion
78426
78978
  //#region src/cli/utils/version.ts
78427
- const VERSION = "0.9.2-dev.b31fd85";
78979
+ const VERSION = "0.9.2-dev.c126684";
78428
78980
  //#endregion
78429
78981
  //#region src/cli/utils/json-mode.ts
78430
78982
  let context = null;
@@ -78782,13 +79334,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
78782
79334
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
78783
79335
  * standard `SENTRY_RELEASE` override.
78784
79336
  */
78785
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.2-dev.b31fd85`;
79337
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.2-dev.c126684`;
78786
79338
  /**
78787
79339
  * Deployment environment shown in Sentry's environment filter. Defaults to
78788
79340
  * `production` for tagged releases and `development` for dev/unbuilt versions,
78789
79341
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
78790
79342
  */
78791
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.2-dev.b31fd85") ? "development" : "production");
79343
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.2-dev.c126684") ? "development" : "production");
78792
79344
  /**
78793
79345
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
78794
79346
  * (set to `0` to disable tracing) and falls back to
@@ -92245,16 +92797,19 @@ const formatClusterLocation = (cluster, resolveSourceRoot, hyperlinks) => {
92245
92797
  if (!hyperlinks) return `${location}${contextTag}`;
92246
92798
  return `${formatHyperlink(location, pathToFileURL(resolveAbsolutePath(lead.filePath, resolveSourceRoot(lead))).href)}${contextTag}`;
92247
92799
  };
92248
- const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, renderCodeFrame, hyperlinks) => {
92800
+ const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, resolveFrameSourceRoot, renderCodeFrame, hyperlinks) => {
92249
92801
  const lead = cluster.diagnostics[0];
92250
92802
  const isMultiSite = cluster.diagnostics.length > 1;
92803
+ const sourceRoot = resolveSourceRoot(lead);
92804
+ const frameSourceRoot = resolveFrameSourceRoot(lead);
92805
+ const frameFilePath = Path.isAbsolute(lead.filePath) && sourceRoot !== frameSourceRoot ? Path.relative(sourceRoot, lead.filePath) : lead.filePath;
92251
92806
  const lines = ["", highlighter.gray(`${TOP_ERROR_DETAIL_INDENT}${formatClusterLocation(cluster, resolveSourceRoot, hyperlinks)}`)];
92252
92807
  const codeFrame = renderCodeFrame ? buildCodeFrame({
92253
- filePath: lead.filePath,
92808
+ filePath: frameFilePath,
92254
92809
  line: cluster.startLine,
92255
92810
  column: isMultiSite ? 0 : lead.column,
92256
92811
  endLine: isMultiSite ? cluster.endLine : void 0,
92257
- rootDirectory: resolveSourceRoot(lead)
92812
+ rootDirectory: frameSourceRoot
92258
92813
  }) : null;
92259
92814
  if (codeFrame) {
92260
92815
  const boxInnerWidth = resolveMeasureWidth(8);
@@ -92267,7 +92822,7 @@ const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, renderCodeFrame
92267
92822
  }
92268
92823
  return lines;
92269
92824
  };
92270
- const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, renderEverySite, isAgentEnvironment, hyperlinks) => {
92825
+ const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, renderEverySite, isAgentEnvironment, hyperlinks) => {
92271
92826
  const representative = pickRepresentativeDiagnostic(ruleDiagnostics);
92272
92827
  const { severity } = representative;
92273
92828
  const trailingBadge = formatTrailingSiteBadge(ruleDiagnostics.length);
@@ -92289,7 +92844,7 @@ const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, rende
92289
92844
  }
92290
92845
  const renderCodeFrame = severity === "error";
92291
92846
  const sites = renderEverySite ? ruleDiagnostics : [representative];
92292
- if (!(isCollapsedWarningGroup && representative.help.includes(representative.filePath))) for (const cluster of clusterNearbyDiagnostics(sites)) lines.push(...buildDiagnosticClusterLines(cluster, resolveSourceRoot, renderCodeFrame, hyperlinks));
92847
+ if (!(isCollapsedWarningGroup && representative.help.includes(representative.filePath))) for (const cluster of clusterNearbyDiagnostics(sites)) lines.push(...buildDiagnosticClusterLines(cluster, resolveSourceRoot, resolveFrameSourceRoot, renderCodeFrame, hyperlinks));
92293
92848
  return lines;
92294
92849
  };
92295
92850
  const selectErrorRuleGroups = (diagnostics, rulePriority) => buildSortedRuleGroups(diagnostics.filter((diagnostic) => diagnostic.severity === "error"), rulePriority);
@@ -92315,7 +92870,7 @@ const buildMigrationScaleAdvisoryLines = (diagnostics) => {
92315
92870
  return lines;
92316
92871
  };
92317
92872
  const getTopErrorRuleKeys = (diagnostics, limit, rulePriority) => new Set(selectTopErrorRuleGroups(diagnostics, limit, rulePriority).map(([ruleKey]) => ruleKey));
92318
- const buildTopErrorsSection = (diagnostics, resolveSourceRoot, hyperlinks, rulePriority) => {
92873
+ const buildTopErrorsSection = (diagnostics, resolveSourceRoot, resolveFrameSourceRoot, hyperlinks, rulePriority) => {
92319
92874
  const topRuleGroups = selectErrorRuleGroups(diagnostics, rulePriority).slice(0, 3);
92320
92875
  if (topRuleGroups.length === 0) return {
92321
92876
  lines: [],
@@ -92325,7 +92880,7 @@ const buildTopErrorsSection = (diagnostics, resolveSourceRoot, hyperlinks, ruleP
92325
92880
  const blockOffsets = [];
92326
92881
  for (const [ruleKey, ruleDiagnostics] of topRuleGroups) {
92327
92882
  blockOffsets.push(lines.length);
92328
- lines.push(...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, false, false, hyperlinks));
92883
+ lines.push(...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, false, false, hyperlinks));
92329
92884
  lines.push("");
92330
92885
  }
92331
92886
  return {
@@ -92363,18 +92918,19 @@ const buildOverviewHeaderLines = (diagnostics) => {
92363
92918
  * single Effect.forEach over Console.log so failures or fiber
92364
92919
  * interruption produce predictable partial output.
92365
92920
  */
92366
- const printDiagnostics = (diagnostics, isVerbose, sourceRoot, rulePriority, isAgentEnvironment = false, onboarding = {}, hyperlinks = false) => gen(function* () {
92921
+ const printDiagnostics = (diagnostics, isVerbose, sourceRoot, rulePriority, isAgentEnvironment = false, onboarding = {}, hyperlinks = false, frameSourceRoot = sourceRoot) => gen(function* () {
92367
92922
  const sectionPause = onboarding.sectionPause ?? void_;
92368
92923
  const animateCountUp = onboarding.animateCountUp ?? false;
92369
92924
  const resolveSourceRoot = typeof sourceRoot === "function" ? sourceRoot : () => sourceRoot;
92925
+ const resolveFrameSourceRoot = typeof frameSourceRoot === "function" ? frameSourceRoot : () => frameSourceRoot;
92370
92926
  let detailLines;
92371
92927
  let topErrorBlockOffsets = [];
92372
92928
  if (!isVerbose) {
92373
- const topErrors = buildTopErrorsSection(diagnostics, resolveSourceRoot, hyperlinks, rulePriority);
92929
+ const topErrors = buildTopErrorsSection(diagnostics, resolveSourceRoot, resolveFrameSourceRoot, hyperlinks, rulePriority);
92374
92930
  detailLines = topErrors.lines;
92375
92931
  topErrorBlockOffsets = topErrors.blockOffsets;
92376
92932
  } else detailLines = buildSortedRuleGroups(diagnostics, rulePriority).flatMap(([ruleKey, ruleDiagnostics]) => {
92377
- return [...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, true, isAgentEnvironment, hyperlinks), ""];
92933
+ return [...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, true, isAgentEnvironment, hyperlinks), ""];
92378
92934
  });
92379
92935
  const overflowLine = isVerbose ? void 0 : buildOverflowSummaryLine(diagnostics, rulePriority);
92380
92936
  const categoryTallies = buildCategoryDiagnosticGroups(diagnostics, rulePriority).map(buildCategoryTally);
@@ -93638,26 +94194,26 @@ const finalizeAndRender = (input) => gen(function* () {
93638
94194
  //#region src/cli/utils/get-staged-files.ts
93639
94195
  const stagedFilesLayer = StagedFiles.layerNode.pipe(provide$2(Git.layerNode));
93640
94196
  const getStagedSourceFiles = async (directory) => {
94197
+ let stagedSourceFiles;
93641
94198
  try {
93642
- return [...await runPromise(gen(function* () {
94199
+ stagedSourceFiles = await runPromise(gen(function* () {
93643
94200
  return yield* (yield* StagedFiles).discoverSourceFiles(directory);
93644
- }).pipe(provide(stagedFilesLayer)))];
94201
+ }).pipe(provide(stagedFilesLayer)));
93645
94202
  } catch (error) {
93646
94203
  cliLogger.warn(`Failed to discover staged files: ${messageFromUnknown(error)}`);
93647
94204
  return [];
93648
94205
  }
94206
+ if (stagedSourceFiles === null) throw new CliInputError("Could not read the git index to list staged files. Check that git can read the index in this directory.");
94207
+ return [...stagedSourceFiles];
93649
94208
  };
93650
- const materializeStagedFiles = async (directory, stagedFiles, tempDirectory) => {
94209
+ const materializeStagedFiles = async (input) => {
93651
94210
  const snapshot = await runPromise(gen(function* () {
93652
- return yield* (yield* StagedFiles).materialize({
93653
- directory,
93654
- stagedFiles,
93655
- tempDirectory
93656
- });
94211
+ return yield* (yield* StagedFiles).materialize(input);
93657
94212
  }).pipe(provide(stagedFilesLayer)));
93658
94213
  return {
93659
94214
  tempDirectory: snapshot.tempDirectory,
93660
94215
  stagedFiles: [...snapshot.stagedFiles],
94216
+ unmaterializedFiles: [...snapshot.unmaterializedFiles],
93661
94217
  cleanup: snapshot.cleanup
93662
94218
  };
93663
94219
  };
@@ -95531,13 +96087,18 @@ const printMultiProjectSummary = (input) => gen(function* () {
95531
96087
  const scoreDiagnostics = new Set(filterScansForSurface(completedScans, "score"));
95532
96088
  const displayedScoreDiagnostics = displayDiagnostics.filter((diagnostic) => scoreDiagnostics.has(diagnostic));
95533
96089
  const projectRootByDiagnostic = /* @__PURE__ */ new WeakMap();
95534
- for (const scan of completedScans) for (const diagnostic of scan.result.diagnostics) projectRootByDiagnostic.set(diagnostic, scan.result.project.rootDirectory);
96090
+ const frameSourceRootByDiagnostic = /* @__PURE__ */ new WeakMap();
96091
+ for (const scan of completedScans) for (const diagnostic of scan.result.diagnostics) {
96092
+ projectRootByDiagnostic.set(diagnostic, scan.result.project.rootDirectory);
96093
+ frameSourceRootByDiagnostic.set(diagnostic, scan.frameSourceRoot ?? scan.result.project.rootDirectory);
96094
+ }
95535
96095
  const resolveDiagnosticSourceRoot = (diagnostic) => projectRootByDiagnostic.get(diagnostic) ?? "";
96096
+ const resolveDiagnosticFrameSourceRoot = (diagnostic) => frameSourceRootByDiagnostic.get(diagnostic) ?? resolveDiagnosticSourceRoot(diagnostic);
95536
96097
  const totalScannedFileCount = countUniqueScannedFiles(completedScans.map((scan) => scan.result));
95537
96098
  yield* log(`${highlighter.success("✔")} Scanned ${totalScannedFileCount} ${totalScannedFileCount === 1 ? "file" : "files"} in ${formatElapsedTime(totalElapsedMilliseconds)}`);
95538
96099
  if (displayDiagnostics.length > 0) {
95539
96100
  yield* log("");
95540
- yield* printDiagnostics(displayDiagnostics, verbose, resolveDiagnosticSourceRoot, buildRulePriorityMap(completedScans.map((scan) => scan.result.score)), isCodingAgentEnvironment(), { animateCountUp: animateRender }, shouldRenderHyperlinks(process.stdout));
96101
+ yield* printDiagnostics(displayDiagnostics, verbose, resolveDiagnosticSourceRoot, buildRulePriorityMap(completedScans.map((scan) => scan.result.score)), isCodingAgentEnvironment(), { animateCountUp: animateRender }, shouldRenderHyperlinks(process.stdout), resolveDiagnosticFrameSourceRoot);
95541
96102
  }
95542
96103
  const lowestScoredScan = findLowestScoredScan(completedScans);
95543
96104
  const aggregateScore = lowestScoredScan?.result.score ?? null;
@@ -95925,6 +96486,45 @@ const runExplain = async (fileLineArgument, context) => {
95925
96486
  }
95926
96487
  };
95927
96488
  //#endregion
96489
+ //#region src/cli/utils/run-project-scan-batch.ts
96490
+ /**
96491
+ * Run one scan per project through the same bounded pool as
96492
+ * `diagnose({ projects })`, with the batch spinner and its progress counter.
96493
+ *
96494
+ * Pool members must not toggle the module-level spinner-silent flag themselves —
96495
+ * overlapping save/restore pairs would race — so the batch owns that toggle once
96496
+ * around the whole run.
96497
+ *
96498
+ * A `scanProject` that returns `null` drops the project from the results: diff
96499
+ * mode skips projects with no changed source.
96500
+ */
96501
+ const runProjectScanBatch = async (input) => {
96502
+ const startTime = performance$1.now();
96503
+ const projectCount = input.projects.length;
96504
+ const isMultiProject = projectCount > 1;
96505
+ const batchSpinner = isMultiProject && !input.isQuiet ? spinner(`Scanning ${projectCount} projects…`).start() : null;
96506
+ const ownsBatchSpinnerSilence = isMultiProject && input.isSilent;
96507
+ const wasSpinnerSilent = isSpinnerSilent();
96508
+ if (ownsBatchSpinnerSilence) setSpinnerSilent(true);
96509
+ let finishedProjectCount = 0;
96510
+ let scanOutcomes;
96511
+ try {
96512
+ scanOutcomes = await mapWithConcurrency(input.projects, isMultiProject ? 4 : 1, async (project) => {
96513
+ const scanOutcome = await input.scanProject(project);
96514
+ finishedProjectCount += 1;
96515
+ batchSpinner?.update(`Scanning ${projectCount} projects… (${finishedProjectCount}/${projectCount})`);
96516
+ return scanOutcome;
96517
+ });
96518
+ } finally {
96519
+ if (ownsBatchSpinnerSilence) setSpinnerSilent(wasSpinnerSilent);
96520
+ batchSpinner?.stop();
96521
+ }
96522
+ return {
96523
+ completedScans: scanOutcomes.filter((scanOutcome) => scanOutcome !== null),
96524
+ elapsedMilliseconds: performance$1.now() - startTime
96525
+ };
96526
+ };
96527
+ //#endregion
95928
96528
  //#region src/cli/utils/project-manifest-changed.ts
95929
96529
  const PACKAGE_JSON = "package.json";
95930
96530
  /**
@@ -95941,6 +96541,29 @@ const projectManifestChanged = (rootDirectory, projectDirectory, diffInfo) => {
95941
96541
  return diffInfo.changedFiles.some((filePath) => toForwardSlashes(filePath) === manifestPath);
95942
96542
  };
95943
96543
  //#endregion
96544
+ //#region src/cli/utils/select-staged-projects.ts
96545
+ /**
96546
+ * Appended to the reason a `--staged` run could not scan per package. Shared so
96547
+ * both fallback sites word it identically.
96548
+ */
96549
+ const STAGED_PROJECT_FALLBACK_HINT = "Scanning the staged files at the scan root instead — fix the `projects` entries in your config to scan per package.";
96550
+ /**
96551
+ * Resolve the project directories a `--staged` scan owns. The interactive picker
96552
+ * is always skipped: a commit hook has nobody to answer it.
96553
+ */
96554
+ const selectStagedProjects = async (input) => {
96555
+ if (input.projectFlag) return selectProjects(input.rootDirectory, input.projectFlag, true, void 0);
96556
+ if (input.configProjects === void 0) return [input.rootDirectory];
96557
+ try {
96558
+ return await selectProjects(input.rootDirectory, void 0, true, input.configProjects);
96559
+ } catch (error) {
96560
+ if (!(error instanceof CliInputError)) throw error;
96561
+ cliLogger.warn(`${error.message} ${STAGED_PROJECT_FALLBACK_HINT}`);
96562
+ cliLogger.break();
96563
+ return [input.rootDirectory];
96564
+ }
96565
+ };
96566
+ //#endregion
95944
96567
  //#region src/cli/utils/should-fail-scan-gate.ts
95945
96568
  const shouldFailScanGate = (input) => {
95946
96569
  if (input.blockingLevel === "none") return false;
@@ -96162,8 +96785,13 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
96162
96785
  json: flags.json
96163
96786
  });
96164
96787
  if (flags.staged) {
96165
- const stagedFiles = await getStagedSourceFiles(resolvedDirectory);
96166
- if (stagedFiles.length === 0) {
96788
+ const configProjectsApply = (userConfig?.projects ?? []).some((projectName) => projectName.trim().length > 0) && scanTarget.requestedDirectory === scanTarget.configSourceDirectory;
96789
+ const projectDirectories = await selectStagedProjects({
96790
+ rootDirectory: resolvedDirectory,
96791
+ projectFlag: flags.project,
96792
+ configProjects: configProjectsApply ? userConfig?.projects : void 0
96793
+ });
96794
+ const reportNothingToScan = (input) => {
96167
96795
  if (isJsonMode) writeJsonReport(buildJsonReport({
96168
96796
  version: VERSION,
96169
96797
  directory: resolvedDirectory,
@@ -96172,71 +96800,197 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
96172
96800
  scans: [],
96173
96801
  totalElapsedMilliseconds: performance$1.now() - startTime
96174
96802
  }));
96175
- else if (!isScoreOnly) cliLogger.dim("No staged source files found.");
96803
+ else if (!isScoreOnly) if (input.severity === "warn") {
96804
+ cliLogger.warn(input.reason);
96805
+ cliLogger.break();
96806
+ } else cliLogger.dim(input.reason);
96807
+ };
96808
+ const rootStagedFiles = await getStagedSourceFiles(resolvedDirectory);
96809
+ if (rootStagedFiles.length === 0) {
96810
+ reportNothingToScan({ reason: "No staged source files found." });
96176
96811
  return;
96177
96812
  }
96178
- if (!isQuiet) {
96179
- cliLogger.log(`Scanning ${highlighter.info(`${stagedFiles.length}`)} staged files...`);
96813
+ const buildProjectScanContext = async (projectDirectory) => {
96814
+ const projectScanTarget = projectDirectory === resolvedDirectory ? scanTarget : await resolveScanTarget(projectDirectory, { allowAmbiguous: true });
96815
+ const scanDirectory = projectScanTarget.resolvedDirectory;
96816
+ const treeRelativeDirectory = resolveProjectRelativeDirectory(resolvedDirectory, scanDirectory);
96817
+ if (treeRelativeDirectory === null) return null;
96818
+ return {
96819
+ projectDirectory,
96820
+ scanDirectory,
96821
+ treeRelativeDirectory,
96822
+ projectConfig: projectDirectory === resolvedDirectory ? userConfig : mergeReactDoctorConfigs(userConfig, projectScanTarget.userConfig ?? void 0),
96823
+ projectConfigSourceDirectory: projectScanTarget.userConfig?.plugins === void 0 ? scanTarget.configSourceDirectory : projectScanTarget.configSourceDirectory
96824
+ };
96825
+ };
96826
+ const projectScanContexts = [];
96827
+ const seenScanDirectories = /* @__PURE__ */ new Set();
96828
+ for (const projectDirectory of projectDirectories) {
96829
+ const projectScanContext = await buildProjectScanContext(projectDirectory);
96830
+ if (projectScanContext === null) {
96831
+ if (flags.project) throw new CliInputError(`Project "${toRelativePath(projectDirectory, resolvedDirectory)}" is outside ${resolvedDirectory}, so it holds none of the staged files. Run --staged from a directory that contains the project.`);
96832
+ continue;
96833
+ }
96834
+ if (seenScanDirectories.has(projectScanContext.scanDirectory)) continue;
96835
+ seenScanDirectories.add(projectScanContext.scanDirectory);
96836
+ projectScanContexts.push(projectScanContext);
96837
+ }
96838
+ if (projectScanContexts.length === 0) {
96839
+ cliLogger.warn(`No configured project is inside ${resolvedDirectory}. ${STAGED_PROJECT_FALLBACK_HINT}`);
96180
96840
  cliLogger.break();
96841
+ const rootScanContext = await buildProjectScanContext(resolvedDirectory);
96842
+ if (rootScanContext !== null) projectScanContexts.push(rootScanContext);
96181
96843
  }
96182
- const tempDirectory = NFS.mkdtempSync(Path.join(tmpdir(), STAGED_FILES_TEMP_DIR_PREFIX));
96183
- const snapshot = await materializeStagedFiles(resolvedDirectory, stagedFiles, tempDirectory).catch((error) => {
96184
- NFS.rmSync(tempDirectory, {
96185
- recursive: true,
96186
- force: true
96844
+ const contextsByLongestPathFirst = [...projectScanContexts].sort((left, right) => right.treeRelativeDirectory.length - left.treeRelativeDirectory.length);
96845
+ const ownedStagedFiles = /* @__PURE__ */ new Map();
96846
+ for (const stagedFile of rootStagedFiles) {
96847
+ const owner = contextsByLongestPathFirst.find((context) => context.treeRelativeDirectory.length === 0 || stagedFile.startsWith(`${context.treeRelativeDirectory}/`));
96848
+ if (owner === void 0) continue;
96849
+ const ownedFiles = ownedStagedFiles.get(owner.scanDirectory);
96850
+ if (ownedFiles === void 0) ownedStagedFiles.set(owner.scanDirectory, [stagedFile]);
96851
+ else ownedFiles.push(stagedFile);
96852
+ }
96853
+ const stagedProjectScans = [];
96854
+ for (const projectScanContext of projectScanContexts) {
96855
+ const projectStagedFiles = ownedStagedFiles.get(projectScanContext.scanDirectory);
96856
+ if (projectStagedFiles === void 0) continue;
96857
+ stagedProjectScans.push({
96858
+ ...projectScanContext,
96859
+ stagedFiles: projectStagedFiles
96187
96860
  });
96188
- throw error;
96189
- });
96861
+ }
96862
+ if (stagedProjectScans.length === 0) {
96863
+ reportNothingToScan({ reason: "No staged source files in the selected projects." });
96864
+ return;
96865
+ }
96866
+ const selectedStagedFiles = stagedProjectScans.flatMap((projectScan) => projectScan.stagedFiles);
96867
+ const stagedFileCount = selectedStagedFiles.length;
96868
+ const unselectedStagedFileCount = rootStagedFiles.length - stagedFileCount;
96869
+ if (!isQuiet) {
96870
+ cliLogger.log(`Scanning ${highlighter.info(`${stagedFileCount}`)} staged files...`);
96871
+ if (unselectedStagedFileCount > 0) cliLogger.dim(`${unselectedStagedFileCount} more staged file${unselectedStagedFileCount === 1 ? "" : "s"} outside the selected projects.`);
96872
+ cliLogger.break();
96873
+ }
96190
96874
  const stagedWantsLines = resolveScope(flags, userConfig).scope === "lines";
96191
96875
  const stagedLineRanges = stagedWantsLines ? await getChangedLineRanges({
96192
96876
  directory: resolvedDirectory,
96193
96877
  cached: true,
96194
- files: snapshot.stagedFiles
96878
+ files: selectedStagedFiles
96195
96879
  }) : null;
96196
96880
  if (stagedWantsLines && stagedLineRanges === null && !isQuiet) {
96197
96881
  cliLogger.warn("Could not determine staged changed lines; reporting all issues in staged files.");
96198
96882
  cliLogger.break();
96199
96883
  }
96200
- try {
96201
- const scanResult = await inspect(snapshot.tempDirectory, {
96884
+ if (stagedProjectScans.some((projectScan) => projectScan.treeRelativeDirectory.length > 0)) recordCount(METRIC.stagedPerProject, 1, { projectCount: stagedProjectScans.length });
96885
+ const tempDirectory = NFS.mkdtempSync(Path.join(tmpdir(), STAGED_FILES_TEMP_DIR_PREFIX));
96886
+ const configSubdirectories = /* @__PURE__ */ new Set();
96887
+ for (const projectScan of stagedProjectScans) {
96888
+ configSubdirectories.add(projectScan.treeRelativeDirectory);
96889
+ const projectRelativeDirectory = resolveProjectRelativeDirectory(resolvedDirectory, projectScan.projectDirectory);
96890
+ if (projectRelativeDirectory !== null) configSubdirectories.add(projectRelativeDirectory);
96891
+ }
96892
+ const snapshot = await materializeStagedFiles({
96893
+ directory: resolvedDirectory,
96894
+ stagedFiles: selectedStagedFiles,
96895
+ tempDirectory,
96896
+ configSubdirectories: [...configSubdirectories]
96897
+ }).catch((error) => {
96898
+ NFS.rmSync(tempDirectory, {
96899
+ recursive: true,
96900
+ force: true
96901
+ });
96902
+ throw error;
96903
+ });
96904
+ const materializedStagedFiles = new Set(snapshot.stagedFiles);
96905
+ const stagedProjectRuns = stagedProjectScans.map((projectScan) => ({
96906
+ projectScan,
96907
+ includePaths: resolveProjectSourceFilePaths(resolvedDirectory, projectScan.scanDirectory, projectScan.stagedFiles.filter((stagedFile) => materializedStagedFiles.has(stagedFile)))
96908
+ })).filter((projectRun) => projectRun.includePaths.length > 0);
96909
+ const isMultiProject = stagedProjectRuns.length > 1;
96910
+ if (stagedProjectRuns.length === 0) {
96911
+ snapshot.cleanup();
96912
+ reportNothingToScan({
96913
+ reason: `Could not read any of the ${stagedFileCount} staged file${stagedFileCount === 1 ? "" : "s"} out of the index, so nothing was scanned. An unusually large staged file is the usual cause.`,
96914
+ severity: "warn"
96915
+ });
96916
+ return;
96917
+ }
96918
+ if (snapshot.unmaterializedFiles.length > 0 && !isQuiet) {
96919
+ const stagedFileLabel = `staged file${stagedFileCount === 1 ? "" : "s"}`;
96920
+ cliLogger.warn(`Skipped ${snapshot.unmaterializedFiles.length} of ${stagedFileCount} ${stagedFileLabel}; they could not be snapshotted from the index.`);
96921
+ cliLogger.break();
96922
+ }
96923
+ const scanStagedProject = async (projectRun) => {
96924
+ const { projectScan, includePaths } = projectRun;
96925
+ const projectTempDirectory = Path.join(snapshot.tempDirectory, projectScan.treeRelativeDirectory);
96926
+ const scanResult = await inspect(projectTempDirectory, {
96202
96927
  ...scanOptions,
96203
96928
  deadlineEpochMs: scanDeadlineEpochMs,
96204
- includePaths: snapshot.stagedFiles,
96205
- configOverride: userConfig,
96206
- configSourceDirectory: scanTarget.configSourceDirectory ?? void 0,
96207
- changedLineRanges: stagedLineRanges ?? void 0
96929
+ includePaths: [...includePaths],
96930
+ configOverride: projectScan.projectConfig,
96931
+ configSourceDirectory: projectScan.projectConfigSourceDirectory ?? void 0,
96932
+ changedLineRanges: stagedLineRanges === null ? void 0 : resolveProjectChangedLineRanges(resolvedDirectory, projectScan.scanDirectory, stagedLineRanges),
96933
+ suppressRendering: isMultiProject,
96934
+ concurrentScan: isMultiProject
96208
96935
  });
96209
96936
  const remappedDiagnostics = scanResult.diagnostics.map((diagnostic) => ({
96210
96937
  ...diagnostic,
96211
- filePath: Path.isAbsolute(diagnostic.filePath) ? diagnostic.filePath.replaceAll(snapshot.tempDirectory, () => resolvedDirectory) : diagnostic.filePath
96938
+ filePath: Path.isAbsolute(diagnostic.filePath) ? diagnostic.filePath.replaceAll(projectTempDirectory, () => projectScan.scanDirectory) : diagnostic.filePath
96212
96939
  }));
96213
- finalizeScans({
96214
- completedScans: [{
96215
- directory: resolvedDirectory,
96216
- result: {
96217
- ...scanResult,
96218
- diagnostics: remappedDiagnostics,
96219
- project: {
96220
- ...scanResult.project,
96221
- rootDirectory: resolvedDirectory
96222
- }
96223
- },
96224
- config: userConfig
96225
- }],
96226
- mode: "staged",
96227
- diff: null,
96228
- baselineIntended: false,
96229
- isJsonMode,
96230
- isScoreOnly,
96231
- flags,
96232
- categoryFilters,
96233
- userConfig,
96234
- resolvedDirectory,
96235
- startTime
96236
- });
96940
+ return {
96941
+ directory: projectScan.scanDirectory,
96942
+ result: {
96943
+ ...scanResult,
96944
+ diagnostics: remappedDiagnostics,
96945
+ project: {
96946
+ ...scanResult.project,
96947
+ rootDirectory: projectScan.scanDirectory
96948
+ }
96949
+ },
96950
+ config: projectScan.projectConfig,
96951
+ frameSourceRoot: projectTempDirectory
96952
+ };
96953
+ };
96954
+ const stagedBatch = await runProjectScanBatch({
96955
+ projects: stagedProjectRuns,
96956
+ isQuiet,
96957
+ isSilent: scanOptions.silent === true,
96958
+ scanProject: scanStagedProject
96959
+ }).catch((error) => {
96960
+ snapshot.cleanup();
96961
+ throw error;
96962
+ });
96963
+ const completedScans = stagedBatch.completedScans;
96964
+ try {
96965
+ if (!isQuiet && isMultiProject) {
96966
+ const showShareLink = !isShareOptedOut(completedScans, scanOptions.noScore) && !scanOptions.isCi;
96967
+ await runPromise(printMultiProjectSummary({
96968
+ completedScans,
96969
+ categoryFilters,
96970
+ verbose: Boolean(flags.verbose),
96971
+ outputDirectory: flags.outputDir,
96972
+ isOffline: !showShareLink,
96973
+ projectName: Path.basename(resolvedDirectory),
96974
+ totalElapsedMilliseconds: stagedBatch.elapsedMilliseconds
96975
+ }));
96976
+ }
96977
+ if (flags.outputDir && isMultiProject && isQuiet) await runPromise(printDiagnosticsDump(filterDiagnosticsByCategories(filterScansForSurface(completedScans, scanOptions.outputSurface ?? "cli"), categoryFilters), flags.outputDir, false, "stderr"));
96237
96978
  } finally {
96238
96979
  snapshot.cleanup();
96239
96980
  }
96981
+ finalizeScans({
96982
+ completedScans,
96983
+ mode: "staged",
96984
+ diff: null,
96985
+ baselineIntended: false,
96986
+ isJsonMode,
96987
+ isScoreOnly,
96988
+ flags,
96989
+ categoryFilters,
96990
+ userConfig,
96991
+ resolvedDirectory,
96992
+ startTime
96993
+ });
96240
96994
  return;
96241
96995
  }
96242
96996
  const projectDirectories = await selectProjects(resolvedDirectory, flags.project, skipPrompts, userConfig?.projects);
@@ -96301,7 +97055,6 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
96301
97055
  }
96302
97056
  cliLogger.break();
96303
97057
  }
96304
- const completedScans = [];
96305
97058
  const isMultiProject = projectDirectories.length > 1;
96306
97059
  const scanProject = async (projectDirectory) => {
96307
97060
  const projectScanTarget = projectDirectory === resolvedDirectory ? scanTarget : await resolveScanTarget(projectDirectory, { allowAmbiguous: true });
@@ -96352,29 +97105,13 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
96352
97105
  config: projectConfig
96353
97106
  };
96354
97107
  };
96355
- const scanLoopStartTime = performance$1.now();
96356
- const projectCount = projectDirectories.length;
96357
- const batchSpinner = isMultiProject && !isQuiet ? spinner(`Scanning ${projectCount} projects…`).start() : null;
96358
- const ownsBatchSpinnerSilence = isMultiProject && scanOptions.silent === true;
96359
- const wasSpinnerSilent = isSpinnerSilent();
96360
- if (ownsBatchSpinnerSilence) setSpinnerSilent(true);
96361
- let finishedProjectCount = 0;
96362
- let scanOutcomes;
96363
- try {
96364
- scanOutcomes = await mapWithConcurrency(projectDirectories, isMultiProject ? 4 : 1, async (projectDirectory) => {
96365
- const scanOutcome = await scanProject(projectDirectory);
96366
- finishedProjectCount += 1;
96367
- batchSpinner?.update(`Scanning ${projectCount} projects… (${finishedProjectCount}/${projectCount})`);
96368
- return scanOutcome;
96369
- });
96370
- } finally {
96371
- if (ownsBatchSpinnerSilence) setSpinnerSilent(wasSpinnerSilent);
96372
- batchSpinner?.stop();
96373
- }
96374
- for (const scanOutcome of scanOutcomes) {
96375
- if (scanOutcome === null) continue;
96376
- completedScans.push(scanOutcome);
96377
- }
97108
+ const projectBatch = await runProjectScanBatch({
97109
+ projects: projectDirectories,
97110
+ isQuiet,
97111
+ isSilent: scanOptions.silent === true,
97112
+ scanProject
97113
+ });
97114
+ const completedScans = projectBatch.completedScans;
96378
97115
  if (!isQuiet && isMultiProject && completedScans.length > 0) {
96379
97116
  const showShareLink = !isShareOptedOut(completedScans, scanOptions.noScore) && !scanOptions.isCi;
96380
97117
  await runPromise(printMultiProjectSummary({
@@ -96384,7 +97121,7 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
96384
97121
  outputDirectory: flags.outputDir,
96385
97122
  isOffline: !showShareLink,
96386
97123
  projectName: Path.basename(resolvedDirectory),
96387
- totalElapsedMilliseconds: performance$1.now() - scanLoopStartTime
97124
+ totalElapsedMilliseconds: projectBatch.elapsedMilliseconds
96388
97125
  }));
96389
97126
  }
96390
97127
  const selectedSurfaceDiagnostics = filterDiagnosticsByCategories(filterScansForSurface(completedScans, scanOptions.outputSurface ?? "cli"), categoryFilters);
@@ -97530,7 +98267,7 @@ ${highlighter.dim("Learn more:")}
97530
98267
  ${highlighter.info(CI_URL)}
97531
98268
  `;
97532
98269
  const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
97533
- const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
98270
+ const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks (honors --project and config `projects`; exits 0 when nothing is staged)").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
97534
98271
  program.action(inspectAction);
97535
98272
  program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
97536
98273
  program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
@@ -97613,4 +98350,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
97613
98350
  export { toForwardSlashes as A, getCategoryImpact as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, TUI_REPORT_DETAIL_WIDTH_FRACTION as F, runPromise as G, mapWithConcurrency as H, isCiEnvironment as I, succeed$3 as J, sync as K, DIAGNOSTIC_CATEGORY_BUCKETS as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_COMPACT_MAX_ROWS as P, Progress as R, hasLintHardFailure as S, formatFixRecipeLine as T, mergeReactDoctorConfigs as U, highlighter as V, resolveScanTarget as W, canAnimateOnboarding as _, resolveCliInspectOptions as a, buildCodeFrame as b, detectLaunchableAgents as c, launchCliAgent as d, isShareOptedOut as f, doctorFace as g, easeOutCubic as h, selectProjects as i, findNearestPackageDirectory as j, recordCount as k, CLI_AGENT_BINARIES as l, printFooter as m, shouldFailScanGate as n, countUniqueScannedFiles as o, inspect as p, void_ as q, discoverWorkspacePackages as r, setUpGitHubActions as s, exitGracefully as t, copyToClipboard as u, computeProjectedScore as v, buildSortedRuleGroups as w, buildNoScoreMessage as x, formatElapsedTime as y, Reporter as z };
97614
98351
 
97615
98352
  //# sourceMappingURL=cli.js.map
97616
- //# debugId=3ced4c14-18cb-5b0c-811c-3448b5c2f139
98353
+ //# debugId=bb982094-8280-5afe-b061-eb103665c55c