@stackguide/mcp-server 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.
- package/LICENSE +674 -0
- package/README.md +453 -0
- package/data/knowledge/python-django/architecture/architecture-patterns.md +201 -0
- package/data/knowledge/python-django/common-issues/common-issues.md +181 -0
- package/data/knowledge/python-django/patterns/drf-patterns.md +133 -0
- package/data/knowledge/react-node/architecture/node-architecture.md +257 -0
- package/data/knowledge/react-node/common-issues/common-issues.md +262 -0
- package/data/knowledge/react-node/patterns/react-patterns.md +244 -0
- package/data/rules/python-django/best-practices/django-best-practices.md +120 -0
- package/data/rules/python-django/coding-standards/django-standards.md +104 -0
- package/data/rules/python-django/security/security-guidelines.md +146 -0
- package/data/rules/react-node/best-practices/react-best-practices.md +195 -0
- package/data/rules/react-node/coding-standards/node-standards.md +192 -0
- package/data/rules/react-node/coding-standards/react-standards.md +155 -0
- package/data/rules/react-node/security/security-guidelines.md +228 -0
- package/dist/config/persistence.d.ts +15 -0
- package/dist/config/persistence.d.ts.map +1 -0
- package/dist/config/persistence.js +171 -0
- package/dist/config/persistence.js.map +1 -0
- package/dist/config/types.d.ts +47 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +116 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1799 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/knowledgeProvider.d.ts +10 -0
- package/dist/resources/knowledgeProvider.d.ts.map +1 -0
- package/dist/resources/knowledgeProvider.js +130 -0
- package/dist/resources/knowledgeProvider.js.map +1 -0
- package/dist/resources/rulesProvider.d.ts +10 -0
- package/dist/resources/rulesProvider.d.ts.map +1 -0
- package/dist/resources/rulesProvider.js +135 -0
- package/dist/resources/rulesProvider.js.map +1 -0
- package/dist/services/cursorDirectory.d.ts +55 -0
- package/dist/services/cursorDirectory.d.ts.map +1 -0
- package/dist/services/cursorDirectory.js +367 -0
- package/dist/services/cursorDirectory.js.map +1 -0
- package/dist/services/ruleManager.d.ts +18 -0
- package/dist/services/ruleManager.d.ts.map +1 -0
- package/dist/services/ruleManager.js +382 -0
- package/dist/services/ruleManager.js.map +1 -0
- package/dist/services/webDocumentation.d.ts +41 -0
- package/dist/services/webDocumentation.d.ts.map +1 -0
- package/dist/services/webDocumentation.js +237 -0
- package/dist/services/webDocumentation.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { getConfigPath } from '../config/persistence.js';
|
|
4
|
+
// User custom rules directory
|
|
5
|
+
const USER_RULES_DIR = join(getConfigPath(), 'rules');
|
|
6
|
+
// Rule templates
|
|
7
|
+
export const RULE_TEMPLATES = {
|
|
8
|
+
'coding-standard': {
|
|
9
|
+
name: 'Coding Standard Template',
|
|
10
|
+
content: `# {{RULE_NAME}}
|
|
11
|
+
|
|
12
|
+
{{DESCRIPTION}}
|
|
13
|
+
|
|
14
|
+
## Main Rules
|
|
15
|
+
|
|
16
|
+
### 1. Primary Rule
|
|
17
|
+
|
|
18
|
+
Explanation of the rule...
|
|
19
|
+
|
|
20
|
+
\`\`\`{{LANGUAGE}}
|
|
21
|
+
// Code example
|
|
22
|
+
\`\`\`
|
|
23
|
+
|
|
24
|
+
### 2. Conventions
|
|
25
|
+
|
|
26
|
+
- Convention 1
|
|
27
|
+
- Convention 2
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
### ✅ Correct
|
|
32
|
+
|
|
33
|
+
\`\`\`{{LANGUAGE}}
|
|
34
|
+
// Correct code
|
|
35
|
+
\`\`\`
|
|
36
|
+
|
|
37
|
+
### ❌ Incorrect
|
|
38
|
+
|
|
39
|
+
\`\`\`{{LANGUAGE}}
|
|
40
|
+
// Incorrect code
|
|
41
|
+
\`\`\`
|
|
42
|
+
|
|
43
|
+
## Checklist
|
|
44
|
+
|
|
45
|
+
- [ ] Verify item 1
|
|
46
|
+
- [ ] Verify item 2
|
|
47
|
+
`
|
|
48
|
+
},
|
|
49
|
+
'best-practice': {
|
|
50
|
+
name: 'Best Practice Template',
|
|
51
|
+
content: `# {{RULE_NAME}}
|
|
52
|
+
|
|
53
|
+
{{DESCRIPTION}}
|
|
54
|
+
|
|
55
|
+
## Why It Matters
|
|
56
|
+
|
|
57
|
+
Explanation of the importance...
|
|
58
|
+
|
|
59
|
+
## Implementation
|
|
60
|
+
|
|
61
|
+
### Step 1: Preparation
|
|
62
|
+
|
|
63
|
+
Instructions...
|
|
64
|
+
|
|
65
|
+
### Step 2: Execution
|
|
66
|
+
|
|
67
|
+
Instructions...
|
|
68
|
+
|
|
69
|
+
## Before and After
|
|
70
|
+
|
|
71
|
+
### Before (❌)
|
|
72
|
+
|
|
73
|
+
\`\`\`{{LANGUAGE}}
|
|
74
|
+
// Problematic code
|
|
75
|
+
\`\`\`
|
|
76
|
+
|
|
77
|
+
### After (✅)
|
|
78
|
+
|
|
79
|
+
\`\`\`{{LANGUAGE}}
|
|
80
|
+
// Improved code
|
|
81
|
+
\`\`\`
|
|
82
|
+
|
|
83
|
+
## Benefits
|
|
84
|
+
|
|
85
|
+
- Benefit 1
|
|
86
|
+
- Benefit 2
|
|
87
|
+
- Benefit 3
|
|
88
|
+
`
|
|
89
|
+
},
|
|
90
|
+
'security': {
|
|
91
|
+
name: 'Security Guideline Template',
|
|
92
|
+
content: `# {{RULE_NAME}}
|
|
93
|
+
|
|
94
|
+
⚠️ **Risk Level**: High/Medium/Low
|
|
95
|
+
|
|
96
|
+
{{DESCRIPTION}}
|
|
97
|
+
|
|
98
|
+
## Vulnerability
|
|
99
|
+
|
|
100
|
+
Description of the security issue...
|
|
101
|
+
|
|
102
|
+
## Impact
|
|
103
|
+
|
|
104
|
+
What can happen if not implemented?
|
|
105
|
+
|
|
106
|
+
- Impact 1
|
|
107
|
+
- Impact 2
|
|
108
|
+
|
|
109
|
+
## Vulnerable Code
|
|
110
|
+
|
|
111
|
+
\`\`\`{{LANGUAGE}}
|
|
112
|
+
// ❌ Vulnerable code
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
## Secure Solution
|
|
116
|
+
|
|
117
|
+
\`\`\`{{LANGUAGE}}
|
|
118
|
+
// ✅ Secure code
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
## Verification
|
|
122
|
+
|
|
123
|
+
- [ ] Verification step 1
|
|
124
|
+
- [ ] Verification step 2
|
|
125
|
+
|
|
126
|
+
## References
|
|
127
|
+
|
|
128
|
+
- [OWASP](https://owasp.org)
|
|
129
|
+
`
|
|
130
|
+
},
|
|
131
|
+
'architecture': {
|
|
132
|
+
name: 'Architecture Pattern Template',
|
|
133
|
+
content: `# {{RULE_NAME}}
|
|
134
|
+
|
|
135
|
+
{{DESCRIPTION}}
|
|
136
|
+
|
|
137
|
+
## Diagram
|
|
138
|
+
|
|
139
|
+
\`\`\`
|
|
140
|
+
┌─────────────┐ ┌─────────────┐
|
|
141
|
+
│ Component │────▶│ Component │
|
|
142
|
+
└─────────────┘ └─────────────┘
|
|
143
|
+
\`\`\`
|
|
144
|
+
|
|
145
|
+
## Components
|
|
146
|
+
|
|
147
|
+
### Component 1
|
|
148
|
+
|
|
149
|
+
Description and responsibilities...
|
|
150
|
+
|
|
151
|
+
### Component 2
|
|
152
|
+
|
|
153
|
+
Description and responsibilities...
|
|
154
|
+
|
|
155
|
+
## Implementation
|
|
156
|
+
|
|
157
|
+
\`\`\`{{LANGUAGE}}
|
|
158
|
+
// Implementation code
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
## When to Use
|
|
162
|
+
|
|
163
|
+
- Use case 1
|
|
164
|
+
- Use case 2
|
|
165
|
+
|
|
166
|
+
## When NOT to Use
|
|
167
|
+
|
|
168
|
+
- Anti-pattern 1
|
|
169
|
+
- Anti-pattern 2
|
|
170
|
+
`
|
|
171
|
+
},
|
|
172
|
+
'testing': {
|
|
173
|
+
name: 'Testing Guideline Template',
|
|
174
|
+
content: `# {{RULE_NAME}}
|
|
175
|
+
|
|
176
|
+
{{DESCRIPTION}}
|
|
177
|
+
|
|
178
|
+
## Test Types
|
|
179
|
+
|
|
180
|
+
### Unit Tests
|
|
181
|
+
|
|
182
|
+
\`\`\`{{LANGUAGE}}
|
|
183
|
+
// Unit test example
|
|
184
|
+
\`\`\`
|
|
185
|
+
|
|
186
|
+
### Integration Tests
|
|
187
|
+
|
|
188
|
+
\`\`\`{{LANGUAGE}}
|
|
189
|
+
// Integration test example
|
|
190
|
+
\`\`\`
|
|
191
|
+
|
|
192
|
+
## Naming Conventions
|
|
193
|
+
|
|
194
|
+
- Test names: \`should_ExpectedBehavior_When_Condition\`
|
|
195
|
+
- Files: \`*.test.ts\` or \`*.spec.ts\`
|
|
196
|
+
|
|
197
|
+
## Minimum Coverage
|
|
198
|
+
|
|
199
|
+
| Type | Minimum |
|
|
200
|
+
|------|--------|
|
|
201
|
+
| Statements | 80% |
|
|
202
|
+
| Branches | 75% |
|
|
203
|
+
| Functions | 80% |
|
|
204
|
+
| Lines | 80% |
|
|
205
|
+
|
|
206
|
+
## Mocking
|
|
207
|
+
|
|
208
|
+
\`\`\`{{LANGUAGE}}
|
|
209
|
+
// Mock example
|
|
210
|
+
\`\`\`
|
|
211
|
+
`
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
// Ensure user rules directory exists
|
|
215
|
+
function ensureUserRulesDir(projectType) {
|
|
216
|
+
const dir = join(USER_RULES_DIR, projectType);
|
|
217
|
+
if (!existsSync(dir)) {
|
|
218
|
+
mkdirSync(dir, { recursive: true });
|
|
219
|
+
}
|
|
220
|
+
return dir;
|
|
221
|
+
}
|
|
222
|
+
// Create user rule
|
|
223
|
+
export function createUserRule(projectType, category, name, content, description = '') {
|
|
224
|
+
const dir = ensureUserRulesDir(projectType);
|
|
225
|
+
const id = `user-${projectType}-${category}-${slugify(name)}`;
|
|
226
|
+
const filename = `${slugify(name)}.json`;
|
|
227
|
+
const filepath = join(dir, filename);
|
|
228
|
+
const rule = {
|
|
229
|
+
id,
|
|
230
|
+
name,
|
|
231
|
+
category,
|
|
232
|
+
description,
|
|
233
|
+
content,
|
|
234
|
+
enabled: true,
|
|
235
|
+
priority: 100, // High priority for user rules
|
|
236
|
+
projectType
|
|
237
|
+
};
|
|
238
|
+
writeFileSync(filepath, JSON.stringify(rule, null, 2));
|
|
239
|
+
return rule;
|
|
240
|
+
}
|
|
241
|
+
// Create rule from template
|
|
242
|
+
export function createRuleFromTemplate(projectType, category, templateId, name, description, language = 'typescript') {
|
|
243
|
+
const template = RULE_TEMPLATES[templateId];
|
|
244
|
+
if (!template)
|
|
245
|
+
return null;
|
|
246
|
+
let content = template.content
|
|
247
|
+
.replace(/\{\{RULE_NAME\}\}/g, name)
|
|
248
|
+
.replace(/\{\{DESCRIPTION\}\}/g, description)
|
|
249
|
+
.replace(/\{\{LANGUAGE\}\}/g, language);
|
|
250
|
+
return createUserRule(projectType, category, name, content, description);
|
|
251
|
+
}
|
|
252
|
+
// Get user rules
|
|
253
|
+
export function getUserRules(projectType) {
|
|
254
|
+
const dir = join(USER_RULES_DIR, projectType);
|
|
255
|
+
if (!existsSync(dir)) {
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
const rules = [];
|
|
259
|
+
try {
|
|
260
|
+
const files = readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
261
|
+
for (const file of files) {
|
|
262
|
+
try {
|
|
263
|
+
const content = readFileSync(join(dir, file), 'utf-8');
|
|
264
|
+
const rule = JSON.parse(content);
|
|
265
|
+
rules.push(rule);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Skip invalid files
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Directory doesn't exist or error reading
|
|
274
|
+
}
|
|
275
|
+
return rules;
|
|
276
|
+
}
|
|
277
|
+
// Update user rule
|
|
278
|
+
export function updateUserRule(ruleId, updates) {
|
|
279
|
+
// Parsear el ID para encontrar la regla
|
|
280
|
+
if (!ruleId.startsWith('user-'))
|
|
281
|
+
return null;
|
|
282
|
+
const parts = ruleId.split('-');
|
|
283
|
+
const projectType = parts.slice(1, 3).join('-');
|
|
284
|
+
const dir = join(USER_RULES_DIR, projectType);
|
|
285
|
+
if (!existsSync(dir))
|
|
286
|
+
return null;
|
|
287
|
+
const files = readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
288
|
+
for (const file of files) {
|
|
289
|
+
const filepath = join(dir, file);
|
|
290
|
+
try {
|
|
291
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
292
|
+
const rule = JSON.parse(content);
|
|
293
|
+
if (rule.id === ruleId) {
|
|
294
|
+
const updated = { ...rule, ...updates };
|
|
295
|
+
writeFileSync(filepath, JSON.stringify(updated, null, 2));
|
|
296
|
+
return updated;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
// Delete user rule
|
|
306
|
+
export function deleteUserRule(ruleId) {
|
|
307
|
+
if (!ruleId.startsWith('user-'))
|
|
308
|
+
return false;
|
|
309
|
+
const parts = ruleId.split('-');
|
|
310
|
+
const projectType = parts.slice(1, 3).join('-');
|
|
311
|
+
const dir = join(USER_RULES_DIR, projectType);
|
|
312
|
+
if (!existsSync(dir))
|
|
313
|
+
return false;
|
|
314
|
+
const files = readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
315
|
+
for (const file of files) {
|
|
316
|
+
const filepath = join(dir, file);
|
|
317
|
+
try {
|
|
318
|
+
const content = readFileSync(filepath, 'utf-8');
|
|
319
|
+
const rule = JSON.parse(content);
|
|
320
|
+
if (rule.id === ruleId) {
|
|
321
|
+
unlinkSync(filepath);
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
// List available templates
|
|
332
|
+
export function listTemplates() {
|
|
333
|
+
return Object.entries(RULE_TEMPLATES).map(([id, template]) => ({
|
|
334
|
+
id,
|
|
335
|
+
name: template.name
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
// Get template content
|
|
339
|
+
export function getTemplateContent(templateId) {
|
|
340
|
+
return RULE_TEMPLATES[templateId]?.content || null;
|
|
341
|
+
}
|
|
342
|
+
// Helper: slugify
|
|
343
|
+
function slugify(text) {
|
|
344
|
+
return text
|
|
345
|
+
.toLowerCase()
|
|
346
|
+
.trim()
|
|
347
|
+
.replace(/[^\w\s-]/g, '')
|
|
348
|
+
.replace(/[\s_-]+/g, '-')
|
|
349
|
+
.replace(/^-+|-+$/g, '');
|
|
350
|
+
}
|
|
351
|
+
// Export all user rules
|
|
352
|
+
export function exportAllUserRules() {
|
|
353
|
+
const allRules = {};
|
|
354
|
+
if (!existsSync(USER_RULES_DIR)) {
|
|
355
|
+
return JSON.stringify(allRules, null, 2);
|
|
356
|
+
}
|
|
357
|
+
const projectTypes = readdirSync(USER_RULES_DIR, { withFileTypes: true })
|
|
358
|
+
.filter(d => d.isDirectory())
|
|
359
|
+
.map(d => d.name);
|
|
360
|
+
for (const pt of projectTypes) {
|
|
361
|
+
allRules[pt] = getUserRules(pt);
|
|
362
|
+
}
|
|
363
|
+
return JSON.stringify(allRules, null, 2);
|
|
364
|
+
}
|
|
365
|
+
// Import user rules
|
|
366
|
+
export function importUserRules(jsonString) {
|
|
367
|
+
try {
|
|
368
|
+
const data = JSON.parse(jsonString);
|
|
369
|
+
let count = 0;
|
|
370
|
+
for (const [projectType, rules] of Object.entries(data)) {
|
|
371
|
+
for (const rule of rules) {
|
|
372
|
+
createUserRule(projectType, rule.category, rule.name, rule.content, rule.description);
|
|
373
|
+
count++;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return count;
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
return 0;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=ruleManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleManager.js","sourceRoot":"","sources":["../../src/services/ruleManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface WebDocument {
|
|
2
|
+
id: string;
|
|
3
|
+
url: string;
|
|
4
|
+
title: string;
|
|
5
|
+
content: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
fetchedAt: string;
|
|
8
|
+
projectType?: string;
|
|
9
|
+
category?: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function fetchWebDocumentation(url: string, options?: {
|
|
13
|
+
projectType?: string;
|
|
14
|
+
category?: string;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
}): Promise<WebDocument>;
|
|
17
|
+
export declare function fetchMultipleDocuments(urls: string[], options?: {
|
|
18
|
+
projectType?: string;
|
|
19
|
+
category?: string;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
successful: WebDocument[];
|
|
22
|
+
failed: {
|
|
23
|
+
url: string;
|
|
24
|
+
error: string;
|
|
25
|
+
}[];
|
|
26
|
+
}>;
|
|
27
|
+
export declare function searchWebDocuments(query: string): WebDocument[];
|
|
28
|
+
export declare function getWebDocumentById(id: string): WebDocument | null;
|
|
29
|
+
export declare function getWebDocumentByUrl(url: string): WebDocument | null;
|
|
30
|
+
export declare function listCachedDocuments(): Omit<WebDocument, 'content'>[];
|
|
31
|
+
export declare function clearWebDocCache(): void;
|
|
32
|
+
export declare function removeFromCache(urlOrId: string): boolean;
|
|
33
|
+
export declare const POPULAR_DOCS: Record<string, {
|
|
34
|
+
name: string;
|
|
35
|
+
url: string;
|
|
36
|
+
}[]>;
|
|
37
|
+
export declare function getSuggestedDocs(projectType: string): {
|
|
38
|
+
name: string;
|
|
39
|
+
url: string;
|
|
40
|
+
}[];
|
|
41
|
+
//# sourceMappingURL=webDocumentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webDocumentation.d.ts","sourceRoot":"","sources":["../../src/services/webDocumentation.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAwFD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACZ,GACL,OAAO,CAAC,WAAW,CAAC,CA2DtB;AAGD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,GACL,OAAO,CAAC;IAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAoBlF;AAGD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe/D;AAGD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAKjE;AAGD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAEnE;AAGD,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAWpE;AAGD,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAGD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcxD;AAGD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAqBxE,CAAC;AAGF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAErF"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { URL } from 'url';
|
|
2
|
+
// Web documents cache
|
|
3
|
+
const webDocCache = new Map();
|
|
4
|
+
// Extract main content from HTML
|
|
5
|
+
function extractMainContent(html) {
|
|
6
|
+
// Extract title
|
|
7
|
+
const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
8
|
+
const title = titleMatch ? titleMatch[1].trim() : 'Untitled';
|
|
9
|
+
// Remove scripts, styles, navigation, footer, etc.
|
|
10
|
+
let content = html
|
|
11
|
+
// Remove scripts and styles
|
|
12
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
13
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
|
14
|
+
// Remove navigation and footer
|
|
15
|
+
.replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, '')
|
|
16
|
+
.replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '')
|
|
17
|
+
.replace(/<header[^>]*>[\s\S]*?<\/header>/gi, '')
|
|
18
|
+
// Remove comments
|
|
19
|
+
.replace(/<!--[\s\S]*?-->/g, '')
|
|
20
|
+
// Remove unnecessary attributes
|
|
21
|
+
.replace(/<([a-z]+)[^>]*>/gi, '<$1>');
|
|
22
|
+
// Buscar contenido principal (article, main, o el body)
|
|
23
|
+
const mainMatch = content.match(/<(?:article|main)[^>]*>([\s\S]*?)<\/(?:article|main)>/i);
|
|
24
|
+
if (mainMatch) {
|
|
25
|
+
content = mainMatch[1];
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const bodyMatch = content.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
29
|
+
if (bodyMatch) {
|
|
30
|
+
content = bodyMatch[1];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Convert to clean text while maintaining structure
|
|
34
|
+
content = content
|
|
35
|
+
// Convert headers to markdown
|
|
36
|
+
.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '\n# $1\n')
|
|
37
|
+
.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '\n## $1\n')
|
|
38
|
+
.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '\n### $1\n')
|
|
39
|
+
.replace(/<h4[^>]*>(.*?)<\/h4>/gi, '\n#### $1\n')
|
|
40
|
+
// Convert lists
|
|
41
|
+
.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n')
|
|
42
|
+
.replace(/<\/?[ou]l[^>]*>/gi, '\n')
|
|
43
|
+
// Convert paragraphs
|
|
44
|
+
.replace(/<p[^>]*>(.*?)<\/p>/gi, '\n$1\n')
|
|
45
|
+
// Convert code
|
|
46
|
+
.replace(/<pre[^>]*><code[^>]*>([\s\S]*?)<\/code><\/pre>/gi, '\n```\n$1\n```\n')
|
|
47
|
+
.replace(/<code[^>]*>(.*?)<\/code>/gi, '`$1`')
|
|
48
|
+
// Convert links
|
|
49
|
+
.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)')
|
|
50
|
+
// Convert bold and italic
|
|
51
|
+
.replace(/<(?:strong|b)[^>]*>(.*?)<\/(?:strong|b)>/gi, '**$1**')
|
|
52
|
+
.replace(/<(?:em|i)[^>]*>(.*?)<\/(?:em|i)>/gi, '*$1*')
|
|
53
|
+
// Remove remaining tags
|
|
54
|
+
.replace(/<[^>]+>/g, '')
|
|
55
|
+
// Decode HTML entities
|
|
56
|
+
.replace(/ /g, ' ')
|
|
57
|
+
.replace(/&/g, '&')
|
|
58
|
+
.replace(/</g, '<')
|
|
59
|
+
.replace(/>/g, '>')
|
|
60
|
+
.replace(/"/g, '"')
|
|
61
|
+
.replace(/'/g, "'")
|
|
62
|
+
// Clean multiple spaces
|
|
63
|
+
.replace(/\n\s*\n\s*\n/g, '\n\n')
|
|
64
|
+
.trim();
|
|
65
|
+
return { title, content };
|
|
66
|
+
}
|
|
67
|
+
// Generate content summary
|
|
68
|
+
function generateSummary(content, maxLength = 500) {
|
|
69
|
+
const lines = content.split('\n').filter(l => l.trim());
|
|
70
|
+
let summary = '';
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
if (summary.length + line.length > maxLength)
|
|
73
|
+
break;
|
|
74
|
+
if (!line.startsWith('#') && !line.startsWith('```')) {
|
|
75
|
+
summary += line + ' ';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return summary.trim().substring(0, maxLength) + (summary.length > maxLength ? '...' : '');
|
|
79
|
+
}
|
|
80
|
+
// Fetch and process web documentation
|
|
81
|
+
export async function fetchWebDocumentation(url, options = {}) {
|
|
82
|
+
// Check cache
|
|
83
|
+
if (webDocCache.has(url)) {
|
|
84
|
+
return webDocCache.get(url);
|
|
85
|
+
}
|
|
86
|
+
// Validate URL
|
|
87
|
+
try {
|
|
88
|
+
new URL(url);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
92
|
+
}
|
|
93
|
+
// Fetch content
|
|
94
|
+
const response = await fetch(url, {
|
|
95
|
+
headers: {
|
|
96
|
+
'User-Agent': 'StackGuide-MCP/1.0 (Documentation Fetcher)',
|
|
97
|
+
'Accept': 'text/html,application/xhtml+xml,text/plain,text/markdown'
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
const contentType = response.headers.get('content-type') || '';
|
|
104
|
+
let content;
|
|
105
|
+
let title;
|
|
106
|
+
if (contentType.includes('text/html')) {
|
|
107
|
+
const html = await response.text();
|
|
108
|
+
const extracted = extractMainContent(html);
|
|
109
|
+
content = extracted.content;
|
|
110
|
+
title = extracted.title;
|
|
111
|
+
}
|
|
112
|
+
else if (contentType.includes('text/markdown') || url.endsWith('.md')) {
|
|
113
|
+
content = await response.text();
|
|
114
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
115
|
+
title = titleMatch ? titleMatch[1] : new URL(url).pathname.split('/').pop() || 'Untitled';
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
content = await response.text();
|
|
119
|
+
title = new URL(url).pathname.split('/').pop() || 'Untitled';
|
|
120
|
+
}
|
|
121
|
+
const doc = {
|
|
122
|
+
id: `web-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
123
|
+
url,
|
|
124
|
+
title,
|
|
125
|
+
content,
|
|
126
|
+
summary: generateSummary(content),
|
|
127
|
+
fetchedAt: new Date().toISOString(),
|
|
128
|
+
projectType: options.projectType,
|
|
129
|
+
category: options.category,
|
|
130
|
+
tags: options.tags || []
|
|
131
|
+
};
|
|
132
|
+
// Save to cache
|
|
133
|
+
webDocCache.set(url, doc);
|
|
134
|
+
return doc;
|
|
135
|
+
}
|
|
136
|
+
// Fetch multiple URLs
|
|
137
|
+
export async function fetchMultipleDocuments(urls, options = {}) {
|
|
138
|
+
const results = await Promise.allSettled(urls.map(url => fetchWebDocumentation(url, options)));
|
|
139
|
+
const successful = [];
|
|
140
|
+
const failed = [];
|
|
141
|
+
results.forEach((result, index) => {
|
|
142
|
+
if (result.status === 'fulfilled') {
|
|
143
|
+
successful.push(result.value);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
failed.push({
|
|
147
|
+
url: urls[index],
|
|
148
|
+
error: result.reason?.message || 'Unknown error'
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return { successful, failed };
|
|
153
|
+
}
|
|
154
|
+
// Search in cached documents
|
|
155
|
+
export function searchWebDocuments(query) {
|
|
156
|
+
const results = [];
|
|
157
|
+
const queryLower = query.toLowerCase();
|
|
158
|
+
for (const doc of webDocCache.values()) {
|
|
159
|
+
if (doc.title.toLowerCase().includes(queryLower) ||
|
|
160
|
+
doc.content.toLowerCase().includes(queryLower) ||
|
|
161
|
+
doc.tags.some(t => t.toLowerCase().includes(queryLower))) {
|
|
162
|
+
results.push(doc);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return results;
|
|
166
|
+
}
|
|
167
|
+
// Get document by ID
|
|
168
|
+
export function getWebDocumentById(id) {
|
|
169
|
+
for (const doc of webDocCache.values()) {
|
|
170
|
+
if (doc.id === id)
|
|
171
|
+
return doc;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
// Get document by URL
|
|
176
|
+
export function getWebDocumentByUrl(url) {
|
|
177
|
+
return webDocCache.get(url) || null;
|
|
178
|
+
}
|
|
179
|
+
// List all cached documents
|
|
180
|
+
export function listCachedDocuments() {
|
|
181
|
+
return Array.from(webDocCache.values()).map(doc => ({
|
|
182
|
+
id: doc.id,
|
|
183
|
+
url: doc.url,
|
|
184
|
+
title: doc.title,
|
|
185
|
+
summary: doc.summary,
|
|
186
|
+
fetchedAt: doc.fetchedAt,
|
|
187
|
+
projectType: doc.projectType,
|
|
188
|
+
category: doc.category,
|
|
189
|
+
tags: doc.tags
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
// Clear cache
|
|
193
|
+
export function clearWebDocCache() {
|
|
194
|
+
webDocCache.clear();
|
|
195
|
+
}
|
|
196
|
+
// Remove document from cache
|
|
197
|
+
export function removeFromCache(urlOrId) {
|
|
198
|
+
if (webDocCache.has(urlOrId)) {
|
|
199
|
+
webDocCache.delete(urlOrId);
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
for (const [url, doc] of webDocCache.entries()) {
|
|
203
|
+
if (doc.id === urlOrId) {
|
|
204
|
+
webDocCache.delete(url);
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
// Popular documentation URLs by framework
|
|
211
|
+
export const POPULAR_DOCS = {
|
|
212
|
+
'python-django': [
|
|
213
|
+
{ name: 'Django Documentation', url: 'https://docs.djangoproject.com/en/stable/' },
|
|
214
|
+
{ name: 'Django REST Framework', url: 'https://www.django-rest-framework.org/' },
|
|
215
|
+
{ name: 'Django Best Practices', url: 'https://docs.djangoproject.com/en/stable/misc/design-philosophies/' }
|
|
216
|
+
],
|
|
217
|
+
'react-node': [
|
|
218
|
+
{ name: 'React Documentation', url: 'https://react.dev/learn' },
|
|
219
|
+
{ name: 'React Hooks', url: 'https://react.dev/reference/react' },
|
|
220
|
+
{ name: 'Node.js Documentation', url: 'https://nodejs.org/docs/latest/api/' },
|
|
221
|
+
{ name: 'Express.js Guide', url: 'https://expressjs.com/en/guide/routing.html' }
|
|
222
|
+
],
|
|
223
|
+
'nextjs': [
|
|
224
|
+
{ name: 'Next.js Documentation', url: 'https://nextjs.org/docs' },
|
|
225
|
+
{ name: 'Next.js App Router', url: 'https://nextjs.org/docs/app' },
|
|
226
|
+
{ name: 'Next.js API Routes', url: 'https://nextjs.org/docs/pages/building-your-application/routing/api-routes' }
|
|
227
|
+
],
|
|
228
|
+
'typescript': [
|
|
229
|
+
{ name: 'TypeScript Handbook', url: 'https://www.typescriptlang.org/docs/handbook/' },
|
|
230
|
+
{ name: 'TypeScript Deep Dive', url: 'https://basarat.gitbook.io/typescript/' }
|
|
231
|
+
]
|
|
232
|
+
};
|
|
233
|
+
// Get suggested documentation URLs
|
|
234
|
+
export function getSuggestedDocs(projectType) {
|
|
235
|
+
return POPULAR_DOCS[projectType] || [];
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=webDocumentation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webDocumentation.js","sourceRoot":"","sources":["../../src/services/webDocumentation.ts"],"names":[],"mappings":"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"}
|