depvitals 0.2.0 → 0.4.0

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.
Files changed (89) hide show
  1. package/README.md +95 -30
  2. package/dist/cli/entry.js +8 -21
  3. package/dist/cli/entry.js.map +1 -1
  4. package/dist/cli/parseCliArgs.d.ts +5 -2
  5. package/dist/cli/parseCliArgs.d.ts.map +1 -1
  6. package/dist/cli/parseCliArgs.js +51 -36
  7. package/dist/cli/parseCliArgs.js.map +1 -1
  8. package/dist/cli/runCli.d.ts +4 -5
  9. package/dist/cli/runCli.d.ts.map +1 -1
  10. package/dist/cli/runCli.js +41 -46
  11. package/dist/cli/runCli.js.map +1 -1
  12. package/dist/config/ignoreDependencies.d.ts +9 -0
  13. package/dist/config/ignoreDependencies.d.ts.map +1 -0
  14. package/dist/config/ignoreDependencies.js +22 -0
  15. package/dist/config/ignoreDependencies.js.map +1 -0
  16. package/dist/config/ignorePaths.d.ts +13 -0
  17. package/dist/config/ignorePaths.d.ts.map +1 -0
  18. package/dist/config/ignorePaths.js +47 -0
  19. package/dist/config/ignorePaths.js.map +1 -0
  20. package/dist/config/projectConfigError.d.ts +7 -0
  21. package/dist/config/projectConfigError.d.ts.map +1 -0
  22. package/dist/config/projectConfigError.js +10 -0
  23. package/dist/config/projectConfigError.js.map +1 -0
  24. package/dist/config/readProjectConfig.d.ts +28 -0
  25. package/dist/config/readProjectConfig.d.ts.map +1 -0
  26. package/dist/config/readProjectConfig.js +120 -0
  27. package/dist/config/readProjectConfig.js.map +1 -0
  28. package/dist/core/analyzeProject.d.ts +40 -1
  29. package/dist/core/analyzeProject.d.ts.map +1 -1
  30. package/dist/core/analyzeProject.js +189 -45
  31. package/dist/core/analyzeProject.js.map +1 -1
  32. package/dist/core/evidence.d.ts +67 -0
  33. package/dist/core/evidence.d.ts.map +1 -0
  34. package/dist/core/evidence.js +115 -0
  35. package/dist/core/evidence.js.map +1 -0
  36. package/dist/core/scanContext.d.ts +20 -0
  37. package/dist/core/scanContext.d.ts.map +1 -0
  38. package/dist/core/scanContext.js +43 -0
  39. package/dist/core/scanContext.js.map +1 -0
  40. package/dist/detectors/eslintManifestConfig.d.ts +18 -0
  41. package/dist/detectors/eslintManifestConfig.d.ts.map +1 -1
  42. package/dist/detectors/eslintManifestConfig.js +62 -80
  43. package/dist/detectors/eslintManifestConfig.js.map +1 -1
  44. package/dist/detectors/eslintRcJsonConfig.d.ts +8 -2
  45. package/dist/detectors/eslintRcJsonConfig.d.ts.map +1 -1
  46. package/dist/detectors/eslintRcJsonConfig.js +27 -12
  47. package/dist/detectors/eslintRcJsonConfig.js.map +1 -1
  48. package/dist/detectors/jestManifestConfig.d.ts +15 -3
  49. package/dist/detectors/jestManifestConfig.d.ts.map +1 -1
  50. package/dist/detectors/jestManifestConfig.js +63 -83
  51. package/dist/detectors/jestManifestConfig.js.map +1 -1
  52. package/dist/reporters/jsonReporter.d.ts +39 -0
  53. package/dist/reporters/jsonReporter.d.ts.map +1 -0
  54. package/dist/reporters/jsonReporter.js +91 -0
  55. package/dist/reporters/jsonReporter.js.map +1 -0
  56. package/dist/reporters/terminalReporter.d.ts +15 -4
  57. package/dist/reporters/terminalReporter.d.ts.map +1 -1
  58. package/dist/reporters/terminalReporter.js +64 -4
  59. package/dist/reporters/terminalReporter.js.map +1 -1
  60. package/dist/scanner/moduleSpecifiers.d.ts +12 -2
  61. package/dist/scanner/moduleSpecifiers.d.ts.map +1 -1
  62. package/dist/scanner/moduleSpecifiers.js +1154 -183
  63. package/dist/scanner/moduleSpecifiers.js.map +1 -1
  64. package/dist/scanner/packageSpecifier.d.ts +26 -2
  65. package/dist/scanner/packageSpecifier.d.ts.map +1 -1
  66. package/dist/scanner/packageSpecifier.js +70 -2
  67. package/dist/scanner/packageSpecifier.js.map +1 -1
  68. package/dist/scanner/projectManifest.d.ts +28 -3
  69. package/dist/scanner/projectManifest.d.ts.map +1 -1
  70. package/dist/scanner/projectManifest.js +58 -13
  71. package/dist/scanner/projectManifest.js.map +1 -1
  72. package/dist/scanner/scriptUsage.d.ts +15 -1
  73. package/dist/scanner/scriptUsage.d.ts.map +1 -1
  74. package/dist/scanner/scriptUsage.js +284 -69
  75. package/dist/scanner/scriptUsage.js.map +1 -1
  76. package/dist/scanner/sourceFiles.d.ts +21 -2
  77. package/dist/scanner/sourceFiles.d.ts.map +1 -1
  78. package/dist/scanner/sourceFiles.js +19 -6
  79. package/dist/scanner/sourceFiles.js.map +1 -1
  80. package/package.json +4 -2
  81. package/schemas/README.md +47 -0
  82. package/schemas/examples/README.md +27 -0
  83. package/schemas/examples/explain-excluded.json +53 -0
  84. package/schemas/examples/explain-missing.json +65 -0
  85. package/schemas/examples/explain-node-preload.json +70 -0
  86. package/schemas/examples/explain-unknown.json +53 -0
  87. package/schemas/examples/scan-clean.json +40 -0
  88. package/schemas/examples/scan-findings.json +80 -0
  89. package/schemas/report-v1.schema.json +376 -0
