@afterxleep/doc-bot 1.20.0 → 1.22.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +135 -140
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afterxleep/doc-bot",
3
- "version": "1.20.0",
3
+ "version": "1.22.0",
4
4
  "description": "Generic MCP server for intelligent documentation access in any project",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -364,13 +364,17 @@ class DocsServer {
364
364
  },
365
365
  {
366
366
  name: 'doc_bot',
367
- description: 'Your intelligent project assistant. Analyzes ANY request and provides smart routing to the right tools. ALWAYS call this first - it understands coding, documentation, architecture questions, and more.',
367
+ description: 'ALWAYS call this first for any task. Returns mandatory project standards (alwaysApply rules) that must be followed, plus a catalog of available documentation tools. Provides intelligent guidance while trusting your judgment on what additional context you need based on your familiarity with the codebase. Supports pagination for large rule sets.',
368
368
  inputSchema: {
369
369
  type: 'object',
370
370
  properties: {
371
371
  task: {
372
372
  type: 'string',
373
373
  description: 'What do you need help with? Examples: "create REST API", "understand auth flow", "document this pattern", "find database models"'
374
+ },
375
+ page: {
376
+ type: 'number',
377
+ description: 'Page number for paginated results (default: 1). Use this when the response indicates more pages are available.'
374
378
  }
375
379
  },
376
380
  required: ['task']
@@ -700,14 +704,17 @@ class DocsServer {
700
704
  }]
701
705
  };
702
706
 
703
- case 'doc_bot':
707
+ case 'doc_bot': {
704
708
  const assistantTask = args?.task || '';
709
+ const docBotPage = args?.page || 1;
710
+ const docBotMandatoryRules = await this.docService.getGlobalRules();
705
711
  return {
706
712
  content: [{
707
713
  type: 'text',
708
- text: this.getDocBotGuidance(assistantTask)
714
+ text: this.getIntelligentGatekeeperResponse(assistantTask, docBotMandatoryRules, docBotPage)
709
715
  }]
710
716
  };
717
+ }
711
718
 
712
719
  default:
713
720
  throw new Error(`Unknown tool: ${name}`);
@@ -1247,172 +1254,160 @@ Try:
1247
1254
  return output;
1248
1255
  }
1249
1256
 
