@afterxleep/doc-bot 1.7.6 → 1.7.8
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/bin/doc-bot.js +2 -1
- package/package.json +1 -1
- package/prompts/search-results.txt +5 -4
- package/src/index.js +74 -8
package/bin/doc-bot.js
CHANGED
|
@@ -4,11 +4,12 @@ const { program } = require('commander');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs-extra');
|
|
6
6
|
const { DocsServer } = require('../src/index.js');
|
|
7
|
+
const packageJson = require('../package.json');
|
|
7
8
|
|
|
8
9
|
program
|
|
9
10
|
.name('doc-bot')
|
|
10
11
|
.description('Generic MCP server for intelligent documentation access')
|
|
11
|
-
.version(
|
|
12
|
+
.version(packageJson.version)
|
|
12
13
|
.option('-d, --docs <path>', 'Path to docs folder', 'doc-bot')
|
|
13
14
|
.option('-c, --config <path>', 'Path to manifest file')
|
|
14
15
|
.option('-v, --verbose', 'Enable verbose logging')
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 📋 DOCUMENTATION SEARCH RESULTS for "${query}"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Found ${resultCount} relevant document(s) (showing top 10):
|
|
4
4
|
|
|
5
5
|
${results}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
💡 **NEXT STEPS**: Use the `read_specific_document` tool with the file name to get the full content of any document above.
|
|
8
|
+
|
|
9
|
+
⚠️ **REMINDER**: Before implementing any code, use the `check_project_rules` tool to ensure compliance.
|
package/src/index.js
CHANGED
|
@@ -228,6 +228,20 @@ class DocsServer {
|
|
|
228
228
|
},
|
|
229
229
|
required: ['filePath']
|
|
230
230
|
}
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'read_specific_document',
|
|
234
|
+
description: 'Read the full content of a specific documentation file. Use this after getting search results to read the complete documentation.',
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
fileName: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'The file name of the document to read (e.g., "coding-standards.md")'
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
required: ['fileName']
|
|
244
|
+
}
|
|
231
245
|
}
|
|
232
246
|
]
|
|
233
247
|
};
|
|
@@ -297,6 +311,22 @@ class DocsServer {
|
|
|
297
311
|
}]
|
|
298
312
|
};
|
|
299
313
|
|
|
314
|
+
case 'read_specific_document':
|
|
315
|
+
const fileName = args?.fileName;
|
|
316
|
+
if (!fileName) {
|
|
317
|
+
throw new Error('fileName parameter is required');
|
|
318
|
+
}
|
|
319
|
+
const doc = this.docService.getDocument(fileName);
|
|
320
|
+
if (!doc) {
|
|
321
|
+
throw new Error(`Document not found: ${fileName}`);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
content: [{
|
|
325
|
+
type: 'text',
|
|
326
|
+
text: await this.formatSingleDocument(doc)
|
|
327
|
+
}]
|
|
328
|
+
};
|
|
329
|
+
|
|
300
330
|
default:
|
|
301
331
|
throw new Error(`Unknown tool: ${name}`);
|
|
302
332
|
}
|
|
@@ -339,34 +369,44 @@ class DocsServer {
|
|
|
339
369
|
return `No documentation found for query: "${query}"`;
|
|
340
370
|
}
|
|
341
371
|
|
|
372
|
+
// Limit to top 10 results for context efficiency
|
|
373
|
+
const topResults = results.slice(0, 10);
|
|
374
|
+
|
|
342
375
|
const template = await this.loadPromptTemplate('search-results');
|
|
343
376
|
if (!template) {
|
|
344
|
-
// Fallback to
|
|
377
|
+
// Fallback to concise format if template fails to load
|
|
345
378
|
let output = `# Search Results for "${query}"\n\n`;
|
|
346
|
-
output += `Found ${results.length} relevant document(s):\n\n`;
|
|
379
|
+
output += `Found ${results.length} relevant document(s) (showing top ${topResults.length}):\n\n`;
|
|
347
380
|
|
|
348
|
-
|
|
381
|
+
topResults.forEach((doc, index) => {
|
|
349
382
|
output += `## ${index + 1}. ${doc.metadata?.title || doc.fileName}\n`;
|
|
350
383
|
output += `**File:** ${doc.fileName}\n`;
|
|
351
384
|
if (doc.metadata?.description) {
|
|
352
385
|
output += `**Description:** ${doc.metadata.description}\n`;
|
|
353
386
|
}
|
|
354
|
-
|
|
387
|
+
if (doc.metadata?.keywords) {
|
|
388
|
+
output += `**Keywords:** ${Array.isArray(doc.metadata.keywords) ? doc.metadata.keywords.join(', ') : doc.metadata.keywords}\n`;
|
|
389
|
+
}
|
|
390
|
+
output += `**Relevance:** ${doc.relevanceScore?.toFixed(2) || 'N/A'}\n\n`;
|
|
355
391
|
});
|
|
356
392
|
|
|
357
|
-
output += '\n
|
|
393
|
+
output += '\n💡 **Next Steps:** Use the `read_specific_document` tool with the file name to get the full content of any document above.\n';
|
|
394
|
+
output += '⚠️ **Reminder:** Before implementing any code, use the `check_project_rules` tool to ensure compliance.\n';
|
|
358
395
|
return output;
|
|
359
396
|
}
|
|
360
397
|
|
|
361
|
-
// Format results for template
|
|
398
|
+
// Format results for template - concise format
|
|
362
399
|
let formattedResults = '';
|
|
363
|
-
|
|
400
|
+
topResults.forEach((doc, index) => {
|
|
364
401
|
formattedResults += `## ${index + 1}. ${doc.metadata?.title || doc.fileName}\n`;
|
|
365
402
|
formattedResults += `**File:** ${doc.fileName}\n`;
|
|
366
403
|
if (doc.metadata?.description) {
|
|
367
404
|
formattedResults += `**Description:** ${doc.metadata.description}\n`;
|
|
368
405
|
}
|
|
369
|
-
|
|
406
|
+
if (doc.metadata?.keywords) {
|
|
407
|
+
formattedResults += `**Keywords:** ${Array.isArray(doc.metadata.keywords) ? doc.metadata.keywords.join(', ') : doc.metadata.keywords}\n`;
|
|
408
|
+
}
|
|
409
|
+
formattedResults += `**Relevance:** ${doc.relevanceScore?.toFixed(2) || 'N/A'}\n\n`;
|
|
370
410
|
});
|
|
371
411
|
|
|
372
412
|
return template
|
|
@@ -518,6 +558,32 @@ class DocsServer {
|
|
|
518
558
|
.replace('${filePath}', filePath)
|
|
519
559
|
.replace('${docsContent}', docsContent);
|
|
520
560
|
}
|
|
561
|
+
|
|
562
|
+
async formatSingleDocument(doc) {
|
|
563
|
+
if (!doc) {
|
|
564
|
+
return 'Document not found';
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
let output = `# ${doc.metadata?.title || doc.fileName}\n\n`;
|
|
568
|
+
|
|
569
|
+
if (doc.metadata?.description) {
|
|
570
|
+
output += `**Description:** ${doc.metadata.description}\n\n`;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if (doc.metadata?.keywords) {
|
|
574
|
+
output += `**Keywords:** ${Array.isArray(doc.metadata.keywords) ? doc.metadata.keywords.join(', ') : doc.metadata.keywords}\n\n`;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (doc.metadata?.alwaysApply !== undefined) {
|
|
578
|
+
output += `**Always Apply:** ${doc.metadata.alwaysApply ? 'Yes (Global Rule)' : 'No (Contextual Rule)'}\n\n`;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
output += `**File:** ${doc.fileName}\n\n`;
|
|
582
|
+
output += '---\n\n';
|
|
583
|
+
output += doc.content;
|
|
584
|
+
|
|
585
|
+
return output;
|
|
586
|
+
}
|
|
521
587
|
|
|
522
588
|
async generateSystemPrompt() {
|
|
523
589
|
const globalRules = await this.docService.getGlobalRules();
|