@hublo/sentinel 1.5.0-alpha.20 → 1.5.0-alpha.21

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.
@@ -15,7 +15,7 @@ import {
15
15
  palette,
16
16
  registerAdapters,
17
17
  resolve
18
- } from "../chunk-ZN32JGFP.js";
18
+ } from "../chunk-AFM4AJHA.js";
19
19
  import {
20
20
  resolveContext
21
21
  } from "../chunk-KLEXJFJ6.js";
@@ -5433,10 +5433,10 @@ var metricsHelp = {
5433
5433
  },
5434
5434
  unusedFiles: {
5435
5435
  label: "Unreachable files",
5436
- what: "Files no entry point reaches, each with a confidence the tool assigns.",
5437
- read: "The most actionable of the four, and the one to start from: a whole file nothing reaches is a decision, not a cleanup. Open the ones with the highest confidence first.",
5438
- caveat: "Three classes hide in this count and only one of them is a deletion, so read the reason the tool gives before acting: a file nothing reaches at all, a file only a spec or a story reaches, which is alive and breaks if removed, and an entry point of a framework this role has not declared. The tool labels the second itself as `used-only-by-tests`, and that is not a corner: measured over 1 231 findings on this repository, 659 of them carry it, 53.5%. A finding with no reason given is the one to open first.",
5439
- source: "jscpd dead-code findings of category `unused-file`, with the engine's own `reasons` and `message` carried through. The 53.5% was counted over every dead-code report produced on this repository; the third class was separated by hand on `apps/front/console`, where three of five findings were its TanStack bootstrap."
5436
+ what: "Files of this module that nothing reaches: not its own code, not another module, not a spec.",
5437
+ read: "A candidate for deletion, and the only one of the dead-code rows that names whole files. Zero is the ordinary value for an application whose entry points are declared.",
5438
+ caveat: "\u26A0\uFE0F Two classes remain in it and only one is a deletion: a file nothing reaches at all, and an entry point of a framework this role has not been told about, which is a missing declaration rather than dead code. A THIRD class used to sit here and no longer does: a file reached only by a spec, which the tool labels `used-only-by-tests` itself, is now counted on its own row instead. Measured on `libs/nest/auth`, that moved 5 files out of 20, and the figure now agrees with the reason printed beside each finding instead of contradicting it.",
5439
+ source: "jscpd's dead-code walk, category `unused-file`, minus the findings it labels `used-only-by-tests`. The walk starts from the module's declared entry points PLUS the files another module imports, which come from the workspace index: without those seeds a library has no starting point at all and reports 87 unreachable files where 12 are, measured on `libs/nest/auth`."
5440
5440
  },
5441
5441
  unusedExports: {
5442
5442
  label: "Unused exports",
@@ -6701,6 +6701,11 @@ function assembleReport(ctx, config, product, tests, dead, complexity, graph, co
6701
6701
  if (unreadable) {
6702
6702
  notes.push(unreadableNote(coverage));
6703
6703
  }
6704
+ const toolTestOnly = new Set(
6705
+ dead.kind === "figures" ? dead.findings.filter(
6706
+ (finding) => finding.category === "unused-file" && finding.reasons?.includes("used-only-by-tests") === true
6707
+ ).map((finding) => finding.path ?? "").filter(Boolean) : []
6708
+ );
6704
6709
  if (dead.kind === "figures" && !unreadable) {
6705
6710
  const stats = dead.statistics;
6706
6711
  rows.push(
@@ -6710,14 +6715,23 @@ function assembleReport(ctx, config, product, tests, dead, complexity, graph, co
6710
6715
  unit: `of ${stats.files ?? 0} files`
6711
6716
  },
6712
6717
  { metric: "deadLinesPercent", value: share(stats), unit: "%" },
6713
- { metric: "unusedFiles", value: dead.byCategory["unused-file"] ?? 0, unit: "files" },
6718
+ // ⛔ Minus the files the TOOL itself labels `used-only-by-tests`. They were counted as
6719
+ // unreachable while the tool knew better: measured on `libs/nest/auth`, 5 of the 20. A file a
6720
+ // spec reaches is not unreachable, and leaving it in the headline count meant the figure
6721
+ // disagreed with the reason printed beside it.
6722
+ {
6723
+ metric: "unusedFiles",
6724
+ value: Math.max((dead.byCategory["unused-file"] ?? 0) - toolTestOnly.size, 0),
6725
+ unit: "files"
6726
+ },
6714
6727
  { metric: "unusedExports", value: dead.byCategory["unused-export"] ?? 0, unit: "exports" },
6715
6728
  { metric: "unusedSymbols", value: dead.byCategory["unused-symbol"] ?? 0, unit: "symbols" },
6716
6729
  { metric: "unusedImports", value: dead.byCategory["unused-import"] ?? 0, unit: "imports" }
6717
6730
  );
6718
6731
  }
6719
- if (outside.testOnly.size > 0 && !unreadable) {
6720
- rows.push({ metric: "usedOnlyByTests", value: outside.testOnly.size, unit: "files" });
6732
+ const testOnly = /* @__PURE__ */ new Set([...toolTestOnly, ...outside.testOnly]);
6733
+ if (testOnly.size > 0 && !unreadable) {
6734
+ rows.push({ metric: "usedOnlyByTests", value: testOnly.size, unit: "files" });
6721
6735
  }
6722
6736
  if (complexity.functions > 0) {
6723
6737
  rows.push({ metric: "complexityMax", value: complexity.max, unit: "max per function" });
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  registerAdapters,
7
7
  resolve,
8
8
  setDefaultRunner
9
- } from "./chunk-ZN32JGFP.js";
9
+ } from "./chunk-AFM4AJHA.js";
10
10
  import {
11
11
  BaseAdapter
12
12
  } from "./chunk-KLEXJFJ6.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hublo/sentinel",
3
- "version": "1.5.0-alpha.20",
3
+ "version": "1.5.0-alpha.21",
4
4
  "description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
5
5
  "type": "module",
6
6
  "license": "MIT",