1250
- getDocBotGuidance(task) {
1251
- // This is the intelligent guidance that replaces the complex AGENT_INTEGRATION_RULE
1252
- const taskLower = task.toLowerCase();
1253
-
1254
- let guidance = `# 🤖 DOC-BOT INTELLIGENT ASSISTANT\n\n`;
1255
- guidance += `**Your Request**: ${task}\n\n`;
1256
-
1257
+ getIntelligentGatekeeperResponse(task, mandatoryRules, page = 1) {
1257
1258
  // Check for administrative/management tasks first
1258
1259
  const isDocsetManagement = /add.*docset|remove.*docset|list.*docset|install.*docset/i.test(task);
1259
1260
  const isRuleManagement = /add.*rule|create.*rule|update.*rule|document.*pattern|capture.*pattern/i.test(task);
1260
1261
  const isDocumentManagement = /refresh.*doc|reload.*doc|index.*doc|get.*index/i.test(task);
1261
-
1262
- // Handle administrative tasks directly
1262
+
1263
+ // Handle administrative tasks with direct action guidance (no pagination needed)
1263
1264
  if (isDocsetManagement) {
1264
- guidance += `## 📦 DOCSET MANAGEMENT TASK DETECTED\n\n`;
1265
- guidance += `**Direct Actions Required**:\n`;
1266
-
1265
+ let guidance = `# 📦 Docset Management\n\n`;
1266
+
1267
1267
  if (/list/i.test(task)) {
1268
- guidance += `1. \`list_docsets()\` - Show all installed documentation sets\n\n`;
1268
+ guidance += `**Action**: \`list_docsets()\`\n\n`;
1269
+ guidance += `Shows all installed documentation sets with their IDs and metadata.\n`;
1269
1270
  } else if (/add|install/i.test(task)) {
1270
- guidance += `1. \`add_docset(source: "path/to/docset or URL")\` - Install new docset\n\n`;
1271
- guidance += `📝 **Examples**:\n`;
1271
+ guidance += `**Action**: \`add_docset(source: "path or URL")\`\n\n`;
1272
+ guidance += `**Examples**:\n`;
1272
1273
  guidance += `- Local: \`add_docset(source: "/Downloads/Swift.docset")\`\n`;
1273
- guidance += `- URL: \`add_docset(source: "https://example.com/React.docset.tgz")\`\n\n`;
1274
+ guidance += `- URL: \`add_docset(source: "https://example.com/React.docset.tgz")\`\n`;
1274
1275
  } else if (/remove/i.test(task)) {
1275
- guidance += `1. \`list_docsets()\` - First, get the docset ID\n`;
1276
- guidance += `2. \`remove_docset(docsetId: "the-id-from-step-1")\` - Remove the docset\n\n`;
1276
+ guidance += `**Steps**:\n`;
1277
+ guidance += `1. \`list_docsets()\` - Get the docset ID\n`;
1278
+ guidance += `2. \`remove_docset(docsetId: "id-from-step-1")\`\n`;
1277
1279
  }
1278
-
1279
- guidance += `💡 **Note**: This is an administrative task - no documentation search needed.\n`;
1280
+
1280
1281
  return guidance;
1281
1282
  }
1282
-
1283
+
1283
1284
  if (isRuleManagement) {
1284
- guidance += `## 📝 RULE/PATTERN MANAGEMENT TASK DETECTED\n\n`;
1285
- guidance += `**Direct Action Required**:\n`;
1286
- guidance += `1. \`create_or_update_rule(...)\` with these parameters:\n\n`;
1285
+ let guidance = `# 📝 Rule/Pattern Management\n\n`;
1286
+ guidance += `**Action**: \`create_or_update_rule(...)\`\n\n`;
1287
+ guidance += `**Parameters**:\n`;
1287
1288
  guidance += `\`\`\`javascript\n`;
1288
1289
  guidance += `{\n`;
1289
1290
  guidance += ` fileName: "descriptive-name.md",\n`;
1290
- guidance += ` title: "Clear title for the rule/pattern",\n`;
1291
+ guidance += ` title: "Clear title for the rule",\n`;
1291
1292
  guidance += ` content: "Full markdown documentation",\n`;
1292
- guidance += ` alwaysApply: true/false, // true = global, false = contextual\n`;
1293
- guidance += ` keywords: ["relevant", "search", "terms"],\n`;
1293
+ guidance += ` alwaysApply: true, // true = mandatory (like CLAUDE.md)\n`;
1294
+ guidance += ` // false = contextual (found via search)\n`;
1295
+ guidance += ` keywords: ["search", "terms"],\n`;
1294
1296
  guidance += ` description: "Brief summary" // optional\n`;
1295
1297
  guidance += `}\n`;
1296
- guidance += `\`\`\`\n\n`;
1297
- guidance += `💡 **Note**: This captures project knowledge permanently - no search needed.\n`;
1298
+ guidance += `\`\`\`\n`;
1298
1299
  return guidance;
1299
1300
  }
1300
-
1301
+
1301
1302
  if (isDocumentManagement) {
1302
- guidance += `## 🔄 DOCUMENTATION MANAGEMENT TASK DETECTED\n\n`;
1303
- guidance += `**Direct Action Required**:\n`;
1304
-
1303
+ let guidance = `# 🔄 Documentation Management\n\n`;
1304
+
1305
1305
  if (/refresh|reload/i.test(task)) {
1306
- guidance += `1. \`refresh_documentation()\` - Reload all docs from disk\n\n`;
1306
+ guidance += `**Action**: \`refresh_documentation()\`\n\n`;
1307
+ guidance += `Reloads all documentation from disk and rebuilds search indexes.\n`;
1307
1308
  } else {
1308
- guidance += `1. \`get_document_index()\` - List all available documentation\n\n`;
1309
+ guidance += `**Action**: \`get_document_index()\`\n\n`;
1310
+ guidance += `Lists all available documentation files with metadata.\n`;
1309
1311
  }
1310
-
1311
- guidance += `💡 **Note**: This is an administrative task - direct execution only.\n`;
1312
+
1312
1313
  return guidance;
1313
1314
  }
1314
-
1315
- // Analyze the task and provide intelligent routing for non-administrative tasks
1316
- if (taskLower.includes('create') || taskLower.includes('implement') || taskLower.includes('build') ||
1317
- taskLower.includes('write') || taskLower.includes('add') || taskLower.includes('code') ||
1318
- taskLower.includes('function') || taskLower.includes('class') || taskLower.includes('component')) {
1319
- guidance += `## 💻 CODE GENERATION TASK DETECTED\n\n`;
1320
- guidance += `**MANDATORY Steps (in order)**:\n`;
1321
- guidance += `1. FIRST: \`check_project_rules("${task}")\` - Get critical coding standards\n`;
1322
- guidance += `2. 🔍 SEARCH for existing patterns:\n`;
1323
-
1324
- // Extract likely search terms
1325
- const searchTerms = this.extractSearchTerms(task);
1326
- searchTerms.forEach(term => {
1327
- guidance += ` - \`search_documentation("${term}")\`\n`;
1328
- });
1329
-
1330
- guidance += `3. 📚 EXPLORE: If APIs found, use \`explore_api()\` for complete details\n`;
1331
- guidance += `4. IMPLEMENT: Generate code following ALL discovered patterns\n\n`;
1332
- guidance += `⚠️ **CRITICAL**: Never skip step 1 - project rules are mandatory!\n\n`;
1333
- } else if (taskLower.includes('how') || taskLower.includes('what') || taskLower.includes('why') ||
1334
- taskLower.includes('understand') || taskLower.includes('explain') || taskLower.includes('architecture')) {
1335
- guidance += `## 🔍 KNOWLEDGE/UNDERSTANDING TASK DETECTED\n\n`;
1336
- guidance += `**Recommended Flow**:\n`;
1337
- guidance += `1. 📖 START with searches for technical terms:\n`;
1338
-
1339
- const searchTerms = this.extractSearchTerms(task);
1340
- searchTerms.forEach(term => {
1341
- guidance += ` - \`search_documentation("${term}")\`\n`;
1342
- });
1343
-
1344
- guidance += `2. 📋 CONTEXT: \`get_global_rules()\` for project philosophy\n`;
1345
- guidance += `3. 📄 DETAILS: Use \`read_specific_document()\` on relevant results\n`;
1346
- guidance += `4. 🔬 DEEP DIVE: \`explore_api()\` for framework/class details\n\n`;
1347
- } else if (taskLower.includes('document') || taskLower.includes('capture') || taskLower.includes('learned') ||
1348
- taskLower.includes('pattern') || taskLower.includes('convention')) {
1349
- guidance += `## 📝 DOCUMENTATION TASK DETECTED\n\n`;
1350
- guidance += `**To capture new knowledge**:\n`;
1351
- guidance += `Use \`create_or_update_rule()\` with:\n`;
1352
- guidance += `- fileName: descriptive-name.md\n`;
1353
- guidance += `- title: Clear, searchable title\n`;
1354
- guidance += `- content: Full markdown documentation\n`;
1355
- guidance += `- alwaysApply: true/false (is this a global rule?)\n\n`;
1356
- } else if (taskLower.includes('file') || taskLower.includes('working on') || taskLower.includes('modify')) {
1357
- guidance += `## 📁 FILE-SPECIFIC TASK DETECTED\n\n`;
1358
- guidance += `**File Context Flow**:\n`;
1359
- guidance += `1. 📂 GET CONTEXT: \`get_file_docs("${task}")\` for file-specific patterns\n`;
1360
- guidance += `2. 🔍 SEARCH: Look for related components/patterns\n`;
1361
- guidance += `3. ✅ CHECK: \`check_project_rules()\` before modifications\n\n`;
1362
- } else {
1363
- guidance += `## 🎯 GENERAL TASK GUIDANCE\n\n`;
1364
- guidance += `**Intelligent Routing Based on Your Request**:\n`;
1365
- guidance += `1. 🏁 START: \`get_global_rules()\` - Understand the project\n`;
1366
- guidance += `2. 🔍 DISCOVER: \`search_documentation()\` with key terms from your request\n`;
1367
- guidance += `3. 📋 REQUIREMENTS: \`check_project_rules("${task}")\` if generating any output\n`;
1368
- guidance += `4. 📚 EXPLORE: \`explore_api()\` for any frameworks/APIs mentioned\n\n`;
1315
+
1316
+ // For coding/general tasks: Use smart pagination for mandatory rules
1317
+ const TOKEN_LIMIT = 24000; // Keep under 25K with buffer for tool catalog
1318
+ const toolCatalog = this.getToolCatalog(task);
1319
+ const toolCatalogTokens = TokenEstimator.estimateTokens(toolCatalog);
1320
+
1321
+ // Reserve tokens for tool catalog and headers
1322
+ const availableTokensForRules = TOKEN_LIMIT - toolCatalogTokens - 500;
1323
+
1324
+ // Format rules with pagination
1325
+ const formatRuleContent = (rules) => {
1326
+ let content = `# Mandatory Project Standards\n\n`;
1327
+
1328
+ if (!rules || rules.length === 0) {
1329
+ content += `*No mandatory rules defined for this project.*\n\n`;
1330
+ } else {
1331
+ content += `These rules apply to ALL code in this project:\n\n`;
1332
+ rules.forEach((rule, index) => {
1333
+ content += `## ${index + 1}. ${rule.metadata?.title || rule.fileName}\n\n`;
1334
+ content += `${rule.content}\n\n`;
1335
+ if (index < rules.length - 1) {
1336
+ content += `---\n\n`;
1337
+ }
1338
+ });
1339
+ }
1340
+
1341
+ return content;
1342
+ };
1343
+
1344
+ // Use smart pagination service
1345
+ const paginatedResult = this.paginationService.smartPaginate(
1346
+ mandatoryRules || [],
1347
+ formatRuleContent,
1348
+ page,
1349
+ availableTokensForRules
1350
+ );
1351
+
1352
+ let response = paginatedResult.content;
1353
+
1354
+ // Add pagination info if there are multiple pages
1355
+ if (paginatedResult.hasMore) {
1356
+ response += `\n---\n\n`;
1357
+ response += `📄 **Page ${paginatedResult.page} of ${paginatedResult.totalPages}**\n\n`;
1358
+ response += `⚠️ **More mandatory rules available**: Call \`doc_bot(task: "${task}", page: ${paginatedResult.page + 1})\` to see the next page.\n\n`;
1359
+ response += `💡 You must review ALL pages before proceeding to ensure compliance with all project standards.\n\n`;
1369
1360
  }
1370
-
1371
- guidance += `## 🔑 Search Tips for Maximum Effectiveness:\n\n`;
1372
- guidance += `✅ **DO**: Search for class names, API names, technical terms\n`;
1373
- guidance += ` Examples: "Widget", "URLSession", "Authentication", "CoreData"\n\n`;
1374
- guidance += `❌ **DON'T**: Search with questions or descriptions\n`;
1375
- guidance += ` Avoid: "how to create", "new features", "iOS 18 widgets"\n\n`;
1376
- guidance += `🎯 **Best Practice**: Think like you're searching an API index, not Google!\n\n`;
1377
- guidance += `## 💡 Remember:\n`;
1378
- guidance += `- Project documentation ALWAYS overrides general knowledge\n`;
1379
- guidance += `- When in doubt, search first\n`;
1380
- guidance += `- Use \`explore_api()\` after finding relevant APIs\n`;
1381
- guidance += `- Document new patterns with \`create_or_update_rule()\`\n`;
1382
-
1383
- return guidance;
1361
+
1362
+ // Add tool catalog
1363
+ response += toolCatalog;
1364
+
1365
+ return response;
1384
1366
  }
1385
-
1386
- extractSearchTerms(task) {
1387
- // Extract potential API/class names from the task
1388
- const terms = [];
1389
-
1390
- // Common patterns to extract
1391
- const patterns = {
1392
- 'widget': ['Widget', 'WidgetKit'],
1393
- 'auth': ['Authentication', 'Auth', 'Login'],
1394
- 'database': ['Database', 'CoreData', 'SQLite'],
1395
- 'network': ['URLSession', 'Network', 'API'],
1396
- 'cache': ['Cache', 'Caching', 'Redis'],
1397
- 'ui': ['UIKit', 'SwiftUI', 'View'],
1398
- 'react': ['React', 'Component', 'Hook'],
1399
- 'api': ['API', 'REST', 'GraphQL'],
1400
- 'test': ['Test', 'Jest', 'XCTest']
1401
- };
1402
-
1403
- const taskLower = task.toLowerCase();
1404
- Object.keys(patterns).forEach(key => {
1405
- if (taskLower.includes(key)) {
1406
- terms.push(...patterns[key]);
1407
- }
1408
- });
1409
-
1410
- // Also extract capitalized words as potential class names
1411
- const capitalizedWords = task.match(/[A-Z][a-zA-Z]+/g) || [];
1412
- terms.push(...capitalizedWords);
1413
-
1414
- // Remove duplicates and limit to 3-4 terms
1415
- return [...new Set(terms)].slice(0, 4);
1367
+
1368
+ getToolCatalog(task) {
1369
+ let catalog = `---\n\n`;
1370
+ catalog += `## Additional Documentation Tools Available\n\n`;
1371
+ catalog += `You have access to these tools for finding contextual information:\n\n`;
1372
+
1373
+ catalog += `**\`search_documentation(query)\`**\n`;
1374
+ catalog += `- Search project docs for patterns, examples, conventions\n`;
1375
+ catalog += `- Use when: You need to understand how something is implemented in this codebase\n`;
1376
+ catalog += `- Examples: \`search_documentation("authentication")\`, \`search_documentation("validation")\`\n`;
1377
+ catalog += `- Tip: Use technical terms (class names, API names), not descriptions\n\n`;
1378
+
1379
+ catalog += `**\`get_file_docs(filePath)\`**\n`;
1380
+ catalog += `- Get file-specific or directory-specific documentation\n`;
1381
+ catalog += `- Use when: Working with specific files and need conventions for that area\n`;
1382
+ catalog += `- Examples: \`get_file_docs("src/components/Auth.tsx")\`, \`get_file_docs("services/**")\`\n\n`;
1383
+
1384
+ catalog += `**\`explore_api(apiName)\`**\n`;
1385
+ catalog += `- Deep-dive into framework/API documentation (all methods, properties, examples)\n`;
1386
+ catalog += `- Use when: Using frameworks or APIs you're unfamiliar with\n`;
1387
+ catalog += `- Examples: \`explore_api("URLSession")\`, \`explore_api("React.Component")\`\n\n`;
1388
+
1389
+ catalog += `**\`read_specific_document(fileName)\`**\n`;
1390
+ catalog += `- Read full content of a specific documentation file\n`;
1391
+ catalog += `- Use when: Search results show a relevant doc and you need complete details\n`;
1392
+ catalog += `- Examples: \`read_specific_document("api-patterns.md")\`\n\n`;
1393
+
1394
+ catalog += `**\`get_global_rules()\`**\n`;
1395
+ catalog += `- Get complete project philosophy and engineering principles\n`;
1396
+ catalog += `- Use when: Making architectural decisions or need comprehensive context\n\n`;
1397
+
1398
+ catalog += `---\n\n`;
1399
+ catalog += `## Your Task: "${task}"\n\n`;
1400
+ catalog += `**You now have:**\n`;
1401
+ catalog += `✅ Mandatory project standards (above)\n`;
1402
+ catalog += `✅ Tools to explore codebase-specific patterns (listed above)\n\n`;
1403
+
1404
+ catalog += `**Your decision:**\n`;
1405
+ catalog += `- If you understand how to implement this correctly with the standards above → proceed\n`;
1406
+ catalog += `- If you need to understand existing patterns in this codebase → use the tools above\n\n`;
1407
+
1408
+ catalog += `Remember: You know the codebase context best. Use additional tools only if you need them.\n`;
1409
+
1410
+ return catalog;
1416
1411
  }
1417
1412
 
1418
1413
  async createOrUpdateRule({ fileName, title, description, keywords, alwaysApply, content }) {