@@ -8,7 +8,7 @@
8
8
  * It deliberately does not:
9
9
  * - read, parse or execute any discovered file (that belongs to the analyzers / specifier extractor);
10
10
  * - decide whether anything is used, unused or missing;
11
- * - parse `.gitignore` or honor custom ignore configuration (`v0.1.0` uses a fixed built-in set);
11
+ * - parse `.gitignore` or load user configuration (callers supply validated literal rules);
12
12
  * - follow symlinks, which avoids cycles and scanning content outside the intended project tree;
13
13
  * - mutate the analyzed project.
14
14
  *
@@ -16,10 +16,19 @@
16
16
  * instead of walking every subtree and filtering afterwards. The result is sorted deterministically
17
17
  * so the same tree always yields the same order.
18
18
  */
19
+ /** Pure effective defaults for report scope; never starts discovery or exposes mutable sets. */
20
+ export declare function sourceDiscoveryDefaults(): {
21
+ sourceExtensions: readonly string[];
22
+ excludedDirectories: readonly string[];
23
+ };
19
24
  /**
20
25
  * A discovered source file as an absolute, platform-separated path, sorted lexicographically.
21
26
  */
22
27
  export type DiscoveredSourceFile = string;
28
+ /** Internal discovery inputs; callers supply normalized, validated project-relative rules. */
29
+ export type SourceDiscoveryOptions = {
30
+ readonly ignorePaths?: readonly string[] | undefined;
31
+ };
23
32
  /**
24
33
  * Why source discovery could not run.
25
34
  *
@@ -48,5 +57,15 @@ export declare class SourceFilesError extends Error {
48
57
  *
49
58
  * @throws {SourceFilesError} when the root is missing, is not a directory, or cannot be read.
50
59
  */
51
- export declare function discoverSourceFiles(projectRoot: string): Promise<readonly DiscoveredSourceFile[]>;
60
+ export declare function discoverSourceFiles(projectRoot: string, options?: SourceDiscoveryOptions): Promise<readonly DiscoveredSourceFile[]>;
61
+ /**
62
+ * Validate that the resolved root exists and is a directory before walking it. A missing root is
63
+ * reported separately from a root that is a regular file, and any other I/O failure stays
64
+ * `unreadable`.
65
+ *
66
+ * `lstat` (not `stat`) is used on purpose: it does not follow a symlink supplied as the root, so a
67
+ * symlinked root is rejected instead of being traversed, keeping the "never follow symlinks"
68
+ * contract consistent from the entry point down.
69
+ */
70
+ export declare function assertReadableRoot(root: string): Promise<void>;
52
71
  //# sourceMappingURL=sourceFiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sourceFiles.d.ts","sourceRoot":"","sources":["../../src/scanner/sourceFiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA2CH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAEhF;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,OAAO;CAKzE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAY1C"}
