headlamp 0.1.11 → 0.1.13

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/index.js CHANGED
@@ -593,7 +593,7 @@ var init_TimeoutError = __esm({
593
593
 
594
594
  // node_modules/es-toolkit/dist/promise/delay.mjs
595
595
  function delay(ms, { signal } = {}) {
596
- return new Promise((resolve10, reject) => {
596
+ return new Promise((resolve11, reject) => {
597
597
  const abortError = () => {
598
598
  reject(new AbortError());
599
599
  };
@@ -606,7 +606,7 @@ function delay(ms, { signal } = {}) {
606
606
  }
607
607
  const timeoutId = setTimeout(() => {
608
608
  signal?.removeEventListener("abort", abortHandler);
609
- resolve10();
609
+ resolve11();
610
610
  }, ms);
611
611
  signal?.addEventListener("abort", abortHandler, { once: true });
612
612
  });
@@ -671,11 +671,11 @@ var init_exec = __esm({
671
671
  child.stderr?.on("data", (chunk) => {
672
672
  stderr += String(chunk);
673
673
  });
674
- const exec = new Promise((resolve10, reject) => {
674
+ const exec = new Promise((resolve11, reject) => {
675
675
  child.on("error", reject);
676
676
  child.on(
677
677
  "close",
678
- (code) => Number(code) === 0 ? resolve10(stdout) : reject(new Error(stderr || `exit ${code}`))
678
+ (code) => Number(code) === 0 ? resolve11(stdout) : reject(new Error(stderr || `exit ${code}`))
679
679
  );
680
680
  });
681
681
  try {
@@ -695,7 +695,7 @@ var init_exec = __esm({
695
695
  throw caughtError;
696
696
  }
697
697
  };
698
- runExitCode = async (cmd, args, opts = {}) => new Promise((resolve10, reject) => {
698
+ runExitCode = async (cmd, args, opts = {}) => new Promise((resolve11, reject) => {
699
699
  const child = spawn(cmd, [...args], {
700
700
  cwd: opts.cwd,
701
701
  env: opts.env,
@@ -704,9 +704,9 @@ var init_exec = __esm({
704
704
  windowsHide: true
705
705
  });
706
706
  child.on("error", reject);
707
- child.on("close", (code) => resolve10(Number(code)));
707
+ child.on("close", (code) => resolve11(Number(code)));
708
708
  });
709
- runWithCapture = async (cmd, args, opts) => new Promise((resolve10, reject) => {
709
+ runWithCapture = async (cmd, args, opts) => new Promise((resolve11, reject) => {
710
710
  const child = spawn(cmd, [...args], {
711
711
  cwd: opts.cwd,
712
712
  env: opts.env,
@@ -722,7 +722,7 @@ var init_exec = __esm({
722
722
  buf += String(chunk);
723
723
  });
724
724
  child.on("error", reject);
725
- child.on("close", (code) => resolve10({ code: Number(code), output: buf }));
725
+ child.on("close", (code) => resolve11({ code: Number(code), output: buf }));
726
726
  });
727
727
  }
728
728
  });
@@ -735,7 +735,9 @@ __export(fast_related_exports, {
735
735
  findRelatedTestsFast: () => findRelatedTestsFast
736
736
  });
737
737
  import * as path3 from "node:path";
738
+ import * as os2 from "node:os";
738
739
  import * as fs from "node:fs/promises";
740
+ import { createHash } from "node:crypto";
739
741
  var TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
740
742
  var init_fast_related = __esm({
741
743
  "src/lib/fast-related.ts"() {
@@ -788,9 +790,7 @@ var init_fast_related = __esm({
788
790
  }
789
791
  const args = ["-n", "-l", "-S", "-F"];
790
792
  testGlobs.forEach((globPattern) => args.push("-g", globPattern));
791
- excludeGlobs.forEach(
792
- (excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`)
793
- );
793
+ excludeGlobs.forEach((excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`));
794
794
  seeds.forEach((seedToken) => args.push("-e", seedToken));
795
795
  let raw = "";
796
796
  try {
@@ -802,9 +802,7 @@ var init_fast_related = __esm({
802
802
  }
803
803
  const lines = raw.split(/\r?\n/).map((lineText) => lineText.trim()).filter(Boolean);
804
804
  const looksLikeTest = (pathText) => /\.(test|spec)\.[tj]sx?$/i.test(pathText) || /(^|\/)tests?\//i.test(pathText);
805
- const absolute = lines.map(
806
- (relativePath) => path3.resolve(repoRoot, relativePath).replace(/\\/g, "/")
807
- ).filter(looksLikeTest);
805
+ const absolute = lines.map((relativePath) => path3.resolve(repoRoot, relativePath).replace(/\\/g, "/")).filter(looksLikeTest);
808
806
  const uniq = Array.from(new Set(absolute));
809
807
  const results = [];
810
808
  await Promise.all(
@@ -819,17 +817,15 @@ var init_fast_related = __esm({
819
817
  return results;
820
818
  };
821
819
  cachedRelated = async (opts) => {
822
- const cacheDir = path3.join(opts.repoRoot, ".cache");
820
+ const cacheRoot = process.env.HEADLAMP_CACHE_DIR || path3.join(os2.tmpdir(), "headlamp-cache");
821
+ const repoKey = createHash("sha1").update(path3.resolve(opts.repoRoot)).digest("hex").slice(0, 12);
822
+ const cacheDir = path3.join(cacheRoot, repoKey);
823
823
  const cacheFile = path3.join(cacheDir, "relevant-tests.json");
824
824
  let head = "nogit";
825
825
  try {
826
- const raw = await runText(
827
- "git",
828
- ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"],
829
- {
830
- env: safeEnv(process.env, {})
831
- }
832
- );
826
+ const raw = await runText("git", ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"], {
827
+ env: safeEnv(process.env, {})
828
+ });
833
829
  head = raw.trim() || "nogit";
834
830
  } catch {
835
831
  head = "nogit";
@@ -861,10 +857,7 @@ var init_fast_related = __esm({
861
857
  try {
862
858
  const next = { ...bag, [key]: Array.from(new Set(recomputed)) };
863
859
  await fs.mkdir(cacheDir, { recursive: true });
864
- await fs.writeFile(
865
- cacheFile,
866
- JSON.stringify(next, null, JsonIndentSpaces)
867
- );
860
+ await fs.writeFile(cacheFile, JSON.stringify(next, null, JsonIndentSpaces));
868
861
  } catch {
869
862
  }
870
863
  return recomputed;
@@ -1133,8 +1126,8 @@ var require_utils = __commonJS({
1133
1126
  }
1134
1127
  return output;
1135
1128
  };
1136
- exports.basename = (path12, { windows } = {}) => {
1137
- const segs = path12.split(windows ? /[\\/]/ : "/");
1129
+ exports.basename = (path13, { windows } = {}) => {
1130
+ const segs = path13.split(windows ? /[\\/]/ : "/");
1138
1131
  const last = segs[segs.length - 1];
1139
1132
  if (last === "") {
1140
1133
  return segs[segs.length - 2];
@@ -3503,11 +3496,11 @@ var require_lib = __commonJS({
3503
3496
  "node_modules/json5/lib/index.js"(exports, module) {
3504
3497
  var parse = require_parse2();
3505
3498
  var stringify = require_stringify();
3506
- var JSON53 = {
3499
+ var JSON54 = {
3507
3500
  parse,
3508
3501
  stringify
3509
3502
  };
3510
- module.exports = JSON53;
3503
+ module.exports = JSON54;
3511
3504
  }
3512
3505
  });
3513
3506
 
@@ -6133,15 +6126,23 @@ var buildMessageSection = (messageLines, details, _ctx, opts) => {
6133
6126
  const fallbackLines = [];
6134
6127
  if (hasOnlyBareError) {
6135
6128
  const startFrom = hintIdx >= 0 ? hintIdx + 1 : 0;
6129
+ let started = false;
6136
6130
  for (let i = startFrom; i < lines.length; i += 1) {
6137
6131
  const candidate = lines[i];
6138
- if (!candidate.trim()) {
6132
+ if (isStackLine(candidate)) {
6139
6133
  break;
6140
6134
  }
6141
- if (isStackLine(candidate)) {
6135
+ if (!candidate.trim()) {
6136
+ if (!started) {
6137
+ continue;
6138
+ }
6142
6139
  break;
6143
6140
  }
6141
+ started = true;
6144
6142
  fallbackLines.push(candidate);
6143
+ if (fallbackLines.length >= 6) {
6144
+ break;
6145
+ }
6145
6146
  }
6146
6147
  if (fallbackLines.length === 0 && details && details.messages && details.messages.length) {
6147
6148
  fallbackLines.push(
@@ -6209,7 +6210,7 @@ var linesFromDetails = (details) => {
6209
6210
  if (typeof obj.received === "string") {
6210
6211
  pushMaybe(obj.received, messages);
6211
6212
  }
6212
- const arrays = ["errors", "causes", "aggregatedErrors"];
6213
+ const arrays = ["errors", "details", "issues", "inner", "causes", "aggregatedErrors"];
6213
6214
  for (const key of arrays) {
6214
6215
  const arr = obj[key];
6215
6216
  if (Array.isArray(arr)) {
@@ -6218,7 +6219,7 @@ var linesFromDetails = (details) => {
6218
6219
  }
6219
6220
  }
6220
6221
  }
6221
- const nestedCandidates = ["error", "cause", "matcherResult"];
6222
+ const nestedCandidates = ["error", "cause", "matcherResult", "context", "data"];
6222
6223
  for (const key of nestedCandidates) {
6223
6224
  if (obj[key] && typeof obj[key] === "object") {
6224
6225
  visitDeep(obj[key], depth + 1);
@@ -6247,9 +6248,7 @@ var linesFromDetails = (details) => {
6247
6248
  pushMaybe(matcher.expected, messages);
6248
6249
  pushMaybe(matcher.received, messages);
6249
6250
  }
6250
- if (messages.length === 0 && stacks.length === 0) {
6251
- visitDeep(detail, 0);
6252
- }
6251
+ visitDeep(detail, 0);
6253
6252
  }
6254
6253
  }
6255
6254
  return { stacks, messages };
@@ -6313,24 +6312,31 @@ var buildConsoleSection = (maybeConsole) => {
6313
6312
  var buildFallbackMessageBlock = (messageLines, details) => {
6314
6313
  const normalize2 = (arr) => arr.map((lineText) => stripAnsiSimple(lineText)).filter((line) => line.trim().length > 0);
6315
6314
  const normalized = normalize2(messageLines);
6316
- const informative = normalized.filter((line) => !/^\s*(?:Error|AssertionError):?\s*$/.test(line));
6315
+ const informative = normalized.filter(
6316
+ (line) => !/^\s*(?:Error|AssertionError):?\s*$/i.test(line)
6317
+ );
6317
6318
  if (informative.length > 0) {
6318
6319
  return [];
6319
6320
  }
6320
6321
  const errorIdx = normalized.findIndex(
6321
- (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/.test(line)
6322
+ (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/i.test(line)
6322
6323
  );
6323
6324
  const collected = [];
6324
6325
  if (errorIdx >= 0) {
6325
- for (let i = errorIdx; i < normalized.length && collected.length < 8; i += 1) {
6326
- const ln = normalized[i];
6327
- if (!ln.trim()) {
6326
+ let started = false;
6327
+ for (let i = errorIdx + 1; i < messageLines.length && collected.length < 8; i += 1) {
6328
+ const raw = stripAnsiSimple(messageLines[i]);
6329
+ if (isStackLine(raw)) {
6328
6330
  break;
6329
6331
  }
6330
- if (isStackLine(ln)) {
6332
+ if (!raw.trim()) {
6333
+ if (!started) {
6334
+ continue;
6335
+ }
6331
6336
  break;
6332
6337
  }
6333
- collected.push(ln);
6338
+ started = true;
6339
+ collected.push(raw);
6334
6340
  }
6335
6341
  }
6336
6342
  const fromDetails = collected.length > 0 ? [] : normalize2(details.messages).slice(0, 6);
@@ -6578,39 +6584,13 @@ var makeCtx = (opts, showStacks = false) => {
6578
6584
  return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
6579
6585
  };
6580
6586
 
6581
- // src/lib/formatter/bridge.ts
6582
- var import_json52 = __toESM(require_lib(), 1);
6587
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
6588
+ var import_json53 = __toESM(require_lib(), 1);
6583
6589
  import * as fs6 from "node:fs";
6590
+ import * as path11 from "node:path";
6591
+
6592
+ // src/lib/formatter/bridge/logic.ts
6584
6593
  import * as path10 from "node:path";
6585
- var colorTokens2 = {
6586
- pass: Colors.Success,
6587
- fail: Colors.Failure,
6588
- skip: Colors.Skip,
6589
- todo: Colors.Todo,
6590
- passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
6591
- failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
6592
- };
6593
- var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
6594
- var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
6595
- var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
6596
- var summarizeUrl = (method, url, route) => {
6597
- const base = route || url || "";
6598
- const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
6599
- return [method || "", base, qs].filter(Boolean).join(" ").trim();
6600
- };
6601
- var stripBridgeEventsFromConsole = (maybeConsole) => {
6602
- if (!Array.isArray(maybeConsole)) {
6603
- return maybeConsole;
6604
- }
6605
- return maybeConsole.filter((entry) => {
6606
- try {
6607
- const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
6608
- return !raw.includes("[JEST-BRIDGE-EVENT]");
6609
- } catch {
6610
- return true;
6611
- }
6612
- });
6613
- };
6614
6594
  var extractBridgePath2 = (raw, cwd) => {
6615
6595
  const matches = Array.from(
6616
6596
  raw.matchAll(/Test results written to:\s+([^\n\r]+jest-bridge-[^\s'"]+\.json)/g)
@@ -6618,7 +6598,7 @@ var extractBridgePath2 = (raw, cwd) => {
6618
6598
  if (!matches.length) {
6619
6599
  return null;
6620
6600
  }
6621
- const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^["'`]|["'`]$/g, "");
6601
+ const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^['"`]|['"`]$/g, "");
6622
6602
  return path10.isAbsolute(jsonPath) ? jsonPath : path10.resolve(cwd, jsonPath).replace(/\\/g, "/");
6623
6603
  };
6624
6604
  var isTransportError = (msg) => {
@@ -6627,25 +6607,6 @@ var isTransportError = (msg) => {
6627
6607
  lowercaseMessage
6628
6608
  );
6629
6609
  };
6630
- var envNumber = (name, fallback) => {
6631
- const parsed = Number(process.env[name]);
6632
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
6633
- };
6634
- var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
6635
- var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
6636
- var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
6637
- var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
6638
- var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
6639
- var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
6640
- if (typeof ts !== "number" || !Number.isFinite(ts)) {
6641
- return [];
6642
- }
6643
- return http.filter((e) => {
6644
- const timeOk = typeof e.timestampMs === "number" && Math.abs(e.timestampMs - ts) <= windowMs;
6645
- const pathOk = !testPath || e.testPath === testPath;
6646
- return timeOk && pathOk;
6647
- });
6648
- };
6649
6610
  var parseMethodPathFromTitle = (title) => {
6650
6611
  if (!title) {
6651
6612
  return {};
@@ -6653,35 +6614,6 @@ var parseMethodPathFromTitle = (title) => {
6653
6614
  const matchResult = title.match(/\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+([^\s)]+)/i);
6654
6615
  return matchResult ? { method: matchResult[1]?.toUpperCase(), path: matchResult[2] } : {};
6655
6616
  };
6656
- var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
6657
- var hasStatusSemantics = (assertionLike) => {
6658
- if (!assertionLike) {
6659
- return false;
6660
- }
6661
- if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
6662
- return true;
6663
- }
6664
- const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
6665
- const combinedMessage = combinedRaw.toLowerCase();
6666
- return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
6667
- };
6668
- var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
6669
- var inferHttpNumbersFromText = (lines) => {
6670
- const text = lines.join("\n");
6671
- const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
6672
- if (match) {
6673
- return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
6674
- }
6675
- return {};
6676
- };
6677
- var titleSuggestsHttp = (title) => {
6678
- const { method, path: parsedPath } = parseMethodPathFromTitle(title);
6679
- return Boolean(method || parsedPath && parsedPath.startsWith("/"));
6680
- };
6681
- var isHttpRelevant = (ctx) => {
6682
- const assertionCtx = ctx.assertion;
6683
- return ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(assertionCtx) || fileSuggestsHttp(ctx.relPath);
6684
- };
6685
6617
  var routeSimilarityScore = (hint, evt) => {
6686
6618
  if (!hint.path && !hint.method) {
6687
6619
  return 0;
@@ -6702,6 +6634,15 @@ var routeSimilarityScore = (hint, evt) => {
6702
6634
  }
6703
6635
  return methodOk * 10;
6704
6636
  };
6637
+ var envNumber = (name, fallback) => {
6638
+ const parsed = Number(process.env[name]);
6639
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
6640
+ };
6641
+ var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
6642
+ var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
6643
+ var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
6644
+ var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
6645
+ var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
6705
6646
  var scoreHttpForAssertion = (assertion, titleHint) => (candidateEvent) => {
6706
6647
  const tsA = assertion.timestampMs;
6707
6648
  const tsH = candidateEvent.timestampMs;
@@ -6722,14 +6663,20 @@ var pickRelevantHttp = (assertion, http, ctx) => {
6722
6663
  const windowMs = isTransportError(assertion.message) ? HEADLAMP_HTTP_STRICT_WINDOW_MS() : HEADLAMP_HTTP_WINDOW_MS();
6723
6664
  let pool = strictPool;
6724
6665
  if (!pool.length) {
6725
- pool = http.filter(
6726
- (e) => e.testPath === ctx.testPath && typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
6727
- );
6666
+ pool = http.filter((event) => {
6667
+ const samePath = event.testPath === ctx.testPath;
6668
+ const tsA = assertion.timestampMs;
6669
+ const tsH = event.timestampMs;
6670
+ const inWindow = typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
6671
+ return samePath && inWindow;
6672
+ });
6728
6673
  }
6729
6674
  if (!pool.length) {
6730
- pool = http.filter(
6731
- (e) => typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
6732
- );
6675
+ pool = http.filter((event) => {
6676
+ const tsA = assertion.timestampMs;
6677
+ const tsH = event.timestampMs;
6678
+ return typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
6679
+ });
6733
6680
  }
6734
6681
  if (!pool.length) {
6735
6682
  return void 0;
@@ -6739,9 +6686,11 @@ var pickRelevantHttp = (assertion, http, ctx) => {
6739
6686
  const threshold = isTransportError(assertion.message) ? Math.max(HEADLAMP_HTTP_MIN_SCORE(), 1400) : HEADLAMP_HTTP_MIN_SCORE();
6740
6687
  return best && best.s >= threshold ? best.h : void 0;
6741
6688
  };
6742
- var isBridgeJSONLike = (candidateValue) => !!candidateValue && typeof candidateValue === "object" && "aggregated" in candidateValue;
6689
+
6690
+ // src/lib/formatter/bridge/utils.ts
6691
+ var import_json52 = __toESM(require_lib(), 1);
6743
6692
  var coerceJestJsonToBridge = (raw) => {
6744
- if (isBridgeJSONLike(raw)) {
6693
+ if (raw && typeof raw === "object" && "aggregated" in raw) {
6745
6694
  return raw;
6746
6695
  }
6747
6696
  const j = raw;
@@ -6768,19 +6717,85 @@ var coerceJestJsonToBridge = (raw) => {
6768
6717
  }))
6769
6718
  })),
6770
6719
  aggregated: {
6771
- numTotalTestSuites: j.numTotalTestSuites,
6772
- numPassedTestSuites: j.numPassedTestSuites,
6773
- numFailedTestSuites: j.numFailedTestSuites,
6774
- numTotalTests: j.numTotalTests,
6775
- numPassedTests: j.numPassedTests,
6776
- numFailedTests: j.numFailedTests,
6777
- numPendingTests: j.numPendingTests,
6778
- numTodoTests: j.numTodoTests,
6779
- startTime: j.startTime,
6780
- success: j.success
6720
+ numTotalTestSuites: raw.numTotalTestSuites,
6721
+ numPassedTestSuites: raw.numPassedTestSuites,
6722
+ numFailedTestSuites: raw.numFailedTestSuites,
6723
+ numTotalTests: raw.numTotalTests,
6724
+ numPassedTests: raw.numPassedTests,
6725
+ numFailedTests: raw.numFailedTests,
6726
+ numPendingTests: raw.numPendingTests,
6727
+ numTodoTests: raw.numTodoTests,
6728
+ startTime: raw.startTime,
6729
+ success: raw.success,
6730
+ runTimeMs: raw.aggregated?.runTimeMs
6781
6731
  }
6782
6732
  };
6783
6733
  };
6734
+ var colorTokens2 = {
6735
+ pass: Colors.Success,
6736
+ fail: Colors.Failure,
6737
+ skip: Colors.Skip,
6738
+ todo: Colors.Todo,
6739
+ passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
6740
+ failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
6741
+ };
6742
+ var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
6743
+ var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
6744
+ var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
6745
+ var summarizeUrl = (method, url, route) => {
6746
+ const base = route || url || "";
6747
+ const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
6748
+ return [method || "", base, qs].filter(Boolean).join(" ").trim();
6749
+ };
6750
+ var stripBridgeEventsFromConsole = (maybeConsole) => {
6751
+ if (!Array.isArray(maybeConsole)) {
6752
+ return maybeConsole;
6753
+ }
6754
+ return maybeConsole.filter((entry) => {
6755
+ try {
6756
+ const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
6757
+ return !raw.includes("[JEST-BRIDGE-EVENT]");
6758
+ } catch {
6759
+ return true;
6760
+ }
6761
+ });
6762
+ };
6763
+ var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
6764
+ if (typeof ts !== "number" || !Number.isFinite(ts)) {
6765
+ return [];
6766
+ }
6767
+ return http.filter((event) => {
6768
+ const timeOk = typeof event.timestampMs === "number" && Math.abs(event.timestampMs - ts) <= windowMs;
6769
+ const pathOk = !testPath || event.testPath === testPath;
6770
+ return timeOk && pathOk;
6771
+ });
6772
+ };
6773
+ var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
6774
+ var inferHttpNumbersFromText = (lines) => {
6775
+ const text = lines.join("\n");
6776
+ const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
6777
+ if (match) {
6778
+ return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
6779
+ }
6780
+ return {};
6781
+ };
6782
+ var titleSuggestsHttp = (title) => {
6783
+ const { method, path: parsedPath } = parseMethodPathFromTitle(title);
6784
+ return Boolean(method || parsedPath && parsedPath.startsWith("/"));
6785
+ };
6786
+ var hasStatusSemantics = (assertionLike) => {
6787
+ if (!assertionLike) {
6788
+ return false;
6789
+ }
6790
+ if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
6791
+ return true;
6792
+ }
6793
+ const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
6794
+ const combinedMessage = combinedRaw.toLowerCase();
6795
+ return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
6796
+ };
6797
+ var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
6798
+ var isHttpRelevant = (ctx) => ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(ctx.assertion) || fileSuggestsHttp(ctx.relPath);
6784
6799
  var vitestFooter = (agg, durationMs) => {
6785
6800
  const files = [
6786
6801
  agg.numFailedTestSuites ? colorTokens2.fail(`${agg.numFailedTestSuites} failed`) : "",
@@ -7257,13 +7272,21 @@ var renderVitestFromJestJSON = (data, ctx, opts) => {
7257
7272
  out.push(vitestFooter(data.aggregated));
7258
7273
  return out.join("\n");
7259
7274
  };
7275
+
7276
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
7260
7277
  var tryBridgeFallback = (raw, ctx, opts) => {
7261
- const bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
7278
+ let bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
7279
+ if (!bridgeJsonPath) {
7280
+ const def = path11.resolve(ctx.cwd, "coverage/jest-run.json").replace(/\\/g, "/");
7281
+ if (fs6.existsSync(def)) {
7282
+ bridgeJsonPath = def;
7283
+ }
7284
+ }
7262
7285
  if (!bridgeJsonPath || !fs6.existsSync(bridgeJsonPath)) {
7263
7286
  return null;
7264
7287
  }
7265
7288
  try {
7266
- const json = import_json52.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
7289
+ const json = import_json53.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
7267
7290
  const bridge = coerceJestJsonToBridge(json);
7268
7291
  return renderVitestFromJestJSON(bridge, ctx, opts);
7269
7292
  } catch {
@@ -7281,23 +7304,39 @@ var formatJestOutputVitest = (raw, opts) => pipe(
7281
7304
  (state) => ({ ...state, chunks: parseChunks(state.raw) }),
7282
7305
  (state) => ({
7283
7306
  ...state,
7284
- rendered: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
7307
+ native: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
7285
7308
  onlyFailures: Boolean(state.opts?.onlyFailures)
7286
- })
7309
+ }).text
7287
7310
  }),
7288
- (state) => {
7289
- if (state.rendered.hadParsed) {
7290
- return state.rendered.text;
7291
- }
7292
- const fallback = tryBridgeFallback(state.raw, state.ctx, {
7311
+ (state) => ({
7312
+ ...state,
7313
+ bridge: tryBridgeFallback(state.raw, state.ctx, {
7293
7314
  onlyFailures: Boolean(state.opts?.onlyFailures)
7294
- });
7295
- if (!fallback) {
7296
- return state.rendered.text;
7315
+ }) || null
7316
+ }),
7317
+ (state) => {
7318
+ const out = [];
7319
+ const seen = /* @__PURE__ */ new Set();
7320
+ const pushUnique = (text) => {
7321
+ if (!text) {
7322
+ return;
7323
+ }
7324
+ for (const line of text.split(/\r?\n/)) {
7325
+ const key = stripAnsiSimple(line);
7326
+ if (!seen.has(key)) {
7327
+ out.push(line);
7328
+ seen.add(key);
7329
+ }
7330
+ }
7331
+ };
7332
+ pushUnique(state.native);
7333
+ if (state.bridge) {
7334
+ if (out.length) {
7335
+ out.push("");
7336
+ }
7337
+ pushUnique(state.bridge);
7297
7338
  }
7298
- const prefix = state.rendered.text;
7299
- return prefix ? `${prefix}
7300
- ${fallback}` : fallback;
7339
+ return out.join("\n");
7301
7340
  }
7302
7341
  );
7303
7342
 
@@ -7414,8 +7453,8 @@ module.exports = BridgeReporter;`;
7414
7453
  init_env_utils();
7415
7454
  init_exec();
7416
7455
  init_args();
7417
- import * as path11 from "node:path";
7418
- import * as os2 from "node:os";
7456
+ import * as path12 from "node:path";
7457
+ import * as os3 from "node:os";
7419
7458
  import * as fsSync3 from "node:fs";
7420
7459
  import * as fs7 from "node:fs/promises";
7421
7460
  import * as LibReport from "istanbul-lib-report";
@@ -7694,7 +7733,7 @@ var mergeLcov = async () => {
7694
7733
  try {
7695
7734
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
7696
7735
  for (const entry of entries) {
7697
- const full = path11.join(dir, entry.name);
7736
+ const full = path12.join(dir, entry.name);
7698
7737
  if (entry.isDirectory()) {
7699
7738
  out.push(...collectLcovs(full));
7700
7739
  } else if (entry.isFile() && entry.name === "lcov.info") {
@@ -7706,8 +7745,8 @@ var mergeLcov = async () => {
7706
7745
  return out;
7707
7746
  };
7708
7747
  try {
7709
- const jestRoot = path11.join("coverage", "jest");
7710
- const candidates = [path11.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
7748
+ const jestRoot = path12.join("coverage", "jest");
7749
+ const candidates = [path12.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
7711
7750
  for (const filePath of candidates) {
7712
7751
  try {
7713
7752
  const content = await readOrEmpty(filePath);
@@ -7747,7 +7786,7 @@ var emitMergedCoverage = async (ui, opts) => {
7747
7786
  try {
7748
7787
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
7749
7788
  for (const entry of entries) {
7750
- const full = path11.join(dir, entry.name);
7789
+ const full = path12.join(dir, entry.name);
7751
7790
  if (entry.isDirectory()) {
7752
7791
  out.push(...listJsons(full));
7753
7792
  } else if (entry.isFile() && entry.name === "coverage-final.json") {
@@ -7758,11 +7797,11 @@ var emitMergedCoverage = async (ui, opts) => {
7758
7797
  }
7759
7798
  return out;
7760
7799
  };
7761
- const coverageRoot = path11.join("coverage", "jest");
7800
+ const coverageRoot = path12.join("coverage", "jest");
7762
7801
  const jsonCandidates = [
7763
- path11.join(coverageRoot, "coverage-final.json"),
7802
+ path12.join(coverageRoot, "coverage-final.json"),
7764
7803
  ...listJsons(coverageRoot)
7765
- ].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => {
7804
+ ].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => {
7766
7805
  const isFirst = arr.indexOf(absolutePath) === index;
7767
7806
  const exists = fsSync3.existsSync(absolutePath);
7768
7807
  return isFirst && exists;
@@ -7824,7 +7863,7 @@ var emitMergedCoverage = async (ui, opts) => {
7824
7863
  executedTests: opts.executedTests ?? []
7825
7864
  });
7826
7865
  const context = LibReport.createContext({
7827
- dir: path11.resolve("coverage", "merged"),
7866
+ dir: path12.resolve("coverage", "merged"),
7828
7867
  coverageMap: filteredMap,
7829
7868
  defaultSummarizer: "nested"
7830
7869
  });
@@ -7892,8 +7931,8 @@ var emitMergedCoverage = async (ui, opts) => {
7892
7931
  for (const reporter of reporters) {
7893
7932
  reporter.execute(context);
7894
7933
  }
7895
- const textPath = path11.resolve("coverage", "merged", "coverage.txt");
7896
- const summaryPath = path11.resolve("coverage", "merged", "coverage-summary.txt");
7934
+ const textPath = path12.resolve("coverage", "merged", "coverage.txt");
7935
+ const summaryPath = path12.resolve("coverage", "merged", "coverage-summary.txt");
7897
7936
  const filesToPrint = [];
7898
7937
  if (fsSync3.existsSync(textPath)) {
7899
7938
  filesToPrint.push(textPath);
@@ -8036,13 +8075,13 @@ var program = async () => {
8036
8075
  const rels2 = Array.from(
8037
8076
  /* @__PURE__ */ new Set([...branchDiff, ...stagedNow, ...unstagedNow, ...untrackedNow])
8038
8077
  );
8039
- return rels2.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
8078
+ return rels2.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
8040
8079
  }
8041
8080
  const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
8042
8081
  const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
8043
8082
  const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
8044
8083
  const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
8045
- return rels.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
8084
+ return rels.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
8046
8085
  };
8047
8086
  const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
8048
8087
  const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
@@ -8067,18 +8106,18 @@ var program = async () => {
8067
8106
  if (!token) {
8068
8107
  continue;
8069
8108
  }
8070
- const isAbs = path11.isAbsolute(token);
8109
+ const isAbs = path12.isAbsolute(token);
8071
8110
  const looksLikeRelPath = /[\\/]/.test(token);
8072
8111
  let candidateFromRoot;
8073
8112
  if (token.startsWith("/")) {
8074
- candidateFromRoot = path11.join(repoRoot, token.slice(1));
8113
+ candidateFromRoot = path12.join(repoRoot, token.slice(1));
8075
8114
  } else if (looksLikeRelPath) {
8076
- candidateFromRoot = path11.join(repoRoot, token);
8115
+ candidateFromRoot = path12.join(repoRoot, token);
8077
8116
  } else {
8078
8117
  candidateFromRoot = void 0;
8079
8118
  }
8080
8119
  const tryPushIfProd = (absPath) => {
8081
- const norm = path11.resolve(absPath).replace(/\\/g, "/");
8120
+ const norm = path12.resolve(absPath).replace(/\\/g, "/");
8082
8121
  const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
8083
8122
  if (!isTest && fsSync3.existsSync(norm)) {
8084
8123
  results.add(norm);
@@ -8100,7 +8139,7 @@ var program = async () => {
8100
8139
  }),
8101
8140
  timeoutMs: 4e3
8102
8141
  });
8103
- const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path11.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
8142
+ const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path12.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
8104
8143
  (abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
8105
8144
  );
8106
8145
  matches.forEach((abs) => results.add(abs));
@@ -8121,8 +8160,8 @@ var program = async () => {
8121
8160
  const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
8122
8161
  const projectConfigs = [];
8123
8162
  try {
8124
- const baseCfg = path11.resolve("jest.config.js");
8125
- const tsCfg = path11.resolve("jest.ts.config.js");
8163
+ const baseCfg = path12.resolve("jest.config.js");
8164
+ const tsCfg = path12.resolve("jest.ts.config.js");
8126
8165
  if (fsSync3.existsSync(baseCfg)) {
8127
8166
  projectConfigs.push(baseCfg);
8128
8167
  }
@@ -8139,7 +8178,7 @@ var program = async () => {
8139
8178
  );
8140
8179
  const prodSelections2 = expandedProdSelections;
8141
8180
  for (const cfg of projectConfigs) {
8142
- const cfgCwd = path11.dirname(cfg);
8181
+ const cfgCwd = path12.dirname(cfg);
8143
8182
  const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
8144
8183
  cwd: cfgCwd
8145
8184
  });
@@ -8152,7 +8191,7 @@ var program = async () => {
8152
8191
  });
8153
8192
  } catch (err) {
8154
8193
  if (isDebug()) {
8155
- console.warn(`direct selection failed for project ${path11.basename(cfg)}: ${String(err)}`);
8194
+ console.warn(`direct selection failed for project ${path12.basename(cfg)}: ${String(err)}`);
8156
8195
  }
8157
8196
  }
8158
8197
  perProjectFiles.set(cfg, directPerProject);
@@ -8164,7 +8203,7 @@ var program = async () => {
8164
8203
  )} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
8165
8204
  );
8166
8205
  for (const cfg of projectConfigs) {
8167
- const cfgCwd = path11.dirname(cfg);
8206
+ const cfgCwd = path12.dirname(cfg);
8168
8207
  const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
8169
8208
  cwd: cfgCwd
8170
8209
  });
@@ -8179,13 +8218,13 @@ var program = async () => {
8179
8218
  );
8180
8219
  const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
8181
8220
  const absFiles = candidates.map(
8182
- (candidatePath) => path11.isAbsolute(candidatePath) ? candidatePath : path11.join(repoRootForDiscovery, candidatePath)
8221
+ (candidatePath) => path12.isAbsolute(candidatePath) ? candidatePath : path12.join(repoRootForDiscovery, candidatePath)
8183
8222
  ).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
8184
8223
  const onlyOwned = await filterCandidatesForProject(
8185
8224
  cfg,
8186
8225
  jestDiscoveryArgs,
8187
8226
  absFiles,
8188
- path11.dirname(cfg)
8227
+ path12.dirname(cfg)
8189
8228
  );
8190
8229
  perProjectFiltered.set(cfg, onlyOwned);
8191
8230
  }
@@ -8197,7 +8236,7 @@ var program = async () => {
8197
8236
  if (selectionHasPaths && prodSelections.length > 0) {
8198
8237
  console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
8199
8238
  const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
8200
- const selectionKey = prodSelections.map((absPath) => path11.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
8239
+ const selectionKey = prodSelections.map((absPath) => path12.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
8201
8240
  const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
8202
8241
  const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
8203
8242
  const rgMatches = await cachedRelated2({
@@ -8227,7 +8266,7 @@ var program = async () => {
8227
8266
  cfg,
8228
8267
  jestDiscoveryArgs,
8229
8268
  rgCandidates,
8230
- path11.dirname(cfg)
8269
+ path12.dirname(cfg)
8231
8270
  );
8232
8271
  perProjectFromRg.set(cfg, owned);
8233
8272
  }
@@ -8242,9 +8281,9 @@ var program = async () => {
8242
8281
  } else {
8243
8282
  const repoRootForScan = repoRootForDiscovery;
8244
8283
  const toSeeds = (abs) => {
8245
- const rel = path11.relative(repoRootForScan, abs).replace(/\\/g, "/");
8284
+ const rel = path12.relative(repoRootForScan, abs).replace(/\\/g, "/");
8246
8285
  const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
8247
- const base = path11.basename(withoutExt);
8286
+ const base = path12.basename(withoutExt);
8248
8287
  const segs = withoutExt.split("/");
8249
8288
  const tail2 = segs.slice(-2).join("/");
8250
8289
  return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
@@ -8259,8 +8298,8 @@ var program = async () => {
8259
8298
  }
8260
8299
  };
8261
8300
  const resolveLocalImport = (fromFile, spec) => {
8262
- const baseDir = path11.dirname(fromFile);
8263
- const cand = path11.resolve(baseDir, spec);
8301
+ const baseDir = path12.dirname(fromFile);
8302
+ const cand = path12.resolve(baseDir, spec);
8264
8303
  const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
8265
8304
  for (const ext of exts) {
8266
8305
  const full = ext ? `${cand}${ext}` : cand;
@@ -8269,7 +8308,7 @@ var program = async () => {
8269
8308
  }
8270
8309
  }
8271
8310
  for (const ext of exts) {
8272
- const full = path11.join(cand, `index${ext}`);
8311
+ const full = path12.join(cand, `index${ext}`);
8273
8312
  if (fsSync3.existsSync(full)) {
8274
8313
  return full;
8275
8314
  }
@@ -8323,7 +8362,7 @@ var program = async () => {
8323
8362
  cfg,
8324
8363
  jestDiscoveryArgs,
8325
8364
  keptCandidates,
8326
- path11.dirname(cfg)
8365
+ path12.dirname(cfg)
8327
8366
  );
8328
8367
  perProjectFromScan.set(cfg, owned);
8329
8368
  }
@@ -8353,7 +8392,7 @@ var program = async () => {
8353
8392
  try {
8354
8393
  const allAcross = [];
8355
8394
  for (const cfg of projectConfigs) {
8356
- const cfgCwd = path11.dirname(cfg);
8395
+ const cfgCwd = path12.dirname(cfg);
8357
8396
  const listed = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
8358
8397
  cwd: cfgCwd
8359
8398
  });
@@ -8367,9 +8406,9 @@ var program = async () => {
8367
8406
  }
8368
8407
  }
8369
8408
  const seeds = prodSelections.map(
8370
- (abs) => path11.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
8409
+ (abs) => path12.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
8371
8410
  ).flatMap((rel) => {
8372
- const base = path11.basename(rel);
8411
+ const base = path12.basename(rel);
8373
8412
  const segments = rel.split("/");
8374
8413
  return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
8375
8414
  });
@@ -8382,8 +8421,8 @@ var program = async () => {
8382
8421
  }
8383
8422
  };
8384
8423
  const resolveLocalImport = (fromFile, spec) => {
8385
- const baseDir = path11.dirname(fromFile);
8386
- const candidate = path11.resolve(baseDir, spec);
8424
+ const baseDir = path12.dirname(fromFile);
8425
+ const candidate = path12.resolve(baseDir, spec);
8387
8426
  const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
8388
8427
  for (const ext of extensions) {
8389
8428
  const fullPath = ext ? `${candidate}${ext}` : candidate;
@@ -8392,7 +8431,7 @@ var program = async () => {
8392
8431
  }
8393
8432
  }
8394
8433
  for (const ext of extensions) {
8395
- const fullPath = path11.join(candidate, `index${ext}`);
8434
+ const fullPath = path12.join(candidate, `index${ext}`);
8396
8435
  if (fsSync3.existsSync(fullPath)) {
8397
8436
  return fullPath;
8398
8437
  }
@@ -8549,10 +8588,10 @@ var program = async () => {
8549
8588
  };
8550
8589
  const prodSeedsForRun = (() => {
8551
8590
  const changedAbs = (changedSelectionAbs ?? []).map(
8552
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
8591
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
8553
8592
  );
8554
8593
  const selAbs = selectionPathsAugmented.map(
8555
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
8594
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
8556
8595
  );
8557
8596
  return (changedAbs.length ? changedAbs : selAbs).filter(
8558
8597
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
@@ -8567,17 +8606,17 @@ var program = async () => {
8567
8606
  const cfg = projectsToRun[projIndex];
8568
8607
  const files = perProjectFiltered.get(cfg) ?? [];
8569
8608
  if (files.length === 0) {
8570
- console.info(`Project ${path11.basename(cfg)}: 0 matching tests after filter; skipping.`);
8609
+ console.info(`Project ${path12.basename(cfg)}: 0 matching tests after filter; skipping.`);
8571
8610
  continue;
8572
8611
  }
8573
8612
  files.forEach(
8574
- (absTestPath) => executedTestFilesSet.add(path11.resolve(absTestPath).replace(/\\/g, "/"))
8613
+ (absTestPath) => executedTestFilesSet.add(path12.resolve(absTestPath).replace(/\\/g, "/"))
8575
8614
  );
8576
- const outJson = path11.join(
8577
- os2.tmpdir(),
8615
+ const outJson = path12.join(
8616
+ os3.tmpdir(),
8578
8617
  `jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
8579
8618
  );
8580
- const reporterPath = path11.resolve("scripts/jest-vitest-bridge.cjs");
8619
+ const reporterPath = path12.resolve("scripts/jest-vitest-bridge.cjs");
8581
8620
  try {
8582
8621
  const needsWrite = (() => {
8583
8622
  try {
@@ -8588,10 +8627,10 @@ var program = async () => {
8588
8627
  }
8589
8628
  })();
8590
8629
  if (needsWrite) {
8591
- fsSync3.mkdirSync(path11.dirname(reporterPath), { recursive: true });
8630
+ fsSync3.mkdirSync(path12.dirname(reporterPath), { recursive: true });
8592
8631
  fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
8593
8632
  }
8594
- const envPath = path11.resolve("scripts/jest-bridge-env.cjs");
8633
+ const envPath = path12.resolve("scripts/jest-bridge-env.cjs");
8595
8634
  try {
8596
8635
  const existingEnv = fsSync3.readFileSync(envPath, "utf8");
8597
8636
  if (existingEnv !== JEST_BRIDGE_ENV_SOURCE) {
@@ -8599,7 +8638,7 @@ var program = async () => {
8599
8638
  }
8600
8639
  } catch {
8601
8640
  try {
8602
- fsSync3.mkdirSync(path11.dirname(envPath), { recursive: true });
8641
+ fsSync3.mkdirSync(path12.dirname(envPath), { recursive: true });
8603
8642
  } catch {
8604
8643
  }
8605
8644
  fsSync3.writeFileSync(envPath, JEST_BRIDGE_ENV_SOURCE, "utf8");
@@ -8607,7 +8646,7 @@ var program = async () => {
8607
8646
  } catch (ensureReporterError) {
8608
8647
  console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
8609
8648
  }
8610
- const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) => path11.relative(repoRootForDiscovery, pathToken).replace(/\\\\/g, "/")).filter((rel) => rel && !/^\.+\//.test(rel)).map((rel) => rel.startsWith("./") ? rel : `./${rel}`);
8649
+ const selectedFilesForCoverage = selectionPathsAugmented.filter((pathToken) => /[\\/]/.test(pathToken)).filter((pathToken) => !looksLikeTestPath(pathToken)).map((pathToken) => path12.relative(repoRootForDiscovery, pathToken).replace(/\\\\/g, "/")).filter((rel) => rel && !/^\.+\//.test(rel)).map((rel) => rel.startsWith("./") ? rel : `./${rel}`);
8611
8650
  const coverageFromArgs = [];
8612
8651
  for (const relPath2 of selectedFilesForCoverage) {
8613
8652
  coverageFromArgs.push("--collectCoverageFrom", relPath2);
@@ -8625,11 +8664,11 @@ var program = async () => {
8625
8664
  `--reporters=${reporterPath}`,
8626
8665
  "--colors",
8627
8666
  "--env",
8628
- path11.resolve("scripts/jest-bridge-env.cjs"),
8667
+ path12.resolve("scripts/jest-bridge-env.cjs"),
8629
8668
  ...sanitizedJestRunArgs,
8630
8669
  ...collectCoverage ? [
8631
8670
  "--coverageDirectory",
8632
- path11.join("coverage", "jest", path11.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
8671
+ path12.join("coverage", "jest", path12.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
8633
8672
  ] : [],
8634
8673
  ...coverageFromArgs,
8635
8674
  "--passWithNoTests",
@@ -8755,10 +8794,10 @@ ${stripFooter(rawAlso)}`.trimEnd();
8755
8794
  try {
8756
8795
  const prodSeeds = (() => {
8757
8796
  const changedAbs = (changedSelectionAbs ?? []).map(
8758
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
8797
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
8759
8798
  );
8760
8799
  const selAbs = selectionPathsAugmented.map(
8761
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
8800
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
8762
8801
  );
8763
8802
  return (changedAbs.length ? changedAbs : selAbs).filter(
8764
8803
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
@@ -8851,6 +8890,7 @@ export {
8851
8890
  drawFailLine,
8852
8891
  drawRule,
8853
8892
  emitMergedCoverage,
8893
+ extractBridgePath,
8854
8894
  filterCandidatesForProject,
8855
8895
  filterCoverageMap,
8856
8896
  findCodeFrameStart,
@@ -8889,7 +8929,6 @@ export {
8889
8929
  routeSimilarityScore,
8890
8930
  rule,
8891
8931
  runJestBootstrap,
8892
- scoreHttpForAssertion,
8893
8932
  stripAnsiSimple,
8894
8933
  supportsUnicode,
8895
8934
  tintPct,