jsdoczoom 0.3.0 → 0.4.5
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/barrel.js +26 -1
- package/dist/cache.js +97 -0
- package/dist/cli.js +201 -110
- package/dist/drilldown.js +163 -53
- package/dist/file-discovery.js +1 -2
- package/dist/index.js +7 -5
- package/dist/lint.js +38 -15
- package/dist/skill-text.js +7 -6
- package/dist/type-declarations.js +6 -4
- package/dist/types.js +4 -0
- package/dist/validate.js +31 -38
- package/package.json +13 -9
- package/types/barrel.d.ts +10 -0
- package/types/cache.d.ts +74 -0
- package/types/drilldown.d.ts +5 -3
- package/types/file-discovery.d.ts +14 -0
- package/types/index.d.ts +9 -4
- package/types/lint.d.ts +5 -1
- package/types/skill-text.d.ts +1 -1
- package/types/types.d.ts +10 -0
- package/types/validate.d.ts +6 -1
package/dist/validate.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { relative } from "node:path";
|
|
3
|
+
import { findMissingBarrels } from "./barrel.js";
|
|
4
|
+
import { processWithCache } from "./cache.js";
|
|
4
5
|
import { JsdocError } from "./errors.js";
|
|
5
6
|
import {
|
|
6
7
|
createValidationLinter,
|
|
@@ -9,50 +10,28 @@ import {
|
|
|
9
10
|
} from "./eslint-engine.js";
|
|
10
11
|
import { discoverFiles } from "./file-discovery.js";
|
|
11
12
|
import { GUIDANCE } from "./skill-text.js";
|
|
12
|
-
import { VALIDATION_STATUS_PRIORITY } from "./types.js";
|
|
13
|
+
import { DEFAULT_CACHE_DIR, VALIDATION_STATUS_PRIORITY } from "./types.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Classify a single file against validation requirements.
|
|
16
17
|
*
|
|
17
18
|
* Reads the file, lints it with the ESLint engine, and maps the
|
|
18
19
|
* resulting messages to a single ValidationStatus using priority order.
|
|
20
|
+
* Results are cached by file content hash.
|
|
19
21
|
*/
|
|
20
|
-
async function classifyFile(eslint, filePath, cwd) {
|
|
22
|
+
async function classifyFile(eslint, filePath, cwd, config) {
|
|
21
23
|
const relativePath = relative(cwd, filePath);
|
|
22
24
|
let sourceText;
|
|
23
25
|
try {
|
|
24
|
-
sourceText =
|
|
26
|
+
sourceText = await readFile(filePath, "utf-8");
|
|
25
27
|
} catch {
|
|
26
28
|
throw new JsdocError("FILE_NOT_FOUND", `File not found: ${filePath}`);
|
|
27
29
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const BARREL_THRESHOLD = 3;
|
|
34
|
-
/**
|
|
35
|
-
* Find directories with more than BARREL_THRESHOLD .ts/.tsx files
|
|
36
|
-
* that lack a barrel file (index.ts or index.tsx).
|
|
37
|
-
*/
|
|
38
|
-
function findMissingBarrels(filePaths, cwd) {
|
|
39
|
-
const dirCounts = new Map();
|
|
40
|
-
for (const filePath of filePaths) {
|
|
41
|
-
if (isBarrel(filePath)) continue;
|
|
42
|
-
const dir = dirname(filePath);
|
|
43
|
-
dirCounts.set(dir, (dirCounts.get(dir) ?? 0) + 1);
|
|
44
|
-
}
|
|
45
|
-
const missing = [];
|
|
46
|
-
for (const [dir, count] of dirCounts) {
|
|
47
|
-
if (count <= BARREL_THRESHOLD) continue;
|
|
48
|
-
const hasBarrel =
|
|
49
|
-
existsSync(join(dir, "index.ts")) || existsSync(join(dir, "index.tsx"));
|
|
50
|
-
if (!hasBarrel) {
|
|
51
|
-
const rel = relative(cwd, dir) || ".";
|
|
52
|
-
missing.push(rel);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return missing.sort();
|
|
30
|
+
return processWithCache(config, "validate", sourceText, async () => {
|
|
31
|
+
const messages = await lintFileForValidation(eslint, sourceText, filePath);
|
|
32
|
+
const status = mapToValidationStatus(messages);
|
|
33
|
+
return { path: relativePath, status };
|
|
34
|
+
});
|
|
56
35
|
}
|
|
57
36
|
/**
|
|
58
37
|
* Group file statuses into a ValidationResult, applying a limit
|
|
@@ -95,11 +74,19 @@ function buildGroupedResult(statuses, missingBarrels, limit) {
|
|
|
95
74
|
* @param selector - Selector information (glob or path)
|
|
96
75
|
* @param cwd - Working directory for resolving paths
|
|
97
76
|
* @param limit - Max number of invalid file paths to include (default 100)
|
|
77
|
+
* @param gitignore - Whether to respect .gitignore (default true)
|
|
78
|
+
* @param config - Cache configuration (default: enabled with system temp dir)
|
|
98
79
|
* @returns Grouped validation results
|
|
99
80
|
* @throws {JsdocError} NO_FILES_MATCHED if glob selector matches no files
|
|
100
81
|
* @throws {JsdocError} FILE_NOT_FOUND if path selector targets nonexistent file
|
|
101
82
|
*/
|
|
102
|
-
export async function validate(
|
|
83
|
+
export async function validate(
|
|
84
|
+
selector,
|
|
85
|
+
cwd,
|
|
86
|
+
limit = 100,
|
|
87
|
+
gitignore = true,
|
|
88
|
+
config = { enabled: true, directory: DEFAULT_CACHE_DIR },
|
|
89
|
+
) {
|
|
103
90
|
const files = discoverFiles(selector.pattern, cwd, gitignore);
|
|
104
91
|
if (files.length === 0) {
|
|
105
92
|
throw new JsdocError(
|
|
@@ -109,7 +96,7 @@ export async function validate(selector, cwd, limit = 100, gitignore = true) {
|
|
|
109
96
|
}
|
|
110
97
|
const eslint = createValidationLinter();
|
|
111
98
|
const statuses = await Promise.all(
|
|
112
|
-
files.map((f) => classifyFile(eslint, f, cwd)),
|
|
99
|
+
files.map((f) => classifyFile(eslint, f, cwd, config)),
|
|
113
100
|
);
|
|
114
101
|
const missingBarrels = findMissingBarrels(files, cwd);
|
|
115
102
|
return buildGroupedResult(statuses, missingBarrels, limit);
|
|
@@ -122,15 +109,21 @@ export async function validate(selector, cwd, limit = 100, gitignore = true) {
|
|
|
122
109
|
* @param filePaths - List of file paths to validate
|
|
123
110
|
* @param cwd - Working directory for resolving relative paths
|
|
124
111
|
* @param limit - Max number of invalid file paths to include (default 100)
|
|
112
|
+
* @param config - Cache configuration (default: enabled with system temp dir)
|
|
125
113
|
* @returns Grouped validation results
|
|
126
114
|
*/
|
|
127
|
-
export async function validateFiles(
|
|
115
|
+
export async function validateFiles(
|
|
116
|
+
filePaths,
|
|
117
|
+
cwd,
|
|
118
|
+
limit = 100,
|
|
119
|
+
config = { enabled: true, directory: DEFAULT_CACHE_DIR },
|
|
120
|
+
) {
|
|
128
121
|
const tsFiles = filePaths.filter(
|
|
129
122
|
(f) => f.endsWith(".ts") || f.endsWith(".tsx"),
|
|
130
123
|
);
|
|
131
124
|
const eslint = createValidationLinter();
|
|
132
125
|
const statuses = await Promise.all(
|
|
133
|
-
tsFiles.map((f) => classifyFile(eslint, f, cwd)),
|
|
126
|
+
tsFiles.map((f) => classifyFile(eslint, f, cwd, config)),
|
|
134
127
|
);
|
|
135
128
|
const missingBarrels = findMissingBarrels(tsFiles, cwd);
|
|
136
129
|
return buildGroupedResult(statuses, missingBarrels, limit);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsdoczoom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "CLI tool for extracting JSDoc summaries at configurable depths",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,23 +35,27 @@
|
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"typecheck": "tsc --noEmit",
|
|
38
|
-
"build": "
|
|
38
|
+
"build": "yarn build:claude-code-hooks && yarn build:cli && yarn build:hooks",
|
|
39
|
+
"build:cli": "tsc --build tsconfig.build.json",
|
|
40
|
+
"build:claude-code-hooks": "cd ../claude-code-hooks && yarn build",
|
|
41
|
+
"build:hooks": "claude-code-hooks -i \"src/hooks/*.ts\" -o \"../../plugins/jsdoczoom/hooks/hooks.json\"",
|
|
39
42
|
"test": "vitest run",
|
|
40
43
|
"lint": "biome check --write --unsafe --max-diagnostics 500 .",
|
|
41
44
|
"release": "bash ../../scripts/release-package.sh jsdoczoom",
|
|
42
45
|
"release:dry-run": "bash ../../scripts/release-package.sh jsdoczoom --dry-run"
|
|
43
46
|
},
|
|
44
47
|
"dependencies": {
|
|
45
|
-
"@
|
|
46
|
-
"eslint": "^
|
|
47
|
-
"eslint
|
|
48
|
-
"
|
|
48
|
+
"@goodfoot/claude-code-hooks": "workspace:*",
|
|
49
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
50
|
+
"eslint": "^10.0.0",
|
|
51
|
+
"eslint-plugin-jsdoc": "^62.5.5",
|
|
52
|
+
"glob": "^13.0.3",
|
|
49
53
|
"ignore": "^7.0.5",
|
|
50
54
|
"typescript": "^5.9.3"
|
|
51
55
|
},
|
|
52
56
|
"devDependencies": {
|
|
53
|
-
"@biomejs/biome": "2.
|
|
54
|
-
"@types/node": "^
|
|
55
|
-
"vitest": "4.0.
|
|
57
|
+
"@biomejs/biome": "2.4.1",
|
|
58
|
+
"@types/node": "^25.2.3",
|
|
59
|
+
"vitest": "4.0.18"
|
|
56
60
|
}
|
|
57
61
|
}
|
package/types/barrel.d.ts
CHANGED
|
@@ -33,3 +33,13 @@ export declare function getBarrelChildren(
|
|
|
33
33
|
barrelPath: string,
|
|
34
34
|
_cwd: string,
|
|
35
35
|
): string[];
|
|
36
|
+
/** Minimum number of .ts/.tsx files in a directory to require a barrel. */
|
|
37
|
+
export declare const BARREL_THRESHOLD = 3;
|
|
38
|
+
/**
|
|
39
|
+
* Find directories with more than BARREL_THRESHOLD .ts/.tsx files
|
|
40
|
+
* that lack a barrel file (index.ts or index.tsx).
|
|
41
|
+
*/
|
|
42
|
+
export declare function findMissingBarrels(
|
|
43
|
+
filePaths: string[],
|
|
44
|
+
cwd: string,
|
|
45
|
+
): string[];
|
package/types/cache.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-hash-based disk caching layer for expensive operations (TypeScript
|
|
3
|
+
* compilation, ESLint linting, JSDoc parsing). Uses SHA-256 hashing to cache
|
|
4
|
+
* results keyed by file content, enabling near-instantaneous repeated runs
|
|
5
|
+
* when files haven't changed. All cache errors degrade gracefully without
|
|
6
|
+
* propagating to callers.
|
|
7
|
+
*
|
|
8
|
+
* @summary Content-hash-based disk cache with graceful error handling
|
|
9
|
+
*/
|
|
10
|
+
import type { CacheConfig, CacheOperationMode } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Compute a SHA-256 content hash for the given string.
|
|
13
|
+
*
|
|
14
|
+
* @param content - The content to hash
|
|
15
|
+
* @returns Hex-encoded SHA-256 digest
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeContentHash(content: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Ensure the cache directory exists for the given operation mode.
|
|
20
|
+
* Silently swallows all errors (mkdir failures are handled by read/write ops).
|
|
21
|
+
*
|
|
22
|
+
* @param config - Cache configuration
|
|
23
|
+
* @param mode - Operation mode (drilldown, validate, or lint)
|
|
24
|
+
*/
|
|
25
|
+
export declare function ensureCacheDir(
|
|
26
|
+
config: CacheConfig,
|
|
27
|
+
mode: CacheOperationMode,
|
|
28
|
+
): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Read a cached entry from disk. Returns null on any error (cache miss, ENOENT,
|
|
31
|
+
* corrupted JSON, permission denied, etc.). Never throws.
|
|
32
|
+
*
|
|
33
|
+
* @param config - Cache configuration
|
|
34
|
+
* @param mode - Operation mode namespace
|
|
35
|
+
* @param hash - Content hash key
|
|
36
|
+
* @returns Parsed cached data or null on any error
|
|
37
|
+
*/
|
|
38
|
+
export declare function readCacheEntry<T>(
|
|
39
|
+
config: CacheConfig,
|
|
40
|
+
mode: CacheOperationMode,
|
|
41
|
+
hash: string,
|
|
42
|
+
): Promise<T | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Write a cache entry to disk using atomic write (write to .tmp then rename).
|
|
45
|
+
* Silently swallows all errors (permission denied, disk full, etc.). Never throws.
|
|
46
|
+
*
|
|
47
|
+
* @param config - Cache configuration
|
|
48
|
+
* @param mode - Operation mode namespace
|
|
49
|
+
* @param hash - Content hash key
|
|
50
|
+
* @param data - Data to cache (must be JSON-serializable)
|
|
51
|
+
*/
|
|
52
|
+
export declare function writeCacheEntry<T>(
|
|
53
|
+
config: CacheConfig,
|
|
54
|
+
mode: CacheOperationMode,
|
|
55
|
+
hash: string,
|
|
56
|
+
data: T,
|
|
57
|
+
): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Execute a computation with caching. If cache is enabled and entry exists,
|
|
60
|
+
* returns cached result. Otherwise, computes result, stores it (fire-and-forget),
|
|
61
|
+
* and returns it. Degrades gracefully on all cache errors by always computing.
|
|
62
|
+
*
|
|
63
|
+
* @param config - Cache configuration
|
|
64
|
+
* @param mode - Operation mode namespace
|
|
65
|
+
* @param content - File content to hash for cache key
|
|
66
|
+
* @param compute - Function to compute the result on cache miss
|
|
67
|
+
* @returns Cached or computed result
|
|
68
|
+
*/
|
|
69
|
+
export declare function processWithCache<T>(
|
|
70
|
+
config: CacheConfig,
|
|
71
|
+
mode: CacheOperationMode,
|
|
72
|
+
content: string,
|
|
73
|
+
compute: () => T | Promise<T>,
|
|
74
|
+
): Promise<T>;
|
package/types/drilldown.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DrilldownResult, SelectorInfo } from "./types.js";
|
|
1
|
+
import type { CacheConfig, DrilldownResult, SelectorInfo } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Main entry point for normal-mode processing.
|
|
4
4
|
*
|
|
@@ -18,7 +18,8 @@ export declare function drilldown(
|
|
|
18
18
|
cwd: string,
|
|
19
19
|
gitignore?: boolean,
|
|
20
20
|
limit?: number,
|
|
21
|
-
|
|
21
|
+
config?: CacheConfig,
|
|
22
|
+
): Promise<DrilldownResult>;
|
|
22
23
|
/**
|
|
23
24
|
* Process an explicit list of file paths at a given depth.
|
|
24
25
|
*
|
|
@@ -35,4 +36,5 @@ export declare function drilldownFiles(
|
|
|
35
36
|
depth: number | undefined,
|
|
36
37
|
cwd: string,
|
|
37
38
|
limit?: number,
|
|
38
|
-
|
|
39
|
+
config?: CacheConfig,
|
|
40
|
+
): Promise<DrilldownResult>;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import { type Ignore } from "ignore";
|
|
2
|
+
/**
|
|
3
|
+
* Walks .gitignore files from cwd to filesystem root, building an ignore
|
|
4
|
+
* filter that glob results pass through. Direct-path lookups bypass the
|
|
5
|
+
* filter since the user explicitly named the file. The ignore instance is
|
|
6
|
+
* created per call -- no caching -- because cwd may differ between invocations.
|
|
7
|
+
*
|
|
8
|
+
* @summary Resolve selector patterns to absolute file paths with gitignore filtering
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Walk from `cwd` up to the filesystem root, collecting .gitignore entries.
|
|
12
|
+
* Returns an Ignore instance loaded with all discovered rules.
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadGitignore(cwd: string): Ignore;
|
|
1
15
|
/**
|
|
2
16
|
* Resolve a selector pattern to a list of .ts/.tsx file paths.
|
|
3
17
|
*
|
package/types/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Progressively explores TypeScript codebase documentation through a 4-level
|
|
3
|
+
* drill-down (summary, description, type declarations, full source), validates
|
|
4
|
+
* file-level JSDoc structure, and lints comprehensive JSDoc quality using
|
|
5
|
+
* ESLint. Barrel files gate their children at shallow depths, revealing
|
|
6
|
+
* individual files only at deeper levels.
|
|
5
7
|
*
|
|
6
|
-
* @summary
|
|
8
|
+
* @summary Progressive JSDoc exploration, validation, and linting for TypeScript codebases
|
|
7
9
|
*/
|
|
8
10
|
export { getBarrelChildren, isBarrel } from "./barrel.js";
|
|
9
11
|
export { drilldown, drilldownFiles } from "./drilldown.js";
|
|
@@ -14,6 +16,9 @@ export { lint, lintFiles } from "./lint.js";
|
|
|
14
16
|
export { parseSelector } from "./selector.js";
|
|
15
17
|
export { generateTypeDeclarations } from "./type-declarations.js";
|
|
16
18
|
export {
|
|
19
|
+
type CacheConfig,
|
|
20
|
+
type CacheOperationMode,
|
|
21
|
+
DEFAULT_CACHE_DIR,
|
|
17
22
|
type DrilldownResult,
|
|
18
23
|
type ErrorCode,
|
|
19
24
|
type LintDiagnostic,
|
package/types/lint.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @summary Lint files for comprehensive JSDoc quality using ESLint engine
|
|
10
10
|
*/
|
|
11
|
-
import type { LintResult, SelectorInfo } from "./types.js";
|
|
11
|
+
import type { CacheConfig, LintResult, SelectorInfo } from "./types.js";
|
|
12
12
|
/**
|
|
13
13
|
* Lint files matching a selector pattern for comprehensive JSDoc quality.
|
|
14
14
|
*
|
|
@@ -20,6 +20,7 @@ import type { LintResult, SelectorInfo } from "./types.js";
|
|
|
20
20
|
* @param cwd - Working directory for resolving paths
|
|
21
21
|
* @param limit - Max number of files with issues to include (default 100)
|
|
22
22
|
* @param gitignore - Whether to respect .gitignore rules (default true)
|
|
23
|
+
* @param config - Cache configuration (default enabled with DEFAULT_CACHE_DIR)
|
|
23
24
|
* @returns Lint result with per-file diagnostics and summary
|
|
24
25
|
* @throws {JsdocError} NO_FILES_MATCHED if glob selector matches no files
|
|
25
26
|
*/
|
|
@@ -28,6 +29,7 @@ export declare function lint(
|
|
|
28
29
|
cwd: string,
|
|
29
30
|
limit?: number,
|
|
30
31
|
gitignore?: boolean,
|
|
32
|
+
config?: CacheConfig,
|
|
31
33
|
): Promise<LintResult>;
|
|
32
34
|
/**
|
|
33
35
|
* Lint an explicit list of file paths for comprehensive JSDoc quality.
|
|
@@ -38,10 +40,12 @@ export declare function lint(
|
|
|
38
40
|
* @param filePaths - List of absolute file paths to lint
|
|
39
41
|
* @param cwd - Working directory for computing relative paths
|
|
40
42
|
* @param limit - Max number of files with issues to include (default 100)
|
|
43
|
+
* @param config - Cache configuration (default enabled with DEFAULT_CACHE_DIR)
|
|
41
44
|
* @returns Lint result with per-file diagnostics and summary
|
|
42
45
|
*/
|
|
43
46
|
export declare function lintFiles(
|
|
44
47
|
filePaths: string[],
|
|
45
48
|
cwd: string,
|
|
46
49
|
limit?: number,
|
|
50
|
+
config?: CacheConfig,
|
|
47
51
|
): Promise<LintResult>;
|
package/types/skill-text.d.ts
CHANGED
|
@@ -11,6 +11,6 @@ import type { ValidationStatus } from "./types.js";
|
|
|
11
11
|
/** Markdown guidance text for each validation status category */
|
|
12
12
|
export declare const GUIDANCE: Record<ValidationStatus, string>;
|
|
13
13
|
export declare const SKILL_TEXT =
|
|
14
|
-
'# World-Class JSDoc Guidelines for TypeScript\n\nThese guidelines describe the *properties* of excellent inline JSDoc in TypeScript repositories. They are a target to aim for, not a checklist. Use judgment; clarity beats volume.\n\n## Core principle\n\nTypeScript projects already have explicit types. JSDoc should add **intent, behavior, and constraints** rather than repeat what the type system already expresses.\n\n## Would have (high-signal properties)\n\n- **Intent and constraints**: Explains the non-obvious decision, constraint, or tradeoff (e.g., why a particular algorithm is used, why a heuristic exists, or what the runtime environment forbids).\n- **Behavioral contract**: Clearly states what inputs are accepted, what outputs represent, and how boundary cases are treated.\n- **Domain vocabulary**: Uses project-specific terms consistently so readers can navigate the codebase by vocabulary.\n- **Examples that disambiguate**: Includes `@example` blocks when behavior is otherwise ambiguous (e.g., parsing rules, path formats, or object schemas). Examples are short and realistic.\n- **Runtime effects**: Calls out side effects, temporal dependency (polling vs. event-driven), filesystem reads/writes, or external service behavior when those matter.\n- **Edge-case prompts**: Captures "what happens if..." questions that a reviewer would ask, especially where external APIs or platform behavior has caveats.\n- **Consistency with existing style**: Matches the formatting conventions already established in the codebase (multi-line descriptions, bullet lists where helpful).\n- **Future-proof hints**: Notes invariants and assumptions that must hold if the code evolves.\n- **LLM-friendly structure**: Uses short, self-contained paragraphs written in clear International Business English. Avoids prescriptive headers (e.g., "Why:", "Constraint:") in favor of natural prose that states context, purpose, and caveats directly.\n\n## Would not have (low-signal or risky properties)\n\n- **Type restatements**: Repeating TypeScript types in prose (e.g., "@param options - The options object" when the type is already `Options`). Keep `@param`, `@returns`, and `@throws` tags\u2014just make the descriptions add meaning beyond the type.\n- **Obvious narration**: Comments that paraphrase the code or parameter name without additional insight.\n- **Incorrect authority**: Claims that are not enforced by code (e.g., "never throws" when it can, or "always" without guardrails).\n- **Redundant verbosity**: Long descriptions that could be expressed more directly, or boilerplate that hides the key idea.\n- **Unbounded examples**: Large blocks or full payloads when a minimal example would do.\n- **Out-of-date operational details**: References to tooling, CLI flags, or config knobs that are not enforced or checked.\n- **Implementation leakage**: Unnecessary internal steps or private details that are likely to change and add churn to docs.\n- **Non-ASCII decoration**: Fancy symbols or emojis that do not already exist in the file; keep ASCII unless needed.\n\n## Tag usage cues (not rules)\n\n### IntelliSense tags (always include)\n\nThese tags power IDE hover tooltips, autocomplete, and signature help. Always include them for public APIs, constructors, and functions:\n\n- **`@param`**: Include for every parameter. Describe the parameter\'s purpose, valid ranges, or constraints\u2014not just its type.\n- **`@returns`**: Include when the function returns a value. Describe what the return value represents, especially for edge cases.\n- **`@throws`**: Include when the function can throw. Describe the conditions that cause the error.\n- **`@template`**: Include for generic functions and types. Describe what the type parameter represents.\n\n### Cross-reference tags (use to aid navigation)\n\n- **`@see`**: Link to related functions, types, or external documentation.\n- **`{@link Symbol}`**: Inline reference within descriptions. Creates a clickable link to another symbol.\n\n### Structural tags (use when appropriate)\n\n- Use `@module` at the top of files that define a cohesive domain concept.\n- Use `@example` when parsing or formatting behavior could be misread, or when a type is complex.\n- Use `@deprecated` on exports that are retained for compatibility.\n- Prefer short description + bullets for concepts with multiple facets.\n\n---\n\n## Writing file-level @summary and description\n\nEvery TypeScript file should have a file-level JSDoc block before the first code statement. This block is what jsdoczoom reads for orientation and validation.\n\n### Structure\n\n```typescript\n/**\n * Description paragraph goes here. It explains the file\'s responsibilities,\n * invariants, trade-offs, and failure modes. This is the deepest level of\n * native documentation \u2014 enough for someone to understand why this file\n * exists and how it fits into the broader system.\n *\n * @summary Concise one-line overview for quick orientation when scanning a codebase.\n */\n```\n\n### The @summary tag\n\nThe `@summary` tag provides a one-line overview \u2014 the first thing someone sees when scanning with jsdoczoom at the shallowest depth.\n\n**Good summaries:**\n- State what the file *does* or *is responsible for*, not what it contains\n- Are self-contained \u2014 understandable without reading other files\n- Use domain vocabulary consistently with the rest of the codebase\n- Fit on a single line (joined if multi-line in source)\n\n**Examples:**\n- `@summary Barrel tree model for hierarchical gating in glob mode`\n- `@summary Resolve selector patterns to absolute file paths with gitignore filtering`\n- `@summary CLI entry point \u2014 argument parsing, mode dispatch, and exit code handling`\n\n**Avoid:**\n- `@summary This file contains utility functions` \u2014 says what it *contains*, not what it *does*\n- `@summary Helpers` \u2014 too vague, no domain context\n- `@summary The main module` \u2014 no information about purpose or scope\n\n### The description paragraph\n\nThe description is prose that appears before any `@` tags. It provides the deeper context that the summary cannot \u2014 responsibilities, invariants, trade-offs, and failure modes.\n\n**Good descriptions:**\n- Explain *why* this file exists and what problem it solves\n- State invariants and assumptions that callers or maintainers must know\n- Note trade-offs and design decisions (e.g., "uses priority-order fill to keep the limit algorithm simple")\n- Mention failure modes and edge cases relevant to the file as a whole\n- Are 1-4 sentences, not an essay\n\n**Examples:**\n```typescript\n/**\n * Walks .gitignore files from cwd to filesystem root, building an ignore\n * filter that glob results pass through. Direct-path lookups bypass the\n * filter since the user explicitly named the file. The ignore instance is\n * created per call \u2014 no caching \u2014 because cwd may differ between invocations.\n *\n * @summary Resolve selector patterns to absolute file paths with gitignore filtering\n */\n```\n\n```typescript\n/**\n * Each file is classified into exactly one status category: the first\n * failing check wins (syntax_error > missing_jsdoc > missing_summary >\n * missing_description). Valid files are omitted from output entirely.\n * The limit parameter caps the total number of invalid paths shown,\n * filled in priority order across groups.\n *\n * @summary Validate file-level JSDoc and group results by status category\n */\n```\n\n**Avoid:**\n- Restating the summary in longer words\n- Listing every function in the file\n- Implementation details that change frequently (line numbers, internal variable names)\n\n### Barrel files (index.ts / index.tsx)\n\nBarrel files represent their directory. The `@summary` and description describe the module, not individual files.\n\n- **`@summary`**: What the module does as a unit\n- **Description**: The module\'s capabilities and concerns \u2014 describe concepts, not child filenames\n\n```typescript\n// packages/auth/src/index.ts\n/**\n * Provides session lifecycle management, token validation and refresh,\n * and middleware for route-level access control. OAuth2 provider\n * integration is handled here; cryptographic primitives are delegated\n * to the crypto package.\n *\n * @summary Authentication and authorization module\n */\n```\n\n**Avoid:**\n- Listing child filenames in the description\n- `@summary Exports for the auth module` \u2014 describes the mechanism, not the purpose\n- `@summary Index file` \u2014 no information about what the module does\n\n### Placement\n\nThe file-level JSDoc block must appear **before the first code statement** (imports are fine above it, but the block must precede any `export`, `const`, `function`, `class`, etc.). A common pattern is to place it immediately after imports:\n\n```typescript\nimport { resolve } from "node:path";\nimport { globSync } from "glob";\n\n/**\n * Description paragraph here.\n *\n * @summary One-line overview here\n */\n\nexport function discoverFiles(...) { ... }\n```\n\n### Common lint rules and examples\n\nThese rules are enforced in lint mode (`-l`). Understanding what passes and fails reduces trial-and-rerun cycles.\n\n#### `jsdoc/informative-docs` \u2014 descriptions must add meaning\n\nThis rule rejects descriptions that merely restate the parameter name, type, or containing symbol name. Descriptions must provide behavioral context.\n\n**Fails:**\n- `@param id - The id`\n- `@param options - The options object`\n- `@returns The result`\n- `@param name - The name string`\n\n**Passes:**\n- `@param id - Unique identifier used for cache lookup and deduplication`\n- `@param options - Controls retry behavior, timeout, and error handling strategy`\n- `@returns Parsed configuration with defaults applied for missing fields`\n- `@param name - Display name shown in the navigation sidebar`\n\n**Rule of thumb:** If removing the parameter name from the description leaves no useful information, the description is not informative enough.\n\n#### `jsdoc/check-tag-names` \u2014 allowed tags only\n\nThe lint configuration rejects non-standard JSDoc tags. Common tags to **avoid in JSDoc blocks**:\n- `@remarks` \u2014 move content to the description paragraph (prose before tags)\n- `@packageDocumentation` \u2014 use `@module` instead\n- `@concept`, `@constraint` \u2014 move content to the description paragraph\n\nFramework directives that look like tags (e.g., `@vitest-environment`) should use plain comments instead:\n```typescript\n// @vitest-environment node \u2190 correct (plain comment)\n/** @vitest-environment node */ \u2190 incorrect (treated as JSDoc tag)\n```\n\n#### `jsdoc/require-throws` \u2014 document throw conditions\n\nInclude `@throws` for any function that can throw, including catch-and-rethrow patterns:\n```typescript\n/**\n * @param path - File path to read\n * @returns Parsed configuration object\n * @throws {ConfigError} When the file is missing or contains invalid YAML\n */\n```\n\nIf a function catches errors and rethrows them (wrapped or unwrapped), it still needs `@throws`.\n\n### Nested object parameters\n\nWhen a function accepts an inline object parameter, document each property with a nested `@param` tag:\n\n```typescript\n/**\n * Create a new user account.\n *\n * @param data - Account creation payload\n * @param data.email - Email address used for login and notifications\n * @param data.displayName - Public-facing name shown in the UI\n * @param data.role - Initial permission level assigned to the account\n * @returns The created user record with generated ID\n */\nfunction createUser(data: { email: string; displayName: string; role: Role }): User {\n```\n\nFor React component props, use `props` (or `root0` if destructured) as the root:\n\n```typescript\n/**\n * @param props - Component properties\n * @param props.title - Page heading displayed at the top\n * @param props.onSubmit - Callback invoked when the form is submitted\n */\nfunction MyComponent(props: { title: string; onSubmit: () => void }) {\n```\n\n### Overload documentation\n\nWhen a function has TypeScript overload signatures, document **both** the overload declarations and the implementation signature:\n\n```typescript\n/**\n * Parse a value from a string representation.\n *\n * @param input - Raw string to parse\n * @returns Parsed numeric value\n */\nfunction parse(input: string): number;\n/**\n * Parse a value from a buffer.\n *\n * @param input - Binary buffer to parse\n * @returns Parsed numeric value\n */\nfunction parse(input: Buffer): number;\n/**\n * Parse a value from string or buffer input. String inputs are decoded\n * as UTF-8 before numeric parsing.\n *\n * @param input - String or buffer to parse\n * @returns Parsed numeric value\n * @throws {ParseError} When the input cannot be interpreted as a number\n */\nfunction parse(input: string | Buffer): number {\n // implementation\n}\n```\n\n';
|
|
14
|
+
'# World-Class JSDoc Guidelines for TypeScript\n\nThese guidelines describe the *properties* of excellent inline JSDoc in TypeScript repositories. They are a target to aim for, not a checklist. Use judgment; clarity beats volume.\n\n## Core principle\n\nTypeScript projects already have explicit types. JSDoc should add **intent, behavior, and constraints** rather than repeat what the type system already expresses.\n\n## Would have (high-signal properties)\n\n- **Intent and constraints**: Explains the non-obvious decision, constraint, or tradeoff (e.g., why a particular algorithm is used, why a heuristic exists, or what the runtime environment forbids).\n- **Behavioral contract**: Clearly states what inputs are accepted, what outputs represent, and how boundary cases are treated.\n- **Domain vocabulary**: Uses project-specific terms consistently so readers can navigate the codebase by vocabulary.\n- **Examples that disambiguate**: Includes `@example` blocks when behavior is otherwise ambiguous (e.g., parsing rules, path formats, or object schemas). Examples are short and realistic.\n- **Runtime effects**: Calls out side effects, temporal dependency (polling vs. event-driven), filesystem reads/writes, or external service behavior when those matter.\n- **Edge-case prompts**: Captures "what happens if..." questions that a reviewer would ask, especially where external APIs or platform behavior has caveats.\n- **Consistency with existing style**: Matches the formatting conventions already established in the codebase (multi-line descriptions, bullet lists where helpful).\n- **Future-proof hints**: Notes invariants and assumptions that must hold if the code evolves.\n- **LLM-friendly structure**: Uses short, self-contained paragraphs written in clear International Business English. Avoids prescriptive headers (e.g., "Why:", "Constraint:") in favor of natural prose that states context, purpose, and caveats directly.\n\n## Would not have (low-signal or risky properties)\n\n- **Type restatements**: Repeating TypeScript types in prose (e.g., "@param options - The options object" when the type is already `Options`). Keep `@param`, `@returns`, and `@throws` tags\u2014just make the descriptions add meaning beyond the type.\n- **Obvious narration**: Comments that paraphrase the code or parameter name without additional insight.\n- **Incorrect authority**: Claims that are not enforced by code (e.g., "never throws" when it can, or "always" without guardrails).\n- **Redundant verbosity**: Long descriptions that could be expressed more directly, or boilerplate that hides the key idea.\n- **Unbounded examples**: Large blocks or full payloads when a minimal example would do.\n- **Out-of-date operational details**: References to tooling, CLI flags, or config knobs that are not enforced or checked.\n- **Implementation leakage**: Unnecessary internal steps or private details that are likely to change and add churn to docs.\n- **Non-ASCII decoration**: Fancy symbols or emojis that do not already exist in the file; keep ASCII unless needed.\n\n## Tag usage cues (not rules)\n\n### IntelliSense tags (always include)\n\nThese tags power IDE hover tooltips, autocomplete, and signature help. Always include them for public APIs, constructors, and functions:\n\n- **`@param`**: Include for every parameter. Describe the parameter\'s purpose, valid ranges, or constraints\u2014not just its type.\n- **`@returns`**: Include when the function returns a value. Describe what the return value represents, especially for edge cases.\n- **`@throws`**: Include when the function can throw. Describe the conditions that cause the error.\n- **`@template`**: Include for generic functions and types. Describe what the type parameter represents.\n\n### Cross-reference tags (use to aid navigation)\n\n- **`@see`**: Link to related functions, types, or external documentation.\n- **`{@link Symbol}`**: Inline reference within descriptions. Creates a clickable link to another symbol.\n\n### Structural tags (use when appropriate)\n\n- Use `@module` at the top of files that define a cohesive domain concept.\n- Use `@example` when parsing or formatting behavior could be misread, or when a type is complex.\n- Use `@deprecated` on exports that are retained for compatibility.\n- Prefer short description + bullets for concepts with multiple facets.\n\n---\n\n## Writing file-level @summary and description\n\nEvery TypeScript file should have a file-level JSDoc block before the first code statement. This block is what jsdoczoom reads for orientation and validation.\n\n### Structure\n\n```typescript\n/**\n * Description paragraph goes here. It explains the file\'s responsibilities,\n * invariants, trade-offs, and failure modes. This is the deepest level of\n * native documentation \u2014 enough for someone to understand why this file\n * exists and how it fits into the broader system.\n *\n * @summary Concise one-line overview for quick orientation when scanning a codebase.\n */\n```\n\n### The @summary tag\n\nThe `@summary` tag provides a one-line overview \u2014 the first thing someone sees when scanning with jsdoczoom at the shallowest depth.\n\n**Good summaries:**\n- State what the file *does* or *is responsible for*, not what it contains\n- Are self-contained \u2014 understandable without reading other files\n- Use domain vocabulary consistently with the rest of the codebase\n- Fit on a single line (joined if multi-line in source)\n\n**Examples:**\n- `@summary Barrel tree model for hierarchical gating in glob mode`\n- `@summary Resolve selector patterns to absolute file paths with gitignore filtering`\n- `@summary CLI entry point \u2014 argument parsing, mode dispatch, and exit code handling`\n\n**Avoid:**\n- `@summary This file contains utility functions` \u2014 says what it *contains*, not what it *does*\n- `@summary Helpers` \u2014 too vague, no domain context\n- `@summary The main module` \u2014 no information about purpose or scope\n\n### The description paragraph\n\nThe description is prose that appears before any `@` tags. It provides the deeper context that the summary cannot \u2014 responsibilities, invariants, trade-offs, and failure modes.\n\n**Good descriptions:**\n- Explain *why* this file exists and what problem it solves\n- State invariants and assumptions that callers or maintainers must know\n- Note trade-offs and design decisions (e.g., "uses priority-order fill to keep the limit algorithm simple")\n- Mention failure modes and edge cases relevant to the file as a whole\n- Are 1-4 sentences, not an essay\n\n**Examples:**\n```typescript\n/**\n * Walks .gitignore files from cwd to filesystem root, building an ignore\n * filter that glob results pass through. Direct-path lookups bypass the\n * filter since the user explicitly named the file. The ignore instance is\n * created per call \u2014 no caching \u2014 because cwd may differ between invocations.\n *\n * @summary Resolve selector patterns to absolute file paths with gitignore filtering\n */\n```\n\n```typescript\n/**\n * Each file is classified into exactly one status category: the first\n * failing check wins (syntax_error > missing_jsdoc > missing_summary >\n * missing_description). Valid files are omitted from output entirely.\n * The limit parameter caps the total number of invalid paths shown,\n * filled in priority order across groups.\n *\n * @summary Validate file-level JSDoc and group results by status category\n */\n```\n\n**Avoid:**\n- Restating the summary in longer words\n- Listing every function in the file\n- Implementation details that change frequently (line numbers, internal variable names)\n\n### Barrel files (index.ts / index.tsx)\n\nBarrel files represent their directory. Their `@summary` and description should describe the **cumulative functionality of the directory\'s children**, not the barrel file itself.\n\n- **`@summary`**: The collective purpose of the files in this directory\n- **Description**: The combined capabilities and responsibilities of child modules \u2014 what they do together, not their filenames or the re-export mechanism\n\n```typescript\n// packages/auth/src/index.ts\n/**\n * Provides session lifecycle management, token validation and refresh,\n * and middleware for route-level access control. OAuth2 provider\n * integration is handled here; cryptographic primitives are delegated\n * to the crypto package.\n *\n * @summary Authentication and authorization module\n */\n```\n\n**Avoid:**\n- `@summary Re-exports all functions and types` \u2014 describes the barrel mechanism, not what the children do\n- `@summary Exports for the auth module` \u2014 describes the mechanism, not the purpose\n- `@summary Public API barrel` \u2014 names the pattern rather than describing functionality\n- Listing child filenames or saying "This is the entry point"\n\n### Placement\n\nThe file-level JSDoc block must appear **before the first code statement** (imports are fine above it, but the block must precede any `export`, `const`, `function`, `class`, etc.). A common pattern is to place it immediately after imports:\n\n```typescript\nimport { resolve } from "node:path";\nimport { globSync } from "glob";\n\n/**\n * Description paragraph here.\n *\n * @summary One-line overview here\n */\n\nexport function discoverFiles(...) { ... }\n```\n\n### Common lint rules and examples\n\nThese rules are enforced in lint mode (`-l`). Understanding what passes and fails reduces trial-and-rerun cycles.\n\n#### `jsdoc/informative-docs` \u2014 descriptions must add meaning\n\nThis rule rejects descriptions that merely restate the parameter name, type, or containing symbol name. Descriptions must provide behavioral context.\n\n**Fails:**\n- `@param id - The id`\n- `@param options - The options object`\n- `@returns The result`\n- `@param name - The name string`\n\n**Passes:**\n- `@param id - Unique identifier used for cache lookup and deduplication`\n- `@param options - Controls retry behavior, timeout, and error handling strategy`\n- `@returns Parsed configuration with defaults applied for missing fields`\n- `@param name - Display name shown in the navigation sidebar`\n\n**Rule of thumb:** If removing the parameter name from the description leaves no useful information, the description is not informative enough.\n\n#### `jsdoc/check-tag-names` \u2014 allowed tags only\n\nThe lint configuration rejects non-standard JSDoc tags. Common tags to **avoid in JSDoc blocks**:\n- `@remarks` \u2014 move content to the description paragraph (prose before tags)\n- `@packageDocumentation` \u2014 use `@module` instead\n- `@concept`, `@constraint` \u2014 move content to the description paragraph\n\nFramework directives that look like tags (e.g., `@vitest-environment`) should use plain comments instead:\n```typescript\n// @vitest-environment node \u2190 correct (plain comment)\n/** @vitest-environment node */ \u2190 incorrect (treated as JSDoc tag)\n```\n\n#### `jsdoc/require-throws` \u2014 document throw conditions\n\nInclude `@throws` for any function that can throw, including catch-and-rethrow patterns:\n```typescript\n/**\n * @param path - File path to read\n * @returns Parsed configuration object\n * @throws {ConfigError} When the file is missing or contains invalid YAML\n */\n```\n\nIf a function catches errors and rethrows them (wrapped or unwrapped), it still needs `@throws`.\n\n### Nested object parameters\n\nWhen a function accepts an inline object parameter, document each property with a nested `@param` tag:\n\n```typescript\n/**\n * Create a new user account.\n *\n * @param data - Account creation payload\n * @param data.email - Email address used for login and notifications\n * @param data.displayName - Public-facing name shown in the UI\n * @param data.role - Initial permission level assigned to the account\n * @returns The created user record with generated ID\n */\nfunction createUser(data: { email: string; displayName: string; role: Role }): User {\n```\n\nFor React component props, use `props` (or `root0` if destructured) as the root:\n\n```typescript\n/**\n * @param props - Component properties\n * @param props.title - Page heading displayed at the top\n * @param props.onSubmit - Callback invoked when the form is submitted\n */\nfunction MyComponent(props: { title: string; onSubmit: () => void }) {\n```\n\n### Overload documentation\n\nWhen a function has TypeScript overload signatures, document **both** the overload declarations and the implementation signature:\n\n```typescript\n/**\n * Parse a value from a string representation.\n *\n * @param input - Raw string to parse\n * @returns Parsed numeric value\n */\nfunction parse(input: string): number;\n/**\n * Parse a value from a buffer.\n *\n * @param input - Binary buffer to parse\n * @returns Parsed numeric value\n */\nfunction parse(input: Buffer): number;\n/**\n * Parse a value from string or buffer input. String inputs are decoded\n * as UTF-8 before numeric parsing.\n *\n * @param input - String or buffer to parse\n * @returns Parsed numeric value\n * @throws {ParseError} When the input cannot be interpreted as a number\n */\nfunction parse(input: string | Buffer): number {\n // implementation\n}\n```\n\n';
|
|
15
15
|
/** Explanation text for each lint rule, used by --explain-rule */
|
|
16
16
|
export declare const RULE_EXPLANATIONS: Record<string, string>;
|
package/types/types.d.ts
CHANGED
|
@@ -104,6 +104,7 @@ export interface LintFileResult {
|
|
|
104
104
|
/** Overall lint result with summary statistics */
|
|
105
105
|
export interface LintResult {
|
|
106
106
|
files: LintFileResult[];
|
|
107
|
+
missingBarrels?: string[];
|
|
107
108
|
summary: {
|
|
108
109
|
totalFiles: number;
|
|
109
110
|
filesWithIssues: number;
|
|
@@ -111,3 +112,12 @@ export interface LintResult {
|
|
|
111
112
|
truncated?: boolean;
|
|
112
113
|
};
|
|
113
114
|
}
|
|
115
|
+
/** Configuration for the disk cache layer */
|
|
116
|
+
export interface CacheConfig {
|
|
117
|
+
enabled: boolean;
|
|
118
|
+
directory: string;
|
|
119
|
+
}
|
|
120
|
+
/** Operation modes that produce cacheable results */
|
|
121
|
+
export type CacheOperationMode = "drilldown" | "validate" | "lint";
|
|
122
|
+
/** Default cache directory under os.tmpdir() */
|
|
123
|
+
export declare const DEFAULT_CACHE_DIR: string;
|
package/types/validate.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type { SelectorInfo, ValidationResult } from "./types.js";
|
|
1
|
+
import type { CacheConfig, SelectorInfo, ValidationResult } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Validate files matching a selector pattern.
|
|
4
4
|
*
|
|
5
5
|
* @param selector - Selector information (glob or path)
|
|
6
6
|
* @param cwd - Working directory for resolving paths
|
|
7
7
|
* @param limit - Max number of invalid file paths to include (default 100)
|
|
8
|
+
* @param gitignore - Whether to respect .gitignore (default true)
|
|
9
|
+
* @param config - Cache configuration (default: enabled with system temp dir)
|
|
8
10
|
* @returns Grouped validation results
|
|
9
11
|
* @throws {JsdocError} NO_FILES_MATCHED if glob selector matches no files
|
|
10
12
|
* @throws {JsdocError} FILE_NOT_FOUND if path selector targets nonexistent file
|
|
@@ -14,6 +16,7 @@ export declare function validate(
|
|
|
14
16
|
cwd: string,
|
|
15
17
|
limit?: number,
|
|
16
18
|
gitignore?: boolean,
|
|
19
|
+
config?: CacheConfig,
|
|
17
20
|
): Promise<ValidationResult>;
|
|
18
21
|
/**
|
|
19
22
|
* Validate an explicit list of file paths.
|
|
@@ -23,10 +26,12 @@ export declare function validate(
|
|
|
23
26
|
* @param filePaths - List of file paths to validate
|
|
24
27
|
* @param cwd - Working directory for resolving relative paths
|
|
25
28
|
* @param limit - Max number of invalid file paths to include (default 100)
|
|
29
|
+
* @param config - Cache configuration (default: enabled with system temp dir)
|
|
26
30
|
* @returns Grouped validation results
|
|
27
31
|
*/
|
|
28
32
|
export declare function validateFiles(
|
|
29
33
|
filePaths: string[],
|
|
30
34
|
cwd: string,
|
|
31
35
|
limit?: number,
|
|
36
|
+
config?: CacheConfig,
|
|
32
37
|
): Promise<ValidationResult>;
|