doc-freshness-checker 1.0.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 (246) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -0
  3. package/dist/cache/cacheManager.d.ts +42 -0
  4. package/dist/cache/cacheManager.js +138 -0
  5. package/dist/cache/cacheManager.js.map +1 -0
  6. package/dist/cache/cacheManager.test.d.ts +1 -0
  7. package/dist/cache/cacheManager.test.js +142 -0
  8. package/dist/cache/cacheManager.test.js.map +1 -0
  9. package/dist/cli.d.ts +32 -0
  10. package/dist/cli.js +137 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/cli.test.d.ts +1 -0
  13. package/dist/cli.test.js +184 -0
  14. package/dist/cli.test.js.map +1 -0
  15. package/dist/config/defaults.d.ts +5 -0
  16. package/dist/config/defaults.js +135 -0
  17. package/dist/config/defaults.js.map +1 -0
  18. package/dist/config/defineConfig.d.ts +28 -0
  19. package/dist/config/defineConfig.js +30 -0
  20. package/dist/config/defineConfig.js.map +1 -0
  21. package/dist/config/defineConfig.test.d.ts +1 -0
  22. package/dist/config/defineConfig.test.js +10 -0
  23. package/dist/config/defineConfig.test.js.map +1 -0
  24. package/dist/config/loader.d.ts +7 -0
  25. package/dist/config/loader.js +250 -0
  26. package/dist/config/loader.js.map +1 -0
  27. package/dist/config/loader.test.d.ts +1 -0
  28. package/dist/config/loader.test.js +276 -0
  29. package/dist/config/loader.test.js.map +1 -0
  30. package/dist/git/changeTracker.d.ts +44 -0
  31. package/dist/git/changeTracker.js +149 -0
  32. package/dist/git/changeTracker.js.map +1 -0
  33. package/dist/git/changeTracker.test.d.ts +1 -0
  34. package/dist/git/changeTracker.test.js +184 -0
  35. package/dist/git/changeTracker.test.js.map +1 -0
  36. package/dist/graph/codeDocGraph.d.ts +43 -0
  37. package/dist/graph/codeDocGraph.js +103 -0
  38. package/dist/graph/codeDocGraph.js.map +1 -0
  39. package/dist/graph/codeDocGraph.test.d.ts +1 -0
  40. package/dist/graph/codeDocGraph.test.js +78 -0
  41. package/dist/graph/codeDocGraph.test.js.map +1 -0
  42. package/dist/graph/graphBuilder.d.ts +17 -0
  43. package/dist/graph/graphBuilder.js +76 -0
  44. package/dist/graph/graphBuilder.js.map +1 -0
  45. package/dist/graph/graphBuilder.test.d.ts +1 -0
  46. package/dist/graph/graphBuilder.test.js +87 -0
  47. package/dist/graph/graphBuilder.test.js.map +1 -0
  48. package/dist/index.d.ts +37 -0
  49. package/dist/index.js +37 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/parsers/documentParser.d.ts +22 -0
  52. package/dist/parsers/documentParser.js +76 -0
  53. package/dist/parsers/documentParser.js.map +1 -0
  54. package/dist/parsers/documentParser.test.d.ts +1 -0
  55. package/dist/parsers/documentParser.test.js +116 -0
  56. package/dist/parsers/documentParser.test.js.map +1 -0
  57. package/dist/parsers/extractors/baseExtractor.d.ts +19 -0
  58. package/dist/parsers/extractors/baseExtractor.js +33 -0
  59. package/dist/parsers/extractors/baseExtractor.js.map +1 -0
  60. package/dist/parsers/extractors/baseExtractor.test.d.ts +1 -0
  61. package/dist/parsers/extractors/baseExtractor.test.js +43 -0
  62. package/dist/parsers/extractors/baseExtractor.test.js.map +1 -0
  63. package/dist/parsers/extractors/codePatternExtractor.d.ts +13 -0
  64. package/dist/parsers/extractors/codePatternExtractor.js +108 -0
  65. package/dist/parsers/extractors/codePatternExtractor.js.map +1 -0
  66. package/dist/parsers/extractors/codePatternExtractor.test.d.ts +1 -0
  67. package/dist/parsers/extractors/codePatternExtractor.test.js +49 -0
  68. package/dist/parsers/extractors/codePatternExtractor.test.js.map +1 -0
  69. package/dist/parsers/extractors/dependencyExtractor.d.ts +12 -0
  70. package/dist/parsers/extractors/dependencyExtractor.js +92 -0
  71. package/dist/parsers/extractors/dependencyExtractor.js.map +1 -0
  72. package/dist/parsers/extractors/dependencyExtractor.test.d.ts +1 -0
  73. package/dist/parsers/extractors/dependencyExtractor.test.js +48 -0
  74. package/dist/parsers/extractors/dependencyExtractor.test.js.map +1 -0
  75. package/dist/parsers/extractors/directoryStructureExtractor.d.ts +34 -0
  76. package/dist/parsers/extractors/directoryStructureExtractor.js +168 -0
  77. package/dist/parsers/extractors/directoryStructureExtractor.js.map +1 -0
  78. package/dist/parsers/extractors/directoryStructureExtractor.test.d.ts +1 -0
  79. package/dist/parsers/extractors/directoryStructureExtractor.test.js +121 -0
  80. package/dist/parsers/extractors/directoryStructureExtractor.test.js.map +1 -0
  81. package/dist/parsers/extractors/externalUrlExtractor.d.ts +14 -0
  82. package/dist/parsers/extractors/externalUrlExtractor.js +53 -0
  83. package/dist/parsers/extractors/externalUrlExtractor.js.map +1 -0
  84. package/dist/parsers/extractors/externalUrlExtractor.test.d.ts +1 -0
  85. package/dist/parsers/extractors/externalUrlExtractor.test.js +85 -0
  86. package/dist/parsers/extractors/externalUrlExtractor.test.js.map +1 -0
  87. package/dist/parsers/extractors/filePathExtractor.d.ts +18 -0
  88. package/dist/parsers/extractors/filePathExtractor.js +72 -0
  89. package/dist/parsers/extractors/filePathExtractor.js.map +1 -0
  90. package/dist/parsers/extractors/filePathExtractor.test.d.ts +1 -0
  91. package/dist/parsers/extractors/filePathExtractor.test.js +73 -0
  92. package/dist/parsers/extractors/filePathExtractor.test.js.map +1 -0
  93. package/dist/parsers/extractors/versionExtractor.d.ts +11 -0
  94. package/dist/parsers/extractors/versionExtractor.js +74 -0
  95. package/dist/parsers/extractors/versionExtractor.js.map +1 -0
  96. package/dist/parsers/extractors/versionExtractor.test.d.ts +1 -0
  97. package/dist/parsers/extractors/versionExtractor.test.js +55 -0
  98. package/dist/parsers/extractors/versionExtractor.test.js.map +1 -0
  99. package/dist/plugins/plugin.d.ts +32 -0
  100. package/dist/plugins/plugin.js +40 -0
  101. package/dist/plugins/plugin.js.map +1 -0
  102. package/dist/plugins/plugin.test.d.ts +1 -0
  103. package/dist/plugins/plugin.test.js +23 -0
  104. package/dist/plugins/plugin.test.js.map +1 -0
  105. package/dist/reporters/consoleReporter.d.ts +15 -0
  106. package/dist/reporters/consoleReporter.js +73 -0
  107. package/dist/reporters/consoleReporter.js.map +1 -0
  108. package/dist/reporters/consoleReporter.test.d.ts +1 -0
  109. package/dist/reporters/consoleReporter.test.js +155 -0
  110. package/dist/reporters/consoleReporter.test.js.map +1 -0
  111. package/dist/reporters/enhancedReporter.d.ts +12 -0
  112. package/dist/reporters/enhancedReporter.js +81 -0
  113. package/dist/reporters/enhancedReporter.js.map +1 -0
  114. package/dist/reporters/enhancedReporter.test.d.ts +1 -0
  115. package/dist/reporters/enhancedReporter.test.js +152 -0
  116. package/dist/reporters/enhancedReporter.test.js.map +1 -0
  117. package/dist/reporters/jsonReporter.d.ts +11 -0
  118. package/dist/reporters/jsonReporter.js +20 -0
  119. package/dist/reporters/jsonReporter.js.map +1 -0
  120. package/dist/reporters/jsonReporter.test.d.ts +1 -0
  121. package/dist/reporters/jsonReporter.test.js +31 -0
  122. package/dist/reporters/jsonReporter.test.js.map +1 -0
  123. package/dist/reporters/markdownReporter.d.ts +11 -0
  124. package/dist/reporters/markdownReporter.js +55 -0
  125. package/dist/reporters/markdownReporter.js.map +1 -0
  126. package/dist/reporters/markdownReporter.test.d.ts +1 -0
  127. package/dist/reporters/markdownReporter.test.js +136 -0
  128. package/dist/reporters/markdownReporter.test.js.map +1 -0
  129. package/dist/runner.d.ts +9 -0
  130. package/dist/runner.js +265 -0
  131. package/dist/runner.js.map +1 -0
  132. package/dist/runner.test.d.ts +1 -0
  133. package/dist/runner.test.js +353 -0
  134. package/dist/runner.test.js.map +1 -0
  135. package/dist/scoring/freshnessScorer.d.ts +40 -0
  136. package/dist/scoring/freshnessScorer.js +170 -0
  137. package/dist/scoring/freshnessScorer.js.map +1 -0
  138. package/dist/scoring/freshnessScorer.test.d.ts +1 -0
  139. package/dist/scoring/freshnessScorer.test.js +397 -0
  140. package/dist/scoring/freshnessScorer.test.js.map +1 -0
  141. package/dist/semantic/vectorSearch.d.ts +84 -0
  142. package/dist/semantic/vectorSearch.js +484 -0
  143. package/dist/semantic/vectorSearch.js.map +1 -0
  144. package/dist/semantic/vectorSearch.test.d.ts +1 -0
  145. package/dist/semantic/vectorSearch.test.js +660 -0
  146. package/dist/semantic/vectorSearch.test.js.map +1 -0
  147. package/dist/setupTests.d.ts +4 -0
  148. package/dist/setupTests.js +11 -0
  149. package/dist/setupTests.js.map +1 -0
  150. package/dist/test-utils/console.d.ts +2 -0
  151. package/dist/test-utils/console.js +3 -0
  152. package/dist/test-utils/console.js.map +1 -0
  153. package/dist/test-utils/factories.d.ts +3 -0
  154. package/dist/test-utils/factories.js +25 -0
  155. package/dist/test-utils/factories.js.map +1 -0
  156. package/dist/test-utils/tempFiles.d.ts +1 -0
  157. package/dist/test-utils/tempFiles.js +12 -0
  158. package/dist/test-utils/tempFiles.js.map +1 -0
  159. package/dist/types.d.ts +304 -0
  160. package/dist/types.js +5 -0
  161. package/dist/types.js.map +1 -0
  162. package/dist/utils/boundedMap.d.ts +8 -0
  163. package/dist/utils/boundedMap.js +22 -0
  164. package/dist/utils/boundedMap.js.map +1 -0
  165. package/dist/utils/boundedMap.test.d.ts +1 -0
  166. package/dist/utils/boundedMap.test.js +57 -0
  167. package/dist/utils/boundedMap.test.js.map +1 -0
  168. package/dist/utils/illustrativePatterns.d.ts +28 -0
  169. package/dist/utils/illustrativePatterns.js +80 -0
  170. package/dist/utils/illustrativePatterns.js.map +1 -0
  171. package/dist/utils/illustrativePatterns.test.d.ts +1 -0
  172. package/dist/utils/illustrativePatterns.test.js +48 -0
  173. package/dist/utils/illustrativePatterns.test.js.map +1 -0
  174. package/dist/utils/incremental.d.ts +36 -0
  175. package/dist/utils/incremental.js +87 -0
  176. package/dist/utils/incremental.js.map +1 -0
  177. package/dist/utils/incremental.test.d.ts +1 -0
  178. package/dist/utils/incremental.test.js +84 -0
  179. package/dist/utils/incremental.test.js.map +1 -0
  180. package/dist/utils/parallel.d.ts +14 -0
  181. package/dist/utils/parallel.js +43 -0
  182. package/dist/utils/parallel.js.map +1 -0
  183. package/dist/utils/parallel.test.d.ts +1 -0
  184. package/dist/utils/parallel.test.js +48 -0
  185. package/dist/utils/parallel.test.js.map +1 -0
  186. package/dist/utils/pathSecurity.d.ts +12 -0
  187. package/dist/utils/pathSecurity.js +22 -0
  188. package/dist/utils/pathSecurity.js.map +1 -0
  189. package/dist/utils/pathSecurity.test.d.ts +1 -0
  190. package/dist/utils/pathSecurity.test.js +34 -0
  191. package/dist/utils/pathSecurity.test.js.map +1 -0
  192. package/dist/utils/similarity.d.ts +12 -0
  193. package/dist/utils/similarity.js +64 -0
  194. package/dist/utils/similarity.js.map +1 -0
  195. package/dist/utils/similarity.test.d.ts +1 -0
  196. package/dist/utils/similarity.test.js +49 -0
  197. package/dist/utils/similarity.test.js.map +1 -0
  198. package/dist/utils/validation.d.ts +13 -0
  199. package/dist/utils/validation.js +24 -0
  200. package/dist/utils/validation.js.map +1 -0
  201. package/dist/utils/validation.test.d.ts +1 -0
  202. package/dist/utils/validation.test.js +28 -0
  203. package/dist/utils/validation.test.js.map +1 -0
  204. package/dist/validators/codePatternValidator.d.ts +28 -0
  205. package/dist/validators/codePatternValidator.js +200 -0
  206. package/dist/validators/codePatternValidator.js.map +1 -0
  207. package/dist/validators/codePatternValidator.test.d.ts +1 -0
  208. package/dist/validators/codePatternValidator.test.js +86 -0
  209. package/dist/validators/codePatternValidator.test.js.map +1 -0
  210. package/dist/validators/dependencyValidator.d.ts +12 -0
  211. package/dist/validators/dependencyValidator.js +102 -0
  212. package/dist/validators/dependencyValidator.js.map +1 -0
  213. package/dist/validators/dependencyValidator.test.d.ts +1 -0
  214. package/dist/validators/dependencyValidator.test.js +179 -0
  215. package/dist/validators/dependencyValidator.test.js.map +1 -0
  216. package/dist/validators/directoryValidator.d.ts +30 -0
  217. package/dist/validators/directoryValidator.js +192 -0
  218. package/dist/validators/directoryValidator.js.map +1 -0
  219. package/dist/validators/directoryValidator.test.d.ts +1 -0
  220. package/dist/validators/directoryValidator.test.js +193 -0
  221. package/dist/validators/directoryValidator.test.js.map +1 -0
  222. package/dist/validators/fileValidator.d.ts +16 -0
  223. package/dist/validators/fileValidator.js +114 -0
  224. package/dist/validators/fileValidator.js.map +1 -0
  225. package/dist/validators/fileValidator.test.d.ts +1 -0
  226. package/dist/validators/fileValidator.test.js +108 -0
  227. package/dist/validators/fileValidator.test.js.map +1 -0
  228. package/dist/validators/urlValidator.d.ts +25 -0
  229. package/dist/validators/urlValidator.js +320 -0
  230. package/dist/validators/urlValidator.js.map +1 -0
  231. package/dist/validators/urlValidator.test.d.ts +1 -0
  232. package/dist/validators/urlValidator.test.js +252 -0
  233. package/dist/validators/urlValidator.test.js.map +1 -0
  234. package/dist/validators/validationEngine.d.ts +23 -0
  235. package/dist/validators/validationEngine.js +117 -0
  236. package/dist/validators/validationEngine.js.map +1 -0
  237. package/dist/validators/validationEngine.test.d.ts +1 -0
  238. package/dist/validators/validationEngine.test.js +82 -0
  239. package/dist/validators/validationEngine.test.js.map +1 -0
  240. package/dist/validators/versionValidator.d.ts +18 -0
  241. package/dist/validators/versionValidator.js +211 -0
  242. package/dist/validators/versionValidator.js.map +1 -0
  243. package/dist/validators/versionValidator.test.d.ts +1 -0
  244. package/dist/validators/versionValidator.test.js +308 -0
  245. package/dist/validators/versionValidator.test.js.map +1 -0
  246. package/package.json +98 -0
