@theglitchking/hit-em-with-the-docs 2.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 (200) hide show
  1. package/.claude-plugin/marketplace.json +46 -0
  2. package/.claude-plugin/plugin.json +114 -0
  3. package/LICENSE +21 -0
  4. package/MIGRATION.md +255 -0
  5. package/README.backup.md +714 -0
  6. package/README.md +869 -0
  7. package/action.yml +56 -0
  8. package/dist/action/action/index.d.ts +2 -0
  9. package/dist/action/action/index.d.ts.map +1 -0
  10. package/dist/action/cli/index.d.ts +3 -0
  11. package/dist/action/cli/index.d.ts.map +1 -0
  12. package/dist/action/core/audit/auditor.d.ts +43 -0
  13. package/dist/action/core/audit/auditor.d.ts.map +1 -0
  14. package/dist/action/core/audit/rules.d.ts +37 -0
  15. package/dist/action/core/audit/rules.d.ts.map +1 -0
  16. package/dist/action/core/discover/antipatterns.d.ts +24 -0
  17. package/dist/action/core/discover/antipatterns.d.ts.map +1 -0
  18. package/dist/action/core/discover/dependencies.d.ts +57 -0
  19. package/dist/action/core/discover/dependencies.d.ts.map +1 -0
  20. package/dist/action/core/discover/patterns.d.ts +38 -0
  21. package/dist/action/core/discover/patterns.d.ts.map +1 -0
  22. package/dist/action/core/discover/standards.d.ts +58 -0
  23. package/dist/action/core/discover/standards.d.ts.map +1 -0
  24. package/dist/action/core/domains/classifier.d.ts +41 -0
  25. package/dist/action/core/domains/classifier.d.ts.map +1 -0
  26. package/dist/action/core/domains/constants.d.ts +40 -0
  27. package/dist/action/core/domains/constants.d.ts.map +1 -0
  28. package/dist/action/core/domains/detector.d.ts +35 -0
  29. package/dist/action/core/domains/detector.d.ts.map +1 -0
  30. package/dist/action/core/integrate/integrator.d.ts +35 -0
  31. package/dist/action/core/integrate/integrator.d.ts.map +1 -0
  32. package/dist/action/core/links/checker.d.ts +64 -0
  33. package/dist/action/core/links/checker.d.ts.map +1 -0
  34. package/dist/action/core/links/tracker.d.ts +69 -0
  35. package/dist/action/core/links/tracker.d.ts.map +1 -0
  36. package/dist/action/core/maintain/orchestrator.d.ts +39 -0
  37. package/dist/action/core/maintain/orchestrator.d.ts.map +1 -0
  38. package/dist/action/core/metadata/generator.d.ts +26 -0
  39. package/dist/action/core/metadata/generator.d.ts.map +1 -0
  40. package/dist/action/core/metadata/schema.d.ts +201 -0
  41. package/dist/action/core/metadata/schema.d.ts.map +1 -0
  42. package/dist/action/core/metadata/sync.d.ts +36 -0
  43. package/dist/action/core/metadata/sync.d.ts.map +1 -0
  44. package/dist/action/generators/index-generator.d.ts +19 -0
  45. package/dist/action/generators/index-generator.d.ts.map +1 -0
  46. package/dist/action/generators/registry-generator.d.ts +11 -0
  47. package/dist/action/generators/registry-generator.d.ts.map +1 -0
  48. package/dist/action/generators/scaffold.d.ts +30 -0
  49. package/dist/action/generators/scaffold.d.ts.map +1 -0
  50. package/dist/action/generators/templates/document.d.ts +14 -0
  51. package/dist/action/generators/templates/document.d.ts.map +1 -0
  52. package/dist/action/generators/templates/domain-index.d.ts +6 -0
  53. package/dist/action/generators/templates/domain-index.d.ts.map +1 -0
  54. package/dist/action/generators/templates/domain-registry.d.ts +6 -0
  55. package/dist/action/generators/templates/domain-registry.d.ts.map +1 -0
  56. package/dist/action/index.d.ts +31 -0
  57. package/dist/action/index.d.ts.map +1 -0
  58. package/dist/action/index.js +17 -0
  59. package/dist/action/index.js.map +1 -0
  60. package/dist/action/package.json +3 -0
  61. package/dist/action/reports/audit-report.d.ts +15 -0
  62. package/dist/action/reports/audit-report.d.ts.map +1 -0
  63. package/dist/action/reports/health-report.d.ts +15 -0
  64. package/dist/action/reports/health-report.d.ts.map +1 -0
  65. package/dist/action/reports/link-report.d.ts +15 -0
  66. package/dist/action/reports/link-report.d.ts.map +1 -0
  67. package/dist/action/utils/frontmatter.d.ts +50 -0
  68. package/dist/action/utils/frontmatter.d.ts.map +1 -0
  69. package/dist/action/utils/glob.d.ts +63 -0
  70. package/dist/action/utils/glob.d.ts.map +1 -0
  71. package/dist/action/utils/logger.d.ts +42 -0
  72. package/dist/action/utils/logger.d.ts.map +1 -0
  73. package/dist/action/utils/markdown.d.ts +89 -0
  74. package/dist/action/utils/markdown.d.ts.map +1 -0
  75. package/dist/cli/index.d.ts +3 -0
  76. package/dist/cli/index.d.ts.map +1 -0
  77. package/dist/cli/index.js +287 -0
  78. package/dist/cli/index.js.map +1 -0
  79. package/dist/core/audit/auditor.d.ts +43 -0
  80. package/dist/core/audit/auditor.d.ts.map +1 -0
  81. package/dist/core/audit/auditor.js +273 -0
  82. package/dist/core/audit/auditor.js.map +1 -0
  83. package/dist/core/audit/rules.d.ts +37 -0
  84. package/dist/core/audit/rules.d.ts.map +1 -0
  85. package/dist/core/audit/rules.js +223 -0
  86. package/dist/core/audit/rules.js.map +1 -0
  87. package/dist/core/discover/antipatterns.d.ts +24 -0
  88. package/dist/core/discover/antipatterns.d.ts.map +1 -0
  89. package/dist/core/discover/antipatterns.js +354 -0
  90. package/dist/core/discover/antipatterns.js.map +1 -0
  91. package/dist/core/discover/dependencies.d.ts +57 -0
  92. package/dist/core/discover/dependencies.d.ts.map +1 -0
  93. package/dist/core/discover/dependencies.js +311 -0
  94. package/dist/core/discover/dependencies.js.map +1 -0
  95. package/dist/core/discover/patterns.d.ts +38 -0
  96. package/dist/core/discover/patterns.d.ts.map +1 -0
  97. package/dist/core/discover/patterns.js +371 -0
  98. package/dist/core/discover/patterns.js.map +1 -0
  99. package/dist/core/discover/standards.d.ts +58 -0
  100. package/dist/core/discover/standards.d.ts.map +1 -0
  101. package/dist/core/discover/standards.js +359 -0
  102. package/dist/core/discover/standards.js.map +1 -0
  103. package/dist/core/domains/classifier.d.ts +41 -0
  104. package/dist/core/domains/classifier.d.ts.map +1 -0
  105. package/dist/core/domains/classifier.js +208 -0
  106. package/dist/core/domains/classifier.js.map +1 -0
  107. package/dist/core/domains/constants.d.ts +40 -0
  108. package/dist/core/domains/constants.d.ts.map +1 -0
  109. package/dist/core/domains/constants.js +252 -0
  110. package/dist/core/domains/constants.js.map +1 -0
  111. package/dist/core/domains/detector.d.ts +35 -0
  112. package/dist/core/domains/detector.d.ts.map +1 -0
  113. package/dist/core/domains/detector.js +176 -0
  114. package/dist/core/domains/detector.js.map +1 -0
  115. package/dist/core/integrate/integrator.d.ts +35 -0
  116. package/dist/core/integrate/integrator.d.ts.map +1 -0
  117. package/dist/core/integrate/integrator.js +216 -0
  118. package/dist/core/integrate/integrator.js.map +1 -0
  119. package/dist/core/links/checker.d.ts +64 -0
  120. package/dist/core/links/checker.d.ts.map +1 -0
  121. package/dist/core/links/checker.js +190 -0
  122. package/dist/core/links/checker.js.map +1 -0
  123. package/dist/core/links/tracker.d.ts +69 -0
  124. package/dist/core/links/tracker.d.ts.map +1 -0
  125. package/dist/core/links/tracker.js +184 -0
  126. package/dist/core/links/tracker.js.map +1 -0
  127. package/dist/core/maintain/orchestrator.d.ts +39 -0
  128. package/dist/core/maintain/orchestrator.d.ts.map +1 -0
  129. package/dist/core/maintain/orchestrator.js +372 -0
  130. package/dist/core/maintain/orchestrator.js.map +1 -0
  131. package/dist/core/metadata/generator.d.ts +26 -0
  132. package/dist/core/metadata/generator.d.ts.map +1 -0
  133. package/dist/core/metadata/generator.js +221 -0
  134. package/dist/core/metadata/generator.js.map +1 -0
  135. package/dist/core/metadata/schema.d.ts +201 -0
  136. package/dist/core/metadata/schema.d.ts.map +1 -0
  137. package/dist/core/metadata/schema.js +184 -0
  138. package/dist/core/metadata/schema.js.map +1 -0
  139. package/dist/core/metadata/sync.d.ts +36 -0
  140. package/dist/core/metadata/sync.d.ts.map +1 -0
  141. package/dist/core/metadata/sync.js +195 -0
  142. package/dist/core/metadata/sync.js.map +1 -0
  143. package/dist/generators/index-generator.d.ts +19 -0
  144. package/dist/generators/index-generator.d.ts.map +1 -0
  145. package/dist/generators/index-generator.js +191 -0
  146. package/dist/generators/index-generator.js.map +1 -0
  147. package/dist/generators/registry-generator.d.ts +11 -0
  148. package/dist/generators/registry-generator.d.ts.map +1 -0
  149. package/dist/generators/registry-generator.js +156 -0
  150. package/dist/generators/registry-generator.js.map +1 -0
  151. package/dist/generators/scaffold.d.ts +30 -0
  152. package/dist/generators/scaffold.d.ts.map +1 -0
  153. package/dist/generators/scaffold.js +213 -0
  154. package/dist/generators/scaffold.js.map +1 -0
  155. package/dist/generators/templates/document.d.ts +14 -0
  156. package/dist/generators/templates/document.d.ts.map +1 -0
  157. package/dist/generators/templates/document.js +305 -0
  158. package/dist/generators/templates/document.js.map +1 -0
  159. package/dist/generators/templates/domain-index.d.ts +6 -0
  160. package/dist/generators/templates/domain-index.d.ts.map +1 -0
  161. package/dist/generators/templates/domain-index.js +68 -0
  162. package/dist/generators/templates/domain-index.js.map +1 -0
  163. package/dist/generators/templates/domain-registry.d.ts +6 -0
  164. package/dist/generators/templates/domain-registry.d.ts.map +1 -0
  165. package/dist/generators/templates/domain-registry.js +59 -0
  166. package/dist/generators/templates/domain-registry.js.map +1 -0
  167. package/dist/index.d.ts +32 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +39 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/reports/audit-report.d.ts +15 -0
  172. package/dist/reports/audit-report.d.ts.map +1 -0
  173. package/dist/reports/audit-report.js +150 -0
  174. package/dist/reports/audit-report.js.map +1 -0
  175. package/dist/reports/health-report.d.ts +15 -0
  176. package/dist/reports/health-report.d.ts.map +1 -0
  177. package/dist/reports/health-report.js +175 -0
  178. package/dist/reports/health-report.js.map +1 -0
  179. package/dist/reports/link-report.d.ts +15 -0
  180. package/dist/reports/link-report.d.ts.map +1 -0
  181. package/dist/reports/link-report.js +165 -0
  182. package/dist/reports/link-report.js.map +1 -0
  183. package/dist/utils/frontmatter.d.ts +50 -0
  184. package/dist/utils/frontmatter.d.ts.map +1 -0
  185. package/dist/utils/frontmatter.js +93 -0
  186. package/dist/utils/frontmatter.js.map +1 -0
  187. package/dist/utils/glob.d.ts +63 -0
  188. package/dist/utils/glob.d.ts.map +1 -0
  189. package/dist/utils/glob.js +128 -0
  190. package/dist/utils/glob.js.map +1 -0
  191. package/dist/utils/logger.d.ts +42 -0
  192. package/dist/utils/logger.d.ts.map +1 -0
  193. package/dist/utils/logger.js +118 -0
  194. package/dist/utils/logger.js.map +1 -0
  195. package/dist/utils/markdown.d.ts +89 -0
  196. package/dist/utils/markdown.d.ts.map +1 -0
  197. package/dist/utils/markdown.js +192 -0
  198. package/dist/utils/markdown.js.map +1 -0
  199. package/package.json +100 -0
  200. package/templates/claude/CLAUDE.md +204 -0
