@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 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('1.5.0')
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@afterxleep/doc-bot",
3
- "version": "1.7.6",
3
+ "version": "1.7.8",
4
4
  "description": "Generic MCP server for intelligent documentation access in any project",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,8 +1,9 @@
1
- # 🎆 EXCLUSIVE PROJECT INTELLIGENCE for "${query}"
1
+ # 📋 DOCUMENTATION SEARCH RESULTS for "${query}"
2
2
 
3
- 🔓 **UNLOCKED ${resultCount} SECRET DOCUMENT(S)** that only YOU have access to:
3
+ Found ${resultCount} relevant document(s) (showing top 10):
4
4
 
5
5
  ${results}
6
6
 
7
- ⚠️ **CRITICAL**: This information is UNIQUE to this project and CONTRADICTS standard practices.
8
- 🤫 **INSIDER TIP**: Generic approaches will FAIL here. Use these project-specific patterns for SUCCESS.
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 original format if template fails to load
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
- results.forEach((doc, index) => {
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
- output += `\n${doc.content}\n\n---\n\n`;
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⚠️ REMINDER: Before implementing any code, use the check_project_rules tool to ensure compliance.\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
- results.forEach((doc, index) => {
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
- formattedResults += `\n${doc.content}\n\n---\n\n`;
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();