@aiready/doc-drift 0.11.4 → 0.11.8

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.11.3 build /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.11.7 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,15 +10,15 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
  ESM dist/cli.mjs 1.39 KB
13
- ESM dist/chunk-CGSYYULO.mjs 4.85 KB
13
+ ESM dist/chunk-E3YCVHHH.mjs 4.91 KB
14
14
  ESM dist/index.mjs 1.63 KB
15
- ESM ⚡️ Build success in 49ms
16
- CJS dist/cli.js 7.60 KB
17
- CJS dist/index.js 7.21 KB
18
- CJS ⚡️ Build success in 49ms
19
- DTS Build start
20
- DTS ⚡️ Build success in 4340ms
21
- DTS dist/cli.d.ts 108.00 B
22
- DTS dist/index.d.ts 1.07 KB
23
- DTS dist/cli.d.mts 108.00 B
24
- DTS dist/index.d.mts 1.07 KB
15
+ ESM ⚡️ Build success in 69ms
16
+ CJS dist/index.js 7.27 KB
17
+ CJS dist/cli.js 7.66 KB
18
+ CJS ⚡️ Build success in 71ms
19
+ DTS Build start
20
+ DTS ⚡️ Build success in 3944ms
21
+ DTS dist/cli.d.ts 108.00 B
22
+ DTS dist/index.d.ts 1.07 KB
23
+ DTS dist/cli.d.mts 108.00 B
24
+ DTS dist/index.d.mts 1.07 KB
@@ -1,16 +1,16 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.11.3 test /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.11.7 test /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/doc-drift
8
8
 
9
- ✓ src/__tests__/analyzer.test.ts (1 test) 161ms
9
+ ✓ src/__tests__/analyzer.test.ts (1 test) 38ms
10
10
 
11
11
   Test Files  1 passed (1)
12
12
   Tests  1 passed (1)
13
-  Start at  11:12:29
14
-  Duration  2.75s (transform 792ms, setup 0ms, import 1.76s, tests 161ms, environment 0ms)
13
+  Start at  13:15:45
14
+  Duration  610ms (transform 120ms, setup 0ms, import 381ms, tests 38ms, environment 0ms)
15
15
 
