headlamp 0.1.12 → 0.1.14

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
  });
@@ -1980,16 +1980,16 @@ var require_lib = __commonJS({
1980
1980
  "node_modules/json5/lib/index.js"(exports2, module2) {
1981
1981
  var parse = require_parse();
1982
1982
  var stringify = require_stringify();
1983
- var JSON53 = {
1983
+ var JSON54 = {
1984
1984
  parse,
1985
1985
  stringify
1986
1986
  };
1987
- module2.exports = JSON53;
1987
+ module2.exports = JSON54;
1988
1988
  }
1989
1989
  });
1990
1990
 
1991
1991
  // src/lib/program.ts
1992
- var path11 = __toESM(require("node:path"), 1);
1992
+ var path12 = __toESM(require("node:path"), 1);
1993
1993
  var os3 = __toESM(require("node:os"), 1);
1994
1994
  var fsSync3 = __toESM(require("node:fs"), 1);
1995
1995
  var fs7 = __toESM(require("node:fs/promises"), 1);
@@ -3047,11 +3047,11 @@ var tintPct = (pct) => {
3047
3047
  var bar = (pct, width = DEFAULT_BAR_WIDTH) => {
3048
3048
  const filled = Math.round(pct / PERCENT_MAX * width);
3049
3049
  const solid = supportsUnicode() ? "\u2588" : "#";
3050
- const empty = supportsUnicode() ? "\u2591" : "-";
3050
+ const empty2 = supportsUnicode() ? "\u2591" : "-";
3051
3051
  const good = tintPct(pct);
3052
3052
  const MIN_REMAINING = 0;
3053
3053
  return `${good(solid.repeat(filled))}${ansi.gray(
3054
- empty.repeat(Math.max(MIN_REMAINING, width - filled))
3054
+ empty2.repeat(Math.max(MIN_REMAINING, width - filled))
3055
3055
  )}`;
3056
3056
  };
3057
3057
 
@@ -4912,15 +4912,23 @@ var buildMessageSection = (messageLines, details, _ctx, opts) => {
4912
4912
  const fallbackLines = [];
4913
4913
  if (hasOnlyBareError) {
4914
4914
  const startFrom = hintIdx >= 0 ? hintIdx + 1 : 0;
4915
+ let started = false;
4915
4916
  for (let i = startFrom; i < lines.length; i += 1) {
4916
4917
  const candidate = lines[i];
4917
- if (!candidate.trim()) {
4918
+ if (isStackLine(candidate)) {
4918
4919
  break;
4919
4920
  }
4920
- if (isStackLine(candidate)) {
4921
+ if (!candidate.trim()) {
4922
+ if (!started) {
4923
+ continue;
4924
+ }
4921
4925
  break;
4922
4926
  }
4927
+ started = true;
4923
4928
  fallbackLines.push(candidate);
4929
+ if (fallbackLines.length >= 6) {
4930
+ break;
4931
+ }
4924
4932
  }
4925
4933
  if (fallbackLines.length === 0 && details && details.messages && details.messages.length) {
4926
4934
  fallbackLines.push(
@@ -4988,7 +4996,7 @@ var linesFromDetails = (details) => {
4988
4996
  if (typeof obj.received === "string") {
4989
4997
  pushMaybe(obj.received, messages);
4990
4998
  }
4991
- const arrays = ["errors", "causes", "aggregatedErrors"];
4999
+ const arrays = ["errors", "details", "issues", "inner", "causes", "aggregatedErrors"];
4992
5000
  for (const key of arrays) {
4993
5001
  const arr = obj[key];
4994
5002
  if (Array.isArray(arr)) {
@@ -4997,7 +5005,7 @@ var linesFromDetails = (details) => {
4997
5005
  }
4998
5006
  }
4999
5007
  }
5000
- const nestedCandidates = ["error", "cause", "matcherResult"];
5008
+ const nestedCandidates = ["error", "cause", "matcherResult", "context", "data"];
5001
5009
  for (const key of nestedCandidates) {
5002
5010
  if (obj[key] && typeof obj[key] === "object") {
5003
5011
  visitDeep(obj[key], depth + 1);
@@ -5026,9 +5034,7 @@ var linesFromDetails = (details) => {
5026
5034
  pushMaybe(matcher.expected, messages);
5027
5035
  pushMaybe(matcher.received, messages);
5028
5036
  }
5029
- if (messages.length === 0 && stacks.length === 0) {
5030
- visitDeep(detail, 0);
5031
- }
5037
+ visitDeep(detail, 0);
5032
5038
  }
5033
5039
  }
5034
5040
  return { stacks, messages };
@@ -5092,24 +5098,31 @@ var buildConsoleSection = (maybeConsole) => {
5092
5098
  var buildFallbackMessageBlock = (messageLines, details) => {
5093
5099
  const normalize2 = (arr) => arr.map((lineText) => stripAnsiSimple(lineText)).filter((line) => line.trim().length > 0);
5094
5100
  const normalized = normalize2(messageLines);
5095
- 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
+ );
5096
5104
  if (informative.length > 0) {
5097
5105
  return [];
5098
5106
  }
5099
5107
  const errorIdx = normalized.findIndex(
5100
- (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/.test(line)
5108
+ (line) => /(TypeError|ReferenceError|SyntaxError|RangeError|AssertionError|Error):?/i.test(line)
5101
5109
  );
5102
5110
  const collected = [];
5103
5111
  if (errorIdx >= 0) {
5104
- for (let i = errorIdx; i < normalized.length && collected.length < 8; i += 1) {
5105
- const ln = normalized[i];
5106
- 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)) {
5107
5116
  break;
5108
5117
  }
5109
- if (isStackLine(ln)) {
5118
+ if (!raw.trim()) {
5119
+ if (!started) {
5120
+ continue;
5121
+ }
5110
5122
  break;
5111
5123
  }
5112
- collected.push(ln);
5124
+ started = true;
5125
+ collected.push(raw);
5113
5126
  }
5114
5127
  }
5115
5128
  const fromDetails = collected.length > 0 ? [] : normalize2(details.messages).slice(0, 6);
@@ -5357,39 +5370,13 @@ var makeCtx = (opts, showStacks = false) => {
5357
5370
  return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
5358
5371
  };
5359
5372
 
5360
- // src/lib/formatter/bridge.ts
5373
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
5361
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
5362
5379
  var path10 = __toESM(require("node:path"), 1);
5363
- var import_json52 = __toESM(require_lib(), 1);
5364
- var colorTokens2 = {
5365
- pass: Colors.Success,
5366
- fail: Colors.Failure,
5367
- skip: Colors.Skip,
5368
- todo: Colors.Todo,
5369
- passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
5370
- failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
5371
- };
5372
- var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
5373
- var isObject = (candidateValue) => !!candidateValue && typeof candidateValue === "object";
5374
- var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
5375
- var summarizeUrl = (method, url, route) => {
5376
- const base = route || url || "";
5377
- const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
5378
- return [method || "", base, qs].filter(Boolean).join(" ").trim();
5379
- };
5380
- var stripBridgeEventsFromConsole = (maybeConsole) => {
5381
- if (!Array.isArray(maybeConsole)) {
5382
- return maybeConsole;
5383
- }
5384
- return maybeConsole.filter((entry) => {
5385
- try {
5386
- const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
5387
- return !raw.includes("[JEST-BRIDGE-EVENT]");
5388
- } catch {
5389
- return true;
5390
- }
5391
- });
5392
- };
5393
5380
  var extractBridgePath2 = (raw, cwd) => {
5394
5381
  const matches = Array.from(
5395
5382
  raw.matchAll(/Test results written to:\s+([^\n\r]+jest-bridge-[^\s'"]+\.json)/g)
@@ -5397,15 +5384,14 @@ var extractBridgePath2 = (raw, cwd) => {
5397
5384
  if (!matches.length) {
5398
5385
  return null;
5399
5386
  }
5400
- const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^["'`]|["'`]$/g, "");
5387
+ const jsonPath = (matches[matches.length - 1][1] ?? "").trim().replace(/^['"`]|['"`]$/g, "");
5401
5388
  return path10.isAbsolute(jsonPath) ? jsonPath : path10.resolve(cwd, jsonPath).replace(/\\/g, "/");
5402
5389
  };
5403
- var isTransportError = (msg) => {
5404
- const lowercaseMessage = (msg ?? "").toLowerCase();
5405
- return /\bsocket hang up\b|\beconnreset\b|\betimedout\b|\beconnrefused\b|\bwrite epipe\b/.test(
5406
- lowercaseMessage
5407
- );
5408
- };
5390
+
5391
+ // src/lib/formatter/bridge/utils.ts
5392
+ var import_json52 = __toESM(require_lib(), 1);
5393
+
5394
+ // src/lib/formatter/bridge/http.ts
5409
5395
  var envNumber = (name, fallback) => {
5410
5396
  const parsed = Number(process.env[name]);
5411
5397
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
@@ -5415,15 +5401,11 @@ var HEADLAMP_HTTP_STRICT_WINDOW_MS = () => envNumber("HEADLAMP_HTTP_STRICT_WINDO
5415
5401
  var HEADLAMP_HTTP_MIN_SCORE = () => envNumber("HEADLAMP_HTTP_MIN_SCORE", 1200);
5416
5402
  var HEADLAMP_HTTP_DIFF_LIMIT = () => envNumber("HEADLAMP_HTTP_DIFF_LIMIT", 6);
5417
5403
  var HEADLAMP_HTTP_SHOW_MISS = () => process.env.HEADLAMP_HTTP_MISS === "1";
5418
- var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
5419
- if (typeof ts !== "number" || !Number.isFinite(ts)) {
5420
- return [];
5421
- }
5422
- return http.filter((e) => {
5423
- const timeOk = typeof e.timestampMs === "number" && Math.abs(e.timestampMs - ts) <= windowMs;
5424
- const pathOk = !testPath || e.testPath === testPath;
5425
- return timeOk && pathOk;
5426
- });
5404
+ var asHttpList = (candidateValue) => Array.isArray(candidateValue) ? candidateValue : [];
5405
+ var summarizeUrl = (method, url, route) => {
5406
+ const base = route || url || "";
5407
+ const qs = url && url.includes("?") ? ` ? ${url.split("?")[1]}` : "";
5408
+ return [method || "", base, qs].filter(Boolean).join(" ").trim();
5427
5409
  };
5428
5410
  var parseMethodPathFromTitle = (title) => {
5429
5411
  if (!title) {
@@ -5432,19 +5414,17 @@ var parseMethodPathFromTitle = (title) => {
5432
5414
  const matchResult = title.match(/\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+([^\s)]+)/i);
5433
5415
  return matchResult ? { method: matchResult[1]?.toUpperCase(), path: matchResult[2] } : {};
5434
5416
  };
5435
- var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
5436
- var hasStatusSemantics = (assertionLike) => {
5437
- if (!assertionLike) {
5438
- return false;
5439
- }
5440
- if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
5441
- return true;
5417
+ var eventsNear = (http, ts, testPath, windowMs = HEADLAMP_HTTP_WINDOW_MS()) => {
5418
+ if (typeof ts !== "number" || !Number.isFinite(ts)) {
5419
+ return [];
5442
5420
  }
5443
- const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
5444
- const combinedMessage = combinedRaw.toLowerCase();
5445
- return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
5421
+ return http.filter((event) => {
5422
+ const timeOk = typeof event.timestampMs === "number" && Math.abs(event.timestampMs - ts) <= windowMs;
5423
+ const pathOk = !testPath || event.testPath === testPath;
5424
+ return timeOk && pathOk;
5425
+ });
5446
5426
  };
5447
- var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
5427
+ var isHttpStatusNumber = (statusNumber) => typeof statusNumber === "number" && statusNumber >= 100 && statusNumber <= 599;
5448
5428
  var inferHttpNumbersFromText = (lines) => {
5449
5429
  const text = lines.join("\n");
5450
5430
  const match = text.match(/Expected:\s*(\d{3})[\s\S]*?Received:\s*(\d{3})/i);
@@ -5457,10 +5437,19 @@ var titleSuggestsHttp = (title) => {
5457
5437
  const { method, path: parsedPath } = parseMethodPathFromTitle(title);
5458
5438
  return Boolean(method || parsedPath && parsedPath.startsWith("/"));
5459
5439
  };
5460
- var isHttpRelevant = (ctx) => {
5461
- const assertionCtx = ctx.assertion;
5462
- return ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(assertionCtx) || fileSuggestsHttp(ctx.relPath);
5440
+ var hasStatusSemantics = (assertionLike) => {
5441
+ if (!assertionLike) {
5442
+ return false;
5443
+ }
5444
+ if (isHttpStatusNumber(assertionLike.expectedNumber) || isHttpStatusNumber(assertionLike.receivedNumber)) {
5445
+ return true;
5446
+ }
5447
+ const combinedRaw = `${assertionLike.matcher ?? ""} ${assertionLike.message ?? ""}`;
5448
+ const combinedMessage = combinedRaw.toLowerCase();
5449
+ return /\bstatus(code)?\b|\btohaves(tatus|tatuscode)\b/.test(combinedMessage);
5463
5450
  };
5451
+ var fileSuggestsHttp = (relPath2) => /(?:^|\/)(routes?|api|controllers?|e2e|integration)(?:\/|\.test\.)/i.test(relPath2);
5452
+ var isHttpRelevant = (ctx) => ctx.hasTransportSignal || ctx.httpCountInSameTest > 0 || titleSuggestsHttp(ctx.title) || hasStatusSemantics(ctx.assertion) || fileSuggestsHttp(ctx.relPath);
5464
5453
  var routeSimilarityScore = (hint, evt) => {
5465
5454
  if (!hint.path && !hint.method) {
5466
5455
  return 0;
@@ -5481,6 +5470,12 @@ var routeSimilarityScore = (hint, evt) => {
5481
5470
  }
5482
5471
  return methodOk * 10;
5483
5472
  };
5473
+ var isTransportError = (msg) => {
5474
+ const lowercaseMessage = (msg ?? "").toLowerCase();
5475
+ return /\bsocket hang up\b|\beconnreset\b|\betimedout\b|\beconnrefused\b|\bwrite epipe\b/.test(
5476
+ lowercaseMessage
5477
+ );
5478
+ };
5484
5479
  var scoreHttpForAssertion = (assertion, titleHint) => (candidateEvent) => {
5485
5480
  const tsA = assertion.timestampMs;
5486
5481
  const tsH = candidateEvent.timestampMs;
@@ -5501,14 +5496,20 @@ var pickRelevantHttp = (assertion, http, ctx) => {
5501
5496
  const windowMs = isTransportError(assertion.message) ? HEADLAMP_HTTP_STRICT_WINDOW_MS() : HEADLAMP_HTTP_WINDOW_MS();
5502
5497
  let pool = strictPool;
5503
5498
  if (!pool.length) {
5504
- pool = http.filter(
5505
- (e) => e.testPath === ctx.testPath && typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
5506
- );
5499
+ pool = http.filter((event) => {
5500
+ const samePath = event.testPath === ctx.testPath;
5501
+ const tsA = assertion.timestampMs;
5502
+ const tsH = event.timestampMs;
5503
+ const inWindow = typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
5504
+ return samePath && inWindow;
5505
+ });
5507
5506
  }
5508
5507
  if (!pool.length) {
5509
- pool = http.filter(
5510
- (e) => typeof assertion.timestampMs === "number" && typeof e.timestampMs === "number" && Math.abs(e.timestampMs - assertion.timestampMs) <= windowMs
5511
- );
5508
+ pool = http.filter((event) => {
5509
+ const tsA = assertion.timestampMs;
5510
+ const tsH = event.timestampMs;
5511
+ return typeof tsA === "number" && typeof tsH === "number" && Math.abs(tsH - tsA) <= windowMs;
5512
+ });
5512
5513
  }
5513
5514
  if (!pool.length) {
5514
5515
  return void 0;
@@ -5518,9 +5519,390 @@ var pickRelevantHttp = (assertion, http, ctx) => {
5518
5519
  const threshold = isTransportError(assertion.message) ? Math.max(HEADLAMP_HTTP_MIN_SCORE(), 1400) : HEADLAMP_HTTP_MIN_SCORE();
5519
5520
  return best && best.s >= threshold ? best.h : void 0;
5520
5521
  };
5521
- var isBridgeJSONLike = (candidateValue) => !!candidateValue && typeof candidateValue === "object" && "aggregated" in candidateValue;
5522
+
5523
+ // src/lib/formatter/bridge/utils.ts
5524
+ var colorTokens2 = {
5525
+ pass: Colors.Success,
5526
+ fail: Colors.Failure,
5527
+ skip: Colors.Skip,
5528
+ todo: Colors.Todo,
5529
+ passPill: (text) => BackgroundColors.Success(ansi.white(` ${text} `)),
5530
+ failPill: (text) => BackgroundColors.Failure(ansi.white(` ${text} `))
5531
+ };
5532
+ var joinLines = (chunks) => chunks.join("\n");
5533
+ var empty = [];
5534
+ var concat = (...xs) => xs.flat();
5535
+ var by = (keySelector) => (left, right) => keySelector(left) - keySelector(right);
5536
+ var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
5537
+ var stripBridgeEventsFromConsole = (maybeConsole) => {
5538
+ if (!Array.isArray(maybeConsole)) {
5539
+ return maybeConsole;
5540
+ }
5541
+ return maybeConsole.filter((entry) => {
5542
+ try {
5543
+ const raw = Array.isArray(entry.message) ? entry.message.map(String).join(" ") : String(entry.message ?? "");
5544
+ return !raw.includes("[JEST-BRIDGE-EVENT]");
5545
+ } catch {
5546
+ return true;
5547
+ }
5548
+ });
5549
+ };
5550
+ var parseBridgeConsole = (consoleEntries) => {
5551
+ const http = [];
5552
+ const assertions = [];
5553
+ if (!Array.isArray(consoleEntries)) {
5554
+ return { http, assertions };
5555
+ }
5556
+ for (const entry of consoleEntries) {
5557
+ const rec = entry;
5558
+ const rawMsgVal = rec && typeof rec.message !== "undefined" ? rec.message : "";
5559
+ const raw = Array.isArray(rawMsgVal) ? rawMsgVal.map(String).join(" ") : String(rawMsgVal ?? "");
5560
+ if (!raw.includes("[JEST-BRIDGE-EVENT]")) {
5561
+ continue;
5562
+ }
5563
+ const jsonText = raw.split("[JEST-BRIDGE-EVENT]").pop()?.trim() ?? "";
5564
+ try {
5565
+ const evt = import_json52.default.parse(jsonText);
5566
+ const type = evt?.type;
5567
+ if (type === "httpResponse") {
5568
+ const timestampMs = Number(evt.timestampMs ?? Date.now());
5569
+ http.push({
5570
+ kind: "response",
5571
+ timestampMs,
5572
+ method: evt.method,
5573
+ url: evt.url,
5574
+ route: evt.route,
5575
+ statusCode: evt.statusCode,
5576
+ durationMs: evt.durationMs,
5577
+ contentType: evt.contentType,
5578
+ requestId: evt.requestId,
5579
+ json: evt.json,
5580
+ bodyPreview: evt.bodyPreview,
5581
+ testPath: evt.testPath,
5582
+ currentTestName: evt.currentTestName
5583
+ });
5584
+ } else if (type === "httpAbort") {
5585
+ http.push({
5586
+ kind: "abort",
5587
+ timestampMs: Number(evt.timestampMs ?? Date.now()),
5588
+ method: evt.method,
5589
+ url: evt.url,
5590
+ route: evt.route,
5591
+ durationMs: evt.durationMs,
5592
+ testPath: evt.testPath,
5593
+ currentTestName: evt.currentTestName
5594
+ });
5595
+ } else if (type === "httpResponseBatch") {
5596
+ const list = asHttpList(evt?.events);
5597
+ for (const item of list) {
5598
+ const anyItem = item;
5599
+ http.push({
5600
+ timestampMs: Number(anyItem.timestampMs ?? Date.now()),
5601
+ method: anyItem.method,
5602
+ url: anyItem.url,
5603
+ route: anyItem.route,
5604
+ statusCode: anyItem.statusCode,
5605
+ durationMs: anyItem.durationMs,
5606
+ contentType: anyItem.contentType,
5607
+ requestId: anyItem.requestId,
5608
+ json: anyItem.json,
5609
+ bodyPreview: anyItem.bodyPreview,
5610
+ testPath: evt.testPath,
5611
+ currentTestName: evt.currentTestName
5612
+ });
5613
+ }
5614
+ } else if (type === "assertionFailure") {
5615
+ assertions.push({
5616
+ timestampMs: typeof evt.timestampMs === "number" ? evt.timestampMs : void 0,
5617
+ matcher: evt.matcher,
5618
+ expectedNumber: typeof evt.expectedNumber === "number" ? evt.expectedNumber : void 0,
5619
+ receivedNumber: typeof evt.receivedNumber === "number" ? evt.receivedNumber : void 0,
5620
+ message: typeof evt.message === "string" ? evt.message : void 0,
5621
+ stack: typeof evt.stack === "string" ? evt.stack : void 0,
5622
+ testPath: evt.testPath,
5623
+ currentTestName: evt.currentTestName,
5624
+ expectedPreview: typeof evt.expectedPreview === "string" ? evt.expectedPreview : void 0,
5625
+ actualPreview: typeof evt.actualPreview === "string" ? evt.actualPreview : void 0
5626
+ });
5627
+ }
5628
+ } catch {
5629
+ }
5630
+ }
5631
+ return { http, assertions };
5632
+ };
5633
+ var renderRunHeader = ({ ctx, onlyFailures }) => onlyFailures ? empty : [`${BackgroundColors.Run(ansi.white(" RUN "))} ${ansi.dim(ctx.cwd)}`, ""];
5634
+ var renderPerFileOverviewBlock = (rel, testResults, onlyFailures) => onlyFailures ? empty : buildPerFileOverview(rel, testResults);
5635
+ var renderFileBadge = (rel, failedCount, onlyFailures) => onlyFailures && failedCount === 0 ? empty : [buildFileBadgeLine(rel, failedCount)];
5636
+ var condenseBlankRuns = (lines) => {
5637
+ const out = [];
5638
+ let lastBlank = false;
5639
+ for (const ln of lines) {
5640
+ const isBlank = !stripAnsiSimple(String(ln ?? "")).trim();
5641
+ if (isBlank) {
5642
+ if (!lastBlank) {
5643
+ out.push("");
5644
+ }
5645
+ lastBlank = true;
5646
+ } else {
5647
+ out.push(String(ln));
5648
+ lastBlank = false;
5649
+ }
5650
+ }
5651
+ return out;
5652
+ };
5653
+ var mergeMsgLines = (primaryRaw, detailMsgs) => {
5654
+ const primary = primaryRaw.trim() ? primaryRaw.split(/\r?\n/) : [];
5655
+ const key = (line) => stripAnsiSimple(line).trim();
5656
+ const seen = new Set(primary.map(key));
5657
+ const merged = [...primary];
5658
+ for (const msg of detailMsgs) {
5659
+ const msgKey = key(String(msg ?? ""));
5660
+ if (!msgKey) {
5661
+ continue;
5662
+ }
5663
+ if (!seen.has(msgKey)) {
5664
+ merged.push(msg);
5665
+ seen.add(msgKey);
5666
+ }
5667
+ }
5668
+ return condenseBlankRuns(merged);
5669
+ };
5670
+ var renderFileLevelFailure = (file, ctx) => {
5671
+ if (!(file.failureMessage || file.testExecError)) {
5672
+ return empty;
5673
+ }
5674
+ const base = linesFromDetails(file.failureDetails);
5675
+ const exec = linesFromDetails(
5676
+ Array.isArray(file.testExecError) ? file.testExecError : [file.testExecError]
5677
+ );
5678
+ const combinedDetails = {
5679
+ stacks: [...base.stacks, ...exec.stacks],
5680
+ messages: [...base.messages, ...exec.messages]
5681
+ };
5682
+ const msgLines = mergeMsgLines(file.failureMessage || "", combinedDetails.messages);
5683
+ const mergedForStack = collapseStacks([...msgLines, ...combinedDetails.stacks]);
5684
+ const synthLoc = deepestProjectLoc(mergedForStack, ctx.projectHint);
5685
+ const stackPreview = ctx.showStacks ? mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).filter((ln) => ctx.projectHint.test(stripAnsiSimple(ln))).slice(0, 2).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`) : [];
5686
+ const code = buildCodeFrameSection(msgLines, ctx, synthLoc);
5687
+ const pretty = buildPrettyDiffSection(file.failureDetails, msgLines);
5688
+ const message = buildMessageSection(msgLines, combinedDetails, ctx, {
5689
+ suppressDiff: pretty.length > 0,
5690
+ stackPreview
5691
+ });
5692
+ const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null));
5693
+ const stackTail = ctx.showStacks && stackPreview.length === 0 ? (() => {
5694
+ const tail = mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
5695
+ return tail.length ? [ansi.dim(" Stack:"), ...tail, ""] : empty;
5696
+ })() : empty;
5697
+ return concat(code, pretty, message, consoleBlock, stackTail);
5698
+ };
5699
+ var renderHttpCard = (args) => {
5700
+ const { file, relPath: rel, assertion, assertionEvents, httpSorted } = args;
5701
+ const nameMatches = (left, right) => !!left && !!right && (left === right || left.includes(right) || right.includes(left));
5702
+ const inSameCtx = (testPath, testName) => httpSorted.filter(
5703
+ (event) => event.testPath === testPath && nameMatches(event.currentTestName, testName)
5704
+ );
5705
+ const perTestSlice = inSameCtx(file.testFilePath, assertion.fullName);
5706
+ const corresponding = assertionEvents.find(
5707
+ (event) => event.testPath === file.testFilePath && nameMatches(event.currentTestName, assertion.fullName)
5708
+ ) ?? assertion;
5709
+ const nearByTime = eventsNear(
5710
+ httpSorted,
5711
+ corresponding?.timestampMs,
5712
+ file.testFilePath
5713
+ );
5714
+ const hasAbort = perTestSlice.some((event) => event.kind === "abort");
5715
+ const hasTransport = isTransportError(corresponding?.message) || hasAbort;
5716
+ const httpLikely = isHttpRelevant({
5717
+ assertion: corresponding,
5718
+ title: assertion.fullName,
5719
+ relPath: rel,
5720
+ httpCountInSameTest: perTestSlice.length || nearByTime.length,
5721
+ hasTransportSignal: hasTransport
5722
+ });
5723
+ if (!httpLikely) {
5724
+ return empty;
5725
+ }
5726
+ const HEADLAMP_HTTP_DIFF_LIMIT_LOCAL = () => HEADLAMP_HTTP_DIFF_LIMIT();
5727
+ const safeParseJSON = (text) => {
5728
+ try {
5729
+ return text ? import_json52.default.parse(text) : void 0;
5730
+ } catch {
5731
+ return void 0;
5732
+ }
5733
+ };
5734
+ const expPreview = corresponding?.expectedPreview;
5735
+ const actPreview = corresponding?.actualPreview;
5736
+ const parsedExpected = safeParseJSON(expPreview);
5737
+ const parsedActual = safeParseJSON(actPreview);
5738
+ let corr = corresponding;
5739
+ if (!isHttpStatusNumber(corr.expectedNumber) && !isHttpStatusNumber(corr.receivedNumber)) {
5740
+ const inferred = inferHttpNumbersFromText(
5741
+ (assertion.failureMessages?.join("\n") || file.failureMessage || "").split("\n")
5742
+ );
5743
+ if (isHttpStatusNumber(inferred.expectedNumber) || isHttpStatusNumber(inferred.receivedNumber)) {
5744
+ corr = { ...corr, ...inferred };
5745
+ }
5746
+ }
5747
+ const relevant = pickRelevantHttp(
5748
+ {
5749
+ timestampMs: corr?.timestampMs,
5750
+ expectedNumber: corr?.expectedNumber,
5751
+ receivedNumber: corr?.receivedNumber,
5752
+ matcher: corr?.matcher,
5753
+ message: corr?.message,
5754
+ stack: corr?.stack,
5755
+ testPath: file.testFilePath,
5756
+ currentTestName: assertion.title
5757
+ },
5758
+ httpSorted,
5759
+ {
5760
+ testPath: file.testFilePath,
5761
+ currentTestName: assertion.fullName,
5762
+ title: assertion.fullName
5763
+ }
5764
+ );
5765
+ if (hasTransport) {
5766
+ const tsBase = corr?.timestampMs ?? 0;
5767
+ const [nearestAbort] = perTestSlice.filter((event) => event.kind === "abort").sort(
5768
+ (left, right) => Math.abs(tsBase - (left.timestampMs ?? 0)) - Math.abs(tsBase - (right.timestampMs ?? 0))
5769
+ );
5770
+ if (nearestAbort) {
5771
+ const ms = nearestAbort.durationMs;
5772
+ return [
5773
+ " HTTP:",
5774
+ `
5775
+ ${summarizeUrl(nearestAbort.method, nearestAbort.url, nearestAbort.route)} ${ansi.dim("->")} ${ansi.yellow("connection aborted")}`,
5776
+ ms != null ? ` ${ansi.dim(`(${ms}ms)`)} ` : "",
5777
+ "\n"
5778
+ ];
5779
+ }
5780
+ return HEADLAMP_HTTP_SHOW_MISS() ? [
5781
+ " HTTP:",
5782
+ `
5783
+ ${ansi.dim("Transport error; no matching HTTP exchange in window.")}`,
5784
+ "\n"
5785
+ ] : empty;
5786
+ }
5787
+ if (!relevant) {
5788
+ return HEADLAMP_HTTP_SHOW_MISS() ? [
5789
+ " HTTP:",
5790
+ `
5791
+ ${ansi.dim("No relevant HTTP exchange found. (HEADLAMP_HTTP_MISS=0 to hide)")}`,
5792
+ "\n"
5793
+ ] : empty;
5794
+ }
5795
+ const jsonDiff = (expected, actual, limit = HEADLAMP_HTTP_DIFF_LIMIT_LOCAL()) => {
5796
+ const out = [];
5797
+ const queue = [
5798
+ { pathSoFar: "$", expectedValue: expected, actualValue: actual }
5799
+ ];
5800
+ while (queue.length && out.length < limit) {
5801
+ const { pathSoFar, expectedValue, actualValue } = queue.shift();
5802
+ const expectedIsObject = expectedValue && typeof expectedValue === "object";
5803
+ const actualIsObject = actualValue && typeof actualValue === "object";
5804
+ if (!expectedIsObject && !actualIsObject) {
5805
+ if (JSON.stringify(expectedValue) !== JSON.stringify(actualValue)) {
5806
+ out.push({
5807
+ kind: "changed",
5808
+ path: pathSoFar,
5809
+ preview: `${String(expectedValue)} \u2192 ${String(actualValue)}`
5810
+ });
5811
+ }
5812
+ } else if (expectedIsObject && !actualIsObject) {
5813
+ out.push({ kind: "changed", path: pathSoFar, preview: "[object] \u2192 primitive" });
5814
+ } else if (!expectedIsObject && actualIsObject) {
5815
+ out.push({ kind: "changed", path: pathSoFar, preview: "primitive \u2192 [object]" });
5816
+ } else {
5817
+ const expectedKeys = new Set(Object.keys(expectedValue));
5818
+ const actualKeys = new Set(Object.keys(actualValue));
5819
+ for (const key of expectedKeys) {
5820
+ if (!actualKeys.has(key) && out.length < limit) {
5821
+ out.push({ kind: "removed", path: `${pathSoFar}.${key}` });
5822
+ }
5823
+ }
5824
+ for (const key of actualKeys) {
5825
+ if (!expectedKeys.has(key) && out.length < limit) {
5826
+ out.push({ kind: "added", path: `${pathSoFar}.${key}` });
5827
+ }
5828
+ }
5829
+ for (const key of expectedKeys) {
5830
+ if (actualKeys.has(key) && out.length < limit) {
5831
+ queue.push({
5832
+ pathSoFar: `${pathSoFar}.${key}`,
5833
+ expectedValue: expectedValue[key],
5834
+ actualValue: actualValue[key]
5835
+ });
5836
+ }
5837
+ }
5838
+ }
5839
+ }
5840
+ return out;
5841
+ };
5842
+ const importantMessages = (json) => {
5843
+ const msgs = [];
5844
+ try {
5845
+ const obj = isObject(json) ? json : {};
5846
+ const push = (msg) => {
5847
+ if (typeof msg === "string" && msg.trim()) {
5848
+ msgs.push(msg);
5849
+ }
5850
+ };
5851
+ push(obj.displayMessage);
5852
+ push(obj.message);
5853
+ if (Array.isArray(obj.errors)) {
5854
+ for (const event of obj.errors) {
5855
+ push(isObject(event) ? event.message : void 0);
5856
+ }
5857
+ }
5858
+ if (Array.isArray(obj.data)) {
5859
+ for (const event of obj.data) {
5860
+ push(isObject(event) ? event.message : void 0);
5861
+ }
5862
+ }
5863
+ } catch {
5864
+ }
5865
+ return msgs.slice(0, 2);
5866
+ };
5867
+ const where = summarizeUrl(relevant.method, relevant.url, relevant.route);
5868
+ const header = [
5869
+ " HTTP:",
5870
+ `
5871
+ ${where} ${ansi.dim("->")} ${relevant.statusCode ?? "?"}`,
5872
+ typeof relevant.durationMs === "number" ? ` ${ansi.dim(`(${relevant.durationMs}ms)`)} ` : " ",
5873
+ relevant.contentType ? ansi.dim(`(${relevant.contentType})`) : "",
5874
+ relevant.requestId ? ansi.dim(` reqId=${relevant.requestId}`) : ""
5875
+ ].join("");
5876
+ const expVsAct = typeof corr?.expectedNumber === "number" || typeof corr?.receivedNumber === "number" ? (() => {
5877
+ const exp = corr?.expectedNumber != null ? String(corr.expectedNumber) : "?";
5878
+ const got = corr?.receivedNumber != null ? String(corr.receivedNumber) : String(relevant.statusCode ?? "?");
5879
+ return `
5880
+ Expected: ${ansi.yellow(exp)} Received: ${ansi.yellow(got)}`;
5881
+ })() : "";
5882
+ const why = importantMessages(parsedActual ?? relevant.json).map((msg) => `
5883
+ Why: ${ansi.white(msg)}`).slice(0, 1).join("") || "";
5884
+ const diff = (() => {
5885
+ const rightActual = parsedActual ?? relevant.json;
5886
+ if (!parsedExpected || !rightActual) {
5887
+ return "";
5888
+ }
5889
+ const changes = jsonDiff(parsedExpected, rightActual);
5890
+ if (!changes.length) {
5891
+ return "";
5892
+ }
5893
+ const body = changes.map((change) => {
5894
+ const marker = change.kind === "added" ? "+" : change.kind === "removed" ? "-" : "~";
5895
+ const preview = change.preview ? `: ${ansi.dim(change.preview)}` : "";
5896
+ return `
5897
+ ${marker} ${change.path}${preview}`;
5898
+ }).join("");
5899
+ return `
5900
+ Diff:${body}`;
5901
+ })();
5902
+ return [header, expVsAct, why, diff, "\n"].filter(Boolean);
5903
+ };
5522
5904
  var coerceJestJsonToBridge = (raw) => {
5523
- if (isBridgeJSONLike(raw)) {
5905
+ if (raw && typeof raw === "object" && "aggregated" in raw) {
5524
5906
  return raw;
5525
5907
  }
5526
5908
  const j = raw;
@@ -5547,19 +5929,113 @@ var coerceJestJsonToBridge = (raw) => {
5547
5929
  }))
5548
5930
  })),
5549
5931
  aggregated: {
5550
- numTotalTestSuites: j.numTotalTestSuites,
5551
- numPassedTestSuites: j.numPassedTestSuites,
5552
- numFailedTestSuites: j.numFailedTestSuites,
5553
- numTotalTests: j.numTotalTests,
5554
- numPassedTests: j.numPassedTests,
5555
- numFailedTests: j.numFailedTests,
5556
- numPendingTests: j.numPendingTests,
5557
- numTodoTests: j.numTodoTests,
5558
- startTime: j.startTime,
5559
- success: j.success
5932
+ numTotalTestSuites: raw.numTotalTestSuites,
5933
+ numPassedTestSuites: raw.numPassedTestSuites,
5934
+ numFailedTestSuites: raw.numFailedTestSuites,
5935
+ numTotalTests: raw.numTotalTests,
5936
+ numPassedTests: raw.numPassedTests,
5937
+ numFailedTests: raw.numFailedTests,
5938
+ numPendingTests: raw.numPendingTests,
5939
+ numTodoTests: raw.numTodoTests,
5940
+ startTime: raw.startTime,
5941
+ success: raw.success,
5942
+ runTimeMs: raw.aggregated?.runTimeMs
5560
5943
  }
5561
5944
  };
5562
5945
  };
5946
+ var renderFailedAssertion = (args) => {
5947
+ const { file, relPath: rel, assertion, ctx, assertionEvents, httpSorted } = args;
5948
+ const header = `${rel} > ${assertion.fullName}`;
5949
+ const bullet = (text) => `${Colors.Failure("\xD7")} ${ansi.white(text)}`;
5950
+ const failureMessage = file.failureMessage || "";
5951
+ const detailMsgs = linesFromDetails(assertion.failureDetails || file.failureDetails).messages;
5952
+ const primaryBlock = assertion.failureMessages?.length ? assertion.failureMessages.join("\n") : failureMessage;
5953
+ const messagesArray = mergeMsgLines(primaryBlock, detailMsgs);
5954
+ const details = linesFromDetails(assertion.failureDetails || file.failureDetails);
5955
+ const mergedForStack = collapseStacks([...messagesArray, ...details.stacks]);
5956
+ const deepestLoc = deepestProjectLoc(mergedForStack, ctx.projectHint);
5957
+ const locLink = deepestLoc ? (() => {
5958
+ const href = preferredEditorHref(deepestLoc.file, deepestLoc.line, ctx.editorCmd);
5959
+ const base = `${deepestLoc.file.split("/").pop()}:${deepestLoc.line}`;
5960
+ return osc8(base, href);
5961
+ })() : void 0;
5962
+ const headerLine = `${ansi.white(header)}${locLink ? ` ${ansi.dim(`(${locLink})`)}` : ""}`;
5963
+ const msgLines = messagesArray.join("\n").split("\n");
5964
+ const assertFallback = deepestLoc || assertion.location && { file: file.testFilePath, line: assertion.location.line };
5965
+ const matcherMsg = (() => {
5966
+ try {
5967
+ const arr = assertion.failureDetails || file.failureDetails;
5968
+ if (!arr) {
5969
+ return empty;
5970
+ }
5971
+ for (const detailEntry of arr) {
5972
+ const obj = detailEntry && typeof detailEntry === "object" ? detailEntry : null;
5973
+ const mr = obj && obj.matcherResult && typeof obj.matcherResult === "object" ? obj.matcherResult : null;
5974
+ if (mr && typeof mr.message === "string" && mr.message.trim()) {
5975
+ const name = typeof mr.matcherName === "string" ? mr.matcherName : "";
5976
+ const matcherHeader = name ? ` ${ansi.bold("Matcher:")} ${ansi.yellow(name)}` : "";
5977
+ const bodyHeader = ` ${ansi.bold("Message:")}`;
5978
+ const body = String(mr.message).split(/\r?\n/).slice(0, 6).map((ln) => ` ${ansi.yellow(ln)}`);
5979
+ return [matcherHeader, bodyHeader, ...body, ""].filter(Boolean);
5980
+ }
5981
+ }
5982
+ } catch {
5983
+ }
5984
+ return empty;
5985
+ })();
5986
+ const code = concat(
5987
+ ["", drawFailLine(), bullet(headerLine), ""],
5988
+ buildCodeFrameSection(msgLines, ctx, assertFallback || void 0),
5989
+ [""]
5990
+ );
5991
+ const pretty = buildPrettyDiffSection(assertion.failureDetails || file.failureDetails, msgLines);
5992
+ const hasPretty = pretty.length > 0;
5993
+ const stackPreview = ctx.showStacks ? mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).filter((ln) => ctx.projectHint.test(stripAnsiSimple(ln))).slice(0, 2).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`) : [];
5994
+ const message = buildMessageSection(msgLines, details, ctx, {
5995
+ suppressDiff: hasPretty,
5996
+ stackPreview
5997
+ });
5998
+ const httpCard = renderHttpCard({ file, relPath: rel, assertion, assertionEvents, httpSorted });
5999
+ const minimalInfo = msgLines.every((ln) => !ln.trim());
6000
+ const thrown = minimalInfo ? (() => {
6001
+ try {
6002
+ return buildThrownSection(assertion.failureDetails || []);
6003
+ } catch {
6004
+ return empty;
6005
+ }
6006
+ })() : empty;
6007
+ const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null));
6008
+ const stackTail = ctx.showStacks && stackPreview.length === 0 ? (() => {
6009
+ const merged = collapseStacks([...msgLines, ...details.stacks]);
6010
+ const tail = collapseStacks(merged).filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
6011
+ return tail.length ? [ansi.dim(" Stack:"), ...tail, ""] : empty;
6012
+ })() : empty;
6013
+ return concat(code, pretty, matcherMsg, message, httpCard, thrown, consoleBlock, stackTail, [
6014
+ drawFailLine(),
6015
+ ""
6016
+ ]);
6017
+ };
6018
+ var renderFileBlock = (file, env) => {
6019
+ const rel = file.testFilePath.replace(/\\/g, "/").replace(`${env.ctx.cwd}/`, "");
6020
+ const failed = file.testResults.filter((assertion) => assertion.status === "failed");
6021
+ const { http, assertions } = parseBridgeConsole(file.console);
6022
+ const httpSorted = [...http].sort(by((event) => event.timestampMs));
6023
+ return concat(
6024
+ renderPerFileOverviewBlock(rel, file.testResults, env.onlyFailures),
6025
+ renderFileBadge(rel, failed.length, env.onlyFailures),
6026
+ renderFileLevelFailure(file, env.ctx),
6027
+ ...failed.map(
6028
+ (assertion) => renderFailedAssertion({
6029
+ file,
6030
+ relPath: rel,
6031
+ assertion,
6032
+ ctx: env.ctx,
6033
+ assertionEvents: assertions,
6034
+ httpSorted
6035
+ })
6036
+ )
6037
+ );
6038
+ };
5563
6039
  var vitestFooter = (agg, durationMs) => {
5564
6040
  const files = [
5565
6041
  agg.numFailedTestSuites ? colorTokens2.fail(`${agg.numFailedTestSuites} failed`) : "",
@@ -5580,469 +6056,39 @@ var vitestFooter = (agg, durationMs) => {
5580
6056
  `${ansi.bold("Time")} ${time} ${thread}`
5581
6057
  ].join("\n");
5582
6058
  };
5583
- var renderVitestFromJestJSON = (data, ctx, opts) => {
5584
- const out = [];
5585
- const onlyFailures = Boolean(opts?.onlyFailures);
5586
- if (!onlyFailures) {
5587
- out.push(`${BackgroundColors.Run(ansi.white(" RUN "))} ${ansi.dim(ctx.cwd)}`, "");
5588
- }
5589
- for (const file of data.testResults) {
5590
- const rel = file.testFilePath.replace(/\\/g, "/").replace(`${ctx.cwd}/`, "");
5591
- const failed = file.testResults.filter((assertion) => assertion.status === "failed");
5592
- if (!onlyFailures) {
5593
- out.push(...buildPerFileOverview(rel, file.testResults));
5594
- }
5595
- if (!(onlyFailures && failed.length === 0)) {
5596
- out.push(buildFileBadgeLine(rel, failed.length));
5597
- }
5598
- let httpSorted = [];
5599
- let assertionEvents = [];
5600
- {
5601
- const parseBridge = (consoleEntries) => {
5602
- const http = [];
5603
- const assertions = [];
5604
- if (!Array.isArray(consoleEntries)) {
5605
- return { http, assertions };
5606
- }
5607
- for (const entry of consoleEntries) {
5608
- const rec = entry;
5609
- const rawMsgVal = rec && typeof rec.message !== "undefined" ? rec.message : "";
5610
- const raw = Array.isArray(rawMsgVal) ? rawMsgVal.map(String).join(" ") : String(rawMsgVal ?? "");
5611
- if (!raw.includes("[JEST-BRIDGE-EVENT]")) {
5612
- continue;
5613
- }
5614
- const jsonText = raw.split("[JEST-BRIDGE-EVENT]").pop()?.trim() ?? "";
5615
- try {
5616
- const evt = import_json52.default.parse(jsonText);
5617
- const type = evt?.type;
5618
- if (type === "httpResponse") {
5619
- const timestampMs = Number(evt.timestampMs ?? Date.now());
5620
- http.push({
5621
- kind: "response",
5622
- timestampMs,
5623
- method: evt.method,
5624
- url: evt.url,
5625
- route: evt.route,
5626
- statusCode: evt.statusCode,
5627
- durationMs: evt.durationMs,
5628
- contentType: evt.contentType,
5629
- requestId: evt.requestId,
5630
- json: evt.json,
5631
- bodyPreview: evt.bodyPreview,
5632
- testPath: evt.testPath,
5633
- currentTestName: evt.currentTestName
5634
- });
5635
- } else if (type === "httpAbort") {
5636
- http.push({
5637
- kind: "abort",
5638
- timestampMs: Number(evt.timestampMs ?? Date.now()),
5639
- method: evt.method,
5640
- url: evt.url,
5641
- route: evt.route,
5642
- durationMs: evt.durationMs,
5643
- testPath: evt.testPath,
5644
- currentTestName: evt.currentTestName
5645
- });
5646
- } else if (type === "httpResponseBatch") {
5647
- const list = asHttpList(evt?.events);
5648
- for (const item of list) {
5649
- const anyItem = item;
5650
- http.push({
5651
- timestampMs: Number(anyItem.timestampMs ?? Date.now()),
5652
- method: anyItem.method,
5653
- url: anyItem.url,
5654
- route: anyItem.route,
5655
- statusCode: anyItem.statusCode,
5656
- durationMs: anyItem.durationMs,
5657
- contentType: anyItem.contentType,
5658
- requestId: anyItem.requestId,
5659
- json: anyItem.json,
5660
- bodyPreview: anyItem.bodyPreview,
5661
- testPath: evt.testPath,
5662
- currentTestName: evt.currentTestName
5663
- });
5664
- }
5665
- } else if (type === "assertionFailure") {
5666
- assertions.push({
5667
- timestampMs: typeof evt.timestampMs === "number" ? evt.timestampMs : void 0,
5668
- matcher: evt.matcher,
5669
- expectedNumber: typeof evt.expectedNumber === "number" ? evt.expectedNumber : void 0,
5670
- receivedNumber: typeof evt.receivedNumber === "number" ? evt.receivedNumber : void 0,
5671
- message: typeof evt.message === "string" ? evt.message : void 0,
5672
- stack: typeof evt.stack === "string" ? evt.stack : void 0,
5673
- testPath: evt.testPath,
5674
- currentTestName: evt.currentTestName,
5675
- expectedPreview: typeof evt.expectedPreview === "string" ? evt.expectedPreview : void 0,
5676
- actualPreview: typeof evt.actualPreview === "string" ? evt.actualPreview : void 0
5677
- });
5678
- }
5679
- } catch {
5680
- }
5681
- }
5682
- return { http, assertions };
5683
- };
5684
- const parsed = parseBridge(file.console);
5685
- httpSorted = [...parsed.http].sort(by((event) => event.timestampMs));
5686
- assertionEvents = parsed.assertions;
5687
- }
5688
- const inSameCtx = (testPath, testName) => httpSorted.filter(
5689
- (event) => event.testPath === testPath && event.currentTestName === testName
5690
- );
5691
- if (file.failureMessage || file.testExecError) {
5692
- const lines = file.failureMessage.split(/\r?\n/);
5693
- const combinedDetails = (() => {
5694
- const base = linesFromDetails(file.failureDetails);
5695
- const exec = linesFromDetails(
5696
- Array.isArray(file.testExecError) ? file.testExecError : [file.testExecError]
5697
- );
5698
- return {
5699
- stacks: [...base.stacks, ...exec.stacks],
5700
- messages: [...base.messages, ...exec.messages]
5701
- };
5702
- })();
5703
- const mergedForStack = collapseStacks([...lines, ...combinedDetails.stacks]);
5704
- const synthLoc = deepestProjectLoc(mergedForStack, ctx.projectHint);
5705
- out.push(...buildCodeFrameSection(lines, ctx, synthLoc));
5706
- const payloadPretty = buildPrettyDiffSection(file.failureDetails, lines);
5707
- out.push(...payloadPretty);
5708
- const hasPretty = payloadPretty.length > 0;
5709
- const stackPreview = ctx.showStacks ? mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).filter((ln) => ctx.projectHint.test(stripAnsiSimple(ln))).slice(0, 2).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`) : [];
5710
- out.push(
5711
- ...buildMessageSection(lines, combinedDetails, ctx, {
5712
- suppressDiff: hasPretty,
5713
- stackPreview
5714
- })
5715
- );
5716
- out.push(...buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null)));
5717
- if (ctx.showStacks && stackPreview.length === 0) {
5718
- const tail = mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
5719
- if (tail.length) {
5720
- out.push(ansi.dim(" Stack:"), ...tail, "");
5721
- }
5722
- }
5723
- }
5724
- for (const assertion of failed) {
5725
- out.push(drawFailLine());
5726
- const header = `${rel} > ${assertion.fullName}`;
5727
- const messagesArray = (() => {
5728
- if (assertion.failureMessages && assertion.failureMessages.length > 0) {
5729
- return assertion.failureMessages;
5730
- }
5731
- if (file.failureMessage && file.failureMessage.trim().length > 0) {
5732
- return file.failureMessage.split(/\r?\n/);
5733
- }
5734
- const linesFromMatcher = linesFromDetails(
5735
- assertion.failureDetails || file.failureDetails
5736
- ).messages;
5737
- if (Array.isArray(linesFromMatcher) && linesFromMatcher.length > 0) {
5738
- return linesFromMatcher;
5739
- }
5740
- return [""];
5741
- })();
5742
- const details = linesFromDetails(assertion.failureDetails || file.failureDetails);
5743
- const matcherMsg = (() => {
5744
- try {
5745
- const arr = assertion.failureDetails || file.failureDetails;
5746
- if (!arr) {
5747
- return [];
5748
- }
5749
- for (const detailEntry of arr) {
5750
- const obj = detailEntry && typeof detailEntry === "object" ? detailEntry : null;
5751
- const mr = obj && obj.matcherResult && typeof obj.matcherResult === "object" ? obj.matcherResult : null;
5752
- if (mr && typeof mr.message === "string" && mr.message.trim()) {
5753
- const name = typeof mr.matcherName === "string" ? mr.matcherName : "";
5754
- const matcherHeader = name ? ` ${ansi.bold("Matcher:")} ${ansi.yellow(name)}` : "";
5755
- const bodyHeader = ` ${ansi.bold("Message:")}`;
5756
- const body = String(mr.message).split(/\r?\n/).slice(0, 6).map((ln) => ` ${ansi.yellow(ln)}`);
5757
- return [matcherHeader, bodyHeader, ...body, ""].filter(Boolean);
5758
- }
5759
- }
5760
- } catch {
5761
- }
5762
- return [];
5763
- })();
5764
- const mergedForStack = collapseStacks([...messagesArray, ...details.stacks]);
5765
- const deepestLoc = deepestProjectLoc(mergedForStack, ctx.projectHint);
5766
- const locLink = deepestLoc ? (() => {
5767
- const href = preferredEditorHref(deepestLoc.file, deepestLoc.line, ctx.editorCmd);
5768
- const base = `${deepestLoc.file.split("/").pop()}:${deepestLoc.line}`;
5769
- return osc8(base, href);
5770
- })() : void 0;
5771
- const bullet = (text) => `${Colors.Failure("\xD7")} ${ansi.white(text)}`;
5772
- const headerLine = `${ansi.white(header)}${locLink ? ` ${ansi.dim(`(${locLink})`)}` : ""}`;
5773
- out.push(bullet(headerLine));
5774
- const msgLines = messagesArray.join("\n").split("\n");
5775
- const assertFallback = deepestLoc || assertion.location && { file: file.testFilePath, line: assertion.location.line };
5776
- out.push("", ...buildCodeFrameSection(msgLines, ctx, assertFallback || void 0), "");
5777
- const pretty = buildPrettyDiffSection(
5778
- assertion.failureDetails || file.failureDetails,
5779
- msgLines
5780
- );
5781
- out.push(...pretty);
5782
- const hasPretty = pretty.length > 0;
5783
- const stackPreview = ctx.showStacks ? mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).filter((ln) => ctx.projectHint.test(stripAnsiSimple(ln))).slice(0, 2).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`) : [];
5784
- if (matcherMsg.length) {
5785
- out.push(...matcherMsg);
5786
- }
5787
- out.push(
5788
- ...buildMessageSection(msgLines, details, ctx, { suppressDiff: hasPretty, stackPreview })
5789
- );
5790
- {
5791
- const HEADLAMP_HTTP_DIFF_LIMIT_LOCAL = () => HEADLAMP_HTTP_DIFF_LIMIT();
5792
- const safeParseJSON = (text) => {
5793
- try {
5794
- return text ? import_json52.default.parse(text) : void 0;
5795
- } catch {
5796
- return void 0;
5797
- }
5798
- };
5799
- const jsonDiff = (expected, actual, limit = HEADLAMP_HTTP_DIFF_LIMIT_LOCAL()) => {
5800
- const outChanges = [];
5801
- const queue = [];
5802
- queue.push({
5803
- pathSoFar: "$",
5804
- expectedValue: expected,
5805
- actualValue: actual
5806
- });
5807
- while (queue.length && outChanges.length < limit) {
5808
- const { pathSoFar, expectedValue, actualValue } = queue.shift();
5809
- const expectedIsObj = expectedValue && typeof expectedValue === "object";
5810
- const actualIsObj = actualValue && typeof actualValue === "object";
5811
- if (!expectedIsObj && !actualIsObj) {
5812
- if (JSON.stringify(expectedValue) !== JSON.stringify(actualValue)) {
5813
- outChanges.push({
5814
- kind: "changed",
5815
- path: pathSoFar,
5816
- preview: `${String(expectedValue)} \u2192 ${String(actualValue)}`
5817
- });
5818
- }
5819
- } else if (expectedIsObj && !actualIsObj) {
5820
- outChanges.push({
5821
- kind: "changed",
5822
- path: pathSoFar,
5823
- preview: "[object] \u2192 primitive"
5824
- });
5825
- } else if (!expectedIsObj && actualIsObj) {
5826
- outChanges.push({
5827
- kind: "changed",
5828
- path: pathSoFar,
5829
- preview: "primitive \u2192 [object]"
5830
- });
5831
- } else {
5832
- const expectedKeys = new Set(Object.keys(expectedValue));
5833
- const actualKeys = new Set(Object.keys(actualValue));
5834
- for (const key of expectedKeys) {
5835
- if (!actualKeys.has(key) && outChanges.length < limit) {
5836
- outChanges.push({ kind: "removed", path: `${pathSoFar}.${key}` });
5837
- }
5838
- }
5839
- for (const key of actualKeys) {
5840
- if (!expectedKeys.has(key) && outChanges.length < limit) {
5841
- outChanges.push({ kind: "added", path: `${pathSoFar}.${key}` });
5842
- }
5843
- }
5844
- for (const key of expectedKeys) {
5845
- if (actualKeys.has(key) && outChanges.length < limit) {
5846
- queue.push({
5847
- pathSoFar: `${pathSoFar}.${key}`,
5848
- expectedValue: expectedValue[key],
5849
- actualValue: actualValue[key]
5850
- });
5851
- }
5852
- }
5853
- }
5854
- }
5855
- return outChanges;
5856
- };
5857
- const importantMessages = (json) => {
5858
- const msgs = [];
5859
- try {
5860
- const obj = isObject(json) ? json : {};
5861
- const pushMaybe = (candidate) => {
5862
- if (typeof candidate === "string" && candidate.trim()) {
5863
- msgs.push(candidate);
5864
- }
5865
- };
5866
- pushMaybe(obj.displayMessage);
5867
- pushMaybe(obj.message);
5868
- if (Array.isArray(obj.errors)) {
5869
- for (const element of obj.errors) {
5870
- pushMaybe(isObject(element) ? element.message : void 0);
5871
- }
5872
- }
5873
- if (Array.isArray(obj.data)) {
5874
- for (const element of obj.data) {
5875
- pushMaybe(isObject(element) ? element.message : void 0);
5876
- }
5877
- }
5878
- } catch {
5879
- }
5880
- return msgs.slice(0, 2);
5881
- };
5882
- const nameMatches = (leftName, rightName) => !!leftName && !!rightName && (leftName === rightName || leftName.includes(rightName) || rightName.includes(leftName));
5883
- const corresponding = assertionEvents.find(
5884
- (aevt) => aevt.testPath === file.testFilePath && nameMatches(aevt.currentTestName, assertion.title)
5885
- ) ?? assertion;
5886
- const perTestSlice = inSameCtx(file.testFilePath, assertion.title);
5887
- const nearByTime = eventsNear(
5888
- httpSorted,
5889
- corresponding?.timestampMs,
5890
- file.testFilePath
5891
- );
5892
- const hasAbort = perTestSlice.some((event) => event.kind === "abort");
5893
- const hasTransport = isTransportError(corresponding?.message) || hasAbort;
5894
- const httpLikely = isHttpRelevant({
5895
- assertion: corresponding,
5896
- title: assertion.fullName,
5897
- relPath: rel,
5898
- httpCountInSameTest: perTestSlice.length || nearByTime.length,
5899
- hasTransportSignal: hasTransport
5900
- });
5901
- if (!httpLikely) {
5902
- } else {
5903
- const expPreview = corresponding?.expectedPreview;
5904
- const actPreview = corresponding?.actualPreview;
5905
- const parsedExpected = safeParseJSON(expPreview);
5906
- const parsedActual = safeParseJSON(actPreview);
5907
- let corr = corresponding;
5908
- if (!isHttpStatusNumber(corr.expectedNumber) && !isHttpStatusNumber(corr.receivedNumber)) {
5909
- const inferred = inferHttpNumbersFromText(msgLines);
5910
- if (isHttpStatusNumber(inferred.expectedNumber) || isHttpStatusNumber(inferred.receivedNumber)) {
5911
- corr = { ...corr, ...inferred };
5912
- }
5913
- }
5914
- const relevant = pickRelevantHttp(
5915
- {
5916
- timestampMs: corr?.timestampMs,
5917
- expectedNumber: corr?.expectedNumber,
5918
- receivedNumber: corr?.receivedNumber,
5919
- matcher: corr?.matcher,
5920
- message: corr?.message,
5921
- stack: corr?.stack,
5922
- testPath: file.testFilePath,
5923
- currentTestName: assertion.title
5924
- },
5925
- httpSorted,
5926
- {
5927
- testPath: file.testFilePath,
5928
- currentTestName: assertion.title,
5929
- title: assertion.fullName
5930
- }
5931
- );
5932
- if (hasTransport) {
5933
- const tsBase = corresponding?.timestampMs ?? 0;
5934
- const abortCandidates = perTestSlice.filter((event) => event.kind === "abort").sort((leftEvent, rightEvent) => {
5935
- const deltaLeft = Math.abs(tsBase - (leftEvent.timestampMs ?? 0));
5936
- const deltaRight = Math.abs(tsBase - (rightEvent.timestampMs ?? 0));
5937
- return deltaLeft - deltaRight;
5938
- });
5939
- const [nearestAbort] = abortCandidates;
5940
- if (nearestAbort) {
5941
- out.push(
5942
- " HTTP:",
5943
- `
5944
- ${summarizeUrl(nearestAbort.method, nearestAbort.url, nearestAbort.route)} ${ansi.dim("->")} ${ansi.yellow("connection aborted")}`,
5945
- (() => {
5946
- const ms = nearestAbort.durationMs;
5947
- return ms != null ? ` ${ansi.dim(`(${ms}ms)`)} ` : "";
5948
- })(),
5949
- "\n"
5950
- );
5951
- } else if (relevant) {
5952
- } else if (HEADLAMP_HTTP_SHOW_MISS()) {
5953
- out.push(
5954
- " HTTP:",
5955
- `
5956
- ${ansi.dim("Transport error; no matching HTTP exchange in window.")}`,
5957
- "\n"
5958
- );
5959
- }
5960
- }
5961
- if (!hasTransport && relevant) {
5962
- const parts = [];
5963
- const where = summarizeUrl(relevant.method, relevant.url, relevant.route);
5964
- const line1 = [
5965
- " HTTP:",
5966
- `
5967
- ${where} ${ansi.dim("->")} ${relevant.statusCode ?? "?"}`,
5968
- (() => {
5969
- const ms = relevant.durationMs;
5970
- return typeof ms === "number" ? ` ${ansi.dim(`(${ms}ms)`)} ` : " ";
5971
- })(),
5972
- relevant.contentType ? ansi.dim(`(${relevant.contentType})`) : "",
5973
- relevant.requestId ? ansi.dim(` reqId=${relevant.requestId}`) : ""
5974
- ].join("");
5975
- const expVsAct = (() => {
5976
- if (typeof corresponding?.expectedNumber === "number" || typeof corresponding?.receivedNumber === "number") {
5977
- const exp = corresponding?.expectedNumber != null ? String(corresponding.expectedNumber) : "?";
5978
- const got = corresponding?.receivedNumber != null ? String(corresponding.receivedNumber) : String(relevant.statusCode ?? "?");
5979
- return `
5980
- Expected: ${ansi.yellow(exp)} Received: ${ansi.yellow(got)}`;
5981
- }
5982
- return "";
5983
- })();
5984
- const whyLines = importantMessages(relevant.json).map((msg) => `
5985
- Why: ${ansi.white(msg)}`).slice(0, 1).join("");
5986
- const diffLines = (() => {
5987
- const rightActual = parsedActual ?? relevant.json;
5988
- if (!parsedExpected || !rightActual) {
5989
- return "";
5990
- }
5991
- const changes = jsonDiff(parsedExpected, rightActual);
5992
- if (!changes.length) {
5993
- return "";
5994
- }
5995
- const head = "\n Diff:";
5996
- const body = changes.map((change) => {
5997
- const marker = change.kind === "added" ? "+" : change.kind === "removed" ? "-" : "~";
5998
- const previewText = change.preview ? `: ${ansi.dim(change.preview)}` : "";
5999
- return `
6000
- ${marker} ${change.path}${previewText}`;
6001
- }).join("");
6002
- return head + body;
6003
- })();
6004
- parts.push(line1, expVsAct, whyLines, diffLines, "\n");
6005
- out.push(...parts.filter(Boolean));
6006
- } else if (!hasTransport && !relevant && HEADLAMP_HTTP_SHOW_MISS()) {
6007
- out.push(
6008
- " HTTP:",
6009
- `
6010
- ${ansi.dim("No relevant HTTP exchange found. (HEADLAMP_HTTP_MISS=0 to hide)")}`,
6011
- "\n"
6012
- );
6013
- }
6014
- }
6015
- }
6016
- const minimalInfo = msgLines.every((ln) => !ln.trim());
6017
- if (minimalInfo) {
6018
- try {
6019
- out.push(...buildThrownSection(assertion.failureDetails || []));
6020
- } catch {
6021
- }
6022
- }
6023
- out.push(...buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null)));
6024
- if (ctx.showStacks && stackPreview.length === 0) {
6025
- const tail = mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
6026
- if (tail.length) {
6027
- out.push(ansi.dim(" Stack:"), ...tail, "");
6028
- }
6029
- }
6030
- out.push(drawFailLine(), "");
6031
- }
6032
- }
6059
+ var renderFooter = (data) => {
6033
6060
  const failedCount = data.aggregated.numFailedTests;
6034
- out.push(drawRule(BackgroundColors.Failure(ansi.white(` Failed Tests ${failedCount} `))));
6035
- out.push("");
6036
- out.push(vitestFooter(data.aggregated));
6037
- return out.join("\n");
6061
+ return [
6062
+ drawRule(BackgroundColors.Failure(ansi.white(` Failed Tests ${failedCount} `))),
6063
+ "",
6064
+ vitestFooter(data.aggregated)
6065
+ ];
6038
6066
  };
6067
+ var renderVitestFromJestJSON = (data, ctx, opts) => pipe(
6068
+ concat(
6069
+ renderRunHeader({ ctx, onlyFailures: Boolean(opts?.onlyFailures) }),
6070
+ ...data.testResults.map(
6071
+ (file) => renderFileBlock(file, { ctx, onlyFailures: Boolean(opts?.onlyFailures) })
6072
+ ),
6073
+ renderFooter(data)
6074
+ ),
6075
+ joinLines
6076
+ );
6077
+
6078
+ // src/lib/formatter/bridge/tryBridgeFallback.ts
6039
6079
  var tryBridgeFallback = (raw, ctx, opts) => {
6040
- const bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
6080
+ let bridgeJsonPath = extractBridgePath2(raw, ctx.cwd);
6081
+ if (!bridgeJsonPath) {
6082
+ const def = path11.resolve(ctx.cwd, "coverage/jest-run.json").replace(/\\/g, "/");
6083
+ if (fs6.existsSync(def)) {
6084
+ bridgeJsonPath = def;
6085
+ }
6086
+ }
6041
6087
  if (!bridgeJsonPath || !fs6.existsSync(bridgeJsonPath)) {
6042
6088
  return null;
6043
6089
  }
6044
6090
  try {
6045
- const json = import_json52.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
6091
+ const json = import_json53.default.parse(fs6.readFileSync(bridgeJsonPath, "utf8"));
6046
6092
  const bridge = coerceJestJsonToBridge(json);
6047
6093
  return renderVitestFromJestJSON(bridge, ctx, opts);
6048
6094
  } catch {
@@ -6060,23 +6106,39 @@ var formatJestOutputVitest = (raw, opts) => pipe(
6060
6106
  (state) => ({ ...state, chunks: parseChunks(state.raw) }),
6061
6107
  (state) => ({
6062
6108
  ...state,
6063
- rendered: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
6109
+ native: renderChunks(state.chunks, state.ctx, mkPrettyFns(), {
6064
6110
  onlyFailures: Boolean(state.opts?.onlyFailures)
6065
- })
6111
+ }).text
6066
6112
  }),
6067
- (state) => {
6068
- if (state.rendered.hadParsed) {
6069
- return state.rendered.text;
6070
- }
6071
- const fallback = tryBridgeFallback(state.raw, state.ctx, {
6113
+ (state) => ({
6114
+ ...state,
6115
+ bridge: tryBridgeFallback(state.raw, state.ctx, {
6072
6116
  onlyFailures: Boolean(state.opts?.onlyFailures)
6073
- });
6074
- if (!fallback) {
6075
- return state.rendered.text;
6117
+ }) || null
6118
+ }),
6119
+ (state) => {
6120
+ const out = [];
6121
+ const seen = /* @__PURE__ */ new Set();
6122
+ const pushUnique = (text) => {
6123
+ if (!text) {
6124
+ return;
6125
+ }
6126
+ for (const line of text.split(/\r?\n/)) {
6127
+ const key = stripAnsiSimple(line);
6128
+ if (!seen.has(key)) {
6129
+ out.push(line);
6130
+ seen.add(key);
6131
+ }
6132
+ }
6133
+ };
6134
+ pushUnique(state.native);
6135
+ if (state.bridge) {
6136
+ if (out.length) {
6137
+ out.push("");
6138
+ }
6139
+ pushUnique(state.bridge);
6076
6140
  }
6077
- const prefix = state.rendered.text;
6078
- return prefix ? `${prefix}
6079
- ${fallback}` : fallback;
6141
+ return out.join("\n");
6080
6142
  }
6081
6143
  );
6082
6144
 
@@ -6123,7 +6185,7 @@ var mergeLcov = async () => {
6123
6185
  try {
6124
6186
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
6125
6187
  for (const entry of entries) {
6126
- const full = path11.join(dir, entry.name);
6188
+ const full = path12.join(dir, entry.name);
6127
6189
  if (entry.isDirectory()) {
6128
6190
  out.push(...collectLcovs(full));
6129
6191
  } else if (entry.isFile() && entry.name === "lcov.info") {
@@ -6135,8 +6197,8 @@ var mergeLcov = async () => {
6135
6197
  return out;
6136
6198
  };
6137
6199
  try {
6138
- const jestRoot = path11.join("coverage", "jest");
6139
- const candidates = [path11.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
6200
+ const jestRoot = path12.join("coverage", "jest");
6201
+ const candidates = [path12.join(jestRoot, "lcov.info"), ...collectLcovs(jestRoot)].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => arr.indexOf(absolutePath) === index);
6140
6202
  for (const filePath of candidates) {
6141
6203
  try {
6142
6204
  const content = await readOrEmpty(filePath);
@@ -6176,7 +6238,7 @@ var emitMergedCoverage = async (ui, opts) => {
6176
6238
  try {
6177
6239
  const entries = fsSync3.readdirSync(dir, { withFileTypes: true });
6178
6240
  for (const entry of entries) {
6179
- const full = path11.join(dir, entry.name);
6241
+ const full = path12.join(dir, entry.name);
6180
6242
  if (entry.isDirectory()) {
6181
6243
  out.push(...listJsons(full));
6182
6244
  } else if (entry.isFile() && entry.name === "coverage-final.json") {
@@ -6187,11 +6249,11 @@ var emitMergedCoverage = async (ui, opts) => {
6187
6249
  }
6188
6250
  return out;
6189
6251
  };
6190
- const coverageRoot = path11.join("coverage", "jest");
6252
+ const coverageRoot = path12.join("coverage", "jest");
6191
6253
  const jsonCandidates = [
6192
- path11.join(coverageRoot, "coverage-final.json"),
6254
+ path12.join(coverageRoot, "coverage-final.json"),
6193
6255
  ...listJsons(coverageRoot)
6194
- ].map((candidatePath) => path11.resolve(candidatePath)).filter((absolutePath, index, arr) => {
6256
+ ].map((candidatePath) => path12.resolve(candidatePath)).filter((absolutePath, index, arr) => {
6195
6257
  const isFirst = arr.indexOf(absolutePath) === index;
6196
6258
  const exists = fsSync3.existsSync(absolutePath);
6197
6259
  return isFirst && exists;
@@ -6253,7 +6315,7 @@ var emitMergedCoverage = async (ui, opts) => {
6253
6315
  executedTests: opts.executedTests ?? []
6254
6316
  });
6255
6317
  const context = LibReport.createContext({
6256
- dir: path11.resolve("coverage", "merged"),
6318
+ dir: path12.resolve("coverage", "merged"),
6257
6319
  coverageMap: filteredMap,
6258
6320
  defaultSummarizer: "nested"
6259
6321
  });
@@ -6321,8 +6383,8 @@ var emitMergedCoverage = async (ui, opts) => {
6321
6383
  for (const reporter of reporters) {
6322
6384
  reporter.execute(context);
6323
6385
  }
6324
- const textPath = path11.resolve("coverage", "merged", "coverage.txt");
6325
- const summaryPath = path11.resolve("coverage", "merged", "coverage-summary.txt");
6386
+ const textPath = path12.resolve("coverage", "merged", "coverage.txt");
6387
+ const summaryPath = path12.resolve("coverage", "merged", "coverage-summary.txt");
6326
6388
  const filesToPrint = [];
6327
6389
  if (fsSync3.existsSync(textPath)) {
6328
6390
  filesToPrint.push(textPath);
@@ -6465,13 +6527,13 @@ var program = async () => {
6465
6527
  const rels2 = Array.from(
6466
6528
  /* @__PURE__ */ new Set([...branchDiff, ...stagedNow, ...unstagedNow, ...untrackedNow])
6467
6529
  );
6468
- return rels2.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6530
+ return rels2.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6469
6531
  }
6470
6532
  const staged = mode === "staged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB", "--cached"]) : [];
6471
6533
  const unstagedTracked = mode === "unstaged" || mode === "all" ? await collect("git", ["diff", "--name-only", "--diff-filter=ACMRTUXB"]) : [];
6472
6534
  const untracked = mode === "unstaged" || mode === "all" ? await collect("git", ["ls-files", "--others", "--exclude-standard"]) : [];
6473
6535
  const rels = Array.from(/* @__PURE__ */ new Set([...staged, ...unstagedTracked, ...untracked]));
6474
- return rels.map((rel) => path11.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6536
+ return rels.map((rel) => path12.resolve(cwd, rel).replace(/\\/g, "/")).filter((abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/"));
6475
6537
  };
6476
6538
  const repoRootForChanged = workspaceRoot ?? await findRepoRoot();
6477
6539
  const changedSelectionAbs = changed ? await getChangedFiles(changed, repoRootForChanged) : [];
@@ -6496,18 +6558,18 @@ var program = async () => {
6496
6558
  if (!token) {
6497
6559
  continue;
6498
6560
  }
6499
- const isAbs = path11.isAbsolute(token);
6561
+ const isAbs = path12.isAbsolute(token);
6500
6562
  const looksLikeRelPath = /[\\/]/.test(token);
6501
6563
  let candidateFromRoot;
6502
6564
  if (token.startsWith("/")) {
6503
- candidateFromRoot = path11.join(repoRoot, token.slice(1));
6565
+ candidateFromRoot = path12.join(repoRoot, token.slice(1));
6504
6566
  } else if (looksLikeRelPath) {
6505
- candidateFromRoot = path11.join(repoRoot, token);
6567
+ candidateFromRoot = path12.join(repoRoot, token);
6506
6568
  } else {
6507
6569
  candidateFromRoot = void 0;
6508
6570
  }
6509
6571
  const tryPushIfProd = (absPath) => {
6510
- const norm = path11.resolve(absPath).replace(/\\/g, "/");
6572
+ const norm = path12.resolve(absPath).replace(/\\/g, "/");
6511
6573
  const isTest = /(^|\/)tests?\//i.test(norm) || /\.(test|spec)\.[tj]sx?$/i.test(norm);
6512
6574
  if (!isTest && fsSync3.existsSync(norm)) {
6513
6575
  results.add(norm);
@@ -6529,7 +6591,7 @@ var program = async () => {
6529
6591
  }),
6530
6592
  timeoutMs: 4e3
6531
6593
  });
6532
- const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path11.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
6594
+ const matches = out.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((rel) => path12.resolve(repoRoot, rel).replace(/\\/g, "/")).filter(
6533
6595
  (abs) => !abs.includes("/node_modules/") && !abs.includes("/coverage/") && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
6534
6596
  );
6535
6597
  matches.forEach((abs) => results.add(abs));
@@ -6550,8 +6612,8 @@ var program = async () => {
6550
6612
  const jestDiscoveryArgs = selectionIncludesProdPaths ? stripPathTokens(jest) : jest;
6551
6613
  const projectConfigs = [];
6552
6614
  try {
6553
- const baseCfg = path11.resolve("jest.config.js");
6554
- const tsCfg = path11.resolve("jest.ts.config.js");
6615
+ const baseCfg = path12.resolve("jest.config.js");
6616
+ const tsCfg = path12.resolve("jest.ts.config.js");
6555
6617
  if (fsSync3.existsSync(baseCfg)) {
6556
6618
  projectConfigs.push(baseCfg);
6557
6619
  }
@@ -6568,7 +6630,7 @@ var program = async () => {
6568
6630
  );
6569
6631
  const prodSelections2 = expandedProdSelections;
6570
6632
  for (const cfg of projectConfigs) {
6571
- const cfgCwd = path11.dirname(cfg);
6633
+ const cfgCwd = path12.dirname(cfg);
6572
6634
  const allTests = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6573
6635
  cwd: cfgCwd
6574
6636
  });
@@ -6581,7 +6643,7 @@ var program = async () => {
6581
6643
  });
6582
6644
  } catch (err) {
6583
6645
  if (isDebug()) {
6584
- console.warn(`direct selection failed for project ${path11.basename(cfg)}: ${String(err)}`);
6646
+ console.warn(`direct selection failed for project ${path12.basename(cfg)}: ${String(err)}`);
6585
6647
  }
6586
6648
  }
6587
6649
  perProjectFiles.set(cfg, directPerProject);
@@ -6593,7 +6655,7 @@ var program = async () => {
6593
6655
  )} | related=${selectionIncludesProdPaths} | cwd=${repoRootForDiscovery}`
6594
6656
  );
6595
6657
  for (const cfg of projectConfigs) {
6596
- const cfgCwd = path11.dirname(cfg);
6658
+ const cfgCwd = path12.dirname(cfg);
6597
6659
  const files = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6598
6660
  cwd: cfgCwd
6599
6661
  });
@@ -6608,13 +6670,13 @@ var program = async () => {
6608
6670
  );
6609
6671
  const candidates = selectionHasPaths && selectionLooksLikeTest ? selectionTestPaths : files;
6610
6672
  const absFiles = candidates.map(
6611
- (candidatePath) => path11.isAbsolute(candidatePath) ? candidatePath : path11.join(repoRootForDiscovery, candidatePath)
6673
+ (candidatePath) => path12.isAbsolute(candidatePath) ? candidatePath : path12.join(repoRootForDiscovery, candidatePath)
6612
6674
  ).map((absolutePath) => absolutePath.replace(/\\/g, "/"));
6613
6675
  const onlyOwned = await filterCandidatesForProject(
6614
6676
  cfg,
6615
6677
  jestDiscoveryArgs,
6616
6678
  absFiles,
6617
- path11.dirname(cfg)
6679
+ path12.dirname(cfg)
6618
6680
  );
6619
6681
  perProjectFiltered.set(cfg, onlyOwned);
6620
6682
  }
@@ -6626,7 +6688,7 @@ var program = async () => {
6626
6688
  if (selectionHasPaths && prodSelections.length > 0) {
6627
6689
  console.info(`rg related \u2192 prodSelections=${prodSelections.length} (starting)`);
6628
6690
  const repoRootForRefinement = workspaceRoot ?? await findRepoRoot();
6629
- const selectionKey = prodSelections.map((absPath) => path11.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
6691
+ const selectionKey = prodSelections.map((absPath) => path12.relative(repoRootForRefinement, absPath).replace(/\\/g, "/")).sort((firstPath, secondPath) => firstPath.localeCompare(secondPath)).join("|");
6630
6692
  const { cachedRelated: cachedRelated2, findRelatedTestsFast: findRelatedTestsFast2, DEFAULT_TEST_GLOBS: DEFAULT_TEST_GLOBS2 } = await Promise.resolve().then(() => (init_fast_related(), fast_related_exports));
6631
6693
  const { DEFAULT_EXCLUDE: DEFAULT_EXCLUDE2 } = await Promise.resolve().then(() => (init_args(), args_exports));
6632
6694
  const rgMatches = await cachedRelated2({
@@ -6656,7 +6718,7 @@ var program = async () => {
6656
6718
  cfg,
6657
6719
  jestDiscoveryArgs,
6658
6720
  rgCandidates,
6659
- path11.dirname(cfg)
6721
+ path12.dirname(cfg)
6660
6722
  );
6661
6723
  perProjectFromRg.set(cfg, owned);
6662
6724
  }
@@ -6671,9 +6733,9 @@ var program = async () => {
6671
6733
  } else {
6672
6734
  const repoRootForScan = repoRootForDiscovery;
6673
6735
  const toSeeds = (abs) => {
6674
- const rel = path11.relative(repoRootForScan, abs).replace(/\\/g, "/");
6736
+ const rel = path12.relative(repoRootForScan, abs).replace(/\\/g, "/");
6675
6737
  const withoutExt = rel.replace(/\.(m?[tj]sx?)$/i, "");
6676
- const base = path11.basename(withoutExt);
6738
+ const base = path12.basename(withoutExt);
6677
6739
  const segs = withoutExt.split("/");
6678
6740
  const tail2 = segs.slice(-2).join("/");
6679
6741
  return Array.from(new Set([withoutExt, base, tail2].filter(Boolean)));
@@ -6688,8 +6750,8 @@ var program = async () => {
6688
6750
  }
6689
6751
  };
6690
6752
  const resolveLocalImport = (fromFile, spec) => {
6691
- const baseDir = path11.dirname(fromFile);
6692
- const cand = path11.resolve(baseDir, spec);
6753
+ const baseDir = path12.dirname(fromFile);
6754
+ const cand = path12.resolve(baseDir, spec);
6693
6755
  const exts = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
6694
6756
  for (const ext of exts) {
6695
6757
  const full = ext ? `${cand}${ext}` : cand;
@@ -6698,7 +6760,7 @@ var program = async () => {
6698
6760
  }
6699
6761
  }
6700
6762
  for (const ext of exts) {
6701
- const full = path11.join(cand, `index${ext}`);
6763
+ const full = path12.join(cand, `index${ext}`);
6702
6764
  if (fsSync3.existsSync(full)) {
6703
6765
  return full;
6704
6766
  }
@@ -6752,7 +6814,7 @@ var program = async () => {
6752
6814
  cfg,
6753
6815
  jestDiscoveryArgs,
6754
6816
  keptCandidates,
6755
- path11.dirname(cfg)
6817
+ path12.dirname(cfg)
6756
6818
  );
6757
6819
  perProjectFromScan.set(cfg, owned);
6758
6820
  }
@@ -6782,7 +6844,7 @@ var program = async () => {
6782
6844
  try {
6783
6845
  const allAcross = [];
6784
6846
  for (const cfg of projectConfigs) {
6785
- const cfgCwd = path11.dirname(cfg);
6847
+ const cfgCwd = path12.dirname(cfg);
6786
6848
  const listed = await discoverJestResilient([...jestDiscoveryArgs, "--config", cfg], {
6787
6849
  cwd: cfgCwd
6788
6850
  });
@@ -6796,9 +6858,9 @@ var program = async () => {
6796
6858
  }
6797
6859
  }
6798
6860
  const seeds = prodSelections.map(
6799
- (abs) => path11.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
6861
+ (abs) => path12.relative(repoRoot, abs).replace(/\\/g, "/").replace(/\.(m?[tj]sx?)$/i, "")
6800
6862
  ).flatMap((rel) => {
6801
- const base = path11.basename(rel);
6863
+ const base = path12.basename(rel);
6802
6864
  const segments = rel.split("/");
6803
6865
  return Array.from(new Set([rel, base, segments.slice(-2).join("/")].filter(Boolean)));
6804
6866
  });
@@ -6811,8 +6873,8 @@ var program = async () => {
6811
6873
  }
6812
6874
  };
6813
6875
  const resolveLocalImport = (fromFile, spec) => {
6814
- const baseDir = path11.dirname(fromFile);
6815
- const candidate = path11.resolve(baseDir, spec);
6876
+ const baseDir = path12.dirname(fromFile);
6877
+ const candidate = path12.resolve(baseDir, spec);
6816
6878
  const extensions = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
6817
6879
  for (const ext of extensions) {
6818
6880
  const fullPath = ext ? `${candidate}${ext}` : candidate;
@@ -6821,7 +6883,7 @@ var program = async () => {
6821
6883
  }
6822
6884
  }
6823
6885
  for (const ext of extensions) {
6824
- const fullPath = path11.join(candidate, `index${ext}`);
6886
+ const fullPath = path12.join(candidate, `index${ext}`);
6825
6887
  if (fsSync3.existsSync(fullPath)) {
6826
6888
  return fullPath;
6827
6889
  }
@@ -6978,10 +7040,10 @@ var program = async () => {
6978
7040
  };
6979
7041
  const prodSeedsForRun = (() => {
6980
7042
  const changedAbs = (changedSelectionAbs ?? []).map(
6981
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
7043
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
6982
7044
  );
6983
7045
  const selAbs = selectionPathsAugmented.map(
6984
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
7046
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
6985
7047
  );
6986
7048
  return (changedAbs.length ? changedAbs : selAbs).filter(
6987
7049
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)
@@ -6996,17 +7058,17 @@ var program = async () => {
6996
7058
  const cfg = projectsToRun[projIndex];
6997
7059
  const files = perProjectFiltered.get(cfg) ?? [];
6998
7060
  if (files.length === 0) {
6999
- console.info(`Project ${path11.basename(cfg)}: 0 matching tests after filter; skipping.`);
7061
+ console.info(`Project ${path12.basename(cfg)}: 0 matching tests after filter; skipping.`);
7000
7062
  continue;
7001
7063
  }
7002
7064
  files.forEach(
7003
- (absTestPath) => executedTestFilesSet.add(path11.resolve(absTestPath).replace(/\\/g, "/"))
7065
+ (absTestPath) => executedTestFilesSet.add(path12.resolve(absTestPath).replace(/\\/g, "/"))
7004
7066
  );
7005
- const outJson = path11.join(
7067
+ const outJson = path12.join(
7006
7068
  os3.tmpdir(),
7007
7069
  `jest-bridge-${Date.now()}-${Math.random().toString(36).slice(2)}.json`
7008
7070
  );
7009
- const reporterPath = path11.resolve("scripts/jest-vitest-bridge.cjs");
7071
+ const reporterPath = path12.resolve("scripts/jest-vitest-bridge.cjs");
7010
7072
  try {
7011
7073
  const needsWrite = (() => {
7012
7074
  try {
@@ -7017,10 +7079,10 @@ var program = async () => {
7017
7079
  }
7018
7080
  })();
7019
7081
  if (needsWrite) {
7020
- fsSync3.mkdirSync(path11.dirname(reporterPath), { recursive: true });
7082
+ fsSync3.mkdirSync(path12.dirname(reporterPath), { recursive: true });
7021
7083
  fsSync3.writeFileSync(reporterPath, JEST_BRIDGE_REPORTER_SOURCE, "utf8");
7022
7084
  }
7023
- const envPath = path11.resolve("scripts/jest-bridge-env.cjs");
7085
+ const envPath = path12.resolve("scripts/jest-bridge-env.cjs");
7024
7086
  try {
7025
7087
  const existingEnv = fsSync3.readFileSync(envPath, "utf8");
7026
7088
  if (existingEnv !== JEST_BRIDGE_ENV_SOURCE) {
@@ -7028,7 +7090,7 @@ var program = async () => {
7028
7090
  }
7029
7091
  } catch {
7030
7092
  try {
7031
- fsSync3.mkdirSync(path11.dirname(envPath), { recursive: true });
7093
+ fsSync3.mkdirSync(path12.dirname(envPath), { recursive: true });
7032
7094
  } catch {
7033
7095
  }
7034
7096
  fsSync3.writeFileSync(envPath, JEST_BRIDGE_ENV_SOURCE, "utf8");
@@ -7036,7 +7098,7 @@ var program = async () => {
7036
7098
  } catch (ensureReporterError) {
7037
7099
  console.warn(`Unable to ensure jest bridge reporter: ${String(ensureReporterError)}`);
7038
7100
  }
7039
- 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}`);
7101
+ 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}`);
7040
7102
  const coverageFromArgs = [];
7041
7103
  for (const relPath2 of selectedFilesForCoverage) {
7042
7104
  coverageFromArgs.push("--collectCoverageFrom", relPath2);
@@ -7054,11 +7116,11 @@ var program = async () => {
7054
7116
  `--reporters=${reporterPath}`,
7055
7117
  "--colors",
7056
7118
  "--env",
7057
- path11.resolve("scripts/jest-bridge-env.cjs"),
7119
+ path12.resolve("scripts/jest-bridge-env.cjs"),
7058
7120
  ...sanitizedJestRunArgs,
7059
7121
  ...collectCoverage ? [
7060
7122
  "--coverageDirectory",
7061
- path11.join("coverage", "jest", path11.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
7123
+ path12.join("coverage", "jest", path12.basename(cfg).replace(/[^a-zA-Z0-9_.-]+/g, "_"))
7062
7124
  ] : [],
7063
7125
  ...coverageFromArgs,
7064
7126
  "--passWithNoTests",
@@ -7184,10 +7246,10 @@ ${stripFooter(rawAlso)}`.trimEnd();
7184
7246
  try {
7185
7247
  const prodSeeds = (() => {
7186
7248
  const changedAbs = (changedSelectionAbs ?? []).map(
7187
- (absPath) => path11.resolve(absPath).replace(/\\/g, "/")
7249
+ (absPath) => path12.resolve(absPath).replace(/\\/g, "/")
7188
7250
  );
7189
7251
  const selAbs = selectionPathsAugmented.map(
7190
- (pathToken) => path11.resolve(pathToken).replace(/\\/g, "/")
7252
+ (pathToken) => path12.resolve(pathToken).replace(/\\/g, "/")
7191
7253
  );
7192
7254
  return (changedAbs.length ? changedAbs : selAbs).filter(
7193
7255
  (abs) => /[\\/]/.test(abs) && !/(^|\/)tests?\//i.test(abs) && !/\.(test|spec)\.[tj]sx?$/i.test(abs)