@aiready/doc-drift 0.9.2 → 0.9.3
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/.turbo/turbo-build.log +11 -11
- package/.turbo/turbo-test.log +4 -4
- package/dist/chunk-CGSYYULO.mjs +145 -0
- package/dist/cli.js +4 -4
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/src/analyzer.ts +6 -4
- package/src/types.ts +2 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/doc-drift@0.9.
|
|
3
|
+
> @aiready/doc-drift@0.9.2 build /Users/pengcao/projects/aiready/packages/doc-drift
|
|
4
4
|
> tsup src/index.ts src/cli.ts --format cjs,esm --dts
|
|
5
5
|
|
|
6
6
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
|
|
13
|
-
[43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json] [
|
|
13
|
+
[43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json] [90m7:57:09 pm[39m
|
|
14
14
|
|
|
15
15
|
package.json:33:6:
|
|
16
16
|
[37m 33 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
[43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json] [
|
|
34
|
+
[43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json] [90m7:57:09 pm[39m
|
|
35
35
|
|
|
36
36
|
package.json:33:6:
|
|
37
37
|
[37m 33 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
[32mCJS[39m [1mdist/
|
|
55
|
-
[32mCJS[39m [1mdist/
|
|
56
|
-
[32mCJS[39m ⚡️ Build success in
|
|
54
|
+
[32mCJS[39m [1mdist/index.js [22m[32m5.57 KB[39m
|
|
55
|
+
[32mCJS[39m [1mdist/cli.js [22m[32m7.60 KB[39m
|
|
56
|
+
[32mCJS[39m ⚡️ Build success in 38ms
|
|
57
57
|
[32mESM[39m [1mdist/cli.mjs [22m[32m1.39 KB[39m
|
|
58
58
|
[32mESM[39m [1mdist/index.mjs [22m[32m88.00 B[39m
|
|
59
|
-
[32mESM[39m [1mdist/chunk-
|
|
60
|
-
[32mESM[39m ⚡️ Build success in
|
|
59
|
+
[32mESM[39m [1mdist/chunk-CGSYYULO.mjs [22m[32m4.85 KB[39m
|
|
60
|
+
[32mESM[39m ⚡️ Build success in 38ms
|
|
61
61
|
DTS Build start
|
|
62
|
-
DTS ⚡️ Build success in
|
|
62
|
+
DTS ⚡️ Build success in 2875ms
|
|
63
63
|
DTS dist/cli.d.ts 108.00 B
|
|
64
|
-
DTS dist/index.d.ts
|
|
64
|
+
DTS dist/index.d.ts 968.00 B
|
|
65
65
|
DTS dist/cli.d.mts 108.00 B
|
|
66
|
-
DTS dist/index.d.mts
|
|
66
|
+
DTS dist/index.d.mts 968.00 B
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/doc-drift@0.9.
|
|
3
|
+
> @aiready/doc-drift@0.9.2 test /Users/pengcao/projects/aiready/packages/doc-drift
|
|
4
4
|
> vitest run
|
|
5
5
|
|
|
6
6
|
[?25l
|
|
7
7
|
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/pengcao/projects/aiready/packages/doc-drift[39m
|
|
8
8
|
|
|
9
|
-
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
9
|
+
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 273[2mms[22m[39m
|
|
10
10
|
|
|
11
11
|
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
12
12
|
[2m Tests [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
13
|
-
[2m Start at [22m 20:
|
|
14
|
-
[2m Duration [22m
|
|
13
|
+
[2m Start at [22m 20:00:26
|
|
14
|
+
[2m Duration [22m 2.33s[2m (transform 304ms, setup 0ms, import 1.34s, tests 273ms, environment 0ms)[22m
|
|
15
15
|
|
|
16
16
|
[?25h
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/analyzer.ts
|
|
9
|
+
import {
|
|
10
|
+
scanFiles,
|
|
11
|
+
calculateDocDrift,
|
|
12
|
+
getFileCommitTimestamps,
|
|
13
|
+
getLineRangeLastModifiedCached,
|
|
14
|
+
Severity,
|
|
15
|
+
IssueType
|
|
16
|
+
} from "@aiready/core";
|
|
17
|
+
import { readFileSync } from "fs";
|
|
18
|
+
import { parse } from "@typescript-eslint/typescript-estree";
|
|
19
|
+
async function analyzeDocDrift(options) {
|
|
20
|
+
const files = await scanFiles(options);
|
|
21
|
+
const issues = [];
|
|
22
|
+
const staleMonths = options.staleMonths ?? 6;
|
|
23
|
+
const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
|
|
24
|
+
let uncommentedExports = 0;
|
|
25
|
+
let totalExports = 0;
|
|
26
|
+
let outdatedComments = 0;
|
|
27
|
+
let undocumentedComplexity = 0;
|
|
28
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
29
|
+
let processed = 0;
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
processed++;
|
|
32
|
+
options.onProgress?.(processed, files.length, `doc-drift: analyzing files`);
|
|
33
|
+
let code;
|
|
34
|
+
try {
|
|
35
|
+
code = readFileSync(file, "utf-8");
|
|
36
|
+
} catch {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
let ast;
|
|
40
|
+
try {
|
|
41
|
+
ast = parse(code, {
|
|
42
|
+
jsx: file.endsWith(".tsx") || file.endsWith(".jsx"),
|
|
43
|
+
loc: true,
|
|
44
|
+
comment: true
|
|
45
|
+
});
|
|
46
|
+
} catch {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const comments = ast.comments || [];
|
|
50
|
+
let fileLineStamps;
|
|
51
|
+
for (const node of ast.body) {
|
|
52
|
+
if (node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") {
|
|
53
|
+
const decl = node.declaration;
|
|
54
|
+
if (!decl) continue;
|
|
55
|
+
if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration" || decl.type === "VariableDeclaration") {
|
|
56
|
+
totalExports++;
|
|
57
|
+
const nodeLine = node.loc.start.line;
|
|
58
|
+
const jsdocs = comments.filter(
|
|
59
|
+
(c) => c.type === "Block" && c.value.startsWith("*") && c.loc.end.line === nodeLine - 1
|
|
60
|
+
);
|
|
61
|
+
if (jsdocs.length === 0) {
|
|
62
|
+
uncommentedExports++;
|
|
63
|
+
if (decl.type === "FunctionDeclaration" && decl.body?.loc) {
|
|
64
|
+
const lines = decl.body.loc.end.line - decl.body.loc.start.line;
|
|
65
|
+
if (lines > 20) undocumentedComplexity++;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
const jsdoc = jsdocs[0];
|
|
69
|
+
const jsdocText = jsdoc.value;
|
|
70
|
+
if (decl.type === "FunctionDeclaration") {
|
|
71
|
+
const params = decl.params.map((p) => p.name || p.left && p.left.name).filter(Boolean);
|
|
72
|
+
const paramTags = Array.from(
|
|
73
|
+
jsdocText.matchAll(/@param\s+(?:\{[^}]+\}\s+)?([a-zA-Z0-9_]+)/g)
|
|
74
|
+
).map((m) => m[1]);
|
|
75
|
+
const missingParams = params.filter(
|
|
76
|
+
(p) => !paramTags.includes(p)
|
|
77
|
+
);
|
|
78
|
+
if (missingParams.length > 0) {
|
|
79
|
+
outdatedComments++;
|
|
80
|
+
issues.push({
|
|
81
|
+
type: IssueType.DocDrift,
|
|
82
|
+
severity: Severity.Major,
|
|
83
|
+
message: `JSDoc @param mismatch: function has parameters (${missingParams.join(", ")}) not documented in JSDoc.`,
|
|
84
|
+
location: { file, line: nodeLine }
|
|
85
|
+
});
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!fileLineStamps) {
|
|
90
|
+
fileLineStamps = getFileCommitTimestamps(file);
|
|
91
|
+
}
|
|
92
|
+
const commentModified = getLineRangeLastModifiedCached(
|
|
93
|
+
fileLineStamps,
|
|
94
|
+
jsdoc.loc.start.line,
|
|
95
|
+
jsdoc.loc.end.line
|
|
96
|
+
);
|
|
97
|
+
const bodyModified = getLineRangeLastModifiedCached(
|
|
98
|
+
fileLineStamps,
|
|
99
|
+
decl.loc.start.line,
|
|
100
|
+
decl.loc.end.line
|
|
101
|
+
);
|
|
102
|
+
if (commentModified > 0 && bodyModified > 0) {
|
|
103
|
+
if (now - commentModified > staleSeconds && bodyModified - commentModified > staleSeconds / 2) {
|
|
104
|
+
outdatedComments++;
|
|
105
|
+
issues.push({
|
|
106
|
+
type: IssueType.DocDrift,
|
|
107
|
+
severity: Severity.Minor,
|
|
108
|
+
message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
|
|
109
|
+
location: { file, line: jsdoc.loc.start.line }
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const riskResult = calculateDocDrift({
|
|
119
|
+
uncommentedExports,
|
|
120
|
+
totalExports,
|
|
121
|
+
outdatedComments,
|
|
122
|
+
undocumentedComplexity
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
summary: {
|
|
126
|
+
filesAnalyzed: files.length,
|
|
127
|
+
functionsAnalyzed: totalExports,
|
|
128
|
+
score: riskResult.score,
|
|
129
|
+
rating: riskResult.rating
|
|
130
|
+
},
|
|
131
|
+
issues,
|
|
132
|
+
rawData: {
|
|
133
|
+
uncommentedExports,
|
|
134
|
+
totalExports,
|
|
135
|
+
outdatedComments,
|
|
136
|
+
undocumentedComplexity
|
|
137
|
+
},
|
|
138
|
+
recommendations: riskResult.recommendations
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export {
|
|
143
|
+
__require,
|
|
144
|
+
analyzeDocDrift
|
|
145
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -101,8 +101,8 @@ async function analyzeDocDrift(options) {
|
|
|
101
101
|
if (missingParams.length > 0) {
|
|
102
102
|
outdatedComments++;
|
|
103
103
|
issues.push({
|
|
104
|
-
type:
|
|
105
|
-
severity:
|
|
104
|
+
type: import_core.IssueType.DocDrift,
|
|
105
|
+
severity: import_core.Severity.Major,
|
|
106
106
|
message: `JSDoc @param mismatch: function has parameters (${missingParams.join(", ")}) not documented in JSDoc.`,
|
|
107
107
|
location: { file, line: nodeLine }
|
|
108
108
|
});
|
|
@@ -126,8 +126,8 @@ async function analyzeDocDrift(options) {
|
|
|
126
126
|
if (now - commentModified > staleSeconds && bodyModified - commentModified > staleSeconds / 2) {
|
|
127
127
|
outdatedComments++;
|
|
128
128
|
issues.push({
|
|
129
|
-
type:
|
|
130
|
-
severity:
|
|
129
|
+
type: import_core.IssueType.DocDrift,
|
|
130
|
+
severity: import_core.Severity.Minor,
|
|
131
131
|
message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
|
|
132
132
|
location: { file, line: jsdoc.loc.start.line }
|
|
133
133
|
});
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Issue, ScanOptions } from '@aiready/core';
|
|
1
|
+
import { Issue, IssueType, ScanOptions } from '@aiready/core';
|
|
2
2
|
|
|
3
3
|
interface DocDriftOptions extends ScanOptions {
|
|
4
4
|
/** Maximum commit distance to check for drift */
|
|
@@ -7,7 +7,7 @@ interface DocDriftOptions extends ScanOptions {
|
|
|
7
7
|
staleMonths?: number;
|
|
8
8
|
}
|
|
9
9
|
interface DocDriftIssue extends Issue {
|
|
10
|
-
type:
|
|
10
|
+
type: IssueType.DocDrift;
|
|
11
11
|
}
|
|
12
12
|
interface DocDriftReport {
|
|
13
13
|
summary: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Issue, ScanOptions } from '@aiready/core';
|
|
1
|
+
import { Issue, IssueType, ScanOptions } from '@aiready/core';
|
|
2
2
|
|
|
3
3
|
interface DocDriftOptions extends ScanOptions {
|
|
4
4
|
/** Maximum commit distance to check for drift */
|
|
@@ -7,7 +7,7 @@ interface DocDriftOptions extends ScanOptions {
|
|
|
7
7
|
staleMonths?: number;
|
|
8
8
|
}
|
|
9
9
|
interface DocDriftIssue extends Issue {
|
|
10
|
-
type:
|
|
10
|
+
type: IssueType.DocDrift;
|
|
11
11
|
}
|
|
12
12
|
interface DocDriftReport {
|
|
13
13
|
summary: {
|
package/dist/index.js
CHANGED
|
@@ -90,8 +90,8 @@ async function analyzeDocDrift(options) {
|
|
|
90
90
|
if (missingParams.length > 0) {
|
|
91
91
|
outdatedComments++;
|
|
92
92
|
issues.push({
|
|
93
|
-
type:
|
|
94
|
-
severity:
|
|
93
|
+
type: import_core.IssueType.DocDrift,
|
|
94
|
+
severity: import_core.Severity.Major,
|
|
95
95
|
message: `JSDoc @param mismatch: function has parameters (${missingParams.join(", ")}) not documented in JSDoc.`,
|
|
96
96
|
location: { file, line: nodeLine }
|
|
97
97
|
});
|
|
@@ -115,8 +115,8 @@ async function analyzeDocDrift(options) {
|
|
|
115
115
|
if (now - commentModified > staleSeconds && bodyModified - commentModified > staleSeconds / 2) {
|
|
116
116
|
outdatedComments++;
|
|
117
117
|
issues.push({
|
|
118
|
-
type:
|
|
119
|
-
severity:
|
|
118
|
+
type: import_core.IssueType.DocDrift,
|
|
119
|
+
severity: import_core.Severity.Minor,
|
|
120
120
|
message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
|
|
121
121
|
location: { file, line: jsdoc.loc.start.line }
|
|
122
122
|
});
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/doc-drift",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "AI-Readiness: Documentation Drift Detection",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"commander": "^14.0.0",
|
|
11
11
|
"glob": "^13.0.0",
|
|
12
12
|
"picocolors": "^1.0.0",
|
|
13
|
-
"@aiready/core": "0.19.
|
|
13
|
+
"@aiready/core": "0.19.3"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^24.0.0",
|
package/src/analyzer.ts
CHANGED
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
calculateDocDrift,
|
|
4
4
|
getFileCommitTimestamps,
|
|
5
5
|
getLineRangeLastModifiedCached,
|
|
6
|
+
Severity,
|
|
7
|
+
IssueType,
|
|
6
8
|
} from '@aiready/core';
|
|
7
9
|
import type { DocDriftOptions, DocDriftReport, DocDriftIssue } from './types';
|
|
8
10
|
import { readFileSync } from 'fs';
|
|
@@ -103,8 +105,8 @@ export async function analyzeDocDrift(
|
|
|
103
105
|
if (missingParams.length > 0) {
|
|
104
106
|
outdatedComments++;
|
|
105
107
|
issues.push({
|
|
106
|
-
type:
|
|
107
|
-
severity:
|
|
108
|
+
type: IssueType.DocDrift,
|
|
109
|
+
severity: Severity.Major,
|
|
108
110
|
message: `JSDoc @param mismatch: function has parameters (${missingParams.join(', ')}) not documented in JSDoc.`,
|
|
109
111
|
location: { file, line: nodeLine },
|
|
110
112
|
});
|
|
@@ -135,8 +137,8 @@ export async function analyzeDocDrift(
|
|
|
135
137
|
) {
|
|
136
138
|
outdatedComments++;
|
|
137
139
|
issues.push({
|
|
138
|
-
type:
|
|
139
|
-
severity:
|
|
140
|
+
type: IssueType.DocDrift,
|
|
141
|
+
severity: Severity.Minor,
|
|
140
142
|
message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
|
|
141
143
|
location: { file, line: jsdoc.loc.start.line },
|
|
142
144
|
});
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScanOptions, Issue } from '@aiready/core';
|
|
1
|
+
import type { ScanOptions, Issue, IssueType } from '@aiready/core';
|
|
2
2
|
|
|
3
3
|
export interface DocDriftOptions extends ScanOptions {
|
|
4
4
|
/** Maximum commit distance to check for drift */
|
|
@@ -8,7 +8,7 @@ export interface DocDriftOptions extends ScanOptions {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export interface DocDriftIssue extends Issue {
|
|
11
|
-
type:
|
|
11
|
+
type: IssueType.DocDrift;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface DocDriftReport {
|