@@ -0,0 +1,149 @@
1
+ import { execFileSync } from 'child_process';
2
+ /**
3
+ * Tracks git changes for incremental documentation checking
4
+ */
5
+ export class GitChangeTracker {
6
+ rootDir;
7
+ _isGitRepo;
8
+ constructor(config) {
9
+ this.rootDir = config.rootDir || process.cwd();
10
+ this._isGitRepo = null;
11
+ }
12
+ git(args) {
13
+ return execFileSync('git', args, {
14
+ cwd: this.rootDir,
15
+ encoding: 'utf-8',
16
+ stdio: ['pipe', 'pipe', 'pipe'],
17
+ }).trim();
18
+ }
19
+ /**
20
+ * Check if the project is a git repository
21
+ */
22
+ isGitRepo() {
23
+ if (this._isGitRepo !== null) {
24
+ return this._isGitRepo;
25
+ }
26
+ try {
27
+ this.git(['rev-parse', '--git-dir']);
28
+ this._isGitRepo = true;
29
+ }
30
+ catch {
31
+ this._isGitRepo = false;
32
+ }
33
+ return this._isGitRepo;
34
+ }
35
+ /**
36
+ * Get the current git commit hash
37
+ */
38
+ getCurrentCommit() {
39
+ if (!this.isGitRepo())
40
+ return null;
41
+ try {
42
+ return this.git(['rev-parse', 'HEAD']);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ /**
49
+ * Get files changed between two commits
50
+ */
51
+ getChangedFiles(fromCommit, toCommit = 'HEAD') {
52
+ if (!this.isGitRepo())
53
+ return [];
54
+ try {
55
+ const output = this.git(['diff', '--name-only', `${fromCommit}..${toCommit}`]);
56
+ return output.split('\n').filter(Boolean);
57
+ }
58
+ catch {
59
+ return [];
60
+ }
61
+ }
62
+ /**
63
+ * Get files changed since a timestamp
64
+ */
65
+ getChangedFilesSince(timestamp) {
66
+ if (!this.isGitRepo())
67
+ return [];
68
+ try {
69
+ const isoDate = new Date(timestamp).toISOString();
70
+ const output = this.git(['log', `--since=${isoDate}`, '--name-only', '--pretty=format:']);
71
+ const files = [...new Set(output.split('\n').filter(Boolean))];
72
+ return files;
73
+ }
74
+ catch {
75
+ return [];
76
+ }
77
+ }
78
+ /**
79
+ * Get the last modification time of a file from git
80
+ */
81
+ getFileLastModified(filePath) {
82
+ if (!this.isGitRepo())
83
+ return null;
84
+ try {
85
+ const output = this.git(['log', '-1', '--format=%ct', '--', filePath]);
86
+ const timestamp = parseInt(output, 10);
87
+ return timestamp ? timestamp * 1000 : null;
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ }
93
+ /**
94
+ * Get commit info for a file.
95
+ * Uses NUL byte as separator to safely handle commit messages containing |
96
+ */
97
+ getFileCommitInfo(filePath) {
98
+ if (!this.isGitRepo())
99
+ return null;
100
+ try {
101
+ const output = this.git(['log', '-1', '--format=%H%x00%ct%x00%s', '--', filePath]);
102
+ if (!output)
103
+ return null;
104
+ const parts = output.split('\0');
105
+ if (parts.length < 3)
106
+ return null;
107
+ return {
108
+ hash: parts[0],
109
+ timestamp: parseInt(parts[1], 10) * 1000,
110
+ message: parts.slice(2).join('\0'),
111
+ };
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * Determine which docs need re-checking based on code changes
119
+ */
120
+ getAffectedDocs(graph, changedFiles) {
121
+ const affectedDocs = new Set();
122
+ for (const changedFile of changedFiles) {
123
+ const docs = graph.getDocsReferencingCode(changedFile);
124
+ for (const doc of docs) {
125
+ affectedDocs.add(doc);
126
+ }
127
+ }
128
+ return [...affectedDocs];
129
+ }
130
+ /**
131
+ * Get change summary for reporting
132
+ */
133
+ getChangeSummary(graph, changedFiles) {
134
+ const summary = [];
135
+ for (const changedFile of changedFiles) {
136
+ const docs = graph.getDocsReferencingCode(changedFile);
137
+ if (docs.size > 0) {
138
+ const commitInfo = this.getFileCommitInfo(changedFile);
139
+ summary.push({
140
+ codeFile: changedFile,
141
+ affectedDocs: [...docs],
142
+ lastCommit: commitInfo,
143
+ });
144
+ }
145
+ }
146
+ return summary;
147
+ }
148
+ }
149
+ //# sourceMappingURL=changeTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeTracker.js","sourceRoot":"","sources":["../../src/git/changeTracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,184 @@
1
+ import { execFileSync } from 'child_process';
2
+ import { GitChangeTracker } from './changeTracker.js';
3
+ import { CodeDocGraph } from '../graph/codeDocGraph.js';
4
+ vi.mock('child_process');
5
+ const mockExecFileSync = vi.mocked(execFileSync);
6
+ function makeRef(value) {
7
+ return { type: 'file-path', value, lineNumber: 1, raw: value, sourceFile: 'doc.md' };
8
+ }
9
+ describe('GitChangeTracker', () => {
10
+ const config = { rootDir: '/project' };
11
+ beforeEach(() => {
12
+ mockExecFileSync.mockReset();
13
+ });
14
+ describe('isGitRepo', () => {
15
+ it('returns true when git rev-parse succeeds', () => {
16
+ mockExecFileSync.mockReturnValue('.git\n');
17
+ expect(new GitChangeTracker(config).isGitRepo()).toBe(true);
18
+ });
19
+ it('returns false when git rev-parse fails', () => {
20
+ mockExecFileSync.mockImplementation(() => {
21
+ throw new Error('not a git repo');
22
+ });
23
+ expect(new GitChangeTracker(config).isGitRepo()).toBe(false);
24
+ });
25
+ it('caches the result', () => {
26
+ mockExecFileSync.mockReturnValue('.git\n');
27
+ const tracker = new GitChangeTracker(config);
28
+ tracker.isGitRepo();
29
+ tracker.isGitRepo();
30
+ expect(mockExecFileSync).toHaveBeenCalledTimes(1);
31
+ });
32
+ it('uses process.cwd() when rootDir not specified', () => {
33
+ mockExecFileSync.mockReturnValue('.git\n');
34
+ new GitChangeTracker({}).isGitRepo();
35
+ expect(mockExecFileSync).toHaveBeenCalledWith('git', ['rev-parse', '--git-dir'], expect.objectContaining({ cwd: process.cwd() }));
36
+ });
37
+ });
38
+ describe('getCurrentCommit', () => {
39
+ it('returns commit hash', () => {
40
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('abc123\n');
41
+ expect(new GitChangeTracker(config).getCurrentCommit()).toBe('abc123');
42
+ });
43
+ it('returns null for non-git repos', () => {
44
+ mockExecFileSync.mockImplementation(() => {
45
+ throw new Error();
46
+ });
47
+ expect(new GitChangeTracker(config).getCurrentCommit()).toBeNull();
48
+ });
49
+ it('returns null when rev-parse HEAD fails', () => {
50
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockImplementationOnce(() => {
51
+ throw new Error('no commits');
52
+ });
53
+ expect(new GitChangeTracker(config).getCurrentCommit()).toBeNull();
54
+ });
55
+ });
56
+ describe('getChangedFiles', () => {
57
+ it('returns changed file list', () => {
58
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('file1.ts\nfile2.ts\n');
59
+ expect(new GitChangeTracker(config).getChangedFiles('abc', 'def')).toEqual(['file1.ts', 'file2.ts']);
60
+ });
61
+ it('returns empty for non-git repos', () => {
62
+ mockExecFileSync.mockImplementation(() => {
63
+ throw new Error();
64
+ });
65
+ expect(new GitChangeTracker(config).getChangedFiles('a', 'b')).toEqual([]);
66
+ });
67
+ it('returns empty when git diff fails', () => {
68
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockImplementationOnce(() => {
69
+ throw new Error('diff failed');
70
+ });
71
+ expect(new GitChangeTracker(config).getChangedFiles('a', 'b')).toEqual([]);
72
+ });
73
+ });
74
+ describe('getChangedFilesSince', () => {
75
+ it('returns unique changed files since timestamp', () => {
76
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('file1.ts\nfile1.ts\nfile2.ts\n');
77
+ const files = new GitChangeTracker(config).getChangedFilesSince(Date.now() - 7 * 24 * 60 * 60 * 1000);
78
+ expect(files).toEqual(['file1.ts', 'file2.ts']);
79
+ });
80
+ it('returns empty for non-git repos', () => {
81
+ mockExecFileSync.mockImplementation(() => {
82
+ throw new Error();
83
+ });
84
+ expect(new GitChangeTracker(config).getChangedFilesSince(Date.now())).toEqual([]);
85
+ });
86
+ it('returns empty when git log fails', () => {
87
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockImplementationOnce(() => {
88
+ throw new Error('log failed');
89
+ });
90
+ expect(new GitChangeTracker(config).getChangedFilesSince(Date.now())).toEqual([]);
91
+ });
92
+ });
93
+ describe('getFileLastModified', () => {
94
+ it('returns timestamp in milliseconds', () => {
95
+ const ts = Math.floor(Date.now() / 1000);
96
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce(`${ts}\n`);
97
+ expect(new GitChangeTracker(config).getFileLastModified('file.ts')).toBe(ts * 1000);
98
+ });
99
+ it('returns null for non-git repos', () => {
100
+ mockExecFileSync.mockImplementation(() => {
101
+ throw new Error();
102
+ });
103
+ expect(new GitChangeTracker(config).getFileLastModified('file.ts')).toBeNull();
104
+ });
105
+ it('returns null when file has no commits', () => {
106
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('\n');
107
+ expect(new GitChangeTracker(config).getFileLastModified('new-file.ts')).toBeNull();
108
+ });
109
+ it('returns null when git log fails', () => {
110
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockImplementationOnce(() => {
111
+ throw new Error('log failed');
112
+ });
113
+ expect(new GitChangeTracker(config).getFileLastModified('file.ts')).toBeNull();
114
+ });
115
+ });
116
+ describe('getFileCommitInfo', () => {
117
+ it('parses NUL-separated commit info', () => {
118
+ const ts = Math.floor(Date.now() / 1000);
119
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce(`abc123\0${ts}\0Fix bug\n`);
120
+ const info = new GitChangeTracker(config).getFileCommitInfo('file.ts');
121
+ expect(info).toEqual({ hash: 'abc123', timestamp: ts * 1000, message: 'Fix bug' });
122
+ });
123
+ it('returns null when no output', () => {
124
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('\n');
125
+ expect(new GitChangeTracker(config).getFileCommitInfo('file.ts')).toBeNull();
126
+ });
127
+ it('returns null when insufficient parts in output', () => {
128
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce('abc123\n');
129
+ expect(new GitChangeTracker(config).getFileCommitInfo('file.ts')).toBeNull();
130
+ });
131
+ it('returns null for non-git repos', () => {
132
+ mockExecFileSync.mockImplementation(() => {
133
+ throw new Error();
134
+ });
135
+ expect(new GitChangeTracker(config).getFileCommitInfo('file.ts')).toBeNull();
136
+ });
137
+ it('returns null when git log fails', () => {
138
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockImplementationOnce(() => {
139
+ throw new Error();
140
+ });
141
+ expect(new GitChangeTracker(config).getFileCommitInfo('file.ts')).toBeNull();
142
+ });
143
+ });
144
+ describe('getAffectedDocs', () => {
145
+ it('returns docs that reference changed code files', () => {
146
+ mockExecFileSync.mockReturnValue('.git\n');
147
+ const graph = new CodeDocGraph();
148
+ graph.addReference('docs/api.md', 'src/server.ts', makeRef('src/server.ts'));
149
+ expect(new GitChangeTracker(config).getAffectedDocs(graph, ['src/server.ts'])).toEqual(['docs/api.md']);
150
+ });
151
+ it('deduplicates affected docs', () => {
152
+ mockExecFileSync.mockReturnValue('.git\n');
153
+ const graph = new CodeDocGraph();
154
+ graph.addReference('docs/api.md', 'src/a.ts', makeRef('a.ts'));
155
+ graph.addReference('docs/api.md', 'src/b.ts', makeRef('b.ts'));
156
+ expect(new GitChangeTracker(config).getAffectedDocs(graph, ['src/a.ts', 'src/b.ts'])).toEqual(['docs/api.md']);
157
+ });
158
+ it('returns empty when no changed files match graph', () => {
159
+ mockExecFileSync.mockReturnValue('.git\n');
160
+ const graph = new CodeDocGraph();
161
+ expect(new GitChangeTracker(config).getAffectedDocs(graph, ['unrelated.ts'])).toEqual([]);
162
+ });
163
+ });
164
+ describe('getChangeSummary', () => {
165
+ it('returns summary with affected docs and commit info', () => {
166
+ const ts = Math.floor(Date.now() / 1000);
167
+ mockExecFileSync.mockReturnValueOnce('.git\n').mockReturnValueOnce(`hash1\0${ts}\0Update\n`);
168
+ const graph = new CodeDocGraph();
169
+ graph.addReference('docs/api.md', 'src/server.ts', makeRef('src/server.ts'));
170
+ const summary = new GitChangeTracker(config).getChangeSummary(graph, ['src/server.ts']);
171
+ expect(summary).toHaveLength(1);
172
+ expect(summary[0].codeFile).toBe('src/server.ts');
173
+ expect(summary[0].affectedDocs).toEqual(['docs/api.md']);
174
+ });
175
+ it('skips files with no affected docs', () => {
176
+ mockExecFileSync.mockReturnValue('.git\n');
177
+ const graph = new CodeDocGraph();
178
+ graph.addReference('docs/api.md', 'src/server.ts', makeRef('src/server.ts'));
179
+ const summary = new GitChangeTracker(config).getChangeSummary(graph, ['unrelated.ts']);
180
+ expect(summary).toHaveLength(0);
181
+ });
182
+ });
183
+ });
184
+ //# sourceMappingURL=changeTracker.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeTracker.test.js","sourceRoot":"","sources":["../../src/git/changeTracker.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { GraphReference, Reference, SerializedGraph } from '../types.js';
2
+ /**
3
+ * Represents the relationship graph between docs and code
4
+ * Uses adjacency list representation for efficient traversal
5
+ */
6
+ export declare class CodeDocGraph {
7
+ docToCode: Map<string, Set<string>>;
8
+ codeToDoc: Map<string, Set<string>>;
9
+ codeSymbols: Map<string, Set<string>>;
10
+ docReferences: Map<string, GraphReference[]>;
11
+ buildTimestamp: number | null;
12
+ gitCommit: string | null;
13
+ configHash: string | null;
14
+ constructor();
15
+ /**
16
+ * Add a reference from a doc to a code file
17
+ */
18
+ addReference(docPath: string, codeFilePath: string, reference: Reference): void;
19
+ /**
20
+ * Get all docs that reference a specific code file
21
+ */
22
+ getDocsReferencingCode(codeFilePath: string): Set<string>;
23
+ /**
24
+ * Get all code files referenced by a doc
25
+ */
26
+ getCodeReferencedByDoc(docPath: string): Set<string>;
27
+ /**
28
+ * Get all document paths in the graph
29
+ */
30
+ getAllDocs(): string[];
31
+ /**
32
+ * Get all code file paths in the graph
33
+ */
34
+ getAllCodeFiles(): string[];
35
+ /**
36
+ * Serialize graph for caching
37
+ */
38
+ serialize(): SerializedGraph;
39
+ /**
40
+ * Deserialize from cache
41
+ */
42
+ static deserialize(data: SerializedGraph): CodeDocGraph;
43
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Represents the relationship graph between docs and code
3
+ * Uses adjacency list representation for efficient traversal
4
+ */
5
+ export class CodeDocGraph {
6
+ // Map: doc path -> Set of code file paths it references
7
+ docToCode;
8
+ // Map: code file path -> Set of doc paths that reference it
9
+ codeToDoc;
10
+ // Map: code file path -> Set of symbols defined in it
11
+ codeSymbols;
12
+ // Map: doc path -> references with metadata
13
+ docReferences;
14
+ // Metadata
15
+ buildTimestamp;
16
+ gitCommit;
17
+ configHash;
18
+ constructor() {
19
+ this.docToCode = new Map();
20
+ this.codeToDoc = new Map();
21
+ this.codeSymbols = new Map();
22
+ this.docReferences = new Map();
23
+ this.buildTimestamp = null;
24
+ this.gitCommit = null;
25
+ this.configHash = null;
26
+ }
27
+ /**
28
+ * Add a reference from a doc to a code file
29
+ */
30
+ addReference(docPath, codeFilePath, reference) {
31
+ // Doc -> Code edge
32
+ if (!this.docToCode.has(docPath)) {
33
+ this.docToCode.set(docPath, new Set());
34
+ }
35
+ this.docToCode.get(docPath).add(codeFilePath);
36
+ // Code -> Doc edge (reverse index)
37
+ if (!this.codeToDoc.has(codeFilePath)) {
38
+ this.codeToDoc.set(codeFilePath, new Set());
39
+ }
40
+ this.codeToDoc.get(codeFilePath).add(docPath);
41
+ // Store reference metadata
42
+ if (!this.docReferences.has(docPath)) {
43
+ this.docReferences.set(docPath, []);
44
+ }
45
+ this.docReferences.get(docPath).push({
46
+ ...reference,
47
+ resolvedCodeFile: codeFilePath,
48
+ });
49
+ }
50
+ /**
51
+ * Get all docs that reference a specific code file
52
+ */
53
+ getDocsReferencingCode(codeFilePath) {
54
+ return this.codeToDoc.get(codeFilePath) || new Set();
55
+ }
56
+ /**
57
+ * Get all code files referenced by a doc
58
+ */
59
+ getCodeReferencedByDoc(docPath) {
60
+ return this.docToCode.get(docPath) || new Set();
61
+ }
62
+ /**
63
+ * Get all document paths in the graph
64
+ */
65
+ getAllDocs() {
66
+ return Array.from(this.docToCode.keys());
67
+ }
68
+ /**
69
+ * Get all code file paths in the graph
70
+ */
71
+ getAllCodeFiles() {
72
+ return Array.from(this.codeToDoc.keys());
73
+ }
74
+ /**
75
+ * Serialize graph for caching
76
+ */
77
+ serialize() {
78
+ return {
79
+ docToCode: Object.fromEntries([...this.docToCode].map(([k, v]) => [k, [...v]])),
80
+ codeToDoc: Object.fromEntries([...this.codeToDoc].map(([k, v]) => [k, [...v]])),
81
+ codeSymbols: Object.fromEntries([...this.codeSymbols].map(([k, v]) => [k, [...v]])),
82
+ docReferences: Object.fromEntries(this.docReferences),
83
+ buildTimestamp: this.buildTimestamp,
84
+ gitCommit: this.gitCommit,
85
+ configHash: this.configHash,
86
+ };
87
+ }
88
+ /**
89
+ * Deserialize from cache
90
+ */
91
+ static deserialize(data) {
92
+ const graph = new CodeDocGraph();
93
+ graph.docToCode = new Map(Object.entries(data.docToCode || {}).map(([k, v]) => [k, new Set(v)]));
94
+ graph.codeToDoc = new Map(Object.entries(data.codeToDoc || {}).map(([k, v]) => [k, new Set(v)]));
95
+ graph.codeSymbols = new Map(Object.entries(data.codeSymbols || {}).map(([k, v]) => [k, new Set(v)]));
96
+ graph.docReferences = new Map(Object.entries(data.docReferences || {}));
97
+ graph.buildTimestamp = data.buildTimestamp;
98
+ graph.gitCommit = data.gitCommit;
99
+ graph.configHash = data.configHash;
100
+ return graph;
101
+ }
102
+ }
103
+ //# sourceMappingURL=codeDocGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeDocGraph.js","sourceRoot":"","sources":["../../src/graph/codeDocGraph.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,YAAY;IACvB,wDAAwD;IACxD,SAAS,CAA2B;IAEpC,4DAA4D;IAC5D,SAAS,CAA2B;IAEpC,sDAAsD;IACtD,WAAW,CAA2B;IAEtC,4CAA4C;IAC5C,aAAa,CAAgC;IAE7C,WAAW;IACX,cAAc,CAAgB;IAC9B,SAAS,CAAgB;IACzB,UAAU,CAAgB;IAE1B;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,OAAe,EAAE,YAAoB,EAAE,SAAoB;QACtE,mBAAmB;QACnB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE/C,mCAAmC;QACnC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE/C,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC;YACpC,GAAG,SAAS;YACZ,gBAAgB,EAAE,YAAY;SAC/B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,sBAAsB,CAAC,YAAoB;QACzC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,sBAAsB,CAAC,OAAe;QACpC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;YACrD,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAqB;QACtC,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;QACjC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjG,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjG,KAAK,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrG,KAAK,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC3C,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,78 @@
1
+ import { CodeDocGraph } from './codeDocGraph.js';
2
+ function makeRef(type, value) {
3
+ return { type, value, lineNumber: 1, raw: value, sourceFile: 'doc.md' };
4
+ }
5
+ describe('CodeDocGraph', () => {
6
+ let graph;
7
+ beforeEach(() => {
8
+ graph = new CodeDocGraph();
9
+ });
10
+ describe('addReference', () => {
11
+ it('creates doc-to-code and code-to-doc edges', () => {
12
+ graph.addReference('docs/api.md', 'src/server.ts', makeRef('file-path', 'src/server.ts'));
13
+ expect(graph.getCodeReferencedByDoc('docs/api.md').has('src/server.ts')).toBe(true);
14
+ expect(graph.getDocsReferencingCode('src/server.ts').has('docs/api.md')).toBe(true);
15
+ });
16
+ it('stores reference metadata', () => {
17
+ const ref = makeRef('code-pattern', 'MyClass');
18
+ graph.addReference('docs/api.md', 'src/myClass.ts', ref);
19
+ const docRefs = graph.docReferences.get('docs/api.md');
20
+ expect(docRefs).toHaveLength(1);
21
+ expect(docRefs[0].resolvedCodeFile).toBe('src/myClass.ts');
22
+ });
23
+ it('handles multiple references from same doc', () => {
24
+ graph.addReference('docs/api.md', 'src/a.ts', makeRef('file-path', 'a.ts'));
25
+ graph.addReference('docs/api.md', 'src/b.ts', makeRef('file-path', 'b.ts'));
26
+ expect(graph.getCodeReferencedByDoc('docs/api.md').size).toBe(2);
27
+ });
28
+ });
29
+ describe('query methods', () => {
30
+ beforeEach(() => {
31
+ graph.addReference('docs/a.md', 'src/x.ts', makeRef('file-path', 'x.ts'));
32
+ graph.addReference('docs/b.md', 'src/x.ts', makeRef('file-path', 'x.ts'));
33
+ graph.addReference('docs/a.md', 'src/y.ts', makeRef('file-path', 'y.ts'));
34
+ });
35
+ it('getDocsReferencingCode returns all docs referencing a code file', () => {
36
+ expect(graph.getDocsReferencingCode('src/x.ts').size).toBe(2);
37
+ });
38
+ it('returns empty set for unknown paths', () => {
39
+ expect(graph.getDocsReferencingCode('unknown').size).toBe(0);
40
+ expect(graph.getCodeReferencedByDoc('unknown').size).toBe(0);
41
+ });
42
+ it('getAllDocs returns all document paths', () => {
43
+ expect(graph.getAllDocs().sort()).toEqual(['docs/a.md', 'docs/b.md']);
44
+ });
45
+ it('getAllCodeFiles returns all code file paths', () => {
46
+ expect(graph.getAllCodeFiles().sort()).toEqual(['src/x.ts', 'src/y.ts']);
47
+ });
48
+ });
49
+ describe('serialize / deserialize', () => {
50
+ it('round-trips correctly', () => {
51
+ graph.addReference('docs/a.md', 'src/x.ts', makeRef('file-path', 'x.ts'));
52
+ graph.codeSymbols.set('src/x.ts', new Set(['MyClass', 'myFunc']));
53
+ graph.buildTimestamp = 12345;
54
+ graph.gitCommit = 'abc';
55
+ graph.configHash = 'def';
56
+ const serialized = graph.serialize();
57
+ const restored = CodeDocGraph.deserialize(serialized);
58
+ expect(restored.getCodeReferencedByDoc('docs/a.md').has('src/x.ts')).toBe(true);
59
+ expect(restored.codeSymbols.get('src/x.ts').has('MyClass')).toBe(true);
60
+ expect(restored.buildTimestamp).toBe(12345);
61
+ expect(restored.gitCommit).toBe('abc');
62
+ expect(restored.configHash).toBe('def');
63
+ });
64
+ it('handles empty graph', () => {
65
+ const serialized = graph.serialize();
66
+ const restored = CodeDocGraph.deserialize(serialized);
67
+ expect(restored.getAllDocs()).toEqual([]);
68
+ });
69
+ it('handles missing fields in serialized data gracefully', () => {
70
+ const partial = { buildTimestamp: null, gitCommit: null, configHash: null };
71
+ const restored = CodeDocGraph.deserialize(partial);
72
+ expect(restored.getAllDocs()).toEqual([]);
73
+ expect(restored.getAllCodeFiles()).toEqual([]);
74
+ expect(restored.codeSymbols.size).toBe(0);
75
+ });
76
+ });
77
+ });
78
+ //# sourceMappingURL=codeDocGraph.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeDocGraph.test.js","sourceRoot":"","sources":["../../src/graph/codeDocGraph.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { CodeDocGraph } from './codeDocGraph.js';
2
+ import type { DocFreshnessConfig, Document, SymbolLocation } from '../types.js';
3
+ /**
4
+ * Builds the code-to-doc relationship graph
5
+ */
6
+ export declare class GraphBuilder {
7
+ private config;
8
+ constructor(config: DocFreshnessConfig);
9
+ /**
10
+ * Build the complete code-to-doc graph
11
+ */
12
+ buildGraph(documents: Document[], codeIndex: Map<string, SymbolLocation[]> | null): Promise<CodeDocGraph>;
13
+ /**
14
+ * Resolve a reference to actual code files
15
+ */
16
+ private resolveReference;
17
+ }