@@ -0,0 +1,216 @@
1
+ import { readFile, writeFile, mkdir } from 'fs/promises';
2
+ import { join, relative, basename, dirname } from 'path';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { parseFrontmatter, setFrontmatter } from '../../utils/frontmatter.js';
5
+ import { pathExists, findMarkdownFiles } from '../../utils/glob.js';
6
+ import { detectDomain } from '../domains/detector.js';
7
+ import { classifyTier } from '../domains/classifier.js';
8
+ import { generateMetadata, mergeMetadata } from '../metadata/generator.js';
9
+ import levenshtein from 'fast-levenshtein';
10
+ /**
11
+ * Integrate a document into the documentation system
12
+ */
13
+ export async function integrateDocument(options) {
14
+ const { filePath, docsPath, auto = false, dryRun = false, force = false, silent = false, } = options;
15
+ const result = {
16
+ success: false,
17
+ integrated: false,
18
+ originalPath: filePath,
19
+ };
20
+ if (!silent) {
21
+ logger.header('Document Integration');
22
+ logger.info(`File: ${filePath}`);
23
+ if (dryRun)
24
+ logger.info('Running in dry-run mode');
25
+ }
26
+ try {
27
+ // Check if file exists
28
+ if (!(await pathExists(filePath))) {
29
+ result.error = 'File does not exist';
30
+ return result;
31
+ }
32
+ // Read file content
33
+ const content = await readFile(filePath, 'utf-8');
34
+ const { data: existingMetadata } = parseFrontmatter(content);
35
+ // Detect domain
36
+ const domainResult = detectDomain(filePath, content, docsPath);
37
+ if (domainResult.domain) {
38
+ result.domain = domainResult.domain;
39
+ }
40
+ if (!silent) {
41
+ logger.info(`Detected domain: ${result.domain ?? 'unknown'} (${(domainResult.confidence * 100).toFixed(0)}% confidence)`);
42
+ }
43
+ // Classify tier
44
+ const tierResult = classifyTier(content);
45
+ result.tier = tierResult.tier;
46
+ if (!silent) {
47
+ logger.info(`Detected tier: ${result.tier} (${(tierResult.confidence * 100).toFixed(0)}% confidence)`);
48
+ }
49
+ // Check for duplicates
50
+ const duplicates = await findDuplicates(existingMetadata.title ?? basename(filePath, '.md'), content, docsPath);
51
+ if (duplicates.length > 0) {
52
+ result.duplicates = duplicates;
53
+ if (!silent) {
54
+ logger.warn(`Found ${duplicates.length} potential duplicate(s):`);
55
+ for (const dup of duplicates) {
56
+ logger.warn(` - ${dup.path} (${(dup.similarity * 100).toFixed(0)}% similar)`);
57
+ }
58
+ }
59
+ // If high similarity and not force, don't integrate
60
+ const highSimilarity = duplicates.some((d) => d.similarity > 0.7);
61
+ if (highSimilarity && !force && !auto) {
62
+ result.error = 'Potential duplicate detected. Use --force to override.';
63
+ return result;
64
+ }
65
+ }
66
+ // Generate metadata
67
+ const generated = generateMetadata({
68
+ filePath,
69
+ content,
70
+ docsRoot: docsPath,
71
+ existingMetadata,
72
+ });
73
+ const finalMetadata = mergeMetadata(existingMetadata, generated);
74
+ result.metadata = finalMetadata;
75
+ // Determine target path
76
+ const targetDomain = result.domain ?? 'features';
77
+ const fileName = basename(filePath);
78
+ const targetPath = join(docsPath, targetDomain, fileName);
79
+ result.targetPath = targetPath;
80
+ if (!silent) {
81
+ logger.newline();
82
+ logger.info('Generated metadata:');
83
+ logger.info(` Title: ${finalMetadata.title}`);
84
+ logger.info(` Tier: ${finalMetadata.tier}`);
85
+ logger.info(` Domains: ${finalMetadata.domains?.join(', ')}`);
86
+ logger.info(` Status: ${finalMetadata.status}`);
87
+ logger.newline();
88
+ logger.info(`Target path: ${relative(docsPath, targetPath)}`);
89
+ }
90
+ if (dryRun) {
91
+ result.success = true;
92
+ if (!silent) {
93
+ logger.info('Dry-run complete. No changes made.');
94
+ }
95
+ return result;
96
+ }
97
+ // Create target directory if needed
98
+ const targetDir = dirname(targetPath);
99
+ if (!(await pathExists(targetDir))) {
100
+ await mkdir(targetDir, { recursive: true });
101
+ }
102
+ // Write file with updated metadata
103
+ const newContent = setFrontmatter(content, finalMetadata);
104
+ await writeFile(targetPath, newContent, 'utf-8');
105
+ // Update domain INDEX.md
106
+ await updateDomainIndex(docsPath, targetDomain, targetPath, finalMetadata);
107
+ result.success = true;
108
+ result.integrated = true;
109
+ if (!silent) {
110
+ logger.newline();
111
+ logger.success('Document integrated successfully!');
112
+ }
113
+ }
114
+ catch (error) {
115
+ const message = error instanceof Error ? error.message : String(error);
116
+ result.error = message;
117
+ if (!silent) {
118
+ logger.error(`Integration failed: ${message}`);
119
+ }
120
+ }
121
+ return result;
122
+ }
123
+ /**
124
+ * Find potential duplicate documents
125
+ */
126
+ async function findDuplicates(title, content, docsPath) {
127
+ const files = await findMarkdownFiles(docsPath);
128
+ const duplicates = [];
129
+ const normalizedTitle = title.toLowerCase().replace(/[^a-z0-9]/g, '');
130
+ for (const file of files) {
131
+ try {
132
+ const fileContent = await readFile(file, 'utf-8');
133
+ const { data } = parseFrontmatter(fileContent);
134
+ const existingTitle = data.title ?? basename(file, '.md');
135
+ const normalizedExisting = existingTitle.toLowerCase().replace(/[^a-z0-9]/g, '');
136
+ // Calculate title similarity using Levenshtein distance
137
+ const titleDistance = levenshtein.get(normalizedTitle, normalizedExisting);
138
+ const maxLen = Math.max(normalizedTitle.length, normalizedExisting.length);
139
+ const titleSimilarity = maxLen > 0 ? 1 - titleDistance / maxLen : 1;
140
+ // Also check content similarity (simple approach: word overlap)
141
+ const contentSimilarity = calculateContentSimilarity(content, fileContent);
142
+ // Combined similarity
143
+ const similarity = titleSimilarity * 0.6 + contentSimilarity * 0.4;
144
+ if (similarity > 0.5) {
145
+ duplicates.push({
146
+ path: relative(docsPath, file),
147
+ title: existingTitle,
148
+ similarity,
149
+ });
150
+ }
151
+ }
152
+ catch {
153
+ // Skip files that can't be read
154
+ }
155
+ }
156
+ return duplicates.sort((a, b) => b.similarity - a.similarity);
157
+ }
158
+ /**
159
+ * Calculate content similarity using word overlap
160
+ */
161
+ function calculateContentSimilarity(content1, content2) {
162
+ const words1 = new Set(content1.toLowerCase().match(/\b\w+\b/g) ?? []);
163
+ const words2 = new Set(content2.toLowerCase().match(/\b\w+\b/g) ?? []);
164
+ let intersection = 0;
165
+ for (const word of words1) {
166
+ if (words2.has(word)) {
167
+ intersection++;
168
+ }
169
+ }
170
+ const union = words1.size + words2.size - intersection;
171
+ return union > 0 ? intersection / union : 0;
172
+ }
173
+ /**
174
+ * Update domain INDEX.md with new document
175
+ */
176
+ async function updateDomainIndex(docsPath, domain, filePath, metadata) {
177
+ const indexPath = join(docsPath, domain, 'INDEX.md');
178
+ if (!(await pathExists(indexPath))) {
179
+ return;
180
+ }
181
+ try {
182
+ const indexContent = await readFile(indexPath, 'utf-8');
183
+ // Check if document is already listed
184
+ const relPath = relative(join(docsPath, domain), filePath);
185
+ if (indexContent.includes(relPath)) {
186
+ return;
187
+ }
188
+ // Find the documents table and add entry
189
+ const tableRegex = /(\| Document \| Tier \| Status \| Updated \|\n\|[-|\s]+\n)([\s\S]*?)(\n\n|$)/;
190
+ const match = indexContent.match(tableRegex);
191
+ if (match) {
192
+ const [fullMatch, header, existingRows, ending] = match;
193
+ const newRow = `| [${metadata.title}](${relPath}) | ${metadata.tier} | ${metadata.status} | ${metadata.last_updated} |\n`;
194
+ const newContent = indexContent.replace(fullMatch, `${header}${existingRows}${newRow}${ending}`);
195
+ await writeFile(indexPath, newContent, 'utf-8');
196
+ }
197
+ }
198
+ catch {
199
+ // Silently fail if we can't update the index
200
+ }
201
+ }
202
+ /**
203
+ * Batch integrate multiple documents
204
+ */
205
+ export async function batchIntegrate(files, options) {
206
+ const results = [];
207
+ for (const file of files) {
208
+ const result = await integrateDocument({
209
+ ...options,
210
+ filePath: file,
211
+ });
212
+ results.push(result);
213
+ }
214
+ return results;
215
+ }
216
+ //# sourceMappingURL=integrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrator.js","sourceRoot":"","sources":["../../../src/core/integrate/integrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { Domain } from '../domains/constants.js';
2
+ export { type MarkdownLink } from '../../utils/markdown.js';
3
+ export interface LinkCheckOptions {
4
+ docsPath: string;
5
+ domain?: string;
6
+ checkExternal?: boolean;
7
+ silent?: boolean;
8
+ }
9
+ export interface LinkCheckResult {
10
+ totalFiles: number;
11
+ totalLinks: number;
12
+ validLinks: number;
13
+ brokenLinks: BrokenLink[];
14
+ crossDomainLinks: CrossDomainLink[];
15
+ externalLinks: ExternalLink[];
16
+ stats: LinkStats;
17
+ }
18
+ export interface BrokenLink {
19
+ sourceFile: string;
20
+ targetPath: string;
21
+ lineNumber: number;
22
+ linkText: string;
23
+ reason: string;
24
+ }
25
+ export interface CrossDomainLink {
26
+ sourceFile: string;
27
+ sourceDomain: Domain | null;
28
+ targetPath: string;
29
+ targetDomain: Domain | null;
30
+ linkText: string;
31
+ }
32
+ export interface ExternalLink {
33
+ sourceFile: string;
34
+ url: string;
35
+ linkText: string;
36
+ status?: number;
37
+ }
38
+ export interface LinkStats {
39
+ internalLinks: number;
40
+ externalLinks: number;
41
+ crossDomainLinks: number;
42
+ brokenPercentage: number;
43
+ topConnectedDomains: {
44
+ from: string;
45
+ to: string;
46
+ count: number;
47
+ }[];
48
+ }
49
+ /**
50
+ * Check all links in documentation
51
+ */
52
+ export declare function checkLinks(options: LinkCheckOptions): Promise<LinkCheckResult>;
53
+ /**
54
+ * Check a single link and return its status
55
+ */
56
+ export declare function checkSingleLink(linkUrl: string, sourceFile: string, docsPath: string): Promise<{
57
+ valid: boolean;
58
+ reason?: string;
59
+ }>;
60
+ /**
61
+ * Get broken links for a specific file
62
+ */
63
+ export declare function getFileBrokenLinks(filePath: string, docsPath: string): Promise<BrokenLink[]>;
64
+ //# sourceMappingURL=checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../../../src/core/links/checker.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmJpF;AAuBD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAW9C;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBvB"}
@@ -0,0 +1,190 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { join, relative, dirname, resolve } from 'path';
3
+ import { findMarkdownFiles, pathExists } from '../../utils/glob.js';
4
+ import { extractLinks } from '../../utils/markdown.js';
5
+ import { logger } from '../../utils/logger.js';
6
+ import { detectDomainFromPath } from '../domains/detector.js';
7
+ /**
8
+ * Check all links in documentation
9
+ */
10
+ export async function checkLinks(options) {
11
+ const { docsPath, domain, checkExternal = false, silent = false, } = options;
12
+ const result = {
13
+ totalFiles: 0,
14
+ totalLinks: 0,
15
+ validLinks: 0,
16
+ brokenLinks: [],
17
+ crossDomainLinks: [],
18
+ externalLinks: [],
19
+ stats: {
20
+ internalLinks: 0,
21
+ externalLinks: 0,
22
+ crossDomainLinks: 0,
23
+ brokenPercentage: 0,
24
+ topConnectedDomains: [],
25
+ },
26
+ };
27
+ if (!silent) {
28
+ logger.header('Link Checker');
29
+ }
30
+ // Find all markdown files
31
+ let files = await findMarkdownFiles(docsPath);
32
+ // Filter by domain if specified
33
+ if (domain) {
34
+ files = files.filter((f) => {
35
+ const rel = relative(docsPath, f);
36
+ return rel.startsWith(domain + '/') || rel.startsWith(domain + '\\');
37
+ });
38
+ }
39
+ result.totalFiles = files.length;
40
+ if (!silent) {
41
+ logger.info(`Checking ${files.length} files...`);
42
+ }
43
+ const domainConnections = new Map();
44
+ for (const file of files) {
45
+ try {
46
+ const content = await readFile(file, 'utf-8');
47
+ const links = extractLinks(content);
48
+ const relFile = relative(docsPath, file);
49
+ const fileDir = dirname(file);
50
+ for (const link of links) {
51
+ result.totalLinks++;
52
+ if (link.isInternal) {
53
+ result.stats.internalLinks++;
54
+ // Resolve the link path
55
+ const targetPath = resolveLink(link.url, fileDir, docsPath);
56
+ // Check if target exists
57
+ const exists = await pathExists(targetPath);
58
+ if (!exists) {
59
+ result.brokenLinks.push({
60
+ sourceFile: relFile,
61
+ targetPath: link.url,
62
+ lineNumber: link.lineNumber,
63
+ linkText: link.text,
64
+ reason: 'Target file does not exist',
65
+ });
66
+ }
67
+ else {
68
+ result.validLinks++;
69
+ // Track cross-domain links
70
+ const sourceDomain = detectDomainFromPath(file, docsPath).domain;
71
+ const targetDomain = detectDomainFromPath(targetPath, docsPath).domain;
72
+ if (sourceDomain && targetDomain && sourceDomain !== targetDomain) {
73
+ result.stats.crossDomainLinks++;
74
+ result.crossDomainLinks.push({
75
+ sourceFile: relFile,
76
+ sourceDomain,
77
+ targetPath: link.url,
78
+ targetDomain,
79
+ linkText: link.text,
80
+ });
81
+ // Track domain connections
82
+ const connKey = `${sourceDomain} -> ${targetDomain}`;
83
+ domainConnections.set(connKey, (domainConnections.get(connKey) ?? 0) + 1);
84
+ }
85
+ }
86
+ }
87
+ else {
88
+ // External link
89
+ result.stats.externalLinks++;
90
+ result.externalLinks.push({
91
+ sourceFile: relFile,
92
+ url: link.url,
93
+ linkText: link.text,
94
+ });
95
+ // Optionally check external links
96
+ if (checkExternal) {
97
+ // Note: External link checking would go here
98
+ // For now, we just track them
99
+ }
100
+ }
101
+ }
102
+ }
103
+ catch (error) {
104
+ const message = error instanceof Error ? error.message : String(error);
105
+ if (!silent) {
106
+ logger.warn(`Error processing ${relative(docsPath, file)}: ${message}`);
107
+ }
108
+ }
109
+ }
110
+ // Calculate stats
111
+ result.stats.brokenPercentage =
112
+ result.stats.internalLinks > 0
113
+ ? (result.brokenLinks.length / result.stats.internalLinks) * 100
114
+ : 0;
115
+ // Get top connected domains
116
+ result.stats.topConnectedDomains = [...domainConnections.entries()]
117
+ .map(([key, count]) => {
118
+ const [from, to] = key.split(' -> ');
119
+ return { from: from ?? '', to: to ?? '', count };
120
+ })
121
+ .sort((a, b) => b.count - a.count)
122
+ .slice(0, 10);
123
+ if (!silent) {
124
+ logger.newline();
125
+ logger.success(`Link check complete!`);
126
+ logger.info(`Total links: ${result.totalLinks}`);
127
+ logger.info(`Valid: ${result.validLinks}`);
128
+ if (result.brokenLinks.length > 0) {
129
+ logger.warn(`Broken: ${result.brokenLinks.length}`);
130
+ }
131
+ logger.info(`Cross-domain: ${result.stats.crossDomainLinks}`);
132
+ }
133
+ return result;
134
+ }
135
+ /**
136
+ * Resolve a relative link to an absolute path
137
+ */
138
+ function resolveLink(linkUrl, fileDir, docsPath) {
139
+ // Remove anchor
140
+ const pathPart = linkUrl.split('#')[0] ?? '';
141
+ if (!pathPart) {
142
+ // Link is just an anchor, it's valid
143
+ return fileDir;
144
+ }
145
+ // Handle absolute links (from docs root)
146
+ if (pathPart.startsWith('/')) {
147
+ return join(docsPath, pathPart);
148
+ }
149
+ // Handle relative links
150
+ return resolve(fileDir, pathPart);
151
+ }
152
+ /**
153
+ * Check a single link and return its status
154
+ */
155
+ export async function checkSingleLink(linkUrl, sourceFile, docsPath) {
156
+ const fileDir = dirname(sourceFile);
157
+ const targetPath = resolveLink(linkUrl, fileDir, docsPath);
158
+ const exists = await pathExists(targetPath);
159
+ if (!exists) {
160
+ return { valid: false, reason: 'Target file does not exist' };
161
+ }
162
+ return { valid: true };
163
+ }
164
+ /**
165
+ * Get broken links for a specific file
166
+ */
167
+ export async function getFileBrokenLinks(filePath, docsPath) {
168
+ const content = await readFile(filePath, 'utf-8');
169
+ const links = extractLinks(content);
170
+ const brokenLinks = [];
171
+ const fileDir = dirname(filePath);
172
+ const relFile = relative(docsPath, filePath);
173
+ for (const link of links) {
174
+ if (link.isInternal) {
175
+ const targetPath = resolveLink(link.url, fileDir, docsPath);
176
+ const exists = await pathExists(targetPath);
177
+ if (!exists) {
178
+ brokenLinks.push({
179
+ sourceFile: relFile,
180
+ targetPath: link.url,
181
+ lineNumber: link.lineNumber,
182
+ linkText: link.text,
183
+ reason: 'Target file does not exist',
184
+ });
185
+ }
186
+ }
187
+ }
188
+ return brokenLinks;
189
+ }
190
+ //# sourceMappingURL=checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.js","sourceRoot":"","sources":["../../../src/core/links/checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Domain } from '../domains/constants.js';
2
+ export interface LinkGraph {
3
+ nodes: LinkNode[];
4
+ edges: LinkEdge[];
5
+ }
6
+ export interface LinkNode {
7
+ id: string;
8
+ path: string;
9
+ domain: Domain | null;
10
+ title?: string;
11
+ inDegree: number;
12
+ outDegree: number;
13
+ }
14
+ export interface LinkEdge {
15
+ source: string;
16
+ target: string;
17
+ linkText: string;
18
+ lineNumber: number;
19
+ }
20
+ export interface DomainConnectionMatrix {
21
+ domains: Domain[];
22
+ matrix: number[][];
23
+ totalConnections: number;
24
+ }
25
+ /**
26
+ * Build a complete link graph for the documentation
27
+ */
28
+ export declare function buildLinkGraph(docsPath: string): Promise<LinkGraph>;
29
+ /**
30
+ * Build a domain connection matrix showing how domains link to each other
31
+ */
32
+ export declare function buildDomainConnectionMatrix(docsPath: string): Promise<DomainConnectionMatrix>;
33
+ /**
34
+ * Get top connected domain pairs
35
+ */
36
+ export declare function getTopConnectedDomains(docsPath: string, limit?: number): Promise<{
37
+ from: Domain;
38
+ to: Domain;
39
+ count: number;
40
+ }[]>;
41
+ /**
42
+ * Get backlinks for a specific file
43
+ */
44
+ export declare function getBacklinks(targetFile: string, docsPath: string): Promise<{
45
+ source: string;
46
+ linkText: string;
47
+ lineNumber: number;
48
+ }[]>;
49
+ /**
50
+ * Find orphan files (files with no incoming links)
51
+ */
52
+ export declare function findOrphanFiles(docsPath: string): Promise<string[]>;
53
+ /**
54
+ * Find highly connected files (hubs)
55
+ */
56
+ export declare function findHubFiles(docsPath: string, minDegree?: number): Promise<LinkNode[]>;
57
+ /**
58
+ * Get link statistics summary
59
+ */
60
+ export declare function getLinkStatistics(docsPath: string): Promise<{
61
+ totalNodes: number;
62
+ totalEdges: number;
63
+ avgInDegree: number;
64
+ avgOutDegree: number;
65
+ orphanCount: number;
66
+ hubCount: number;
67
+ crossDomainPercentage: number;
68
+ }>;
69
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../src/core/links/tracker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAiEzE;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,CAAC,CA+BjC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAoBxD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWzE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAU,GACpB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAMrB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CA8BD"}