16
16
  [?25h
@@ -0,0 +1,152 @@
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
+ emitProgress
17
+ } from "@aiready/core";
18
+ import { readFileSync } from "fs";
19
+ import { parse } from "@typescript-eslint/typescript-estree";
20
+ async function analyzeDocDrift(options) {
21
+ const files = await scanFiles(options);
22
+ const issues = [];
23
+ const staleMonths = options.staleMonths ?? 6;
24
+ const staleSeconds = staleMonths * 30 * 24 * 60 * 60;
25
+ let uncommentedExports = 0;
26
+ let totalExports = 0;
27
+ let outdatedComments = 0;
28
+ let undocumentedComplexity = 0;
29
+ const now = Math.floor(Date.now() / 1e3);
30
+ let processed = 0;
31
+ for (const file of files) {
32
+ processed++;
33
+ emitProgress(
34
+ processed,
35
+ files.length,
36
+ "doc-drift",
37
+ "analyzing files",
38
+ options.onProgress
39
+ );
40
+ let code;
41
+ try {
42
+ code = readFileSync(file, "utf-8");
43
+ } catch {
44
+ continue;
45
+ }
46
+ let ast;
47
+ try {
48
+ ast = parse(code, {
49
+ jsx: file.endsWith(".tsx") || file.endsWith(".jsx"),
50
+ loc: true,
51
+ comment: true
52
+ });
53
+ } catch {
54
+ continue;
55
+ }
56
+ const comments = ast.comments || [];
57
+ let fileLineStamps;
58
+ for (const node of ast.body) {
59
+ if (node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration") {
60
+ const decl = node.declaration;
61
+ if (!decl) continue;
62
+ if (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration" || decl.type === "VariableDeclaration") {
63
+ totalExports++;
64
+ const nodeLine = node.loc.start.line;
65
+ const jsdocs = comments.filter(
66
+ (c) => c.type === "Block" && c.value.startsWith("*") && c.loc.end.line === nodeLine - 1
67
+ );
68
+ if (jsdocs.length === 0) {
69
+ uncommentedExports++;
70
+ if (decl.type === "FunctionDeclaration" && decl.body?.loc) {
71
+ const lines = decl.body.loc.end.line - decl.body.loc.start.line;
72
+ if (lines > 20) undocumentedComplexity++;
73
+ }
74
+ } else {
75
+ const jsdoc = jsdocs[0];
76
+ const jsdocText = jsdoc.value;
77
+ if (decl.type === "FunctionDeclaration") {
78
+ const params = decl.params.map((p) => p.name || p.left && p.left.name).filter(Boolean);
79
+ const paramTags = Array.from(
80
+ jsdocText.matchAll(/@param\s+(?:\{[^}]+\}\s+)?([a-zA-Z0-9_]+)/g)
81
+ ).map((m) => m[1]);
82
+ const missingParams = params.filter(
83
+ (p) => !paramTags.includes(p)
84
+ );
85
+ if (missingParams.length > 0) {
86
+ outdatedComments++;
87
+ issues.push({
88
+ type: IssueType.DocDrift,
89
+ severity: Severity.Major,
90
+ message: `JSDoc @param mismatch: function has parameters (${missingParams.join(", ")}) not documented in JSDoc.`,
91
+ location: { file, line: nodeLine }
92
+ });
93
+ continue;
94
+ }
95
+ }
96
+ if (!fileLineStamps) {
97
+ fileLineStamps = getFileCommitTimestamps(file);
98
+ }
99
+ const commentModified = getLineRangeLastModifiedCached(
100
+ fileLineStamps,
101
+ jsdoc.loc.start.line,
102
+ jsdoc.loc.end.line
103
+ );
104
+ const bodyModified = getLineRangeLastModifiedCached(
105
+ fileLineStamps,
106
+ decl.loc.start.line,
107
+ decl.loc.end.line
108
+ );
109
+ if (commentModified > 0 && bodyModified > 0) {
110
+ if (now - commentModified > staleSeconds && bodyModified - commentModified > staleSeconds / 2) {
111
+ outdatedComments++;
112
+ issues.push({
113
+ type: IssueType.DocDrift,
114
+ severity: Severity.Minor,
115
+ message: `JSDoc is significantly older than the function body implementation. Code may have drifted.`,
116
+ location: { file, line: jsdoc.loc.start.line }
117
+ });
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ const riskResult = calculateDocDrift({
126
+ uncommentedExports,
127
+ totalExports,
128
+ outdatedComments,
129
+ undocumentedComplexity
130
+ });
131
+ return {
132
+ summary: {
133
+ filesAnalyzed: files.length,
134
+ functionsAnalyzed: totalExports,
135
+ score: riskResult.score,
136
+ rating: riskResult.rating
137
+ },
138
+ issues,
139
+ rawData: {
140
+ uncommentedExports,
141
+ totalExports,
142
+ outdatedComments,
143
+ undocumentedComplexity
144
+ },
145
+ recommendations: riskResult.recommendations
146
+ };
147
+ }
148
+
149
+ export {
150
+ __require,
151
+ analyzeDocDrift
152
+ };
package/dist/cli.js CHANGED
@@ -52,7 +52,13 @@ async function analyzeDocDrift(options) {
52
52
  let processed = 0;
53
53
  for (const file of files) {
54
54
  processed++;
55
- options.onProgress?.(processed, files.length, `doc-drift: analyzing files`);
55
+ (0, import_core.emitProgress)(
56
+ processed,
57
+ files.length,
58
+ "doc-drift",
59
+ "analyzing files",
60
+ options.onProgress
61
+ );
56
62
  let code;
57
63
  try {
58
64
  code = (0, import_fs.readFileSync)(file, "utf-8");
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  analyzeDocDrift
4
- } from "./chunk-CGSYYULO.mjs";
4
+ } from "./chunk-E3YCVHHH.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -46,7 +46,13 @@ async function analyzeDocDrift(options) {
46
46
  let processed = 0;
47
47
  for (const file of files) {
48
48
  processed++;
49
- options.onProgress?.(processed, files.length, `doc-drift: analyzing files`);
49
+ (0, import_core.emitProgress)(
50
+ processed,
51
+ files.length,
52
+ "doc-drift",
53
+ "analyzing files",
54
+ options.onProgress
55
+ );
50
56
  let code;
51
57
  try {
52
58
  code = (0, import_fs.readFileSync)(file, "utf-8");
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  analyzeDocDrift
3
- } from "./chunk-CGSYYULO.mjs";
3
+ } from "./chunk-E3YCVHHH.mjs";
4
4
 
5
5
  // src/index.ts
6
6
  import { ToolRegistry } from "@aiready/core";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/doc-drift",
3
- "version": "0.11.4",
3
+ "version": "0.11.8",
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.21.4"
13
+ "@aiready/core": "0.21.8"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "^24.0.0",
package/src/analyzer.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  getLineRangeLastModifiedCached,
6
6
  Severity,
7
7
  IssueType,
8
+ emitProgress,
8
9
  } from '@aiready/core';
9
10
  import type { DocDriftOptions, DocDriftReport, DocDriftIssue } from './types';
10
11
  import { readFileSync } from 'fs';
@@ -30,7 +31,13 @@ export async function analyzeDocDrift(
30
31
  let processed = 0;
31
32
  for (const file of files) {
32
33
  processed++;
33
- options.onProgress?.(processed, files.length, `doc-drift: analyzing files`);
34
+ emitProgress(
35
+ processed,
36
+ files.length,
37
+ 'doc-drift',
38
+ 'analyzing files',
39
+ options.onProgress
40
+ );
34
41
 
35
42
  let code: string;
36
43
  try {