headlamp 0.1.15 → 0.1.17

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/README.md CHANGED
@@ -69,6 +69,22 @@ npx headlamp --onlyFailures
69
69
  npx headlamp --changed --onlyFailures
70
70
  ```
71
71
 
72
+ - `--showLogs[=true|false]`:
73
+ - When enabled, Headlamp prints a dedicated "Logs" section under each failing test and failing file with the full console output captured by the runner.
74
+ - By default (without this flag), Headlamp shows a condensed "Console errors" snippet with only the most relevant error messages. `--showLogs` includes all console entries (log/info/warn/error).
75
+ - Supported forms: `--showLogs`, `--showLogs=true`, `--showLogs=false`.
76
+ - Works alongside `--onlyFailures`, coverage flags, and selection flags.
77
+
78
+ Examples:
79
+
80
+ ```bash
81
+ # Always include the full console output for each failure
82
+ npx headlamp --showLogs
83
+
84
+ # Combine with only failures visible during the run
85
+ npx headlamp --onlyFailures --showLogs
86
+ ```
87
+
72
88
  ## Changed-file selection
73
89
 
74
90
  - `--changed[=mode]` selects tests by files changed in your working tree or branch.
package/dist/cli.cjs CHANGED
@@ -249,6 +249,7 @@ var init_args = __esm({
249
249
  coverageUi: (value) => ({ type: "coverageUi", value }),
250
250
  coverageAbortOnFailure: (value) => ({ type: "coverageAbortOnFailure", value }),
251
251
  onlyFailures: (value) => ({ type: "onlyFailures", value }),
252
+ showLogs: (value) => ({ type: "showLogs", value }),
252
253
  jestArg: (value) => ({ type: "jestArg", value }),
253
254
  jestArgs: (values) => ({ type: "jestArgs", values }),
254
255
  vitestArg: (value) => ({ type: "vitestArg", value }),
@@ -415,6 +416,16 @@ var init_args = __esm({
415
416
  "--onlyFailures",
416
417
  (_flag, lookahead) => step([ActionBuilders.onlyFailures(isTruthy(String(lookahead)))], true)
417
418
  ),
419
+ // --showLogs flag (boolean)
420
+ rule.eq("--showLogs", () => step([ActionBuilders.showLogs(true)])),
421
+ rule.startsWith(
422
+ "--showLogs=",
423
+ (value) => step([ActionBuilders.showLogs(isTruthy((value.split("=")[1] ?? "").trim().toLowerCase()))])
424
+ ),
425
+ rule.withLookahead(
426
+ "--showLogs",
427
+ (_flag, lookahead) => step([ActionBuilders.showLogs(isTruthy(String(lookahead)))], true)
428
+ ),
418
429
  rule.withLookahead(
419
430
  "--testPathPattern",
420
431
  (flag, lookahead) => step([ActionBuilders.jestArgs([flag, lookahead])], true)
@@ -573,6 +584,8 @@ var init_args = __esm({
573
584
  return { vitest: [], jest: [], coverage: false, coverageAbortOnFailure: action.value };
574
585
  case "onlyFailures":
575
586
  return { vitest: [], jest: [], coverage: false, onlyFailures: action.value };
587
+ case "showLogs":
588
+ return { vitest: [], jest: [], coverage: false, showLogs: action.value };
576
589
  case "jestArgs":
577
590
  return { vitest: [], jest: action.values, coverage: false };
578
591
  case "selectionHint":
@@ -648,6 +661,7 @@ var init_args = __esm({
648
661
  ...right.changedDepth !== void 0 || left.changedDepth !== void 0 ? { changedDepth: right.changedDepth ?? left.changedDepth } : {},
649
662
  ...right.coverageAbortOnFailure !== void 0 || left.coverageAbortOnFailure !== void 0 ? { coverageAbortOnFailure: right.coverageAbortOnFailure ?? left.coverageAbortOnFailure } : {},
650
663
  ...right.onlyFailures !== void 0 || left.onlyFailures !== void 0 ? { onlyFailures: right.onlyFailures ?? left.onlyFailures } : {},
664
+ ...right.showLogs !== void 0 || left.showLogs !== void 0 ? { showLogs: right.showLogs ?? left.showLogs } : {},
651
665
  ...right.coverageDetail !== void 0 || left.coverageDetail !== void 0 ? { coverageDetail: right.coverageDetail ?? left.coverageDetail } : {},
652
666
  ...right.coverageShowCode !== void 0 || left.coverageShowCode !== void 0 ? { coverageShowCode: right.coverageShowCode ?? left.coverageShowCode } : {},
653
667
  ...right.coverageMode !== void 0 || left.coverageMode !== void 0 ? { coverageMode: right.coverageMode ?? left.coverageMode } : {},
@@ -672,6 +686,7 @@ var init_args = __esm({
672
686
  let coverageUi = "both";
673
687
  let coverageAbortOnFailure = false;
674
688
  let onlyFailures = false;
689
+ let showLogs = false;
675
690
  let coverageShowCode = Boolean(process.stdout.isTTY);
676
691
  let coverageMode = "auto";
677
692
  const coverageMaxFilesLocalInit = void 0;
@@ -690,6 +705,7 @@ var init_args = __esm({
690
705
  coverageUi = contrib.coverageUi ?? coverageUi;
691
706
  coverageAbortOnFailure = contrib.coverageAbortOnFailure ?? coverageAbortOnFailure;
692
707
  onlyFailures = contrib.onlyFailures ?? onlyFailures;
708
+ showLogs = contrib.showLogs ?? showLogs;
693
709
  coverageShowCode = contrib.coverageShowCode ?? coverageShowCode;
694
710
  const coverageDetailComputed = contrib.coverageDetail ?? (contrib.selection ? "auto" : void 0);
695
711
  coverageMode = contrib.coverageMode ?? (contrib.selection ? "compact" : "auto");
@@ -724,6 +740,7 @@ var init_args = __esm({
724
740
  coverageUi,
725
741
  coverageAbortOnFailure,
726
742
  onlyFailures,
743
+ showLogs,
727
744
  selectionSpecified: Boolean(contrib.selection),
728
745
  selectionPaths: [...contrib.selectionPaths ?? []],
729
746
  includeGlobs,
@@ -5089,24 +5106,43 @@ var buildStackSection = (mergedForStack, ctx, fallbackLoc) => {
5089
5106
  };
5090
5107
  var MAX_CONSOLE_ERRORS_TO_SHOW = 3;
5091
5108
  var isConsoleEntry = (candidate) => typeof candidate === "object" && candidate !== null;
5092
- var buildConsoleSection = (maybeConsole) => {
5109
+ var buildConsoleSection = (maybeConsole, opts) => {
5093
5110
  const out = [];
5094
5111
  if (!Array.isArray(maybeConsole)) {
5095
5112
  return out;
5096
5113
  }
5097
5114
  const entries = maybeConsole.filter(isConsoleEntry);
5098
- const errorsOnly = entries.filter((entry) => String(entry?.type ?? "").toLowerCase() === "error");
5099
- const scored = errorsOnly.map((entry) => {
5100
- const raw = entry?.message;
5101
- const msg = Array.isArray(raw) ? raw.map(String).join(" ") : typeof raw === "string" ? raw : String(raw ?? "");
5102
- return { msg, score: msg.length };
5103
- }).filter((item) => item.msg.trim().length > 0).sort((left, right) => right.score - left.score).slice(0, MAX_CONSOLE_ERRORS_TO_SHOW);
5104
- if (scored.length) {
5105
- out.push(ansi.dim(" Console errors:"));
5106
- for (const item of scored) {
5107
- out.push(` ${ansi.dim("\u2022")} ${item.msg}`);
5115
+ if (opts?.full) {
5116
+ const toMsg = (entry) => {
5117
+ const type = String(entry?.type ?? "").toLowerCase();
5118
+ const raw = entry?.message;
5119
+ const msg = Array.isArray(raw) ? raw.map(String).join(" ") : typeof raw === "string" ? raw : String(raw ?? "");
5120
+ const origin = String(entry?.origin ?? "");
5121
+ const typeFmt = type ? `${ansi.white(type)}: ` : "";
5122
+ const originFmt = origin ? ` ${ansi.dim(`(${origin})`)}` : "";
5123
+ return ` ${ansi.dim("\u2022")} ${typeFmt}${msg}${originFmt}`;
5124
+ };
5125
+ const lines = entries.map(toMsg).filter((ln) => stripAnsiSimple(ln).trim().length > 0);
5126
+ if (lines.length) {
5127
+ out.push(ansi.dim(" Logs:"));
5128
+ out.push(...lines, "");
5129
+ }
5130
+ } else {
5131
+ const errorsOnly = entries.filter(
5132
+ (entry) => String(entry?.type ?? "").toLowerCase() === "error"
5133
+ );
5134
+ const scored = errorsOnly.map((entry) => {
5135
+ const raw = entry?.message;
5136
+ const msg = Array.isArray(raw) ? raw.map(String).join(" ") : typeof raw === "string" ? raw : String(raw ?? "");
5137
+ return { msg, score: msg.length };
5138
+ }).filter((item) => item.msg.trim().length > 0).sort((left, right) => right.score - left.score).slice(0, MAX_CONSOLE_ERRORS_TO_SHOW);
5139
+ if (scored.length) {
5140
+ out.push(ansi.dim(" Console errors:"));
5141
+ for (const item of scored) {
5142
+ out.push(` ${ansi.dim("\u2022")} ${item.msg}`);
5143
+ }
5144
+ out.push("");
5108
5145
  }
5109
- out.push("");
5110
5146
  }
5111
5147
  return out;
5112
5148
  };
@@ -5168,8 +5204,8 @@ var buildThrownSection = (details) => {
5168
5204
  }
5169
5205
  };
5170
5206
  const candidates = [];
5171
- for (const d of details) {
5172
- const obj = d && typeof d === "object" ? d : null;
5207
+ for (const detailEntry of details) {
5208
+ const obj = detailEntry && typeof detailEntry === "object" ? detailEntry : null;
5173
5209
  if (obj && obj.error && typeof obj.error === "object") {
5174
5210
  const err = obj.error;
5175
5211
  if (typeof err.name === "string") {
@@ -5366,7 +5402,7 @@ var renderChunks = (chunks, ctx, fns, opts) => {
5366
5402
 
5367
5403
  // src/lib/formatter/context.ts
5368
5404
  var fs5 = __toESM(require("node:fs"), 1);
5369
- var makeCtx = (opts, showStacks = false) => {
5405
+ var makeCtx = (opts, showStacks = false, showLogs = false) => {
5370
5406
  const cwd = (opts?.cwd ?? process.cwd()).replace(/\\/g, "/");
5371
5407
  const width = Math.max(
5372
5408
  40,
@@ -5382,7 +5418,15 @@ var makeCtx = (opts, showStacks = false) => {
5382
5418
  return [];
5383
5419
  }
5384
5420
  };
5385
- return { cwd, width, showStacks, projectHint, editorCmd: opts?.editorCmd, readSource: readSource2 };
5421
+ return {
5422
+ cwd,
5423
+ width,
5424
+ showStacks,
5425
+ showLogs,
5426
+ projectHint,
5427
+ editorCmd: opts?.editorCmd,
5428
+ readSource: readSource2
5429
+ };
5386
5430
  };
5387
5431
 
5388
5432
  // src/lib/formatter/bridge/tryBridgeFallback.ts
@@ -5704,7 +5748,9 @@ var renderFileLevelFailure = (file, ctx) => {
5704
5748
  suppressDiff: pretty.length > 0,
5705
5749
  stackPreview
5706
5750
  });
5707
- const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null));
5751
+ const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null), {
5752
+ full: Boolean(ctx.showLogs)
5753
+ });
5708
5754
  const stackTail = ctx.showStacks && stackPreview.length === 0 ? (() => {
5709
5755
  const tail = mergedForStack.filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
5710
5756
  return tail.length ? [ansi.dim(" Stack:"), ...tail, ""] : empty;
@@ -6019,7 +6065,9 @@ var renderFailedAssertion = (args) => {
6019
6065
  return empty;
6020
6066
  }
6021
6067
  })() : empty;
6022
- const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null));
6068
+ const consoleBlock = buildConsoleSection(stripBridgeEventsFromConsole(file.console ?? null), {
6069
+ full: Boolean(ctx.showLogs)
6070
+ });
6023
6071
  const stackTail = ctx.showStacks && stackPreview.length === 0 ? (() => {
6024
6072
  const merged = collapseStacks([...msgLines, ...details.stacks]);
6025
6073
  const tail = collapseStacks(merged).filter((ln) => isStackLine(stripAnsiSimple(ln))).slice(-4).map((ln) => ` ${colorStackLine(String(ln), ctx.projectHint)}`);
@@ -6116,7 +6164,11 @@ var formatJestOutputVitest = (raw, opts) => pipe(
6116
6164
  { raw, opts },
6117
6165
  (state) => ({
6118
6166
  ...state,
6119
- ctx: makeCtx(state.opts, /\bFAIL\b/.test(stripAnsiSimple(state.raw)))
6167
+ ctx: makeCtx(
6168
+ state.opts,
6169
+ /\bFAIL\b/.test(stripAnsiSimple(state.raw)),
6170
+ Boolean(state.opts?.showLogs)
6171
+ )
6120
6172
  }),
6121
6173
  (state) => ({ ...state, chunks: parseChunks(state.raw) }),
6122
6174
  (state) => ({
@@ -6471,6 +6523,7 @@ var program = async () => {
6471
6523
  coverageUi,
6472
6524
  coverageAbortOnFailure,
6473
6525
  onlyFailures,
6526
+ showLogs,
6474
6527
  selectionSpecified,
6475
6528
  selectionPaths,
6476
6529
  includeGlobs,
@@ -7173,7 +7226,8 @@ var program = async () => {
7173
7226
  reordered,
7174
7227
  makeCtx(
7175
7228
  { cwd: repoRootForDiscovery, ...editorCmd !== void 0 ? { editorCmd } : {} },
7176
- /\bFAIL\b/.test(stripAnsiSimple(output))
7229
+ /\bFAIL\b/.test(stripAnsiSimple(output)),
7230
+ Boolean(showLogs)
7177
7231
  ),
7178
7232
  { onlyFailures }
7179
7233
  );
@@ -7182,7 +7236,8 @@ var program = async () => {
7182
7236
  bridge,
7183
7237
  makeCtx(
7184
7238
  { cwd: repoRootForDiscovery, ...editorCmd !== void 0 ? { editorCmd } : {} },
7185
- /\bFAIL\b/.test(stripAnsiSimple(output))
7239
+ /\bFAIL\b/.test(stripAnsiSimple(output)),
7240
+ Boolean(showLogs)
7186
7241
  ),
7187
7242
  { onlyFailures }
7188
7243
  );
@@ -7284,7 +7339,8 @@ ${stripFooter(rawAlso)}`.trimEnd();
7284
7339
  unified,
7285
7340
  makeCtx(
7286
7341
  { cwd: repoRootForDiscovery, ...editorCmd !== void 0 ? { editorCmd } : {} },
7287
- showStacks
7342
+ showStacks,
7343
+ Boolean(showLogs)
7288
7344
  ),
7289
7345
  { onlyFailures }
7290
7346
  );