mcp-docs-scraper 0.1.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/LICENSE +21 -0
- package/README.md +357 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +231 -0
- package/dist/server.js.map +1 -0
- package/dist/services/cache-manager.d.ts +100 -0
- package/dist/services/cache-manager.d.ts.map +1 -0
- package/dist/services/cache-manager.js +212 -0
- package/dist/services/cache-manager.js.map +1 -0
- package/dist/services/content-cleaner.d.ts +48 -0
- package/dist/services/content-cleaner.d.ts.map +1 -0
- package/dist/services/content-cleaner.js +295 -0
- package/dist/services/content-cleaner.js.map +1 -0
- package/dist/services/github-detector.d.ts +49 -0
- package/dist/services/github-detector.d.ts.map +1 -0
- package/dist/services/github-detector.js +276 -0
- package/dist/services/github-detector.js.map +1 -0
- package/dist/services/github-fetcher.d.ts +94 -0
- package/dist/services/github-fetcher.d.ts.map +1 -0
- package/dist/services/github-fetcher.js +393 -0
- package/dist/services/github-fetcher.js.map +1 -0
- package/dist/services/search-index.d.ts +106 -0
- package/dist/services/search-index.d.ts.map +1 -0
- package/dist/services/search-index.js +210 -0
- package/dist/services/search-index.js.map +1 -0
- package/dist/services/web-scraper.d.ts +88 -0
- package/dist/services/web-scraper.d.ts.map +1 -0
- package/dist/services/web-scraper.js +244 -0
- package/dist/services/web-scraper.js.map +1 -0
- package/dist/tools/clear-cache.d.ts +24 -0
- package/dist/tools/clear-cache.d.ts.map +1 -0
- package/dist/tools/clear-cache.js +29 -0
- package/dist/tools/clear-cache.js.map +1 -0
- package/dist/tools/detect-github.d.ts +21 -0
- package/dist/tools/detect-github.d.ts.map +1 -0
- package/dist/tools/detect-github.js +18 -0
- package/dist/tools/detect-github.js.map +1 -0
- package/dist/tools/get-content.d.ts +43 -0
- package/dist/tools/get-content.d.ts.map +1 -0
- package/dist/tools/get-content.js +84 -0
- package/dist/tools/get-content.js.map +1 -0
- package/dist/tools/get-tree.d.ts +31 -0
- package/dist/tools/get-tree.d.ts.map +1 -0
- package/dist/tools/get-tree.js +102 -0
- package/dist/tools/get-tree.js.map +1 -0
- package/dist/tools/index-docs.d.ts +63 -0
- package/dist/tools/index-docs.d.ts.map +1 -0
- package/dist/tools/index-docs.js +371 -0
- package/dist/tools/index-docs.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-cached.d.ts +19 -0
- package/dist/tools/list-cached.d.ts.map +1 -0
- package/dist/tools/list-cached.js +20 -0
- package/dist/tools/list-cached.js.map +1 -0
- package/dist/tools/search-docs.d.ts +31 -0
- package/dist/tools/search-docs.d.ts.map +1 -0
- package/dist/tools/search-docs.js +64 -0
- package/dist/tools/search-docs.js.map +1 -0
- package/dist/types/cache.d.ts +53 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +2 -0
- package/dist/types/cache.js.map +1 -0
- package/dist/types/errors.d.ts +102 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +216 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/fs.d.ts +45 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +113 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/rate-limit.d.ts +55 -0
- package/dist/utils/rate-limit.d.ts.map +1 -0
- package/dist/utils/rate-limit.js +89 -0
- package/dist/utils/rate-limit.js.map +1 -0
- package/dist/utils/url.d.ts +69 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +251 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { githubRateLimit } from "../utils/rate-limit.js";
|
|
2
|
+
import { GitHubRateLimitError, GitHubNotFoundError, GitHubAccessDeniedError, NetworkError, } from "../types/errors.js";
|
|
3
|
+
const GITHUB_API_BASE = "https://api.github.com";
|
|
4
|
+
const DEFAULT_EXTENSIONS = [".md", ".mdx", ".markdown"];
|
|
5
|
+
/**
|
|
6
|
+
* Parses "owner/repo" format into separate parts.
|
|
7
|
+
*/
|
|
8
|
+
export function parseRepoString(repoString) {
|
|
9
|
+
const parts = repoString.split("/");
|
|
10
|
+
if (parts.length !== 2) {
|
|
11
|
+
throw new Error(`Invalid repo format: "${repoString}". Expected "owner/repo".`);
|
|
12
|
+
}
|
|
13
|
+
return { owner: parts[0], repo: parts[1] };
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Gets GitHub API headers, including auth token if available.
|
|
17
|
+
*/
|
|
18
|
+
function getGitHubHeaders() {
|
|
19
|
+
const headers = {
|
|
20
|
+
Accept: "application/vnd.github.v3+json",
|
|
21
|
+
"User-Agent": "mcp-docs-scraper",
|
|
22
|
+
};
|
|
23
|
+
// Use GITHUB_TOKEN if available (increases rate limit from 60 to 5000/hour)
|
|
24
|
+
const token = process.env.GITHUB_TOKEN;
|
|
25
|
+
if (token) {
|
|
26
|
+
headers.Authorization = `Bearer ${token}`;
|
|
27
|
+
}
|
|
28
|
+
return headers;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Checks if GitHub authentication is configured.
|
|
32
|
+
*/
|
|
33
|
+
export function isAuthenticated() {
|
|
34
|
+
return !!process.env.GITHUB_TOKEN;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Makes a GitHub API request with proper headers and rate limit tracking.
|
|
38
|
+
*/
|
|
39
|
+
async function githubFetch(url) {
|
|
40
|
+
const response = await fetch(url, {
|
|
41
|
+
headers: getGitHubHeaders(),
|
|
42
|
+
});
|
|
43
|
+
githubRateLimit.updateFromHeaders(response.headers);
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Detects the default branch for a repository using the Git Trees API.
|
|
48
|
+
* Tries "main" first, then "master".
|
|
49
|
+
*/
|
|
50
|
+
async function detectDefaultBranch(owner, repo) {
|
|
51
|
+
const repoString = `${owner}/${repo}`;
|
|
52
|
+
// Check rate limit before making requests
|
|
53
|
+
if (githubRateLimit.isExhausted()) {
|
|
54
|
+
throw new GitHubRateLimitError(githubRateLimit.getResetTime());
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
// Try main first using Git Trees API
|
|
58
|
+
const mainUrl = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/main`;
|
|
59
|
+
const mainResponse = await githubFetch(mainUrl);
|
|
60
|
+
if (mainResponse.ok) {
|
|
61
|
+
return "main";
|
|
62
|
+
}
|
|
63
|
+
// Check for specific error types
|
|
64
|
+
if (mainResponse.status === 403) {
|
|
65
|
+
throw new GitHubAccessDeniedError(repoString);
|
|
66
|
+
}
|
|
67
|
+
// Try master
|
|
68
|
+
const masterUrl = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/master`;
|
|
69
|
+
const masterResponse = await githubFetch(masterUrl);
|
|
70
|
+
if (masterResponse.ok) {
|
|
71
|
+
return "master";
|
|
72
|
+
}
|
|
73
|
+
if (masterResponse.status === 403) {
|
|
74
|
+
throw new GitHubAccessDeniedError(repoString);
|
|
75
|
+
}
|
|
76
|
+
// Neither branch found - repo might not exist
|
|
77
|
+
throw new GitHubNotFoundError(repoString);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (error instanceof GitHubRateLimitError ||
|
|
81
|
+
error instanceof GitHubAccessDeniedError ||
|
|
82
|
+
error instanceof GitHubNotFoundError) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
throw new NetworkError(`https://github.com/${repoString}`, error instanceof Error ? error : undefined);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Fetches the entire tree from GitHub using the Git Trees API.
|
|
90
|
+
* This uses only 1 API request instead of 1 per directory.
|
|
91
|
+
*/
|
|
92
|
+
async function fetchGitTree(owner, repo, branch) {
|
|
93
|
+
const repoString = `${owner}/${repo}`;
|
|
94
|
+
// Check rate limit before making request
|
|
95
|
+
if (githubRateLimit.isExhausted()) {
|
|
96
|
+
throw new GitHubRateLimitError(githubRateLimit.getResetTime());
|
|
97
|
+
}
|
|
98
|
+
if (githubRateLimit.isLow()) {
|
|
99
|
+
console.error(`Warning: ${githubRateLimit.getStatusMessage()}`);
|
|
100
|
+
}
|
|
101
|
+
const url = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`;
|
|
102
|
+
try {
|
|
103
|
+
const response = await githubFetch(url);
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
if (response.status === 404) {
|
|
106
|
+
throw new GitHubNotFoundError(repoString);
|
|
107
|
+
}
|
|
108
|
+
if (response.status === 403) {
|
|
109
|
+
// Could be rate limit or access denied
|
|
110
|
+
if (githubRateLimit.isExhausted()) {
|
|
111
|
+
throw new GitHubRateLimitError(githubRateLimit.getResetTime());
|
|
112
|
+
}
|
|
113
|
+
throw new GitHubAccessDeniedError(repoString);
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
|
|
116
|
+
}
|
|
117
|
+
return response.json();
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (error instanceof GitHubRateLimitError ||
|
|
121
|
+
error instanceof GitHubNotFoundError ||
|
|
122
|
+
error instanceof GitHubAccessDeniedError) {
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
if (error instanceof Error && error.message.includes("GitHub API error")) {
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
throw new NetworkError(url, error instanceof Error ? error : undefined);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Checks if a file should be included based on extension filter.
|
|
133
|
+
*/
|
|
134
|
+
function shouldIncludeFile(filename, extensions) {
|
|
135
|
+
if (extensions.length === 0)
|
|
136
|
+
return true;
|
|
137
|
+
const lowerName = filename.toLowerCase();
|
|
138
|
+
return extensions.some((ext) => lowerName.endsWith(ext.toLowerCase()));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Gets the depth of a path (number of directory levels).
|
|
142
|
+
*/
|
|
143
|
+
function getPathDepth(path) {
|
|
144
|
+
if (!path)
|
|
145
|
+
return 0;
|
|
146
|
+
return path.split("/").length;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the file/folder name from a path.
|
|
150
|
+
*/
|
|
151
|
+
function getNameFromPath(path) {
|
|
152
|
+
const parts = path.split("/");
|
|
153
|
+
return parts[parts.length - 1];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Gets the parent path from a path.
|
|
157
|
+
*/
|
|
158
|
+
function getParentPath(path) {
|
|
159
|
+
const parts = path.split("/");
|
|
160
|
+
parts.pop();
|
|
161
|
+
return parts.join("/");
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Converts a flat list of tree items into a hierarchical DocsTreeNode structure.
|
|
165
|
+
*/
|
|
166
|
+
function buildHierarchicalTree(items, basePath, extensions, maxDepth) {
|
|
167
|
+
// Filter items by base path and extensions
|
|
168
|
+
const filteredItems = items.filter((item) => {
|
|
169
|
+
// Must be under base path
|
|
170
|
+
if (basePath &&
|
|
171
|
+
!item.path.startsWith(basePath + "/") &&
|
|
172
|
+
item.path !== basePath) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
// Calculate relative depth
|
|
176
|
+
const relativePath = basePath
|
|
177
|
+
? item.path.slice(basePath.length + 1)
|
|
178
|
+
: item.path;
|
|
179
|
+
const depth = getPathDepth(relativePath);
|
|
180
|
+
if (depth > maxDepth) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
// For files, check extension filter
|
|
184
|
+
if (item.type === "blob") {
|
|
185
|
+
return shouldIncludeFile(item.path, extensions);
|
|
186
|
+
}
|
|
187
|
+
return true; // Include directories for now, we'll filter empty ones later
|
|
188
|
+
});
|
|
189
|
+
// Build a map of path -> node for quick lookups
|
|
190
|
+
const nodeMap = new Map();
|
|
191
|
+
let fileCount = 0;
|
|
192
|
+
let totalSize = 0;
|
|
193
|
+
// First pass: create nodes for all matching files
|
|
194
|
+
for (const item of filteredItems) {
|
|
195
|
+
if (item.type === "blob") {
|
|
196
|
+
const node = {
|
|
197
|
+
name: getNameFromPath(item.path),
|
|
198
|
+
path: item.path,
|
|
199
|
+
type: "file",
|
|
200
|
+
size_bytes: item.size,
|
|
201
|
+
};
|
|
202
|
+
nodeMap.set(item.path, node);
|
|
203
|
+
fileCount++;
|
|
204
|
+
totalSize += item.size || 0;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Second pass: create folder nodes for paths that have files under them
|
|
208
|
+
const folderPaths = new Set();
|
|
209
|
+
for (const item of filteredItems) {
|
|
210
|
+
if (item.type === "blob") {
|
|
211
|
+
// Walk up the path and add all parent folders
|
|
212
|
+
let parentPath = getParentPath(item.path);
|
|
213
|
+
while (parentPath &&
|
|
214
|
+
(!basePath ||
|
|
215
|
+
parentPath.startsWith(basePath) ||
|
|
216
|
+
parentPath === basePath)) {
|
|
217
|
+
// Don't add folders above basePath
|
|
218
|
+
if (basePath && parentPath.length < basePath.length)
|
|
219
|
+
break;
|
|
220
|
+
folderPaths.add(parentPath);
|
|
221
|
+
parentPath = getParentPath(parentPath);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Create folder nodes
|
|
226
|
+
for (const folderPath of folderPaths) {
|
|
227
|
+
if (!nodeMap.has(folderPath)) {
|
|
228
|
+
nodeMap.set(folderPath, {
|
|
229
|
+
name: getNameFromPath(folderPath),
|
|
230
|
+
path: folderPath,
|
|
231
|
+
type: "folder",
|
|
232
|
+
children: [],
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Third pass: build the hierarchy
|
|
237
|
+
for (const [path, node] of nodeMap) {
|
|
238
|
+
const parentPath = getParentPath(path);
|
|
239
|
+
// Skip if this is at the root level (relative to basePath)
|
|
240
|
+
if (!parentPath || (basePath && parentPath.length < basePath.length)) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const parent = nodeMap.get(parentPath);
|
|
244
|
+
if (parent && parent.type === "folder") {
|
|
245
|
+
parent.children = parent.children || [];
|
|
246
|
+
parent.children.push(node);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Collect root-level nodes
|
|
250
|
+
const rootNodes = [];
|
|
251
|
+
for (const [path, node] of nodeMap) {
|
|
252
|
+
const parentPath = getParentPath(path);
|
|
253
|
+
const isRootLevel = basePath
|
|
254
|
+
? path.startsWith(basePath + "/") &&
|
|
255
|
+
!parentPath.includes("/", basePath.length + 1) &&
|
|
256
|
+
parentPath === basePath
|
|
257
|
+
: !path.includes("/");
|
|
258
|
+
// For base path, check if direct child
|
|
259
|
+
if (basePath) {
|
|
260
|
+
const relativePath = path.slice(basePath.length + 1);
|
|
261
|
+
if (!relativePath.includes("/")) {
|
|
262
|
+
rootNodes.push(node);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else if (!path.includes("/")) {
|
|
266
|
+
rootNodes.push(node);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Sort all nodes: folders first, then files, both alphabetically
|
|
270
|
+
const sortNodes = (nodes) => {
|
|
271
|
+
nodes.sort((a, b) => {
|
|
272
|
+
if (a.type !== b.type) {
|
|
273
|
+
return a.type === "folder" ? -1 : 1;
|
|
274
|
+
}
|
|
275
|
+
return a.name.localeCompare(b.name);
|
|
276
|
+
});
|
|
277
|
+
for (const node of nodes) {
|
|
278
|
+
if (node.children) {
|
|
279
|
+
sortNodes(node.children);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
sortNodes(rootNodes);
|
|
284
|
+
return { tree: rootNodes, fileCount, totalSize };
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Fetches the file tree from a GitHub repository.
|
|
288
|
+
* Uses the Git Trees API for efficiency (1 request for entire tree).
|
|
289
|
+
*
|
|
290
|
+
* @param repoString Repository in "owner/repo" format
|
|
291
|
+
* @param options Fetch options
|
|
292
|
+
* @returns Tree structure with metadata
|
|
293
|
+
*/
|
|
294
|
+
export async function fetchRepoTree(repoString, options = {}) {
|
|
295
|
+
const { owner, repo } = parseRepoString(repoString);
|
|
296
|
+
const { path = "", branch: requestedBranch, extensions = DEFAULT_EXTENSIONS, maxDepth = 10, } = options;
|
|
297
|
+
// Detect or use specified branch
|
|
298
|
+
const branch = requestedBranch || (await detectDefaultBranch(owner, repo));
|
|
299
|
+
// Fetch the entire tree in one API call
|
|
300
|
+
const gitTree = await fetchGitTree(owner, repo, branch);
|
|
301
|
+
if (gitTree.truncated) {
|
|
302
|
+
console.error("Warning: Repository tree was truncated due to size. Some files may be missing.");
|
|
303
|
+
}
|
|
304
|
+
// Build hierarchical tree from flat list
|
|
305
|
+
const result = buildHierarchicalTree(gitTree.tree, path, extensions, maxDepth);
|
|
306
|
+
return {
|
|
307
|
+
repo: `${owner}/${repo}`,
|
|
308
|
+
branch,
|
|
309
|
+
tree: result.tree,
|
|
310
|
+
fileCount: result.fileCount,
|
|
311
|
+
totalSize: result.totalSize,
|
|
312
|
+
truncated: gitTree.truncated,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Fetches raw file content from GitHub via raw.githubusercontent.com.
|
|
317
|
+
* This endpoint has no rate limits (served from CDN).
|
|
318
|
+
*
|
|
319
|
+
* @param repoString Repository in "owner/repo" format
|
|
320
|
+
* @param branch Branch name
|
|
321
|
+
* @param filePath Path to the file within the repo
|
|
322
|
+
* @returns File content or null if not found
|
|
323
|
+
*/
|
|
324
|
+
export async function fetchFileContent(repoString, branch, filePath) {
|
|
325
|
+
const { owner, repo } = parseRepoString(repoString);
|
|
326
|
+
// Use raw.githubusercontent.com - no rate limits, served from CDN
|
|
327
|
+
const url = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${filePath}`;
|
|
328
|
+
const response = await fetch(url, {
|
|
329
|
+
headers: {
|
|
330
|
+
"User-Agent": "mcp-docs-scraper",
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
if (!response.ok) {
|
|
334
|
+
if (response.status === 404) {
|
|
335
|
+
// File not found - return null gracefully
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
throw new Error(`Failed to fetch file content: ${response.status} ${response.statusText}`);
|
|
339
|
+
}
|
|
340
|
+
const content = await response.text();
|
|
341
|
+
return {
|
|
342
|
+
path: filePath,
|
|
343
|
+
content,
|
|
344
|
+
size: new TextEncoder().encode(content).length,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Fetches multiple files from a repository.
|
|
349
|
+
* Handles 404s gracefully by skipping missing files.
|
|
350
|
+
*
|
|
351
|
+
* @param repoString Repository in "owner/repo" format
|
|
352
|
+
* @param branch Branch name
|
|
353
|
+
* @param filePaths Array of file paths to fetch
|
|
354
|
+
* @returns Array of successfully fetched files and array of not found paths
|
|
355
|
+
*/
|
|
356
|
+
export async function fetchMultipleFiles(repoString, branch, filePaths) {
|
|
357
|
+
const files = [];
|
|
358
|
+
const notFound = [];
|
|
359
|
+
// Fetch files in parallel for better performance
|
|
360
|
+
const results = await Promise.all(filePaths.map(async (filePath) => {
|
|
361
|
+
try {
|
|
362
|
+
const result = await fetchFileContent(repoString, branch, filePath);
|
|
363
|
+
return { filePath, result };
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
// Log error but don't fail the whole batch
|
|
367
|
+
console.error(`Error fetching ${filePath}:`, error);
|
|
368
|
+
return { filePath, result: null };
|
|
369
|
+
}
|
|
370
|
+
}));
|
|
371
|
+
for (const { filePath, result } of results) {
|
|
372
|
+
if (result) {
|
|
373
|
+
files.push(result);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
notFound.push(filePath);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return { files, notFound };
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Gets the current GitHub API rate limit status.
|
|
383
|
+
*/
|
|
384
|
+
export function getRateLimitStatus() {
|
|
385
|
+
return githubRateLimit.getStatusMessage();
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Gets the raw rate limit info.
|
|
389
|
+
*/
|
|
390
|
+
export function getRateLimitInfo() {
|
|
391
|
+
return githubRateLimit.getInfo();
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=github-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-fetcher.js","sourceRoot":"","sources":["../../src/services/github-fetcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search index service - Full-text search using MiniSearch.
|
|
3
|
+
*
|
|
4
|
+
* Indexes documentation content for fast searching.
|
|
5
|
+
* Index is built during docs indexing and stored in cache.
|
|
6
|
+
*/
|
|
7
|
+
import MiniSearch from "minisearch";
|
|
8
|
+
/**
|
|
9
|
+
* Document to be indexed.
|
|
10
|
+
*/
|
|
11
|
+
export interface IndexableDocument {
|
|
12
|
+
/** File path (unique identifier) */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Document title (from first H1 or filename) */
|
|
15
|
+
title: string;
|
|
16
|
+
/** All headings concatenated */
|
|
17
|
+
headings: string;
|
|
18
|
+
/** Full text content */
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Search result with snippet.
|
|
23
|
+
*/
|
|
24
|
+
export interface SearchResult {
|
|
25
|
+
/** File path */
|
|
26
|
+
path: string;
|
|
27
|
+
/** Document title */
|
|
28
|
+
title: string;
|
|
29
|
+
/** Matching excerpt with context */
|
|
30
|
+
snippet: string;
|
|
31
|
+
/** Relevance score (higher = more relevant) */
|
|
32
|
+
score: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Serialized index format for storage.
|
|
36
|
+
*/
|
|
37
|
+
export interface SerializedSearchIndex {
|
|
38
|
+
/** MiniSearch serialized index */
|
|
39
|
+
index: ReturnType<MiniSearch<IndexableDocument>["toJSON"]>;
|
|
40
|
+
/** Document metadata for generating snippets */
|
|
41
|
+
documents: Map<string, {
|
|
42
|
+
title: string;
|
|
43
|
+
content: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** Version for future compatibility */
|
|
46
|
+
version: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates and manages a full-text search index for documentation.
|
|
50
|
+
*/
|
|
51
|
+
export declare class SearchIndex {
|
|
52
|
+
private miniSearch;
|
|
53
|
+
private documents;
|
|
54
|
+
constructor();
|
|
55
|
+
/**
|
|
56
|
+
* Adds a document to the index.
|
|
57
|
+
*/
|
|
58
|
+
addDocument(doc: IndexableDocument): void;
|
|
59
|
+
/**
|
|
60
|
+
* Adds multiple documents to the index.
|
|
61
|
+
*/
|
|
62
|
+
addDocuments(docs: IndexableDocument[]): void;
|
|
63
|
+
/**
|
|
64
|
+
* Searches the index and returns results with snippets.
|
|
65
|
+
*/
|
|
66
|
+
search(query: string, limit?: number): SearchResult[];
|
|
67
|
+
/**
|
|
68
|
+
* Converts a MiniSearch result to our SearchResult format.
|
|
69
|
+
*/
|
|
70
|
+
private toSearchResult;
|
|
71
|
+
/**
|
|
72
|
+
* Generates a snippet with the matching text highlighted.
|
|
73
|
+
*/
|
|
74
|
+
private generateSnippet;
|
|
75
|
+
/**
|
|
76
|
+
* Returns the number of indexed documents.
|
|
77
|
+
*/
|
|
78
|
+
get documentCount(): number;
|
|
79
|
+
/**
|
|
80
|
+
* Serializes the index for storage.
|
|
81
|
+
*/
|
|
82
|
+
toJSON(): string;
|
|
83
|
+
/**
|
|
84
|
+
* Creates a SearchIndex from serialized JSON.
|
|
85
|
+
*/
|
|
86
|
+
static fromJSON(json: string): SearchIndex;
|
|
87
|
+
/**
|
|
88
|
+
* Clears the index.
|
|
89
|
+
*/
|
|
90
|
+
clear(): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Extracts a title from markdown content.
|
|
94
|
+
* Returns the first H1 heading, or undefined if none found.
|
|
95
|
+
*/
|
|
96
|
+
export declare function extractTitle(content: string): string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Extracts all headings from markdown content.
|
|
99
|
+
* Returns a concatenated string of all headings.
|
|
100
|
+
*/
|
|
101
|
+
export declare function extractHeadings(content: string): string;
|
|
102
|
+
/**
|
|
103
|
+
* Creates an indexable document from file content.
|
|
104
|
+
*/
|
|
105
|
+
export declare function createIndexableDocument(path: string, content: string): IndexableDocument;
|
|
106
|
+
//# sourceMappingURL=search-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/services/search-index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,UAAgD,MAAM,YAAY,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,gDAAgD;IAChD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB;AASD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,SAAS,CAAkD;;IAenE;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI;IAWzC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAM7C;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,YAAY,EAAE;IAazD;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmDvB;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,MAAM,IAAI,MAAM;IAchB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IA6B1C;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,iBAAiB,CAUnB"}
|