@aiready/doc-drift 0.1.8 → 0.1.10

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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.1.8 build /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.1.10 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
  CLI Building entry: src/cli.ts, src/index.ts
@@ -10,7 +10,7 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
 
13
- [12:55:25 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
13
+ [1:59:55 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
14
14
 
15
15
  package.json:33:6:
16
16
   33 │ "types": "./dist/index.d.ts"
@@ -31,7 +31,7 @@
31
31
 
32
32
 
33
33
 
34
- [12:55:25 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
34
+ [1:59:55 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
35
35
 
36
36
  package.json:33:6:
37
37
   33 │ "types": "./dist/index.d.ts"
@@ -51,15 +51,15 @@
51
51
 
52
52
 
53
53
 
54
- CJS dist/cli.js 7.58 KB
55
- CJS dist/index.js 5.55 KB
56
- CJS ⚡️ Build success in 511ms
57
- ESM dist/chunk-5EFFNN6L.mjs 4.85 KB
58
- ESM dist/index.mjs 88.00 B
59
54
  ESM dist/cli.mjs 1.39 KB
60
- ESM ⚡️ Build success in 495ms
55
+ ESM dist/chunk-FMK4O4O7.mjs 4.79 KB
56
+ ESM dist/index.mjs 88.00 B
57
+ ESM ⚡️ Build success in 163ms
58
+ CJS dist/index.js 5.50 KB
59
+ CJS dist/cli.js 7.52 KB
60
+ CJS ⚡️ Build success in 163ms
61
61
  DTS Build start
62
- DTS ⚡️ Build success in 10279ms
62
+ DTS ⚡️ Build success in 4161ms
63
63
  DTS dist/cli.d.ts 108.00 B
64
64
  DTS dist/index.d.ts 950.00 B
65
65
  DTS dist/cli.d.mts 108.00 B
@@ -0,0 +1,143 @@
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
+ } from "@aiready/core";
15
+ import { readFileSync } from "fs";
16
+ import { parse } from "@typescript-eslint/typescript-estree";
17
+ async function analyzeDocDrift(options) {
18
+ const files = await scanFiles(options);
19
+ const issues = [];
20
+ const staleMonths = options.staleMonths ?? 6;
21
+ const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
22
+ let uncommentedExports = 0;
23
+ let totalExports = 0;
24
+ let outdatedComments = 0;
25
+ let undocumentedComplexity = 0;
26
+ const now = Math.floor(Date.now() / 1e3);
27
+ let processed = 0;
28
+ for (const file of files) {
29
+ processed++;
30
+ options.onProgress?.(processed, files.length, `doc-drift: analyzing files`);
31
+ let code;
32
+ try {
33
+ code = readFileSync(file, "utf-8");
34
+ } catch {
35
+ continue;
36
+ }
37
+ let ast;
38
+ try {
39
+ ast = parse(code, {
40
+ jsx: file.endsWith(".tsx") || file.endsWith(".jsx"),
41
+ loc: true,
42
+ comment: true
43
+ });
44
+ } catch {
45
+ continue;
46
+ }
47
+ const comments = ast.comments || [];
48
+ let fileLineStamps;
49
+ for (const node of ast.body) {
50
+ if (node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") {
51
+ const decl = node.declaration;
52
+ if (!decl) continue;
53
+ if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration" || decl.type === "VariableDeclaration") {
54
+ totalExports++;
55
+ const nodeLine = node.loc.start.line;
56
+ const jsdocs = comments.filter(
57
+ (c) => c.type === "Block" && c.value.startsWith("*") && c.loc.end.line === nodeLine - 1
58
+ );
59
+ if (jsdocs.length === 0) {
60
+ uncommentedExports++;
61
+ if (decl.type === "FunctionDeclaration" && decl.body?.loc) {
62
+ const lines = decl.body.loc.end.line - decl.body.loc.start.line;
63
+ if (lines > 20) undocumentedComplexity++;
64
+ }
65
+ } else {
66
+ const jsdoc = jsdocs[0];
67
+ const jsdocText = jsdoc.value;
68
+ if (decl.type === "FunctionDeclaration") {
69
+ const params = decl.params.map((p) => p.name || p.left && p.left.name).filter(Boolean);
70
+ const paramTags = Array.from(
71
+ jsdocText.matchAll(/@param\s+(?:\{[^}]+\}\s+)?([a-zA-Z0-9_]+)/g)
72
+ ).map((m) => m[1]);
73
+ const missingParams = params.filter(
74
+ (p) => !paramTags.includes(p)
75
+ );
76
+ if (missingParams.length > 0) {
77
+ outdatedComments++;
78
+ issues.push({
79
+ type: "doc-drift",
80
+ severity: "major",
81
+ message: `JSDoc @param mismatch: function has parameters (${missingParams.join(", ")}) not documented in JSDoc.`,
82
+ location: { file, line: nodeLine }
83
+ });
84
+ continue;
85
+ }
86
+ }
87
+ if (!fileLineStamps) {
88
+ fileLineStamps = getFileCommitTimestamps(file);
89
+ }
90
+ const commentModified = getLineRangeLastModifiedCached(
91
+ fileLineStamps,
92
+ jsdoc.loc.start.line,
93
+ jsdoc.loc.end.line
94
+ );
95
+ const bodyModified = getLineRangeLastModifiedCached(
96
+ fileLineStamps,
97
+ decl.loc.start.line,
98
+ decl.loc.end.line
99
+ );
100
+ if (commentModified > 0 && bodyModified > 0) {
101
+ if (now - commentModified > staleSeconds && bodyModified - commentModified > staleSeconds / 2) {
102
+ outdatedComments++;
103
+ issues.push({
104
+ type: "doc-drift",
105
+ severity: "minor",
106
+ message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
107
+ location: { file, line: jsdoc.loc.start.line }
108
+ });
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ const riskResult = calculateDocDrift({
117
+ uncommentedExports,
118
+ totalExports,
119
+ outdatedComments,
120
+ undocumentedComplexity
121
+ });
122
+ return {
123
+ summary: {
124
+ filesAnalyzed: files.length,
125
+ functionsAnalyzed: totalExports,
126
+ score: riskResult.score,
127
+ rating: riskResult.rating
128
+ },
129
+ issues,
130
+ rawData: {
131
+ uncommentedExports,
132
+ totalExports,
133
+ outdatedComments,
134
+ undocumentedComplexity
135
+ },
136
+ recommendations: riskResult.recommendations
137
+ };
138
+ }
139
+
140
+ export {
141
+ __require,
142
+ analyzeDocDrift
143
+ };
package/dist/cli.js CHANGED
@@ -40,10 +40,8 @@ var import_core = require("@aiready/core");
40
40
  var import_fs = require("fs");
41
41
  var import_typescript_estree = require("@typescript-eslint/typescript-estree");
42
42
  async function analyzeDocDrift(options) {
43
- const rootDir = options.rootDir;
44
43
  const files = await (0, import_core.scanFiles)(options);
45
44
  const issues = [];
46
- const results = [];
47
45
  const staleMonths = options.staleMonths ?? 6;
48
46
  const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
49
47
  let uncommentedExports = 0;
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  analyzeDocDrift
4
- } from "./chunk-5EFFNN6L.mjs";
4
+ } from "./chunk-FMK4O4O7.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -29,10 +29,8 @@ var import_core = require("@aiready/core");
29
29
  var import_fs = require("fs");
30
30
  var import_typescript_estree = require("@typescript-eslint/typescript-estree");
31
31
  async function analyzeDocDrift(options) {
32
- const rootDir = options.rootDir;
33
32
  const files = await (0, import_core.scanFiles)(options);
34
33
  const issues = [];
35
- const results = [];
36
34
  const staleMonths = options.staleMonths ?? 6;
37
35
  const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
38
36
  let uncommentedExports = 0;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  analyzeDocDrift
3
- } from "./chunk-5EFFNN6L.mjs";
3
+ } from "./chunk-FMK4O4O7.mjs";
4
4
  export {
5
5
  analyzeDocDrift
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/doc-drift",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
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.9.35"
13
+ "@aiready/core": "0.9.37"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "^24.0.0",
package/src/analyzer.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  scanFiles,
3
- readFileContent,
4
3
  calculateDocDrift,
5
4
  getFileCommitTimestamps,
6
5
  getLineRangeLastModifiedCached,
@@ -13,11 +12,9 @@ import type { TSESTree } from '@typescript-eslint/types';
13
12
  export async function analyzeDocDrift(
14
13
  options: DocDriftOptions
15
14
  ): Promise<DocDriftReport> {
16
- const rootDir = options.rootDir;
17
15
  // Use core scanFiles which respects .gitignore recursively
18
16
  const files = await scanFiles(options);
19
17
  const issues: DocDriftIssue[] = [];
20
- const results: DocDriftIssue[] = [];
21
18
  const staleMonths = options.staleMonths ?? 6;
22
19
  const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
23
20