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/cli.cjs CHANGED
@@ -93,7 +93,7 @@ var init_TimeoutError = __esm({
93
93
 
94
94
  // node_modules/es-toolkit/dist/promise/delay.mjs
95
95
  function delay(ms, { signal } = {}) {
96
- return new Promise((resolve10, reject) => {
96
+ return new Promise((resolve11, reject) => {
97
97
  const abortError = () => {
98
98
  reject(new AbortError());
99
99
  };
@@ -106,7 +106,7 @@ function delay(ms, { signal } = {}) {
106
106
  }
107
107
  const timeoutId = setTimeout(() => {
108
108
  signal?.removeEventListener("abort", abortHandler);
109
- resolve10();
109
+ resolve11();
110
110
  }, ms);
111
111
  signal?.addEventListener("abort", abortHandler, { once: true });
112
112
  });
@@ -171,11 +171,11 @@ var init_exec = __esm({
171
171
  child.stderr?.on("data", (chunk) => {
172
172
  stderr += String(chunk);
173
173
  });
174
- const exec = new Promise((resolve10, reject) => {
174
+ const exec = new Promise((resolve11, reject) => {
175
175
  child.on("error", reject);
176
176
  child.on(
177
177
  "close",
178
- (code) => Number(code) === 0 ? resolve10(stdout) : reject(new Error(stderr || `exit ${code}`))
178
+ (code) => Number(code) === 0 ? resolve11(stdout) : reject(new Error(stderr || `exit ${code}`))
179
179
  );
180
180
  });
181
181
  try {
@@ -195,7 +195,7 @@ var init_exec = __esm({
195
195
  throw caughtError;
196
196
  }
197
197
  };
198
- runExitCode = async (cmd, args, opts = {}) => new Promise((resolve10, reject) => {
198
+ runExitCode = async (cmd, args, opts = {}) => new Promise((resolve11, reject) => {
199
199
  const child = (0, import_node_child_process.spawn)(cmd, [...args], {
200
200
  cwd: opts.cwd,
201
201
  env: opts.env,
@@ -204,9 +204,9 @@ var init_exec = __esm({
204
204
  windowsHide: true
205
205
  });
206
206
  child.on("error", reject);
207
- child.on("close", (code) => resolve10(Number(code)));
207
+ child.on("close", (code) => resolve11(Number(code)));
208
208
  });
209
- runWithCapture = async (cmd, args, opts) => new Promise((resolve10, reject) => {
209
+ runWithCapture = async (cmd, args, opts) => new Promise((resolve11, reject) => {
210
210
  const child = (0, import_node_child_process.spawn)(cmd, [...args], {
211
211
  cwd: opts.cwd,
212
212
  env: opts.env,
@@ -222,7 +222,7 @@ var init_exec = __esm({
222
222
  buf += String(chunk);
223
223
  });
224
224
  child.on("error", reject);
225
- child.on("close", (code) => resolve10({ code: Number(code), output: buf }));
225
+ child.on("close", (code) => resolve11({ code: Number(code), output: buf }));
226
226
  });
227
227
  }
228
228
  });
@@ -736,12 +736,14 @@ __export(fast_related_exports, {
736
736
  cachedRelated: () => cachedRelated,
737
737
  findRelatedTestsFast: () => findRelatedTestsFast
738
738
  });
739
- var path2, fs, TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
739
+ var path2, os2, fs, import_node_crypto, TailSegmentCount, EmptyCount, JsonIndentSpaces, DEFAULT_TEST_GLOBS, findRelatedTestsFast, cachedRelated;
740
740
  var init_fast_related = __esm({
741
741
  "src/lib/fast-related.ts"() {
742
742
  "use strict";
743
743
  path2 = __toESM(require("node:path"), 1);
744
+ os2 = __toESM(require("node:os"), 1);
744
745
  fs = __toESM(require("node:fs/promises"), 1);
746
+ import_node_crypto = require("node:crypto");
745
747
  init_env_utils();
746
748
  init_exec();
747
749
  TailSegmentCount = 2;
@@ -790,9 +792,7 @@ var init_fast_related = __esm({
790
792
  }
791
793
  const args = ["-n", "-l", "-S", "-F"];
792
794
  testGlobs.forEach((globPattern) => args.push("-g", globPattern));
793
- excludeGlobs.forEach(
794
- (excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`)
795
- );
795
+ excludeGlobs.forEach((excludeGlobPattern) => args.push("-g", `!${excludeGlobPattern}`));
796
796
  seeds.forEach((seedToken) => args.push("-e", seedToken));
797
797
  let raw = "";
798
798
  try {
@@ -804,9 +804,7 @@ var init_fast_related = __esm({
804
804
  }
805
805
  const lines = raw.split(/\r?\n/).map((lineText) => lineText.trim()).filter(Boolean);
806
806
  const looksLikeTest = (pathText) => /\.(test|spec)\.[tj]sx?$/i.test(pathText) || /(^|\/)tests?\//i.test(pathText);
807
- const absolute = lines.map(
808
- (relativePath) => path2.resolve(repoRoot, relativePath).replace(/\\/g, "/")
809
- ).filter(looksLikeTest);
807
+ const absolute = lines.map((relativePath) => path2.resolve(repoRoot, relativePath).replace(/\\/g, "/")).filter(looksLikeTest);
810
808
  const uniq = Array.from(new Set(absolute));
811
809
  const results = [];
812
810
  await Promise.all(
@@ -821,17 +819,15 @@ var init_fast_related = __esm({
821
819
  return results;
822
820
  };
823
821
  cachedRelated = async (opts) => {
824
- const cacheDir = path2.join(opts.repoRoot, ".cache");
822
+ const cacheRoot = process.env.HEADLAMP_CACHE_DIR || path2.join(os2.tmpdir(), "headlamp-cache");
823
+ const repoKey = (0, import_node_crypto.createHash)("sha1").update(path2.resolve(opts.repoRoot)).digest("hex").slice(0, 12);
824
+ const cacheDir = path2.join(cacheRoot, repoKey);
825
825
  const cacheFile = path2.join(cacheDir, "relevant-tests.json");
826
826
  let head = "nogit";
827
827
  try {
828
- const raw = await runText(
829
- "git",
830
- ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"],
831
- {
832
- env: safeEnv(process.env, {})
833
- }
834
- );
828
+ const raw = await runText("git", ["-C", opts.repoRoot, "rev-parse", "--short", "HEAD"], {
829
+ env: safeEnv(process.env, {})
830
+ });
835
831
  head = raw.trim() || "nogit";
836
832
  } catch {
837
833
  head = "nogit";
@@ -863,10 +859,7 @@ var init_fast_related = __esm({
863
859
  try {
864
860
  const next = { ...bag, [key]: Array.from(new Set(recomputed)) };
865
861
  await fs.mkdir(cacheDir, { recursive: true });
866
- await fs.writeFile(
867
- cacheFile,
868
- JSON.stringify(next, null, JsonIndentSpaces)
869
- );
862
+ await fs.writeFile(cacheFile, JSON.stringify(next, null, JsonIndentSpaces));
870
863
  } catch {
871
864
  }
872
865
  return recomputed;
@@ -1987,17 +1980,17 @@ var require_lib = __commonJS({
1987
1980
  "node_modules/json5/lib/index.js"(exports2, module2) {
1988
1981
  var parse = require_parse();
1989
1982
  var stringify = require_stringify();
1990
- var JSON53 = {
1983
+ var JSON54 = {
1991
1984
  parse,
1992
1985
  stringify
1993
1986
  };
1994
- module2.exports = JSON53;
1987
+ module2.exports = JSON54;
1995
1988
  }
1996
1989
  });
1997
1990
 
1998
1991
  // src/lib/program.ts
1999
- var path11 = __toESM(require("node:path"), 1);
2000
- var os2 = __toESM(require("node:os"), 1);
1992
+ var path12 = __toESM(require("node:path"), 1);
1993
+ var os3 = __toESM(require("node:os"), 1);
2001
1994
  var fsSync3 = __toESM(require("node:fs"), 1);
2002
1995
  var fs7 = __toESM(require("node:fs/promises"), 1);
2003
1996
  var LibReport = __toESM(require("istanbul-lib-report"), 1);
@@ -4919,15 +4912,23 @@ var buildMessageSection = (messageLines, details, _ctx, opts) => {
4919
4912
  const fallbackLines = [];
4920
4913
  if (hasOnlyBareError) {
4921
4914
  const startFrom = hintIdx >= 0 ? hintIdx + 1 : 0;
4915
+ let started = false;
4922
4916
  for (let i = startFrom; i < lines.length; i += 1) {
4923
4917
  const candidate = lines[i];
4924
- if (!candidate.trim()) {
4918
+ if (isStackLine(candidate)) {
4925
4919
  break;
4926
4920
  }
4927
- if (isStackLine(candidate)) {
4921
+ if (!candidate.trim()) {
4922
+ if (!started) {
4923
+ continue;
4924
+ }
4928
4925
  break;
4929
4926
  }
4927
+ started = true;
4930
4928
  fallbackLines.push(candidate);
4929
+ if (fallbackLines.length >= 6) {
4930
+ break;
4931
+ }
4931
4932
  }
4932
4933
  if (fallbackLines.length === 0 && details && details.messages && details.messages.length) {
4933
4934
  fallbackLines.push(
@@ -4995,7 +4996,7 @@ var linesFromDetails = (details) => {
4995
4996
  if (typeof obj.received === "string") {
4996
4997
  pushMaybe(obj.received, messages);
4997
4998
  }
4998
- const arrays = ["errors", "causes", "aggregatedErrors"];
4999
+ const arrays = ["errors", "details", "issues", "inner", "causes", "aggregatedErrors"];
4999
5000
  for (const key of arrays) {
5000
5001
  const arr = obj[key];
5001
5002
  if (Array.isArray(arr)) {
@@ -5004,7 +5005,7 @@ var linesFromDetails = (details) => {
5004
5005
  }
5005
5006
  }
5006
5007
  }
5007
- const nestedCandidates = ["error", "cause", "matcherResult"];
5008
+ const nestedCandidates = ["error", "cause", "matcherResult", "context", "data"];
5008
5009
  for (const key of nestedCandidates) {
5009
5010
  if (obj[key] && typeof obj[key] === "object") {
5010
5011
  visitDeep(obj[key], depth + 1);
@@ -5033,9 +5034,7 @@ var linesFromDetails = (details) => {
5033
5034
  pushMaybe(matcher.expected, messages);
5034
5035
  pushMaybe(matcher.received, messages);
5035
5036
  }
5036
- if (messages.length === 0 && stacks.length === 0) {
5037
- visitDeep(detail, 0);
5038
- }
5037
+ visitDeep(detail, 0);
5039
5038
  }
5040
5039
  }
5041
5040
  return { stacks, messages };
@@ -5099,24 +5098,31 @@ var buildConsoleSection = (maybeConsole) => {
5099
5098
  var buildFallbackMessageBlock = (messageLines, details) => {
5100
5099
  const normalize2 = (arr) => arr.map((lineText) => stripAnsiSimple(lineText)).filter((line) => line.trim().length > 0);
5101
5100
  const normalized = normalize2(messageLines);
5102
- const informative = normalized.filter((line) => !/^\s*(?:Error|AssertionError):?\s*$/.test(line));
5101
+ const informative = normalized.filter(
5102
+ (line) => !/^\s*(?:Error|AssertionError):?\s*$/i.test(line)
5103
+ );
5103
5104
  if (informative.length > 0) {
5104
5105
  return [];
5105
5106
  }
5106
5107
  const errorIdx = normalized.findIndex(
5107
- (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/.test(line)
5108
+ (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/i.test(line)
5108
5109
  );
5109
5110
  const collected = [];
5110
5111
  if (errorIdx >= 0) {
5111
- for (let i = errorIdx; i < normalized.length && collected.length < 8; i += 1) {
5112
- const ln = normalized[i];
5113
- if (!ln.trim()) {
5112
+ let started = false;
5113
+ for (let i = errorIdx + 1; i < messageLines.length && collected.length < 8; i += 1) {
5114
+ const raw = stripAnsiSimple(messageLines[i]);
5115
+ if (isStackLine(raw)) {
5114
5116
  break;
5115
5117
  }
5116
- if (isStackLine(ln)) {
5118
+ if (!raw.trim()) {
5119
+ if (!started) {
5120
+ continue;
5121
+ }
5117
5122
  break;
5118
5123
  }
5119
- collected.push(ln);
5124
+ started = true;
5125
+ collected.push(raw);
5120
5126
  }
5121
5127
  }
5122
5128
  const fromDetails = collected.length > 0 ? [] : normalize2(details.messages).slice(0, 6);
@@ -5364,39 +5370,13 @@ var makeCtx = (opts, showStacks = false) => {
5364
5370
  return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
5365
5371
  };
5366
5372
 
5367
- // src/lib/formatter/bridge.ts
5373
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
5368
5374
  var fs6 = __toESM(require("node:fs"), 1);
5375
+ var path11 = __toESM(require("node:path"), 1);
5376
+ var import_json53 = __toESM(require_lib(), 1);
5377
+
5378
+ // src/lib/formatter/bridge/logic.ts
5369
5379
  var path10 = __toESM(require("node:path"), 1);
5370
- var import_json52 = __toESM(require_lib(), 1);
5371
- var colorTokens2 = {
5372
- pass: Colors.Success,
5373
- fail: Colors.Failure,
5374
- skip: Colors.Skip,
5375
- todo: Colors.Todo,
5376
- passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
5377
- failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
5378
- };
5379
- var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
5380
- var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
5381
- var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
5382
- var summarizeUrl = (method, url, route) => {
5383
- const base = route || url || "";
5384
- const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
5385
- return [method || "", base, qs].filter(Boolean).join(" ").trim();
5386
- };
5387
- var stripBridgeEventsFromConsole = (maybeConsole) => {
5388
- if (!Array.isArray(maybeConsole)) {
5389
- return maybeConsole;
5390
- }
5391
- return maybeConsole.filter((entry) => {
5392
- try {
5393
- const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
5394
- return !raw.includes("[JEST-BRIDGE-EVENT]");
5395
- } catch {
5396
- return true;
5397
- }
5398
- });
5399
- };
5400
5380
  var extractBridgePath2 = (raw, cwd) => {
5401
5381
  const matches = Array.from(
5402
5382
  raw.matchAll(/Test results written to:\s+([^\n\r]+jest-bridge-[^\s'"]+\.json)/g)
@@ -5404,7 +5384,7 @@ var extractBridgePath2 = (raw, cwd) => {
5404
5384
  if (!matches.length) {
5405
5385
  return null;
5406
5386
  }
5407
- const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^["'`]|["'`]$/g, "");
5387
+ const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^['"`]|['"`]$/g, "");
5408
5388
  return path10.isAbsolute(jsonPath) ? jsonPath : path10.resolve(cwd, jsonPath).replace(/\\/g, "/");
5409
5389
  };
5410
5390
  var isTransportError = (msg) => {
@@ -5413,25 +5393,6 @@ var isTransportError = (msg) => {
5413
5393
  lowercaseMessage
5414
5394
  );
5415
5395
  };
5416
- var envNumber = (name, fallback) => {
5417
- const parsed = Number(process.env[name]);
5418
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
5419
- };
5420
- var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
5421
- var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
5422
- var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
5423
- var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
5424
- var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
5425
- var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
5426
- if (typeof ts !== "number" || !Number.isFinite(ts)) {
5427
- return [];
5428
- }
5429
- return http.filter((e) => {
5430
- const timeOk = typeof e.timestampMs === "number" && Math.abs(e.timestampMs - ts) <= windowMs;
5431
- const pathOk = !testPath || e.testPath === testPath;
5432
- return timeOk && pathOk;
5433
- });
5434
- };
5435
5396
  var parseMethodPathFromTitle = (title) => {
5436
5397
  if (!title) {
5437
5398
  return {};
@@ -5439,35 +5400,6 @@ var parseMethodPathFromTitle = (title) => {
5439
5400
  const matchResult = title.match(/\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+([^\s)]+)/i);
5440
5401
  return matchResult ? { method: matchResult[1]?.toUpperCase(), path: matchResult[2] } : {};
5441
5402
  };
5442
- var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
5443
- var hasStatusSemantics = (assertionLike) => {
5444
- if (!assertionLike) {
5445
- return false;
5446
- }
5447
- if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
5448
- return true;
5449
- }
5450
- const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
5451
- const combinedMessage = combinedRaw.toLowerCase();
5452
- return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
5453
- };
5454
- var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
5455
- var inferHttpNumbersFromText = (lines) => {
5456
- const text = lines.join("\n");
5457
- const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
5458
- if (match) {
5459
- return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
5460
- }
5461
- return {};
5462
- };
5463
- var titleSuggestsHttp = (title) => {
5464
- const { method, path: parsedPath } = parseMethodPathFromTitle(title);
5465
- return Boolean(method || parsedPath && parsedPath.startsWith("/"));
5466
- };
5467
- var isHttpRelevant = (ctx) => {
5468
- const assertionCtx = ctx.assertion;
5469
- return ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(assertionCtx) || fileSuggestsHttp(ctx.relPath);
5470
- };
5471
5403
  var routeSimilarityScore = (hint, evt) => {
5472
5404
  if (!hint.path && !hint.method) {
5473
5405
  return 0;
@@ -5488,6 +5420,15 @@ var routeSimilarityScore = (hint, evt) => {
5488
5420
  }
5489
5421
  return methodOk * 10;
5490
5422
  };
5423
+ var envNumber = (name, fallback) => {
5424
+ const parsed = Number(process.env[name]);
5425
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
5426
+ };
5427
+ var HEADLAMP_HTTP_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_WINDOW_MS", 3e3);
5428
+ var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDOW_MS", 600);
5429
+ var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
5430
+ var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
5431
+ var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
5491
5432
  var scoreHttpForAssertion = (assertion, titleHint) => (candidateEvent) => {
5492
5433
  const tsA = assertion.timestampMs;
5493
5434
  const tsH = candidateEvent.timestampMs;
@@ -5508,14 +5449,20 @@ var pickRelevantHttp = (assertion, http, ctx) => {
5508
5449
  const windowMs = isTransportError(assertion.message) ? HEADLAMP_HTTP_STRICT_WINDOW_MS() : HEADLAMP_HTTP_WINDOW_MS();
5509
5450
  let pool = strictPool;
5510
5451
  if (!pool.length) {
5511
- pool = http.filter(
5512
- (e) => e.testPath === ctx.testPath && typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
5513
- );
5452
+ pool = http.filter((event) => {
5453
+ const samePath = event.testPath === ctx.testPath;
5454
+ const tsA = assertion.timestampMs;
5455
+ const tsH = event.timestampMs;
5456
+ const inWindow = typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
5457
+ return samePath && inWindow;
5458
+ });
5514
5459
  }
5515
5460
  if (!pool.length) {
5516
- pool = http.filter(
5517
- (e) => typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
5518
- );
5461
+ pool = http.filter((event) => {
5462
+ const tsA = assertion.timestampMs;
5463
+ const tsH = event.timestampMs;
5464
+ return typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
5465
+ });
5519
5466
  }
5520
5467
  if (!pool.length) {
5521
5468
  return void 0;
@@ -5525,9 +5472,11 @@ var pickRelevantHttp = (assertion, http, ctx) => {
5525
5472
  const threshold = isTransportError(assertion.message) ? Math.max(HEADLAMP_HTTP_MIN_SCORE(), 1400) : HEADLAMP_HTTP_MIN_SCORE();
5526
5473
  return best && best.s >= threshold ? best.h : void 0;
5527
5474
  };
5528
- var isBridgeJSONLike = (candidateValue) => !!candidateValue && typeof candidateValue === "object" && "aggregated" in candidateValue;
5475
+
5476
+ // src/lib/formatter/bridge/utils.ts
5477
+ var import_json52 = __toESM(require_lib(), 1);
5529
5478
  var coerceJestJsonToBridge = (raw) => {
5530
- if (isBridgeJSONLike(raw)) {
5479
+ if (raw && typeof raw === "object" && "aggregated" in raw) {
5531
5480
  return raw;
5532
5481
  }
5533
5482
  const j = raw;
@@ -5554,19 +5503,85 @@ var coerceJestJsonToBridge = (raw) => {
5554
5503
  }))
5555
5504
  })),
5556
5505
  aggregated: {
5557
- numTotalTestSuites: j.numTotalTestSuites,
5558
- numPassedTestSuites: j.numPassedTestSuites,
5559
- numFailedTestSuites: j.numFailedTestSuites,
5560
- numTotalTests: j.numTotalTests,
5561
- numPassedTests: j.numPassedTests,
5562
- numFailedTests: j.numFailedTests,
5563
- numPendingTests: j.numPendingTests,
5564
- numTodoTests: j.numTodoTests,
5565
- startTime: j.startTime,
5566
- success: j.success
5506
+ numTotalTestSuites: raw.numTotalTestSuites,
5507
+ numPassedTestSuites: raw.numPassedTestSuites,
5508
+ numFailedTestSuites: raw.numFailedTestSuites,
5509
+ numTotalTests: raw.numTotalTests,
5510
+ numPassedTests: raw.numPassedTests,
5511
+ numFailedTests: raw.numFailedTests,
5512
+ numPendingTests: raw.numPendingTests,
5513
+ numTodoTests: raw.numTodoTests,
5514
+ startTime: raw.startTime,
5515
+ success: raw.success,
5516
+ runTimeMs: raw.aggregated?.runTimeMs
5567
5517
  }
5568
5518
  };
5569
5519
  };
5520
+ var colorTokens2 = {
5521
+ pass: Colors.Success,
5522
+ fail: Colors.Failure,
5523
+ skip: Colors.Skip,
5524
+ todo: Colors.Todo,
5525
+ passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
5526
+ failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
5527
+ };
5528
+ var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
5529
+ var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
5530
+ var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
5531
+ var summarizeUrl = (method, url, route) => {
5532
+ const base = route || url || "";
5533
+ const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
5534
+ return [method || "", base, qs].filter(Boolean).join(" ").trim();
5535
+ };
5536
+ var stripBridgeEventsFromConsole = (maybeConsole) => {
5537
+ if (!Array.isArray(maybeConsole)) {
5538
+ return maybeConsole;
5539
+ }
5540
+ return maybeConsole.filter((entry) => {
5541
+ try {
5542
+ const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
5543
+ return !raw.includes("[JEST-BRIDGE-EVENT]");
5544
+ } catch {
5545
+ return true;
5546
+ }
5547
+ });
5548
+ };
5549
+ var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
5550
+ if (typeof ts !== "number" || !Number.isFinite(ts)) {
5551
+ return [];
5552
+ }
5553
+ return http.filter((event) => {
5554
+ const timeOk = typeof event.timestampMs === "number" && Math.abs(event.timestampMs - ts) <= windowMs;
5555
+ const pathOk = !testPath || event.testPath === testPath;
5556
+ return timeOk && pathOk;
5557
+ });
5558
+ };
5559
+ var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
5560
+ var inferHttpNumbersFromText = (lines) => {
5561
+ const text = lines.join("\n");
5562
+ const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
5563
+ if (match) {
5564
+ return { expectedNumber: Number(match[1]), receivedNumber: Number(match[2]) };
5565
+ }
5566
+ return {};
5567
+ };
5568
+ var titleSuggestsHttp = (title) => {
5569
+ const { method, path: parsedPath } = parseMethodPathFromTitle(title);
5570
+ return Boolean(method || parsedPath && parsedPath.startsWith("/"));
5571
+ };
5572
+ var hasStatusSemantics = (assertionLike) => {
5573
+ if (!assertionLike) {
5574
+ return false;
5575
+ }
5576
+ if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
5577
+ return true;
5578
+ }
5579
+ const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
5580
+ const combinedMessage = combinedRaw.toLowerCase();
5581
+ return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
5582
+ };
5583
+ var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
5584
+ var isHttpRelevant = (ctx) => ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(ctx.assertion) || fileSuggestsHttp(ctx.relPath);
5570
5585
  var vitestFooter = (agg, durationMs) => {
5571
5586
  const files = [
5572
5587
  agg.numFailedTestSuites ? colorTokens2.fail(`${agg.numFailedTestSuites} failed`) : "",
@@ -6043,13 +6058,21 @@ var renderVitestFromJestJSON = (data, ctx, opts) => {
6043
6058
  out.push(vitestFooter(data.aggregated));
6044
6059
  return out.join("\n");
6045
6060
  };
6061
+
6062
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
6046
6063
  var tryBridgeFallback = (raw, ctx, opts) => {
6047
- const bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
6064
+ let bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
6065
+ if (!bridgeJsonPath) {
6066
+ const def = path11.resolve(ctx.cwd, "coverage/jest-run.json").replace(/\\/g, "/");
6067
+ if (fs6.existsSync(def)) {
6068
+ bridgeJsonPath = def;
6069
+ }
6070
+ }
6048
6071
  if (!bridgeJsonPath || !fs6.existsSync(bridgeJsonPath)) {
6049
6072
  return null;
6050
6073
  }
6051
6074
  try {
6052
- const json = import_json52.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
6075
+ const json = import_json53.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
6053
6076
  const bridge = coerceJestJsonToBridge(json);
6054
6077
  return renderVitestFromJestJSON(bridge, ctx, opts);
6055
6078
  } catch {
@@ -6067,23 +6090,39 @@ var formatJestOutputVitest = (raw, opts) => pipe(
6067
6090
  (state) => ({ ...state, chunks: parseChunks(state.raw) }),
6068
6091
  (state) => ({
6069
6092
  ...state,
6070
- rendered: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
6093
+ native: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
6071
6094
  onlyFailures: Boolean(state.opts?.onlyFailures)
6072
- })
6095
+ }).text
6073
6096
  }),
6074
- (state) => {
6075
- if (state.rendered.hadParsed) {
6076
- return state.rendered.text;
6077
- }
6078
- const fallback = tryBridgeFallback(state.raw, state.ctx, {
6097
+ (state) => ({
6098
+ ...state,
6099
+ bridge: tryBridgeFallback(state.raw, state.ctx, {
6079
6100
  onlyFailures: Boolean(state.opts?.onlyFailures)
6080
- });
6081
- if (!fallback) {
6082
- return state.rendered.text;
6101
+ }) || null
6102
+ }),
6103
+ (state) => {
6104
+ const out = [];
6105
+ const seen = /* @__PURE__ */ new Set();
6106
+ const pushUnique = (text) => {
6107
+ if (!text) {
6108
+ return;
6109
+ }
6110
+ for (const line of text.split(/\r?\n/)) {
6111
+ const key = stripAnsiSimple(line);
6112
+ if (!seen.has(key)) {
6113
+ out.push(line);
6114
+ seen.add(key);
6115
+ }
6116
+ }
6117
+ };
6118
+ pushUnique(state.native);
6119
+ if (state.bridge) {
6120
+ if (out.length) {
6121
+ out.push("");
6122
+ }
6123
+ pushUnique(state.bridge);
6083
6124
  }
6084
- const prefix = state.rendered.text;
6085
- return prefix ? `${prefix}
6086
- ${fallback}` : fallback;
6125
+ return out.join("\n");
6087
6126
  }
6088
6127
  );
6089
6128
 
@@ -6130,7 +6169,7 @@ var mergeLcov = async () => {
6130
6169
  try {
6131
6170
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
6132
6171
  for (const entry of entries) {
6133
- const full = path11.join(dir, entry.name);
6172
+ const full = path12.join(dir, entry.name);
6134
6173
  if (entry.isDirectory()) {
6135
6174
  out.push(...collectLcovs(full));
6136
6175
  } else if (entry.isFile() && entry.name === "lcov.info") {
@@ -6142,8 +6181,8 @@ var mergeLcov = async () => {
6142
6181
  return out;
6143
6182
  };
6144
6183
  try {
6145
- const jestRoot = path11.join("coverage", "jest");
6146
- const candidates = [path11.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
6184
+ const jestRoot = path12.join("coverage", "jest");
6185
+ const candidates = [path12.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
6147
6186
  for (const filePath of candidates) {
6148
6187
  try {
6149
6188
  const content = await readOrEmpty(filePath);
@@ -6183,7 +6222,7 @@ var emitMergedCoverage = async (ui, opts) => {
6183
6222
  try {
6184
6223
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
6185
6224
  for (const entry of entries) {
6186
- const full = path11.join(dir, entry.name);
6225
+ const full = path12.join(dir, entry.name);
6187
6226
  if (entry.isDirectory()) {
6188
6227
  out.push(...listJsons(full));
6189
6228
  } else if (entry.isFile() && entry.name === "coverage-final.json") {
@@ -6194,11 +6233,11 @@ var emitMergedCoverage = async (ui, opts) => {
6194
6233
  }
6195
6234
  return out;
6196
6235
  };
6197
- const coverageRoot = path11.join("coverage", "jest");
6236
+ const coverageRoot = path12.join("coverage", "jest");
6198
6237
  const jsonCandidates = [
6199
- path11.join(coverageRoot, "coverage-final.json"),
6238
+ path12.join(coverageRoot, "coverage-final.json"),
6200
6239
  ...listJsons(coverageRoot)
6201
- ].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => {
6240
+ ].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => {
6202
6241
  const isFirst = arr.indexOf(absolutePath) === index;
6203
6242
  const exists = fsSync3.existsSync(absolutePath);
6204
6243
  return isFirst && exists;
@@ -6260,7 +6299,7 @@ var emitMergedCoverage = async (ui, opts) => {
6260
6299
  executedTests: opts.executedTests ?? []
6261
6300
  });
6262
6301
  const context = LibReport.createContext({
6263
- dir: path11.resolve("coverage", "merged"),
6302
+ dir: path12.resolve("coverage", "merged"),
6264
6303
  coverageMap: filteredMap,
6265
6304
  defaultSummarizer: "nested"
6266
6305
  });
@@ -6328,8 +6367,8 @@ var emitMergedCoverage = async (ui, opts) => {
6328
6367
  for (const reporter of reporters) {
6329
6368
  reporter.execute(context);
6330
6369
  }
6331
- const textPath = path11.resolve("coverage", "merged", "coverage.txt");
6332
- const summaryPath = path11.resolve("coverage", "merged", "coverage-summary.txt");
6370
+ const textPath = path12.resolve("coverage", "merged", "coverage.txt");
6371
+ const summaryPath = path12.resolve("coverage", "merged", "coverage-summary.txt");
6333
6372
  const filesToPrint = [];
6334
6373
  if (fsSync3.existsSync(textPath)) {
6335
6374
  filesToPrint.push(textPath);
@@ -6472,13 +6511,13 @@ var program = async () => {
6472
6511
  const rels2 = Array.from(
6473
6512
  /* @__PURE__ */ new Set([...branchDiff, ...stagedNow, ...unstagedNow, ...untrackedNow])
6474
6513
  );
6475
- return rels2.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6514
+ return rels2.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6476
6515
  }
6477
6516
  const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
6478
6517
  const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
6479
6518
  const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
6480
6519
  const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
6481
- return rels.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6520
+ return rels.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6482
6521
  };
6483
6522
  const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
6484
6523
  const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
@@ -6503,18 +6542,18 @@ var program = async () => {
6503
6542
  if (!token) {
6504
6543
  continue;
6505
6544
  }
6506
- const isAbs = path11.isAbsolute(token);
6545
+ const isAbs = path12.isAbsolute(token);
6507
6546
  const looksLikeRelPath = /[\\/]/.test(token);
6508
6547
  let candidateFromRoot;
6509
6548
  if (token.startsWith("/")) {
6510
- candidateFromRoot = path11.join(repoRoot, token.slice(1));
6549
+ candidateFromRoot = path12.join(repoRoot, token.slice(1));
6511
6550
  } else if (looksLikeRelPath) {
6512
- candidateFromRoot = path11.join(repoRoot, token);
6551
+ candidateFromRoot = path12.join(repoRoot, token);
6513
6552
  } else {
6514
6553
  candidateFromRoot = void 0;
6515
6554
  }
6516
6555
  const tryPushIfProd = (absPath) => {
6517
- const norm = path11.resolve(absPath).replace(/\\/g, "/");
6556
+ const norm = path12.resolve(absPath).replace(/\\/g, "/");
6518
6557
  const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
6519
6558
  if (!isTest && fsSync3.existsSync(norm)) {
6520
6559
  results.add(norm);
@@ -6536,7 +6575,7 @@ var program = async () => {
6536
6575
  }),
6537
6576
  timeoutMs: 4e3
6538
6577
  });
6539
- const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path11.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
6578
+ const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path12.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
6540
6579
  (abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
6541
6580
  );
6542
6581
  matches.forEach((abs) => results.add(abs));
@@ -6557,8 +6596,8 @@ var program = async () => {
6557
6596
  const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
6558
6597
  const projectConfigs = [];
6559
6598
  try {
6560
- const baseCfg = path11.resolve("jest.config.js");
6561
- const tsCfg = path11.resolve("jest.ts.config.js");
6599
+ const baseCfg = path12.resolve("jest.config.js");
6600
+ const tsCfg = path12.resolve("jest.ts.config.js");
6562
6601
  if (fsSync3.existsSync(baseCfg)) {
6563
6602
  projectConfigs.push(baseCfg);
6564
6603
  }
@@ -6575,7 +6614,7 @@ var program = async () => {
6575
6614
  );
6576
6615
  const prodSelections2 = expandedProdSelections;
6577
6616
  for (const cfg of projectConfigs) {
6578
- const cfgCwd = path11.dirname(cfg);
6617
+ const cfgCwd = path12.dirname(cfg);
6579
6618
  const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6580
6619
  cwd: cfgCwd
6581
6620
  });
@@ -6588,7 +6627,7 @@ var program = async () => {
6588
6627
  });
6589
6628
  } catch (err) {
6590
6629
  if (isDebug()) {
6591
- console.warn(`direct selection failed for project ${path11.basename(cfg)}: ${String(err)}`);
6630
+ console.warn(`direct selection failed for project ${path12.basename(cfg)}: ${String(err)}`);
6592
6631
  }
6593
6632
  }
6594
6633
  perProjectFiles.set(cfg, directPerProject);
@@ -6600,7 +6639,7 @@ var program = async () => {
6600
6639
  )} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
6601
6640
  );
6602
6641
  for (const cfg of projectConfigs) {
6603
- const cfgCwd = path11.dirname(cfg);
6642
+ const cfgCwd = path12.dirname(cfg);
6604
6643
  const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6605
6644
  cwd: cfgCwd
6606
6645
  });
@@ -6615,13 +6654,13 @@ var program = async () => {
6615
6654
  );
6616
6655
  const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
6617
6656
  const absFiles = candidates.map(
6618
- (candidatePath) => path11.isAbsolute(candidatePath) ? candidatePath : path11.join(repoRootForDiscovery, candidatePath)
6657
+ (candidatePath) => path12.isAbsolute(candidatePath) ? candidatePath : path12.join(repoRootForDiscovery, candidatePath)
6619
6658
  ).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
6620
6659
  const onlyOwned = await filterCandidatesForProject(
6621
6660
  cfg,
6622
6661
  jestDiscoveryArgs,
6623
6662
  absFiles,
6624
- path11.dirname(cfg)
6663
+ path12.dirname(cfg)
6625
6664
  );
6626
6665
  perProjectFiltered.set(cfg, onlyOwned);
6627
6666
  }
@@ -6633,7 +6672,7 @@ var program = async () => {
6633
6672
  if (selectionHasPaths && prodSelections.length > 0) {
6634
6673
  console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
6635
6674
  const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
6636
- const selectionKey = prodSelections.map((absPath) => path11.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
6675
+ const selectionKey = prodSelections.map((absPath) => path12.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
6637
6676
  const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
6638
6677
  const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
6639
6678
  const rgMatches = await cachedRelated2({
@@ -6663,7 +6702,7 @@ var program = async () => {
6663
6702
  cfg,
6664
6703
  jestDiscoveryArgs,
6665
6704
  rgCandidates,
6666
- path11.dirname(cfg)
6705
+ path12.dirname(cfg)
6667
6706
  );
6668
6707
  perProjectFromRg.set(cfg, owned);
6669
6708
  }
@@ -6678,9 +6717,9 @@ var program = async () => {
6678
6717
  } else {
6679
6718
  const repoRootForScan = repoRootForDiscovery;
6680
6719
  const toSeeds = (abs) => {
6681
- const rel = path11.relative(repoRootForScan, abs).replace(/\\/g, "/");
6720
+ const rel = path12.relative(repoRootForScan, abs).replace(/\\/g, "/");
6682
6721
  const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
6683
- const base = path11.basename(withoutExt);
6722
+ const base = path12.basename(withoutExt);
6684
6723
  const segs = withoutExt.split("/");
6685
6724
  const tail2 = segs.slice(-2).join("/");
6686
6725
  return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
@@ -6695,8 +6734,8 @@ var program = async () => {
6695
6734
  }
6696
6735
  };
6697
6736
  const resolveLocalImport = (fromFile, spec) => {
6698
- const baseDir = path11.dirname(fromFile);
6699
- const cand = path11.resolve(baseDir, spec);
6737
+ const baseDir = path12.dirname(fromFile);
6738
+ const cand = path12.resolve(baseDir, spec);
6700
6739
  const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
6701
6740
  for (const ext of exts) {
6702
6741
  const full = ext ? `${cand}${ext}` : cand;
@@ -6705,7 +6744,7 @@ var program = async () => {
6705
6744
  }
6706
6745
  }
6707
6746
  for (const ext of exts) {
6708
- const full = path11.join(cand, `index${ext}`);
6747
+ const full = path12.join(cand, `index${ext}`);
6709
6748
  if (fsSync3.existsSync(full)) {
6710
6749
  return full;
6711
6750
  }
@@ -6759,7 +6798,7 @@ var program = async () => {
6759
6798
  cfg,
6760
6799
  jestDiscoveryArgs,
6761
6800
  keptCandidates,
6762
- path11.dirname(cfg)
6801
+ path12.dirname(cfg)
6763
6802
  );
6764
6803
  perProjectFromScan.set(cfg, owned);
6765
6804
  }
@@ -6789,7 +6828,7 @@ var program = async () => {
6789
6828
  try {
6790
6829
  const allAcross = [];
6791
6830
  for (const cfg of projectConfigs) {
6792
- const cfgCwd = path11.dirname(cfg);
6831
+ const cfgCwd = path12.dirname(cfg);
6793
6832
  const listed = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6794
6833
  cwd: cfgCwd
6795
6834
  });
@@ -6803,9 +6842,9 @@ var program = async () => {
6803
6842
  }
6804
6843
  }
6805
6844
  const seeds = prodSelections.map(
6806
- (abs) => path11.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
6845
+ (abs) => path12.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
6807
6846
  ).flatMap((rel) => {
6808
- const base = path11.basename(rel);
6847
+ const base = path12.basename(rel);
6809
6848
  const segments = rel.split("/");
6810
6849
  return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
6811
6850
  });
@@ -6818,8 +6857,8 @@ var program = async () => {
6818
6857
  }
6819
6858
  };
6820
6859
  const resolveLocalImport = (fromFile, spec) => {
6821
- const baseDir = path11.dirname(fromFile);
6822
- const candidate = path11.resolve(baseDir, spec);
6860
+ const baseDir = path12.dirname(fromFile);
6861
+ const candidate = path12.resolve(baseDir, spec);
6823
6862
  const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
6824
6863
  for (const ext of extensions) {
6825
6864
  const fullPath = ext ? `${candidate}${ext}` : candidate;
@@ -6828,7 +6867,7 @@ var program = async () => {
6828
6867
  }
6829
6868
  }
6830
6869
  for (const ext of extensions) {
6831
- const fullPath = path11.join(candidate, `index${ext}`);
6870
+ const fullPath = path12.join(candidate, `index${ext}`);
6832
6871
  if (fsSync3.existsSync(fullPath)) {
6833
6872
  return fullPath;
6834
6873
  }
@@ -6985,10 +7024,10 @@ var program = async () => {
6985
7024
  };
6986
7025
  const prodSeedsForRun = (() => {
6987
7026
  const changedAbs = (changedSelectionAbs ?? []).map(
6988
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
7027
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
6989
7028
  );
6990
7029
  const selAbs = selectionPathsAugmented.map(
6991
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
7030
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
6992
7031
  );
6993
7032
  return (changedAbs.length ? changedAbs : selAbs).filter(
6994
7033
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
@@ -7003,17 +7042,17 @@ var program = async () => {
7003
7042
  const cfg = projectsToRun[projIndex];
7004
7043
  const files = perProjectFiltered.get(cfg) ?? [];
7005
7044
  if (files.length === 0) {
7006
- console.info(`Project ${path11.basename(cfg)}: 0 matching tests after filter; skipping.`);
7045
+ console.info(`Project ${path12.basename(cfg)}: 0 matching tests after filter; skipping.`);
7007
7046
  continue;
7008
7047
  }
7009
7048
  files.forEach(
7010
- (absTestPath) => executedTestFilesSet.add(path11.resolve(absTestPath).replace(/\\/g, "/"))
7049
+ (absTestPath) => executedTestFilesSet.add(path12.resolve(absTestPath).replace(/\\/g, "/"))
7011
7050
  );
7012
- const outJson = path11.join(
7013
- os2.tmpdir(),
7051
+ const outJson = path12.join(
7052
+ os3.tmpdir(),
7014
7053
  `jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
7015
7054
  );
7016
- const reporterPath = path11.resolve("scripts/jest-vitest-bridge.cjs");
7055
+ const reporterPath = path12.resolve("scripts/jest-vitest-bridge.cjs");
7017
7056
  try {
7018
7057
  const needsWrite = (() => {
7019
7058
  try {
@@ -7024,10 +7063,10 @@ var program = async () => {
7024
7063
  }
7025
7064
  })();
7026
7065
  if (needsWrite) {
7027
- fsSync3.mkdirSync(path11.dirname(reporterPath), { recursive: true });
7066
+ fsSync3.mkdirSync(path12.dirname(reporterPath), { recursive: true });
7028
7067
  fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
7029
7068
  }
7030
- const envPath = path11.resolve("scripts/jest-bridge-env.cjs");
7069
+ const envPath = path12.resolve("scripts/jest-bridge-env.cjs");
7031
7070
  try {
7032
7071
  const existingEnv = fsSync3.readFileSync(envPath, "utf8");
7033
7072
  if (existingEnv !== JEST_BRIDGE_ENV_SOURCE) {
@@ -7035,7 +7074,7 @@ var program = async () => {
7035
7074
  }
7036
7075
  } catch {
7037
7076
  try {
7038
- fsSync3.mkdirSync(path11.dirname(envPath), { recursive: true });
7077
+ fsSync3.mkdirSync(path12.dirname(envPath), { recursive: true });
7039
7078
  } catch {
7040
7079
  }
7041
7080
  fsSync3.writeFileSync(envPath, JEST_BRIDGE_ENV_SOURCE, "utf8");
@@ -7043,7 +7082,7 @@ var program = async () => {
7043
7082
  } catch (ensureReporterError) {
7044
7083
  console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
7045
7084
  }
7046
- 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}`);
7085
+ 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}`);
7047
7086
  const coverageFromArgs = [];
7048
7087
  for (const relPath2 of selectedFilesForCoverage) {
7049
7088
  coverageFromArgs.push("--collectCoverageFrom", relPath2);
@@ -7061,11 +7100,11 @@ var program = async () => {
7061
7100
  `--reporters=${reporterPath}`,
7062
7101
  "--colors",
7063
7102
  "--env",
7064
- path11.resolve("scripts/jest-bridge-env.cjs"),
7103
+ path12.resolve("scripts/jest-bridge-env.cjs"),
7065
7104
  ...sanitizedJestRunArgs,
7066
7105
  ...collectCoverage ? [
7067
7106
  "--coverageDirectory",
7068
- path11.join("coverage", "jest", path11.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
7107
+ path12.join("coverage", "jest", path12.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
7069
7108
  ] : [],
7070
7109
  ...coverageFromArgs,
7071
7110
  "--passWithNoTests",
@@ -7191,10 +7230,10 @@ ${stripFooter(rawAlso)}`.trimEnd();
7191
7230
  try {
7192
7231
  const prodSeeds = (() => {
7193
7232
  const changedAbs = (changedSelectionAbs ?? []).map(
7194
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
7233
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
7195
7234
  );
7196
7235
  const selAbs = selectionPathsAugmented.map(
7197
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
7236
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
7198
7237
  );
7199
7238
  return (changedAbs.length ? changedAbs : selAbs).filter(
7200
7239
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)