1
+ {"version":3,"file":"sourceFiles.d.ts","sourceRoot":"","sources":["../../src/scanner/sourceFiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA6CH,gGAAgG;AAChG,wBAAgB,uBAAuB,IAAI;IACzC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAKA;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE1C,8FAA8F;AAC9F,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACtD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAEhF;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,OAAO;CAKzE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAY1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBpE"}
@@ -8,7 +8,7 @@
8
8
  * It deliberately does not:
9
9
  * - read, parse or execute any discovered file (that belongs to the analyzers / specifier extractor);
10
10
  * - decide whether anything is used, unused or missing;
11
- * - parse `.gitignore` or honor custom ignore configuration (`v0.1.0` uses a fixed built-in set);
11
+ * - parse `.gitignore` or load user configuration (callers supply validated literal rules);
12
12
  * - follow symlinks, which avoids cycles and scanning content outside the intended project tree;
13
13
  * - mutate the analyzed project.
14
14
  *
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import { lstat, readdir } from 'node:fs/promises';
20
20
  import { extname, join, resolve } from 'node:path';
21
+ import { matchesIgnoredPath } from '../config/ignorePaths.js';
21
22
  /**
22
23
  * The supported source and declaration extensions for `v0.1.0`.
23
24
  *
@@ -54,6 +55,13 @@ const IGNORED_DIRECTORY_NAMES = new Set([
54
55
  '.next',
55
56
  '.nuxt',
56
57
  ]);
58
+ /** Pure effective defaults for report scope; never starts discovery or exposes mutable sets. */
59
+ export function sourceDiscoveryDefaults() {
60
+ return {
61
+ sourceExtensions: [...SUPPORTED_EXTENSIONS].sort(),
62
+ excludedDirectories: [...IGNORED_DIRECTORY_NAMES].sort(),
63
+ };
64
+ }
57
65
  /**
58
66
  * Operational error for source discovery. The `code` lets callers (the CLI in a later step) render
59
67
  * a clean message without matching on error strings.
@@ -77,11 +85,11 @@ export class SourceFilesError extends Error {
77
85
  *
78
86
  * @throws {SourceFilesError} when the root is missing, is not a directory, or cannot be read.
79
87
  */
80
- export async function discoverSourceFiles(projectRoot) {
88
+ export async function discoverSourceFiles(projectRoot, options = {}) {
81
89
  const root = resolve(projectRoot);
82
90
  await assertReadableRoot(root);
83
91
  const files = [];
84
- await walk(root, files);
92
+ await walk(root, '', files, options.ignorePaths ?? []);
85
93
  // Sort the final result so the contract is explicitly deterministic regardless of filesystem
86
94
  // enumeration order.
87
95
  files.sort(comparePaths);
@@ -96,7 +104,7 @@ export async function discoverSourceFiles(projectRoot) {
96
104
  * symlinked root is rejected instead of being traversed, keeping the "never follow symlinks"
97
105
  * contract consistent from the entry point down.
98
106
  */
99
- async function assertReadableRoot(root) {
107
+ export async function assertReadableRoot(root) {
100
108
  try {
101
109
  const info = await lstat(root);
102
110
  if (info.isSymbolicLink()) {
@@ -117,7 +125,7 @@ async function assertReadableRoot(root) {
117
125
  * Recursively collect supported files under `directory`, pruning ignored directories and skipping
118
126
  * symlinks before descending.
119
127
  */
120
- async function walk(directory, files) {
128
+ async function walk(directory, relativeDirectory, files, ignorePaths) {
121
129
  let entries;
122
130
  try {
123
131
  entries = await readdir(directory, { withFileTypes: true });
@@ -130,13 +138,18 @@ async function walk(directory, files) {
130
138
  if (entry.isSymbolicLink()) {
131
139
  continue;
132
140
  }
141
+ // Build the portable matching path from directory entries, preserving literal backslashes on
142
+ // POSIX. Only traversal separators become '/', independently of the host's native separator.
143
+ const relativePath = relativeDirectory === '' ? entry.name : `${relativeDirectory}/${entry.name}`;
144
+ if (matchesIgnoredPath(relativePath, ignorePaths))
145
+ continue;
133
146
  const fullPath = join(directory, entry.name);
134
147
  if (entry.isDirectory()) {
135
148
  if (IGNORED_DIRECTORY_NAMES.has(entry.name)) {
136
149
  // Prune before descending so trees like `node_modules` are never enumerated.
137
150
  continue;
138
151
  }
139
- await walk(fullPath, files);
152
+ await walk(fullPath, relativePath, files, ignorePaths);
140
153
  continue;
141
154
  }
142
155
  if (entry.isFile() && isSupportedFile(entry.name)) {
@@ -1 +1 @@
1
- {"version":3,"file":"sourceFiles.js","sourceRoot":"","sources":["../../src/scanner/sourceFiles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sourceFiles.js","sourceRoot":"","sources":["../../src/scanner/sourceFiles.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "depvitals",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Find unused and undeclared npm dependencies in JavaScript and TypeScript projects with a zero-config CLI and no runtime dependencies.",
5
5
  "keywords": [
6
6
  "nodejs",
@@ -30,7 +30,8 @@
30
30
  "homepage": "https://github.com/MatiasRicardi/depvitals#readme",
31
31
  "files": [
32
32
  "dist",
33
- "README.md"
33
+ "README.md",
34
+ "schemas"
34
35
  ],
35
36
  "bin": {
36
37
  "depvitals": "./dist/cli/index.js"
@@ -59,6 +60,7 @@
59
60
  "@eslint/js": "10.0.1",
60
61
  "@types/node": "22.20.5",
61
62
  "@vitest/coverage-v8": "5.0.3",
63
+ "ajv": "6.15.0",
62
64
  "eslint": "10.12.0",
63
65
  "eslint-config-prettier": "10.1.8",
64
66
  "globals": "17.13.0",
@@ -0,0 +1,47 @@
1
+ # DepVitals JSON report format v1
2
+
3
+ [report-v1.schema.json](report-v1.schema.json) is the Draft 7 schema for dependency scans and exact-package explanations. It is a data artifact, not a JavaScript API or a runtime validation dependency. The schema version is independent of the CLI release version; `tool.version` identifies the actual producing version.
4
+
5
+ A report is one UTF-8 JSON document, indented by two spaces, followed by one LF. Its fields are `schemaVersion`, `tool`, `mode`, `project`, `scope`, `findings`, `counts`, `packages` and `query`, in that order. There are no timestamps, durations, banners or error-shaped documents. An operational failure produces no report.
6
+
7
+ `project.root` is the absolute native-platform root. Evidence filenames are relative paths using `/` separators, preserving casing and literal filename characters. JSON escaping preserves the original strings, including control characters and backslashes; terminal display escaping is separate. Changing the checkout root changes document identity.
8
+
9
+ `scope` contains the actual source extensions, fixed excluded directory names and effective normalized `ignorePaths` and `ignoreDependencies`. It describes supported discovery, not proof that a package can safely be removed. Source evidence can suppress unused findings and produce missing findings. Script/config evidence only credits eligible declared packages. Exclusions are policy, not evidence.
10
+
11
+ A package retains all four declaration memberships, status, dependency exclusion, underlying findings before exclusions, visible findings after exclusions and genuine source/script/config evidence. Unused dependencies and devDependencies remain separate, including when a name occurs in both. Peer/optional-only declarations are not unused candidates. Exclusion preserves evidence and underlying findings while hiding visible findings.
12
+
13
+ In scan mode, `query` is null. In explanation mode, exactly one package and its visible findings/counts are reported, with `{ "packageName": "...", "known": true }` or false. An absent valid query is a completed unknown record; exclusion-only names are known. Unrelated findings are omitted, but unrelated retained-input errors still prevent completion of the scan.
14
+
15
+ Consumers should ignore unknown object properties. In addition to schema validation, check that counts equal corresponding visible array lengths, packages agree with findings/status, query identity matches its single record and all prescribed sorting/identity rules hold. Schema validation alone cannot prove these relationships or the correctness of source locations.
16
+
17
+ ## Ordering and duplicate identity
18
+
19
+ All string comparisons use case-sensitive ECMAScript lexicographic order over UTF-16 code units, independent of locale. Do not lowercase or Unicode-normalize strings. Findings and each scope array are sorted and duplicate-free. Packages are unique by exact `name` and sorted by that string; an empty scanned name remains valid data.
20
+
21
+ Declaration groups always follow `dependencies`, `devDependencies`, `peerDependencies`, `optionalDependencies`. Finding identifiers in package `underlyingFindings` and `findings` always follow `unusedDependencies`, `unusedDevDependencies`, `missingDependencies`. These arrays have no duplicates. The three fields in the envelope's findings/counts objects follow that same category order. Count each category independently: a name unused in both dependency groups contributes one to each corresponding count.
22
+
23
+ Within each package, evidence is ordered by kind (source, script, config), then by `file` using the string comparison above, then by these kind-specific fields, in order:
24
+
25
+ | Kind | Remaining sort keys |
26
+ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | source | Numeric `position.offset`; reference rank `import`, `export-from`, `dynamic-import`, `require`; `specifier`; numeric `position.line`; numeric `position.column`. The final two keys break ties deterministically. |
28
+ | script | `pointer`; numeric `occurrence`; via rank `direct`, `mapping`, `runner`, `node-preload`; `command`. |
29
+ | config | `pointer`; detector rank `eslint`, `jest`; `value`. |
30
+
31
+ Deduplicate only complete semantic records of the same kind. Source identity includes `kind`, `file`, `reference`, `specifier` and all three position fields. Script identity includes `kind`, `file`, `pointer`, `command`, `via` and `occurrence`. Config identity includes `kind`, `file`, `pointer`, `value` and `detector`. Object-property insertion order and unrecognized additive properties do not change these identities. Distinct offsets, script ordinals, config pointers or kinds remain distinct even when they name the same package or selector. Do not deduplicate solely by package name or specifier.
32
+
33
+ ## Evidence meaning and position units
34
+
35
+ Source records have fields `kind`, `file`, `reference`, `specifier`, `position`, in that order; position has `offset`, `line`, `column`. The specifier is the decoded recognized string before package-root normalization. A subpath may therefore differ from the owning package name.
36
+
37
+ `position.offset` is the zero-based UTF-16 code-unit offset of the opening quote of the specifier literal in the original source text decoded as UTF-8. It points to the quote, not the import/require keyword. Lines and columns are one-based; columns count UTF-16 code units, not bytes, Unicode scalar values or display width. A tab adds one column and a surrogate pair adds two. LF, CR, CRLF, U+2028 and U+2029 end a line, with CRLF counted once. Do not normalize line endings or strip a BOM before measuring: both CRLF code units participate in offsets, and a BOM participates in offsets/columns. Escapes are decoded in `specifier` but positions still refer to the original source spelling. No end position or JSON-config character position is implied.
38
+
39
+ Evidence filenames are lexical project-relative paths with `/` separators and no leading slash, empty component, `.` or `..` component. Preserve actual casing; a literal backslash in a POSIX filename remains data. Do not resolve filesystem targets to interpret a display path.
40
+
41
+ Script fields are `kind`, `file`, `pointer`, `command`, `via`, `occurrence`. The file is `package.json`; the pointer identifies the actual script key. `command` is the dequoted semantic selector: executable for direct/mapped commands, immediate package argument for a supported runner, or module selector without the option prefix for a supported Node preload. It is not the complete script text or an installed executable path. `occurrence` is a zero-based ordinal of accepted external candidate events across the whole script, before declaration filtering, deduplication or dependency exclusions; it resets per script key. Undeclared external candidates consume ordinals; internal/builtin/unsupported selectors and discarded candidates do not. Repeated accepted selectors keep distinct ordinals. Script credit remains gated to dependencies/devDependencies and never creates missing findings.
42
+
43
+ Config fields are `kind`, `file`, `pointer`, `value`, `detector`. The filename preserves the actual selected configuration filename's casing. `value` is the exact recognized string, not inferred source usage. The detector is `eslint` or `jest`; only eligible declared packages gain config evidence. Neither config nor script records claim source line/column positions.
44
+
45
+ Pointers are RFC 6901 data pointers, not URL fragments: escape each object-key token's `~` as `~0` and `/` as `~1`; array indices are zero-based decimal without leading zeroes. A pointer identifies the exact string field/array element, not a config object or transformer options. Preserve original pointer strings through JSON escaping; do not percent-encode them or interpret literal escape text as a control character.
46
+
47
+ The six [normative examples](examples/README.md) illustrate target-release documents. They are not evidence of release publication or feature availability in an earlier installed CLI. No package JavaScript entrypoint is introduced.
@@ -0,0 +1,27 @@
1
+ # Report format v1 examples
2
+
3
+ These six normative examples describe the target v0.4.0 release. Their conceptual root is `/example/project` and their illustrative `tool.version` is `0.4.0`; actual reports use the real selected root and installed tool version. They do not claim that an earlier CLI already accepts format or explanation options. See the [schema](../report-v1.schema.json) and [format description](../README.md).
4
+
5
+ | Document | Scenario and intended exit |
6
+ | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
7
+ | [scan-clean.json](scan-clean.json) | Empty manifest and no supported source; scan exit 0. |
8
+ | [scan-findings.json](scan-findings.json) | Dependencies declare `unused`, devDependencies declare `unused-tool`; `src/index.ts` contains `import item from 'missing';` and a final LF. Scan exit 1. The quote is at zero-based UTF-16 offset 17, line 1, column 18. |
9
+ | [explain-missing.json](explain-missing.json) | Query `missing` in that same project; exit 1, excluding unrelated unused findings. |
10
+ | [explain-excluded.json](explain-excluded.json) | Dependency `unused`, no sources, exact ignoreDependencies entry `unused`; query exit 0, preserving its underlying unused finding. |
11
+ | [explain-unknown.json](explain-unknown.json) | Empty project, query `absent`; completed unknown record and exit 1. |
12
+ | [explain-node-preload.json](explain-node-preload.json) | Dev dependency `preload` used by the selected Node preload recognition described below; query exit 0. |
13
+
14
+ The Node-preload example assumes this manifest and an empty `entry.cjs`:
15
+
16
+ ```json
17
+ {
18
+ "devDependencies": { "preload": "1" },
19
+ "scripts": {
20
+ "check/node~": "unlisted-tool && node --import=preload/esm --import=preload/esm ./entry.cjs"
21
+ }
22
+ }
23
+ ```
24
+
25
+ The candidate ordinals are unlisted-tool=0, node=1, preload=2 and preload=3 before declaration filtering. The undeclared commands create no package records or missing findings. The two preload selectors retain distinct script occurrences and the escaped pointer `/scripts/check~1node~0`. Their module selector is `preload/esm`, owned by package `preload`, without installed resolution or execution. This example describes the target recognition; serializing supplied facts alone does not establish that a particular CLI version collects them.
26
+
27
+ Invalid manifest/config/source inputs intentionally have no report fixture. Their expected stdout is empty, stderr identifies the error and exit is 1. They must not be represented as successful clean documents.
@@ -0,0 +1,53 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "explain",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": ["unused"]
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": [],
30
+ "unusedDevDependencies": [],
31
+ "missingDependencies": []
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 0,
35
+ "unusedDevDependencies": 0,
36
+ "missingDependencies": 0
37
+ },
38
+ "packages": [
39
+ {
40
+ "name": "unused",
41
+ "status": "excluded",
42
+ "declaredIn": ["dependencies"],
43
+ "excluded": true,
44
+ "underlyingFindings": ["unusedDependencies"],
45
+ "findings": [],
46
+ "evidence": []
47
+ }
48
+ ],
49
+ "query": {
50
+ "packageName": "unused",
51
+ "known": true
52
+ }
53
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "explain",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": []
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": [],
30
+ "unusedDevDependencies": [],
31
+ "missingDependencies": ["missing"]
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 0,
35
+ "unusedDevDependencies": 0,
36
+ "missingDependencies": 1
37
+ },
38
+ "packages": [
39
+ {
40
+ "name": "missing",
41
+ "status": "missing",
42
+ "declaredIn": [],
43
+ "excluded": false,
44
+ "underlyingFindings": ["missingDependencies"],
45
+ "findings": ["missingDependencies"],
46
+ "evidence": [
47
+ {
48
+ "kind": "source",
49
+ "file": "src/index.ts",
50
+ "reference": "import",
51
+ "specifier": "missing",
52
+ "position": {
53
+ "offset": 17,
54
+ "line": 1,
55
+ "column": 18
56
+ }
57
+ }
58
+ ]
59
+ }
60
+ ],
61
+ "query": {
62
+ "packageName": "missing",
63
+ "known": true
64
+ }
65
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "explain",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": []
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": [],
30
+ "unusedDevDependencies": [],
31
+ "missingDependencies": []
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 0,
35
+ "unusedDevDependencies": 0,
36
+ "missingDependencies": 0
37
+ },
38
+ "packages": [
39
+ {
40
+ "name": "preload",
41
+ "status": "used",
42
+ "declaredIn": ["devDependencies"],
43
+ "excluded": false,
44
+ "underlyingFindings": [],
45
+ "findings": [],
46
+ "evidence": [
47
+ {
48
+ "kind": "script",
49
+ "file": "package.json",
50
+ "pointer": "/scripts/check~1node~0",
51
+ "command": "preload/esm",
52
+ "via": "node-preload",
53
+ "occurrence": 2
54
+ },
55
+ {
56
+ "kind": "script",
57
+ "file": "package.json",
58
+ "pointer": "/scripts/check~1node~0",
59
+ "command": "preload/esm",
60
+ "via": "node-preload",
61
+ "occurrence": 3
62
+ }
63
+ ]
64
+ }
65
+ ],
66
+ "query": {
67
+ "packageName": "preload",
68
+ "known": true
69
+ }
70
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "explain",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": []
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": [],
30
+ "unusedDevDependencies": [],
31
+ "missingDependencies": []
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 0,
35
+ "unusedDevDependencies": 0,
36
+ "missingDependencies": 0
37
+ },
38
+ "packages": [
39
+ {
40
+ "name": "absent",
41
+ "status": "unknown",
42
+ "declaredIn": [],
43
+ "excluded": false,
44
+ "underlyingFindings": [],
45
+ "findings": [],
46
+ "evidence": []
47
+ }
48
+ ],
49
+ "query": {
50
+ "packageName": "absent",
51
+ "known": false
52
+ }
53
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "scan",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": []
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": [],
30
+ "unusedDevDependencies": [],
31
+ "missingDependencies": []
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 0,
35
+ "unusedDevDependencies": 0,
36
+ "missingDependencies": 0
37
+ },
38
+ "packages": [],
39
+ "query": null
40
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "tool": {
4
+ "name": "depvitals",
5
+ "version": "0.4.0"
6
+ },
7
+ "mode": "scan",
8
+ "project": {
9
+ "root": "/example/project"
10
+ },
11
+ "scope": {
12
+ "sourceExtensions": [".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"],
13
+ "excludedDirectories": [
14
+ ".cache",
15
+ ".git",
16
+ ".next",
17
+ ".nuxt",
18
+ ".turbo",
19
+ "build",
20
+ "coverage",
21
+ "dist",
22
+ "node_modules",
23
+ "out"
24
+ ],
25
+ "ignorePaths": [],
26
+ "ignoreDependencies": []
27
+ },
28
+ "findings": {
29
+ "unusedDependencies": ["unused"],
30
+ "unusedDevDependencies": ["unused-tool"],
31
+ "missingDependencies": ["missing"]
32
+ },
33
+ "counts": {
34
+ "unusedDependencies": 1,
35
+ "unusedDevDependencies": 1,
36
+ "missingDependencies": 1
37
+ },
38
+ "packages": [
39
+ {
40
+ "name": "missing",
41
+ "status": "missing",
42
+ "declaredIn": [],
43
+ "excluded": false,
44
+ "underlyingFindings": ["missingDependencies"],
45
+ "findings": ["missingDependencies"],
46
+ "evidence": [
47
+ {
48
+ "kind": "source",
49
+ "file": "src/index.ts",
50
+ "reference": "import",
51
+ "specifier": "missing",
52
+ "position": {
53
+ "offset": 17,
54
+ "line": 1,
55
+ "column": 18
56
+ }
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ "name": "unused",
62
+ "status": "unused",
63
+ "declaredIn": ["dependencies"],
64
+ "excluded": false,
65
+ "underlyingFindings": ["unusedDependencies"],
66
+ "findings": ["unusedDependencies"],
67
+ "evidence": []
68
+ },
69
+ {
70
+ "name": "unused-tool",
71
+ "status": "unused",
72
+ "declaredIn": ["devDependencies"],
73
+ "excluded": false,
74
+ "underlyingFindings": ["unusedDevDependencies"],
75
+ "findings": ["unusedDevDependencies"],
76
+ "evidence": []
77
+ }
78
+ ],
79
+ "query": null
80
+ }