react-docs-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ /**
2
+ * embeddingService.ts
3
+ * Generate embeddings using transformers.js for semantic search
4
+ */
5
+ import { pipeline, env } from '@xenova/transformers';
6
+ // Configure transformers.js
7
+ env.allowLocalModels = true;
8
+ env.allowRemoteModels = true;
9
+ /**
10
+ * Embedding service using all-MiniLM-L6-v2 model
11
+ * This is a lightweight model (23MB) optimized for semantic similarity
12
+ */
13
+ export class EmbeddingService {
14
+ pipeline = null;
15
+ initialized = false;
16
+ modelName = 'Xenova/all-MiniLM-L6-v2';
17
+ /**
18
+ * Initialize the embedding pipeline
19
+ * Downloads model on first run (~23MB)
20
+ */
21
+ async initialize() {
22
+ if (this.initialized)
23
+ return;
24
+ console.log('Initializing embedding model (first run may take a moment)...');
25
+ try {
26
+ this.pipeline = await pipeline('feature-extraction', this.modelName);
27
+ this.initialized = true;
28
+ console.log('Embedding model initialized successfully');
29
+ }
30
+ catch (error) {
31
+ console.error('Failed to initialize embedding model:', error);
32
+ throw new Error(`Embedding initialization failed: ${error instanceof Error ? error.message : String(error)}`);
33
+ }
34
+ }
35
+ /**
36
+ * Generate embedding for a text
37
+ * @param text - Text to embed
38
+ * @returns Vector embedding (384 dimensions for all-MiniLM-L6-v2)
39
+ */
40
+ async generateEmbedding(text) {
41
+ if (!this.initialized) {
42
+ await this.initialize();
43
+ }
44
+ try {
45
+ // Truncate text to reasonable length (512 tokens max)
46
+ const truncated = text.slice(0, 2000);
47
+ const output = await this.pipeline(truncated, {
48
+ pooling: 'mean',
49
+ normalize: true,
50
+ });
51
+ // Convert tensor to array
52
+ const embedding = Array.from(output.data);
53
+ return embedding;
54
+ }
55
+ catch (error) {
56
+ console.error('Failed to generate embedding:', error);
57
+ throw new Error(`Embedding generation failed: ${error instanceof Error ? error.message : String(error)}`);
58
+ }
59
+ }
60
+ /**
61
+ * Generate embeddings for multiple texts (batch processing)
62
+ * @param texts - Array of texts to embed
63
+ * @returns Array of vector embeddings
64
+ */
65
+ async generateEmbeddings(texts) {
66
+ const embeddings = [];
67
+ for (const text of texts) {
68
+ const embedding = await this.generateEmbedding(text);
69
+ embeddings.push(embedding);
70
+ }
71
+ return embeddings;
72
+ }
73
+ /**
74
+ * Calculate cosine similarity between two vectors
75
+ * @param a - First vector
76
+ * @param b - Second vector
77
+ * @returns Similarity score (0-1, higher is more similar)
78
+ */
79
+ cosineSimilarity(a, b) {
80
+ if (a.length !== b.length) {
81
+ throw new Error('Vectors must have same length');
82
+ }
83
+ let dotProduct = 0;
84
+ let normA = 0;
85
+ let normB = 0;
86
+ for (let i = 0; i < a.length; i++) {
87
+ dotProduct += a[i] * b[i];
88
+ normA += a[i] * a[i];
89
+ normB += b[i] * b[i];
90
+ }
91
+ const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
92
+ if (magnitude === 0)
93
+ return 0;
94
+ return dotProduct / magnitude;
95
+ }
96
+ /**
97
+ * Find most similar vectors to a query vector
98
+ * @param queryEmbedding - Query vector
99
+ * @param docEmbeddings - Array of document vectors with metadata
100
+ * @param topK - Number of results to return
101
+ * @returns Array of {index, similarity} sorted by similarity desc
102
+ */
103
+ findMostSimilar(queryEmbedding, docEmbeddings, topK) {
104
+ const similarities = docEmbeddings.map(({ embedding, index }) => ({
105
+ index,
106
+ similarity: this.cosineSimilarity(queryEmbedding, embedding),
107
+ }));
108
+ // Sort by similarity descending
109
+ similarities.sort((a, b) => b.similarity - a.similarity);
110
+ return similarities.slice(0, topK);
111
+ }
112
+ }
113
+ //# sourceMappingURL=embeddingService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddingService.js","sourceRoot":"","sources":["../src/embeddingService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAErD,4BAA4B;AAC5B,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;AAC5B,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC;AAE7B;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,QAAQ,GAAQ,IAAI,CAAC;IACrB,WAAW,GAAY,KAAK,CAAC;IAC7B,SAAS,GAAW,yBAAyB,CAAC;IAEtD;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAE7E,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACrE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB,CAAC,IAAY;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,CAAC;QAED,IAAI,CAAC;YACH,sDAAsD;YACtD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAEtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;gBAC5C,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;YAEH,0BAA0B;YAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAa,CAAC;YACtD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,kBAAkB,CAAC,KAAe;QACtC,MAAM,UAAU,GAAe,EAAE,CAAC;QAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACrD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,CAAW,EAAE,CAAW;QACvC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEtD,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAE9B,OAAO,UAAU,GAAG,SAAS,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACH,eAAe,CACb,cAAwB,EACxB,aAA4D,EAC5D,IAAY;QAEZ,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YAChE,KAAK;YACL,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,SAAS,CAAC;SAC7D,CAAC,CAAC,CAAC;QAEJ,gCAAgC;QAChC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAEzD,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * index.ts
4
+ * MCP server entry point implementing the protocol
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * index.ts
4
+ * MCP server entry point implementing the protocol
5
+ */
6
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
+ import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
9
+ import { z } from 'zod';
10
+ import { DocsManager } from './docsManager.js';
11
+ import { SearchEngine } from './searchEngine.js';
12
+ import { summarizeContent, extractStructure } from './summarizer.js';
13
+ import CONFIG from './config.js';
14
+ // Initialize components
15
+ const docsManager = new DocsManager();
16
+ const searchEngine = new SearchEngine(docsManager);
17
+ // Create MCP server
18
+ const server = new Server({
19
+ name: CONFIG.server.name,
20
+ version: CONFIG.server.version,
21
+ }, {
22
+ capabilities: {
23
+ resources: {},
24
+ tools: {},
25
+ },
26
+ });
27
+ // Tool input schemas
28
+ const searchDocsSchema = z.object({
29
+ query: z.string().describe('Search query string'),
30
+ section: z.string().optional().describe('Filter by section (learn, reference, blog, community)'),
31
+ limit: z.number().min(1).max(CONFIG.search.maxLimit).optional().describe('Maximum number of results'),
32
+ });
33
+ const getDocSchema = z.object({
34
+ path: z.string().describe('Document path (e.g., "learn/hooks/useState")'),
35
+ });
36
+ // Register list resources handler
37
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
38
+ return {
39
+ resources: [
40
+ {
41
+ uri: 'react-docs://learn',
42
+ name: 'React Learn Documentation',
43
+ description: 'Interactive React tutorial and learning materials',
44
+ mimeType: 'text/plain',
45
+ },
46
+ {
47
+ uri: 'react-docs://reference',
48
+ name: 'React API Reference',
49
+ description: 'Complete React API reference documentation',
50
+ mimeType: 'text/plain',
51
+ },
52
+ {
53
+ uri: 'react-docs://blog',
54
+ name: 'React Blog',
55
+ description: 'React team blog posts and announcements',
56
+ mimeType: 'text/plain',
57
+ },
58
+ ],
59
+ };
60
+ });
61
+ // Register read resource handler
62
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
63
+ const uri = request.params.uri.toString();
64
+ // Parse URI: react-docs://{section}/{path}
65
+ const match = uri.match(/^react-docs:\/\/(.+)$/);
66
+ if (!match) {
67
+ throw new Error(`Invalid resource URI: ${uri}`);
68
+ }
69
+ const resourcePath = match[1];
70
+ // If requesting just a section, list docs in that section
71
+ if (CONFIG.sections.includes(resourcePath)) {
72
+ const docs = await searchEngine.getDocsBySection(resourcePath);
73
+ const docList = docs
74
+ .map(doc => `- ${doc.metadata.title} (${doc.path})`)
75
+ .join('\n');
76
+ return {
77
+ contents: [
78
+ {
79
+ uri,
80
+ mimeType: 'text/plain',
81
+ text: `# ${resourcePath} Documentation\n\nAvailable documents:\n\n${docList}`,
82
+ },
83
+ ],
84
+ };
85
+ }
86
+ // Otherwise, fetch specific document
87
+ const doc = await searchEngine.getDocByPath(resourcePath);
88
+ if (!doc) {
89
+ throw new Error(`Document not found: ${resourcePath}`);
90
+ }
91
+ return {
92
+ contents: [
93
+ {
94
+ uri,
95
+ mimeType: 'text/markdown',
96
+ text: `# ${doc.metadata.title}\n\n${doc.content}`,
97
+ },
98
+ ],
99
+ };
100
+ });
101
+ // Register list tools handler
102
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
103
+ return {
104
+ tools: [
105
+ {
106
+ name: 'search_react_docs',
107
+ description: 'Search across React documentation. Returns relevant documentation pages with snippets.',
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ query: {
112
+ type: 'string',
113
+ description: 'Search query string',
114
+ },
115
+ section: {
116
+ type: 'string',
117
+ description: 'Filter by section (learn, reference, blog, community)',
118
+ enum: [...CONFIG.sections],
119
+ },
120
+ limit: {
121
+ type: 'number',
122
+ description: 'Maximum number of results',
123
+ minimum: 1,
124
+ maximum: CONFIG.search.maxLimit,
125
+ },
126
+ },
127
+ required: ['query'],
128
+ },
129
+ },
130
+ {
131
+ name: 'list_sections',
132
+ description: 'List all available documentation sections',
133
+ inputSchema: {
134
+ type: 'object',
135
+ properties: {},
136
+ },
137
+ },
138
+ {
139
+ name: 'get_doc',
140
+ description: 'Get a concise summary of a documentation page (~1500 chars). Use search_react_docs first - only call this if you need more detail than the search snippet provides.',
141
+ inputSchema: {
142
+ type: 'object',
143
+ properties: {
144
+ path: {
145
+ type: 'string',
146
+ description: 'Document path (e.g., "learn/hooks/useState")',
147
+ },
148
+ },
149
+ required: ['path'],
150
+ },
151
+ },
152
+ {
153
+ name: 'update_docs',
154
+ description: 'Pull latest documentation from Git repository',
155
+ inputSchema: {
156
+ type: 'object',
157
+ properties: {},
158
+ },
159
+ },
160
+ ],
161
+ };
162
+ });
163
+ // Register call tool handler
164
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
165
+ const { name, arguments: args } = request.params;
166
+ try {
167
+ switch (name) {
168
+ case 'search_react_docs': {
169
+ const { query, section, limit } = searchDocsSchema.parse(args);
170
+ const results = await searchEngine.search(query, { section, limit });
171
+ return {
172
+ content: [
173
+ {
174
+ type: 'text',
175
+ text: JSON.stringify(results.map(r => ({
176
+ path: r.doc.path,
177
+ title: r.doc.metadata.title,
178
+ snippet: r.snippet,
179
+ score: r.score,
180
+ url: `https://react.dev/${r.doc.path}`,
181
+ })), null, 2),
182
+ },
183
+ ],
184
+ };
185
+ }
186
+ case 'list_sections': {
187
+ const sections = searchEngine.getSections();
188
+ return {
189
+ content: [
190
+ {
191
+ type: 'text',
192
+ text: JSON.stringify(sections, null, 2),
193
+ },
194
+ ],
195
+ };
196
+ }
197
+ case 'get_doc': {
198
+ const { path } = getDocSchema.parse(args);
199
+ const doc = await searchEngine.getDocByPath(path);
200
+ if (!doc) {
201
+ throw new Error(`Document not found: ${path}`);
202
+ }
203
+ // Return concise summary instead of full content
204
+ const summary = summarizeContent(doc.content, 1500);
205
+ const structure = extractStructure(doc.content);
206
+ return {
207
+ content: [
208
+ {
209
+ type: 'text',
210
+ text: JSON.stringify({
211
+ path: doc.path,
212
+ section: doc.section,
213
+ title: doc.metadata.title,
214
+ description: doc.metadata.description,
215
+ summary,
216
+ structure,
217
+ url: `https://react.dev/${doc.path}`,
218
+ note: 'This is a summary. Visit the URL for full documentation.',
219
+ }, null, 2),
220
+ },
221
+ ],
222
+ };
223
+ }
224
+ case 'update_docs': {
225
+ const updated = await docsManager.updateRepo();
226
+ if (updated) {
227
+ // Re-index documents after update
228
+ await searchEngine.indexDocuments();
229
+ }
230
+ return {
231
+ content: [
232
+ {
233
+ type: 'text',
234
+ text: JSON.stringify({
235
+ updated,
236
+ message: updated
237
+ ? 'Documentation updated successfully'
238
+ : 'Documentation already up to date',
239
+ }, null, 2),
240
+ },
241
+ ],
242
+ };
243
+ }
244
+ default:
245
+ throw new Error(`Unknown tool: ${name}`);
246
+ }
247
+ }
248
+ catch (error) {
249
+ if (error instanceof z.ZodError) {
250
+ throw new Error(`Invalid arguments: ${error.message}`);
251
+ }
252
+ throw error;
253
+ }
254
+ });
255
+ // Start server
256
+ async function main() {
257
+ console.error('Initializing React Docs MCP Server...');
258
+ try {
259
+ // Initialize repository
260
+ await docsManager.initialize();
261
+ // Start server with stdio transport
262
+ const transport = new StdioServerTransport();
263
+ await server.connect(transport);
264
+ console.error('React Docs MCP Server running');
265
+ }
266
+ catch (error) {
267
+ console.error('Failed to start server:', error);
268
+ process.exit(1);
269
+ }
270
+ }
271
+ main();
272
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * markdownParser.ts
3
+ * Parse markdown files and extract metadata and content
4
+ */
5
+ import type { ParsedDoc } from './types.js';
6
+ /**
7
+ * Parse a markdown file
8
+ * @param content - Raw markdown content
9
+ * @param path - File path for context
10
+ * @returns Parsed document with metadata and content
11
+ */
12
+ export declare function parseMarkdown(content: string, path: string): Promise<ParsedDoc>;
13
+ /**
14
+ * Strip markdown formatting to plain text
15
+ * Used for search indexing
16
+ * @param markdown - Markdown content
17
+ * @returns Plain text
18
+ */
19
+ export declare function markdownToPlainText(markdown: string): Promise<string>;
20
+ /**
21
+ * Extract section from file path
22
+ * E.g., "learn/hooks/useState.md" -> "learn"
23
+ */
24
+ export declare function extractSection(path: string): string;
25
+ //# sourceMappingURL=markdownParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownParser.d.ts","sourceRoot":"","sources":["../src/markdownParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,CAAC,CA2BpB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * markdownParser.ts
3
+ * Parse markdown files and extract metadata and content
4
+ */
5
+ import matter from 'gray-matter';
6
+ import { remark } from 'remark';
7
+ import stripMarkdown from 'strip-markdown';
8
+ /**
9
+ * Parse a markdown file
10
+ * @param content - Raw markdown content
11
+ * @param path - File path for context
12
+ * @returns Parsed document with metadata and content
13
+ */
14
+ export async function parseMarkdown(content, path) {
15
+ // Parse frontmatter
16
+ const { data, content: markdownContent } = matter(content);
17
+ // Extract metadata
18
+ const metadata = {
19
+ title: data.title || extractTitleFromPath(path),
20
+ description: data.description,
21
+ date: data.date,
22
+ author: data.author,
23
+ tags: data.tags,
24
+ ...data,
25
+ };
26
+ // Convert to plain text for search
27
+ const plainText = await markdownToPlainText(markdownContent);
28
+ // Extract section from path
29
+ const section = extractSection(path);
30
+ return {
31
+ path: normalizePath(path),
32
+ section,
33
+ metadata,
34
+ content: markdownContent,
35
+ plainText,
36
+ };
37
+ }
38
+ /**
39
+ * Strip markdown formatting to plain text
40
+ * Used for search indexing
41
+ * @param markdown - Markdown content
42
+ * @returns Plain text
43
+ */
44
+ export async function markdownToPlainText(markdown) {
45
+ const result = await remark()
46
+ .use(stripMarkdown)
47
+ .process(markdown);
48
+ return String(result)
49
+ .replace(/\s+/g, ' ') // Normalize whitespace
50
+ .trim();
51
+ }
52
+ /**
53
+ * Extract section from file path
54
+ * E.g., "learn/hooks/useState.md" -> "learn"
55
+ */
56
+ export function extractSection(path) {
57
+ const normalized = normalizePath(path);
58
+ const parts = normalized.split('/');
59
+ return parts[0] || 'unknown';
60
+ }
61
+ /**
62
+ * Normalize path (forward slashes, no leading slash, no .md extension for display)
63
+ */
64
+ function normalizePath(filePath) {
65
+ return filePath
66
+ .replace(/\\/g, '/') // Convert backslashes to forward slashes
67
+ .replace(/^\/+/, '') // Remove leading slashes
68
+ .replace(/\.md$/, ''); // Remove .md extension for cleaner paths
69
+ }
70
+ /**
71
+ * Extract title from path if not in frontmatter
72
+ * E.g., "learn/hooks/useState" -> "useState"
73
+ */
74
+ function extractTitleFromPath(filePath) {
75
+ const normalized = normalizePath(filePath);
76
+ const parts = normalized.split('/');
77
+ const filename = parts[parts.length - 1] || 'Untitled';
78
+ // Convert kebab-case or snake_case to Title Case
79
+ return filename
80
+ .replace(/[-_]/g, ' ')
81
+ .split(' ')
82
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
83
+ .join(' ');
84
+ }
85
+ //# sourceMappingURL=markdownParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownParser.js","sourceRoot":"","sources":["../src/markdownParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAG3C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAe,EACf,IAAY;IAEZ,oBAAoB;IACpB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAE3D,mBAAmB;IACnB,MAAM,QAAQ,GAAgB;QAC5B,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,oBAAoB,CAAC,IAAI,CAAC;QAC/C,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,IAAI;KACR,CAAC;IAEF,mCAAmC;IACnC,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAAC;IAE7D,4BAA4B;IAC5B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAErC,OAAO;QACL,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC;QACzB,OAAO;QACP,QAAQ;QACR,OAAO,EAAE,eAAe;QACxB,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,MAAM,MAAM,GAAG,MAAM,MAAM,EAAE;SAC1B,GAAG,CAAC,aAAa,CAAC;SAClB,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB,OAAO,MAAM,CAAC,MAAM,CAAC;SAClB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,uBAAuB;SAC5C,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,QAAQ;SACZ,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,yCAAyC;SAC7D,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,yBAAyB;SAC7C,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,yCAAyC;AACpE,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,UAAU,CAAC;IAEvD,iDAAiD;IACjD,OAAO,QAAQ;SACZ,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACzD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * searchEngine.ts
3
+ * Implement search functionality over documentation
4
+ */
5
+ import { DocsManager } from './docsManager.js';
6
+ import type { ParsedDoc, SearchOptions, SearchResult } from './types.js';
7
+ export declare class SearchEngine {
8
+ private docsManager;
9
+ private embeddingService;
10
+ private documentIndex;
11
+ private indexed;
12
+ private embeddingsGenerated;
13
+ /**
14
+ * Initialize search engine
15
+ * @param docsManager - Instance of DocsManager
16
+ */
17
+ constructor(docsManager: DocsManager);
18
+ /**
19
+ * Index all documents for searching
20
+ * Should be called after repo update
21
+ */
22
+ indexDocuments(): Promise<void>;
23
+ /**
24
+ * Generate embeddings for all documents
25
+ * Called lazily when semantic search is first used
26
+ */
27
+ generateEmbeddings(): Promise<void>;
28
+ /**
29
+ * Search documents
30
+ * @param query - Search query string
31
+ * @param options - Search options (section filter, limit, etc.)
32
+ * @returns Ranked search results
33
+ */
34
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
35
+ /**
36
+ * Keyword-based search
37
+ */
38
+ private keywordSearch;
39
+ /**
40
+ * Semantic search using embeddings (hybrid with keyword search)
41
+ */
42
+ private semanticSearch;
43
+ /**
44
+ * Score a document based on query terms
45
+ */
46
+ private scoreDocument;
47
+ /**
48
+ * Generate context snippet showing matched text
49
+ */
50
+ private generateSnippet;
51
+ /**
52
+ * Get document by exact path
53
+ * @param path - Document path relative to content root
54
+ * @returns Parsed document or null if not found
55
+ */
56
+ getDocByPath(path: string): Promise<ParsedDoc | null>;
57
+ /**
58
+ * List all available sections
59
+ */
60
+ getSections(): string[];
61
+ /**
62
+ * Get all documents in a section
63
+ */
64
+ getDocsBySection(section: string): Promise<ParsedDoc[]>;
65
+ }
66
+ //# sourceMappingURL=searchEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchEngine.d.ts","sourceRoot":"","sources":["../src/searchEngine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEzE,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,mBAAmB,CAAkB;IAE7C;;;OAGG;gBACS,WAAW,EAAE,WAAW;IAKpC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBrC;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BzC;;;;;OAKG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC;IAsB1B;;OAEG;YACW,aAAa;IAsC3B;;OAEG;YACW,cAAc;IA0D5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAkCvB;;;;OAIG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAY3D;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAiB9D"}