@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.
- package/.claude-plugin/marketplace.json +46 -0
- package/.claude-plugin/plugin.json +114 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +255 -0
- package/README.backup.md +714 -0
- package/README.md +869 -0
- package/action.yml +56 -0
- package/dist/action/action/index.d.ts +2 -0
- package/dist/action/action/index.d.ts.map +1 -0
- package/dist/action/cli/index.d.ts +3 -0
- package/dist/action/cli/index.d.ts.map +1 -0
- package/dist/action/core/audit/auditor.d.ts +43 -0
- package/dist/action/core/audit/auditor.d.ts.map +1 -0
- package/dist/action/core/audit/rules.d.ts +37 -0
- package/dist/action/core/audit/rules.d.ts.map +1 -0
- package/dist/action/core/discover/antipatterns.d.ts +24 -0
- package/dist/action/core/discover/antipatterns.d.ts.map +1 -0
- package/dist/action/core/discover/dependencies.d.ts +57 -0
- package/dist/action/core/discover/dependencies.d.ts.map +1 -0
- package/dist/action/core/discover/patterns.d.ts +38 -0
- package/dist/action/core/discover/patterns.d.ts.map +1 -0
- package/dist/action/core/discover/standards.d.ts +58 -0
- package/dist/action/core/discover/standards.d.ts.map +1 -0
- package/dist/action/core/domains/classifier.d.ts +41 -0
- package/dist/action/core/domains/classifier.d.ts.map +1 -0
- package/dist/action/core/domains/constants.d.ts +40 -0
- package/dist/action/core/domains/constants.d.ts.map +1 -0
- package/dist/action/core/domains/detector.d.ts +35 -0
- package/dist/action/core/domains/detector.d.ts.map +1 -0
- package/dist/action/core/integrate/integrator.d.ts +35 -0
- package/dist/action/core/integrate/integrator.d.ts.map +1 -0
- package/dist/action/core/links/checker.d.ts +64 -0
- package/dist/action/core/links/checker.d.ts.map +1 -0
- package/dist/action/core/links/tracker.d.ts +69 -0
- package/dist/action/core/links/tracker.d.ts.map +1 -0
- package/dist/action/core/maintain/orchestrator.d.ts +39 -0
- package/dist/action/core/maintain/orchestrator.d.ts.map +1 -0
- package/dist/action/core/metadata/generator.d.ts +26 -0
- package/dist/action/core/metadata/generator.d.ts.map +1 -0
- package/dist/action/core/metadata/schema.d.ts +201 -0
- package/dist/action/core/metadata/schema.d.ts.map +1 -0
- package/dist/action/core/metadata/sync.d.ts +36 -0
- package/dist/action/core/metadata/sync.d.ts.map +1 -0
- package/dist/action/generators/index-generator.d.ts +19 -0
- package/dist/action/generators/index-generator.d.ts.map +1 -0
- package/dist/action/generators/registry-generator.d.ts +11 -0
- package/dist/action/generators/registry-generator.d.ts.map +1 -0
- package/dist/action/generators/scaffold.d.ts +30 -0
- package/dist/action/generators/scaffold.d.ts.map +1 -0
- package/dist/action/generators/templates/document.d.ts +14 -0
- package/dist/action/generators/templates/document.d.ts.map +1 -0
- package/dist/action/generators/templates/domain-index.d.ts +6 -0
- package/dist/action/generators/templates/domain-index.d.ts.map +1 -0
- package/dist/action/generators/templates/domain-registry.d.ts +6 -0
- package/dist/action/generators/templates/domain-registry.d.ts.map +1 -0
- package/dist/action/index.d.ts +31 -0
- package/dist/action/index.d.ts.map +1 -0
- package/dist/action/index.js +17 -0
- package/dist/action/index.js.map +1 -0
- package/dist/action/package.json +3 -0
- package/dist/action/reports/audit-report.d.ts +15 -0
- package/dist/action/reports/audit-report.d.ts.map +1 -0
- package/dist/action/reports/health-report.d.ts +15 -0
- package/dist/action/reports/health-report.d.ts.map +1 -0
- package/dist/action/reports/link-report.d.ts +15 -0
- package/dist/action/reports/link-report.d.ts.map +1 -0
- package/dist/action/utils/frontmatter.d.ts +50 -0
- package/dist/action/utils/frontmatter.d.ts.map +1 -0
- package/dist/action/utils/glob.d.ts +63 -0
- package/dist/action/utils/glob.d.ts.map +1 -0
- package/dist/action/utils/logger.d.ts +42 -0
- package/dist/action/utils/logger.d.ts.map +1 -0
- package/dist/action/utils/markdown.d.ts +89 -0
- package/dist/action/utils/markdown.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +287 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/audit/auditor.d.ts +43 -0
- package/dist/core/audit/auditor.d.ts.map +1 -0
- package/dist/core/audit/auditor.js +273 -0
- package/dist/core/audit/auditor.js.map +1 -0
- package/dist/core/audit/rules.d.ts +37 -0
- package/dist/core/audit/rules.d.ts.map +1 -0
- package/dist/core/audit/rules.js +223 -0
- package/dist/core/audit/rules.js.map +1 -0
- package/dist/core/discover/antipatterns.d.ts +24 -0
- package/dist/core/discover/antipatterns.d.ts.map +1 -0
- package/dist/core/discover/antipatterns.js +354 -0
- package/dist/core/discover/antipatterns.js.map +1 -0
- package/dist/core/discover/dependencies.d.ts +57 -0
- package/dist/core/discover/dependencies.d.ts.map +1 -0
- package/dist/core/discover/dependencies.js +311 -0
- package/dist/core/discover/dependencies.js.map +1 -0
- package/dist/core/discover/patterns.d.ts +38 -0
- package/dist/core/discover/patterns.d.ts.map +1 -0
- package/dist/core/discover/patterns.js +371 -0
- package/dist/core/discover/patterns.js.map +1 -0
- package/dist/core/discover/standards.d.ts +58 -0
- package/dist/core/discover/standards.d.ts.map +1 -0
- package/dist/core/discover/standards.js +359 -0
- package/dist/core/discover/standards.js.map +1 -0
- package/dist/core/domains/classifier.d.ts +41 -0
- package/dist/core/domains/classifier.d.ts.map +1 -0
- package/dist/core/domains/classifier.js +208 -0
- package/dist/core/domains/classifier.js.map +1 -0
- package/dist/core/domains/constants.d.ts +40 -0
- package/dist/core/domains/constants.d.ts.map +1 -0
- package/dist/core/domains/constants.js +252 -0
- package/dist/core/domains/constants.js.map +1 -0
- package/dist/core/domains/detector.d.ts +35 -0
- package/dist/core/domains/detector.d.ts.map +1 -0
- package/dist/core/domains/detector.js +176 -0
- package/dist/core/domains/detector.js.map +1 -0
- package/dist/core/integrate/integrator.d.ts +35 -0
- package/dist/core/integrate/integrator.d.ts.map +1 -0
- package/dist/core/integrate/integrator.js +216 -0
- package/dist/core/integrate/integrator.js.map +1 -0
- package/dist/core/links/checker.d.ts +64 -0
- package/dist/core/links/checker.d.ts.map +1 -0
- package/dist/core/links/checker.js +190 -0
- package/dist/core/links/checker.js.map +1 -0
- package/dist/core/links/tracker.d.ts +69 -0
- package/dist/core/links/tracker.d.ts.map +1 -0
- package/dist/core/links/tracker.js +184 -0
- package/dist/core/links/tracker.js.map +1 -0
- package/dist/core/maintain/orchestrator.d.ts +39 -0
- package/dist/core/maintain/orchestrator.d.ts.map +1 -0
- package/dist/core/maintain/orchestrator.js +372 -0
- package/dist/core/maintain/orchestrator.js.map +1 -0
- package/dist/core/metadata/generator.d.ts +26 -0
- package/dist/core/metadata/generator.d.ts.map +1 -0
- package/dist/core/metadata/generator.js +221 -0
- package/dist/core/metadata/generator.js.map +1 -0
- package/dist/core/metadata/schema.d.ts +201 -0
- package/dist/core/metadata/schema.d.ts.map +1 -0
- package/dist/core/metadata/schema.js +184 -0
- package/dist/core/metadata/schema.js.map +1 -0
- package/dist/core/metadata/sync.d.ts +36 -0
- package/dist/core/metadata/sync.d.ts.map +1 -0
- package/dist/core/metadata/sync.js +195 -0
- package/dist/core/metadata/sync.js.map +1 -0
- package/dist/generators/index-generator.d.ts +19 -0
- package/dist/generators/index-generator.d.ts.map +1 -0
- package/dist/generators/index-generator.js +191 -0
- package/dist/generators/index-generator.js.map +1 -0
- package/dist/generators/registry-generator.d.ts +11 -0
- package/dist/generators/registry-generator.d.ts.map +1 -0
- package/dist/generators/registry-generator.js +156 -0
- package/dist/generators/registry-generator.js.map +1 -0
- package/dist/generators/scaffold.d.ts +30 -0
- package/dist/generators/scaffold.d.ts.map +1 -0
- package/dist/generators/scaffold.js +213 -0
- package/dist/generators/scaffold.js.map +1 -0
- package/dist/generators/templates/document.d.ts +14 -0
- package/dist/generators/templates/document.d.ts.map +1 -0
- package/dist/generators/templates/document.js +305 -0
- package/dist/generators/templates/document.js.map +1 -0
- package/dist/generators/templates/domain-index.d.ts +6 -0
- package/dist/generators/templates/domain-index.d.ts.map +1 -0
- package/dist/generators/templates/domain-index.js +68 -0
- package/dist/generators/templates/domain-index.js.map +1 -0
- package/dist/generators/templates/domain-registry.d.ts +6 -0
- package/dist/generators/templates/domain-registry.d.ts.map +1 -0
- package/dist/generators/templates/domain-registry.js +59 -0
- package/dist/generators/templates/domain-registry.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/reports/audit-report.d.ts +15 -0
- package/dist/reports/audit-report.d.ts.map +1 -0
- package/dist/reports/audit-report.js +150 -0
- package/dist/reports/audit-report.js.map +1 -0
- package/dist/reports/health-report.d.ts +15 -0
- package/dist/reports/health-report.d.ts.map +1 -0
- package/dist/reports/health-report.js +175 -0
- package/dist/reports/health-report.js.map +1 -0
- package/dist/reports/link-report.d.ts +15 -0
- package/dist/reports/link-report.d.ts.map +1 -0
- package/dist/reports/link-report.js +165 -0
- package/dist/reports/link-report.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +50 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +93 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/glob.d.ts +63 -0
- package/dist/utils/glob.d.ts.map +1 -0
- package/dist/utils/glob.js +128 -0
- package/dist/utils/glob.js.map +1 -0
- package/dist/utils/logger.d.ts +42 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +118 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +89 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +192 -0
- package/dist/utils/markdown.js.map +1 -0
- package/package.json +100 -0
- 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"}
|