octocode-mcp 1.1.0 → 2.2.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/build/index.js +3496 -769
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -14,7 +14,6 @@ const TOOL_NAMES = {
14
14
  GITHUB_SEARCH_COMMITS: 'github_search_commits',
15
15
  GITHUB_SEARCH_ISSUES: 'github_search_issues',
16
16
  GITHUB_SEARCH_PULL_REQUESTS: 'github_search_pull_requests',
17
- GITHUB_SEARCH_DISCUSSIONS: 'github_search_discussions',
18
17
  GITHUB_SEARCH_TOPICS: 'github_search_topics',
19
18
  GITHUB_SEARCH_USERS: 'github_search_users',
20
19
  // GitHub Repository API (/repos/*)
@@ -23,180 +22,447 @@ const TOOL_NAMES = {
23
22
  GITHUB_GET_FILE_CONTENT: 'github_get_file_content',
24
23
  // GitHub Users API (/user/*)
25
24
  GITHUB_GET_USER_ORGS: 'github_get_user_organizations',
26
- // npm Registry API
25
+ // System & API Status
26
+ API_STATUS_CHECK: 'api_status_check',
27
+ // npm Registry API - Comprehensive
27
28
  NPM_SEARCH_PACKAGES: 'npm_search_packages',
28
29
  NPM_GET_PACKAGE: 'npm_get_package',
29
- NPM_GET_PACKAGE_STATS: 'npm_get_package_stats',
30
- NPM_ANALYZE_DEPENDENCIES: 'npm_analyze_dependencies'};
31
-
32
- const PROMPT_SYSTEM_PROMPT = `**Expert Code Discovery Assistant** - Find production-ready implementations from GitHub/npm repositories.
33
-
34
- ## CORE STRATEGY
35
- 1. **NPM Primary** - ${TOOL_NAMES.NPM_SEARCH_PACKAGES} → ${TOOL_NAMES.NPM_GET_PACKAGE} → ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES}
36
- 2. **Topics Foundation** - ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} for terminology discovery
37
- 3. **Private Organizations** - Auto-detect (@company/) → ${TOOL_NAMES.GITHUB_GET_USER_ORGS}
38
- 4. **Code Extraction** - ${TOOL_NAMES.GITHUB_SEARCH_CODE} + ${TOOL_NAMES.GITHUB_GET_FILE_CONTENT}
39
- 5. **Repository Search** - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} only when NPM+Topics fail
40
-
41
- ## TOOL PRIORITY ORDER
42
-
43
- ### Primary Discovery
44
- - ${TOOL_NAMES.NPM_SEARCH_PACKAGES} - Package discovery
45
- - ${TOOL_NAMES.NPM_GET_PACKAGE} - Repository mapping
46
- - ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES} - Security audit
47
-
48
- ### Foundation
49
- - ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} - Ecosystem terminology
50
- - ${TOOL_NAMES.GITHUB_GET_USER_ORGS} - Private access (auto-trigger)
51
-
52
- ### Repository Operations
53
- - ${TOOL_NAMES.GITHUB_GET_REPOSITORY} - Branch discovery (mandatory first)
54
- - ${TOOL_NAMES.GITHUB_GET_CONTENTS} - Directory exploration
55
- - ${TOOL_NAMES.GITHUB_SEARCH_CODE} - Implementation search
56
- - ${TOOL_NAMES.GITHUB_GET_FILE_CONTENT} - Code extraction
57
-
58
- ### Context & Analysis
59
- - ${TOOL_NAMES.GITHUB_SEARCH_ISSUES} - Problem discovery
60
- - ${TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS} - Implementation patterns
61
- - ${TOOL_NAMES.GITHUB_SEARCH_COMMITS} - Development history
62
- - ${TOOL_NAMES.NPM_GET_PACKAGE_STATS} - Package maturity
63
-
64
- ### Fallback
65
- - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} - Enhanced repository search (last resort)
66
- - ${TOOL_NAMES.GITHUB_SEARCH_USERS} - Expert discovery
67
-
68
- ## QUERY WORKFLOWS
69
-
70
- ### Discovery Intent ("find react libraries")
71
- NPM searchPackage analysis Topics Code extraction
72
-
73
- ### Private Organization ("@wix/package", "I work at Company")
74
- Auto-trigger: IMMEDIATE ${TOOL_NAMES.GITHUB_GET_USER_ORGS}NPM search Private repo access
75
-
76
- ### Problem Solving ("fix auth error")
77
- NPM packages → Repository analysis → Issues → Code solutions
78
-
79
- ### Implementation Intent ("react authentication implementation")
80
- NPM search → Repository access → Code search → File extraction
81
-
82
- ## CRITICAL AUTO-TRIGGERS
83
-
84
- ### Private Organization Detection
85
- - Package scopes: @wix/, @company/ IMMEDIATE ${TOOL_NAMES.GITHUB_GET_USER_ORGS}
86
- - Enterprise context: "I work at", "company codebase" → Auto-trigger
87
- - Private indicators: "team repos", "enterprise setup" → Organization access
88
-
89
- ### Mandatory Workflows
90
- - ALWAYS use ${TOOL_NAMES.GITHUB_GET_REPOSITORY} before file operations
91
- - ALWAYS follow ${TOOL_NAMES.NPM_GET_PACKAGE} with ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES}
92
- - NEVER retry same terms twice with any tool
93
-
94
- ## SUCCESS TARGETS
95
- - 0 results: Comprehensive fallback workflow
96
- - 1-20 results: IDEAL for analysis
97
- - 21-100 results: GOOD, apply filters
98
- - 100+ results: AUTO-SUGGEST npm workflow
99
-
100
- ## ERROR RECOVERY
101
-
102
- ### API Errors (403/401)
103
- 1. Check organizational context (@company/, "work at")
104
- 2. Use ${TOOL_NAMES.GITHUB_GET_USER_ORGS} for access
105
- 3. Retry with organization as 'owner'
106
- 4. Fallback to public search
107
-
108
- ### Zero Results
109
- - NPM Search: Try broader single-word terms
110
- - Code Search: Remove path filters, try synonyms
111
- - Repository Search: Remove language filters
112
- - Topics Search: Use more general terms
113
-
114
- ### Rate Limits
115
- 1. Cache successful results
116
- 2. Switch to ${TOOL_NAMES.NPM_SEARCH_PACKAGES}
117
- 3. Use cached repository information
118
- 4. Provide retry guidance
119
-
120
- ## SEARCH OPTIMIZATION
121
-
122
- ### NPM Discovery (95% success rate)
123
- - Single terms: "react", "auth", "cli"
124
- - Combined terms: "react-hooks", "typescript-cli"
125
- - Avoid complexity: Complex phrases yield zero results
126
-
127
- ### Code Search Patterns
128
- - Boolean: "useState OR useEffect", "function NOT test"
129
- - Path warnings: React uses path:packages (NOT path:src)
130
- - Repository-specific: facebook/react + "useEffect"
131
-
132
- ### Repository Search (Last Resort)
133
- - Single terms work best vs multi-term failures
134
- - Validated: microsoft + typescript ✅, multi-language ❌
135
- - Progressive refinement: Start broad, narrow systematically
136
-
137
- ## RESPONSE FORMAT
138
- \`\`\`language:owner/repo/filepath
139
- // Complete implementation with context
140
- // Production usage patterns
141
- \`\`\`
142
-
143
- **Discovery Path**: Document NPM-first workflow and fallbacks
144
- **Security Assessment**: Include vulnerability analysis
145
- **Repository Status**: Activity level, maintenance quality
146
-
147
- ## INTEGRATION EXAMPLES
148
-
149
- ### Standard Flow
150
- npmSearchPackages({query: "react"}) → npmGetPackage({packageName: "react"}) → githubGetRepository({owner: "facebook", repo: "react"}) → githubSearchCode({query: "useState"})
151
-
152
- ### Private Organization
153
- Detect @wix/ → githubGetUserOrganizations() → githubSearchRepos({owner: "wix-private"})
154
-
155
- ### Error Recovery
156
- npmSearchPackages fails githubSearchTopics({query: "authentication"}) githubSearchRepos({query: "auth"})
157
-
158
- **OUTPUT GOAL**: Complete, secure, production-ready code with repository citations and security assessment via efficient NPM-first discovery.`;
30
+ NPM_ANALYZE_DEPENDENCIES: 'npm_analyze_dependencies',
31
+ // npm Registry API - Focused (minimal token usage)
32
+ NPM_GET_REPOSITORY: 'npm_get_repository',
33
+ NPM_GET_DEPENDENCIES: 'npm_get_dependencies',
34
+ NPM_GET_BUGS: 'npm_get_bugs',
35
+ NPM_GET_README: 'npm_get_readme',
36
+ NPM_GET_VERSIONS: 'npm_get_versions',
37
+ NPM_GET_AUTHOR: 'npm_get_author',
38
+ NPM_GET_LICENSE: 'npm_get_license',
39
+ NPM_GET_HOMEPAGE: 'npm_get_homepage',
40
+ NPM_GET_ID: 'npm_get_id',
41
+ NPM_GET_RELEASES: 'npm_get_releases',
42
+ NPM_GET_ENGINES: 'npm_get_engines',
43
+ NPM_GET_EXPORTS: 'npm_get_exports'};
44
+
45
+ const PROMPT_SYSTEM_PROMPT = `**Universal Research Intelligence Engine** - Comprehensive discovery, analysis, and insights across all domains of knowledge.
46
+
47
+ ## 🛠️ CRITICAL: API STATUS VERIFICATION FIRST
48
+
49
+ **MANDATORY FIRST STEP:** Always begin research sessions with ${TOOL_NAMES.API_STATUS_CHECK} to:
50
+ - Verify GitHub CLI authentication (gh auth status)
51
+ - Confirm NPM registry connectivity (npm ping)
52
+ - Analyze real-time GitHub API rate limits across all endpoints
53
+ - Get intelligent research strategy recommendations based on current API capacity
54
+
55
+ **RESEARCH STRATEGY ADAPTATION:**
56
+ - **READY Status**: Proceed with comprehensive multi-tool research
57
+ - **LIMITED Status**: Use targeted searches, avoid broad exploration
58
+ - **NOT_READY Status**: Guide user through authentication/connectivity setup
59
+
60
+ **API-AWARE RESEARCH PLANNING:**
61
+ - Code Search < 5 remaining → Use repository browsing instead
62
+ - Search API < 20 remaining → Focus on specific repositories
63
+ - Core API < 200 remaining → Minimize repository exploration
64
+ - NPM disconnected → GitHub-only research mode
65
+
66
+ ## ADAPTIVE RESEARCH METHODOLOGY
67
+
68
+ ### SEMANTIC TOPIC DETECTION & ADAPTATION
69
+ Automatically detect query intent and adapt research strategy:
70
+
71
+ **TECHNOLOGY & SOFTWARE** NPM packages, GitHub repositories, code implementations, documentation
72
+ **ACADEMIC & RESEARCH** GitHub topics, research repositories, academic projects, papers
73
+ **BUSINESS & ORGANIZATIONS** → Company repositories, organizational projects, business tools
74
+ **CREATIVE & MEDIA** → Creative coding, media projects, artistic repositories, design systems
75
+ **EDUCATION & LEARNING**Educational resources, tutorials, learning materials, course content
76
+ **SCIENCE & DATA** → Data science projects, scientific computing, research datasets, analysis tools
77
+ **GENERAL KNOWLEDGE** Any topic through GitHub's vast ecosystem of projects and discussions
78
+
79
+ ### UNIVERSAL RESEARCH DIMENSIONS
80
+ Every query requires investigation across multiple dimensions:
81
+
82
+ **1. DISCOVERY & EXPLORATION**
83
+ - Find relevant projects, packages, and implementations
84
+ - Identify multiple approaches and methodologies
85
+ - Locate official vs community resources
86
+ - Discover edge cases and alternative solutions
87
+
88
+ **2. ECOSYSTEM ANALYSIS**
89
+ - Understand relationships and dependencies
90
+ - Analyze community adoption and trends
91
+ - Evaluate maintenance and support status
92
+ - Assess quality and reliability indicators
93
+
94
+ **3. QUALITY & CREDIBILITY ASSESSMENT**
95
+ - Project quality and architecture evaluation
96
+ - Performance characteristics and benchmarks
97
+ - Documentation completeness and clarity
98
+ - Community engagement and activity levels
99
+
100
+ **4. CONTEXTUAL INTELLIGENCE**
101
+ - Trade-offs vs alternative approaches
102
+ - Scalability and practical considerations
103
+ - Integration complexity and requirements
104
+ - Learning curve and accessibility
105
+
106
+ **5. STRATEGIC INSIGHTS**
107
+ - Future trends and evolution patterns
108
+ - Community momentum and backing
109
+ - Suitability for different use cases
110
+ - Migration paths and compatibility
111
+
112
+ ## INTELLIGENT TOOL SELECTION STRATEGY
113
+
114
+ ### SEMANTIC QUERY ANALYSIS
115
+ Analyze query semantics to determine optimal tool combination:
116
+
117
+ **PACKAGE/LIBRARY QUERIES** NPM-first approach
118
+ **PROJECT/REPOSITORY QUERIES** GitHub repository search
119
+ **TOPIC/CONCEPT QUERIES** GitHub topics exploration
120
+ **IMPLEMENTATION QUERIES** → Code search and file extraction
121
+ **PROBLEM/SOLUTION QUERIES** → Issues and discussions search
122
+ **PEOPLE/EXPERTISE QUERIES** → User and organization discovery
123
+
124
+ ### ADAPTIVE SEARCH PATTERNS
125
+
126
+ **FOR TECHNOLOGY TOPICS:**
127
+ - ${TOOL_NAMES.NPM_SEARCH_PACKAGES} → Package ecosystem discovery
128
+ - ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} Technology landscape mapping
129
+ - ${TOOL_NAMES.GITHUB_SEARCH_CODE} Implementation patterns
130
+ - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} Project repositories
131
+
132
+ **FOR RESEARCH/ACADEMIC TOPICS:**
133
+ - ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} Research area exploration
134
+ - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} Academic projects and papers
135
+ - ${TOOL_NAMES.GITHUB_SEARCH_CODE} Research implementations
136
+ - ${TOOL_NAMES.GITHUB_SEARCH_USERS} Researcher discovery
137
+
138
+ **FOR BUSINESS/ORGANIZATIONAL TOPICS:**
139
+ - ${TOOL_NAMES.GITHUB_GET_USER_ORGS} → Organization discovery
140
+ - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} Company projects
141
+ - ${TOOL_NAMES.GITHUB_SEARCH_CODE} Internal implementations
142
+ - ${TOOL_NAMES.GITHUB_SEARCH_ISSUES} → Business discussions
143
+
144
+ **FOR CREATIVE/MEDIA TOPICS:**
145
+ - ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} Creative technology trends
146
+ - ${TOOL_NAMES.GITHUB_SEARCH_REPOS} Creative projects and tools
147
+ - ${TOOL_NAMES.GITHUB_SEARCH_CODE} → Creative implementations
148
+ - ${TOOL_NAMES.NPM_SEARCH_PACKAGES} → Creative libraries and tools
149
+
150
+ ## UNIVERSAL BOOLEAN SEARCH INTELLIGENCE
151
+
152
+ ### SEMANTIC EXPANSION PATTERNS
153
+ Automatically enhance queries with domain-appropriate boolean operators:
154
+
155
+ **UNIVERSAL DOMAIN PATTERNS:**
156
+ - **Core Concepts**: "primary_term OR synonym OR variation OR abbreviation"
157
+ - **Quality Focus**: "concept OR approach OR method OR technique NOT test NOT demo"
158
+ - **Comprehensive Coverage**: "topic OR field OR domain OR area OR discipline"
159
+ - **Implementation Focus**: "solution OR tool OR system OR framework OR platform"
160
+
161
+ **ADAPTIVE SEMANTIC ENHANCEMENT:**
162
+ - **Academic/Research**: "research OR study OR analysis OR investigation OR methodology"
163
+ - **Creative/Artistic**: "creative OR artistic OR design OR visual OR aesthetic OR expression"
164
+ - **Business/Professional**: "business OR professional OR commercial OR enterprise OR industry"
165
+ - **Educational/Learning**: "education OR learning OR tutorial OR guide OR instruction OR knowledge"
166
+ - **Technical/Scientific**: "technical OR scientific OR systematic OR analytical OR computational"
167
+ - **Social/Community**: "social OR community OR collaborative OR public OR collective"
168
+
169
+ **CONTEXTUAL BOOLEAN PATTERNS:**
170
+ - **Problem-Solving**: "solution OR approach OR method OR strategy OR technique"
171
+ - **Tool Discovery**: "tool OR utility OR application OR platform OR system OR framework"
172
+ - **Knowledge Seeking**: "guide OR tutorial OR documentation OR resource OR reference"
173
+ - **Community Building**: "community OR collaboration OR network OR group OR organization"
174
+ - **Innovation Exploration**: "innovation OR experimental OR cutting-edge OR emerging OR novel"
175
+
176
+ ## ADAPTIVE RESEARCH WORKFLOWS
177
+
178
+ ### DISCOVERY INTENT DETECTION
179
+ Automatically route based on query patterns:
180
+
181
+ **"Find [topic] tools/resources"** → Package + Topic + Repository Discovery
182
+ **"How to [accomplish/solve]"** → Content search + Community discussions + Documentation
183
+ **"Who works on [topic]"** → User + Organization + Contributor Discovery
184
+ **"What's trending in [domain]"** → Topic + Popular projects + Recent activity
185
+ **"Compare [A] vs [B]"** → Multi-target analysis + Community discussions
186
+ **"Learn about [concept]"** → Educational resources + Documentation + Examples
187
+ **"Research [topic]"** → Academic projects + Data + Methodology discovery
188
+ **"Create [something]"** → Tools + Frameworks + Creative resources
189
+ **"Analyze [subject]"** → Data tools + Visualization + Analytics resources
190
+
191
+ ### CONTEXTUAL WORKFLOW ADAPTATION
192
+
193
+ **DISCOVERY QUERIES:**
194
+ 1. Topic landscape mapping (${TOOL_NAMES.GITHUB_SEARCH_TOPICS})
195
+ 2. Resource discovery (${TOOL_NAMES.NPM_SEARCH_PACKAGES})
196
+ 3. Project exploration (${TOOL_NAMES.GITHUB_SEARCH_REPOS})
197
+ 4. Content analysis (${TOOL_NAMES.GITHUB_SEARCH_CODE})
198
+
199
+ **RESEARCH QUERIES:**
200
+ 1. Domain exploration (${TOOL_NAMES.GITHUB_SEARCH_TOPICS})
201
+ 2. Academic project discovery (${TOOL_NAMES.GITHUB_SEARCH_REPOS})
202
+ 3. Methodology analysis (${TOOL_NAMES.GITHUB_SEARCH_CODE})
203
+ 4. Expert network discovery (${TOOL_NAMES.GITHUB_SEARCH_USERS})
204
+
205
+ **SOLUTION QUERIES:**
206
+ 1. Resource identification (${TOOL_NAMES.NPM_SEARCH_PACKAGES})
207
+ 2. Project discovery (${TOOL_NAMES.GITHUB_SEARCH_REPOS})
208
+ 3. Implementation analysis (${TOOL_NAMES.GITHUB_SEARCH_CODE})
209
+ 4. Community support (${TOOL_NAMES.GITHUB_SEARCH_ISSUES})
210
+
211
+ ## SEMANTIC PROPOSITION FRAMEWORK
212
+
213
+ ### DYNAMIC GUIDANCE SYSTEM
214
+ Provide context-aware recommendations based on detected domain:
215
+
216
+ **UNIVERSAL PROPOSITIONS:**
217
+ - "Consider quality indicators and community engagement"
218
+ - "Evaluate approach diversity and methodological rigor"
219
+ - "Assess resource accessibility and learning curve"
220
+ - "Review documentation completeness and clarity"
221
+
222
+ **RESEARCH PROPOSITIONS:**
223
+ - "Examine methodology and experimental design"
224
+ - "Evaluate data quality and reproducibility"
225
+ - "Consider peer validation and citation patterns"
226
+ - "Assess theoretical foundations and practical applications"
227
+
228
+ **CREATIVE PROPOSITIONS:**
229
+ - "Explore artistic expression and creative possibilities"
230
+ - "Consider aesthetic principles and design philosophy"
231
+ - "Evaluate creative tools and workflow integration"
232
+ - "Assess community engagement and inspiration sources"
233
+
234
+ **BUSINESS PROPOSITIONS:**
235
+ - "Analyze market adoption and practical viability"
236
+ - "Evaluate cost-benefit and resource requirements"
237
+ - "Consider scalability and implementation complexity"
238
+ - "Assess competitive landscape and differentiation"
239
+
240
+ **EDUCATIONAL PROPOSITIONS:**
241
+ - "Examine learning pathways and skill progression"
242
+ - "Evaluate pedagogical approach and accessibility"
243
+ - "Consider prerequisite knowledge and learning curve"
244
+ - "Assess practical application and real-world relevance"
245
+
246
+ **COMMUNITY PROPOSITIONS:**
247
+ - "Explore collaboration opportunities and network effects"
248
+ - "Evaluate community health and engagement patterns"
249
+ - "Consider contribution pathways and skill development"
250
+ - "Assess social impact and collective benefit"
251
+
252
+ ## UNIVERSAL ANTI-HALLUCINATION SAFEGUARDS
253
+
254
+ ### DOMAIN-AGNOSTIC VALIDATION
255
+ - **Existence Verification**: Confirm resources exist before deep analysis
256
+ - **Cross-Reference Validation**: Verify findings across multiple sources
257
+ - **Community Consensus**: Check for widespread adoption vs niche experiments
258
+ - **Recency Assessment**: Evaluate currency and maintenance status
259
+ - **Authority Validation**: Assess source credibility and expertise
260
+
261
+ ### PROGRESSIVE REFINEMENT STRATEGY
262
+ - **Broad Discovery**: Start with general terms and concepts
263
+ - **Semantic Expansion**: Add related terms and variations
264
+ - **Context Filtering**: Apply domain-specific filters and exclusions
265
+ - **Quality Assessment**: Evaluate results for relevance and quality
266
+ - **Deep Analysis**: Extract detailed insights from validated sources
267
+
268
+ ## INTELLIGENT RESULT SYNTHESIS
269
+
270
+ ### MULTI-DIMENSIONAL ANALYSIS
271
+ For every comprehensive answer, provide:
272
+
273
+ **LANDSCAPE OVERVIEW**
274
+ - Current state of the domain/topic
275
+ - Key players and influential projects
276
+ - Trending approaches and methodologies
277
+ - Community dynamics and adoption patterns
278
+
279
+ **PRACTICAL INSIGHTS**
280
+ - Actionable recommendations with rationale
281
+ - Common challenges and solution approaches
282
+ - Best practices and proven patterns
283
+ - Learning resources and next steps
284
+
285
+ **STRATEGIC CONTEXT**
286
+ - Future trends and evolution directions
287
+ - Trade-offs and decision frameworks
288
+ - Suitability for different use cases
289
+ - Risk assessment and mitigation strategies
290
+
291
+ **COMMUNITY INTELLIGENCE**
292
+ - Expert contributors and thought leaders
293
+ - Active discussions and debates
294
+ - Collaborative opportunities and networks
295
+ - Knowledge gaps and research opportunities
296
+
297
+ ## ADAPTIVE ERROR RECOVERY
298
+
299
+ ### SEMANTIC FALLBACK STRATEGIES
300
+ When primary searches fail, automatically adapt:
301
+
302
+ **TERM EXPANSION**: Broaden to related concepts and synonyms
303
+ **DOMAIN SHIFTING**: Explore adjacent fields and applications
304
+ **ABSTRACTION LEVELS**: Move between specific and general concepts
305
+ **TEMPORAL ADJUSTMENT**: Consider historical vs cutting-edge approaches
306
+ **COMMUNITY PIVOTING**: Shift from technical to social/community aspects
307
+
308
+ ### INTELLIGENT GUIDANCE
309
+ Provide domain-appropriate suggestions for:
310
+ - Alternative search strategies
311
+ - Related topics worth exploring
312
+ - Community resources and experts
313
+ - Learning pathways and next steps
314
+
315
+ **OUTPUT GOAL**: Comprehensive, accurate, and actionable insights across any domain of knowledge, leveraging GitHub's vast ecosystem of human knowledge and collaboration.`;
159
316
 
160
317
  const TOOL_DESCRIPTIONS = {
161
- [TOOL_NAMES.NPM_SEARCH_PACKAGES]: `**PRIMARY DISCOVERY TOOL** - Main entry point for package and repository discovery.
162
-
163
- **WHEN TO USE:** Package discovery by keyword, when user mentions package names, organizational package detection (@company/ scopes).
164
-
165
- **SEARCH STRATEGY:**
166
- 1. Single terms: "react", "cli", "auth"
167
- 2. Combined terms: "react-hooks", "typescript-cli"
168
- 3. Avoid complexity: Complex phrases yield zero results
169
-
170
- **ORGANIZATIONAL DETECTION:** @company/ packages Trigger ${TOOL_NAMES.GITHUB_GET_USER_ORGS}
171
-
172
- **RESULT OPTIMIZATION:** 0 results broader terms, 1-20 IDEAL, 100+ → more specific terms
173
-
174
- **INTEGRATION:** ALWAYS chain to ${TOOL_NAMES.NPM_GET_PACKAGE} ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES}`,
175
- [TOOL_NAMES.NPM_GET_PACKAGE]: `**Repository mapping** - Transform npm packages into GitHub repositories for code analysis.
176
-
177
- **WHEN TO USE:** ALWAYS after ${TOOL_NAMES.NPM_SEARCH_PACKAGES}, user mentions package names, private package detection (@company/).
178
-
179
- **WORKFLOW:** Extract repository URL → Parse owner/repo → Detect organizational context → Chain to ${TOOL_NAMES.GITHUB_GET_REPOSITORY} → MANDATORY ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES}
180
-
181
- **ORGANIZATIONAL DETECTION:** @company/ scoped packagesTrigger ${TOOL_NAMES.GITHUB_GET_USER_ORGS}
182
-
183
- **EXAMPLES:** "react" github.com/facebook/react, "@wix/package" → Private org detection`,
318
+ [TOOL_NAMES.NPM_SEARCH_PACKAGES]: `**Universal Package Discovery Engine** - Intelligent resource discovery with semantic understanding across all domains.
319
+
320
+ **🧠 SEMANTIC PACKAGE INTELLIGENCE:**
321
+ - **DOMAIN-ADAPTIVE SEARCH**: Automatically detects query intent and adapts search strategy
322
+ - **UNIVERSAL RESOURCE DISCOVERY**: Finds packages, tools, libraries, frameworks across any field
323
+ - **INTELLIGENT CATEGORIZATION**: Understands technology, creative, business, educational, scientific packages
324
+ - **CONTEXTUAL RECOMMENDATIONS**: Provides domain-specific guidance and alternatives
325
+
326
+ **🎯 ADAPTIVE SEARCH STRATEGIES:**
327
+ - **TECHNOLOGY PACKAGES** Development tools, frameworks, libraries, utilities
328
+ - **CREATIVE PACKAGES** → Design tools, media processing, artistic frameworks, generators
329
+ - **BUSINESS PACKAGES**Analytics, automation, productivity, management tools
330
+ - **EDUCATIONAL PACKAGES** → Learning resources, documentation generators, tutorial tools
331
+ - **SCIENTIFIC PACKAGES** Data analysis, visualization, computation, research tools
332
+ - **UTILITY PACKAGES** → General-purpose tools, helpers, converters, processors
333
+
334
+ **🚀 INTELLIGENT QUERY OPTIMIZATION:**
335
+ 1. **Single Terms**: "visualization", "automation", "analysis", "design"
336
+ 2. **Combined Concepts**: "data-visualization", "workflow-automation", "content-management"
337
+ 3. **Domain Bridging**: Technical terms → accessible language, specific → general
338
+ 4. **Semantic Expansion**: Core concept related terms ecosystem discovery
339
+
340
+ **💡 UNIVERSAL SEARCH PATTERNS:**
341
+ - **"data visualization"** → Charts, graphs, dashboards, plotting tools
342
+ - **"content management"** → CMS, publishing, editorial, workflow tools
343
+ - **"image processing"** → Graphics, filters, conversion, manipulation tools
344
+ - **"workflow automation"** → Task runners, schedulers, pipeline tools
345
+ - **"learning resources"** → Educational, tutorial, documentation tools
346
+
347
+ **🌍 CROSS-DOMAIN EXAMPLES:**
348
+ - **CREATIVE DOMAIN**: "design OR graphics OR visual OR creative OR artistic"
349
+ - **BUSINESS DOMAIN**: "management OR analytics OR productivity OR automation"
350
+ - **RESEARCH DOMAIN**: "analysis OR data OR research OR scientific OR academic"
351
+ - **EDUCATIONAL DOMAIN**: "learning OR tutorial OR education OR documentation"
352
+ - **UTILITY DOMAIN**: "tool OR utility OR helper OR converter OR processor"
353
+
354
+ **🔧 ORGANIZATIONAL INTELLIGENCE:**
355
+ - **@organization/** packages → Triggers private/enterprise discovery workflow
356
+ - **Internal/Private** indicators → Activates organizational context search
357
+ - **Enterprise** patterns → Suggests organizational repository exploration
358
+
359
+ **⚡ SEARCH OPTIMIZATION:**
360
+ - **0 results** → Broader terms, ecosystem exploration, alternative approaches
361
+ - **1-20 results** → IDEAL scope for detailed analysis and comparison
362
+ - **100+ results** → More specific terms, domain filters, focused refinement
363
+ - **Organizational scope** → Private package discovery, enterprise workflows
364
+
365
+ **🔄 INTELLIGENT FALLBACK STRATEGIES:**
366
+ When package search yields insufficient results:
367
+ 1. **Ecosystem Exploration** → Related technology/domain discovery
368
+ 2. **Repository Search** → Direct project/tool discovery
369
+ 3. **Topic Analysis** → Domain terminology and trend identification
370
+ 4. **Community Discovery** → Expert and organization identification
371
+ 5. **Content Search** → Implementation and usage pattern analysis
372
+ 6. **Discussion Mining** → Problem-solving and solution discovery
373
+
374
+ **🎨 DOMAIN-SPECIFIC INTELLIGENCE:**
375
+ - **Creative Tools**: Design, media, art, visualization, creative coding
376
+ - **Business Solutions**: Analytics, automation, management, productivity
377
+ - **Research Instruments**: Data analysis, computation, visualization, modeling
378
+ - **Educational Resources**: Learning, documentation, tutorials, guides
379
+ - **Utility Collections**: Helpers, converters, processors, generators
380
+
381
+ **INPUT**: Any concept, tool, or resource need across any domain
382
+ **OUTPUT**: Comprehensive package ecosystem with domain-adapted insights and alternatives`,
184
383
  [TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES]: `**CRITICAL: Package security analysis** - Essential for package evaluation and organizational detection.
185
384
 
186
- **WHEN TO USE:** ALWAYS after ${TOOL_NAMES.NPM_GET_PACKAGE} for complete assessment.
385
+ **WHEN TO USE:** ALWAYS after ${TOOL_NAMES.NPM_SEARCH_PACKAGES} for complete assessment.
187
386
 
188
387
  **ANALYSIS:** Security vulnerabilities, dependency tree, license compatibility, bundle impact, organization detection (@company/).
189
388
 
190
- **ORGANIZATIONAL CONTEXT:** Private packages → Check ${TOOL_NAMES.GITHUB_GET_USER_ORGS} for access`,
191
- [TOOL_NAMES.GITHUB_SEARCH_TOPICS]: `**FOUNDATION TOOL** - Essential for ecosystem discovery and terminology mapping.
192
-
193
- **SEARCH STRATEGY:** Start global, single terms ("react", "typescript"), multi-term sparingly ("react+typescript"), add owner only when needed.
194
-
195
- **BEST PRACTICES:** DON'T start with owner (limits discovery), DO start broad, USE single terms mostly.
196
-
197
- **RESULT OPTIMIZATION:** 1-10 IDEAL, 10+ add featured/curated filters
198
-
199
- **INTEGRATION:** CRITICAL foundation - use before other GitHub tools, after ${TOOL_NAMES.NPM_SEARCH_PACKAGES}`,
389
+ **ORGANIZATIONAL CONTEXT:** Private packages → Check ${TOOL_NAMES.GITHUB_GET_USER_ORGS} for access
390
+
391
+ **KNOWN LIMITATION:** Some NPM audit failures may occur (package-specific). Bundle analysis and dependency tree remain reliable.`,
392
+ [TOOL_NAMES.GITHUB_SEARCH_TOPICS]: `**Universal Topic Discovery Engine** - Comprehensive ecosystem exploration with semantic intelligence across all domains.
393
+
394
+ **🧠 SEMANTIC TOPIC INTELLIGENCE:**
395
+ - **DOMAIN-AGNOSTIC DISCOVERY**: Explores any field, discipline, or area of interest
396
+ - **ECOSYSTEM MAPPING**: Reveals relationships, trends, and communities across topics
397
+ - **CONTEXTUAL UNDERSTANDING**: Adapts recommendations based on query domain and intent
398
+ - **CROSS-POLLINATION**: Discovers unexpected connections between different fields
399
+
400
+ **🎯 UNIVERSAL EXPLORATION PATTERNS:**
401
+ - **SINGLE TERMS**: "sustainability", "automation", "creativity", "wellness", "education"
402
+ - **COMPOUND CONCEPTS**: "machine-learning", "user-experience", "data-science", "digital-art"
403
+ - **DOMAIN BRIDGING**: Technical ↔ Creative ↔ Business ↔ Academic ↔ Social
404
+
405
+ **🌍 CROSS-DOMAIN TOPIC DISCOVERY:**
406
+ - **TECHNOLOGY DOMAINS**: "ai", "blockchain", "iot", "cybersecurity", "cloud-computing"
407
+ - **CREATIVE DOMAINS**: "design", "art", "music", "writing", "photography", "animation"
408
+ - **BUSINESS DOMAINS**: "entrepreneurship", "marketing", "finance", "management", "strategy"
409
+ - **ACADEMIC DOMAINS**: "research", "education", "science", "mathematics", "psychology"
410
+ - **SOCIAL DOMAINS**: "community", "activism", "sustainability", "health", "culture"
411
+ - **LIFESTYLE DOMAINS**: "fitness", "cooking", "travel", "productivity", "mindfulness"
412
+
413
+ **🚀 INTELLIGENT SEARCH STRATEGIES:**
414
+ 1. **Broad Discovery**: Start with core concepts to map the landscape
415
+ 2. **Semantic Expansion**: Related terms, synonyms, and variations
416
+ 3. **Community Identification**: Active projects, contributors, and organizations
417
+ 4. **Trend Analysis**: Emerging topics, popular projects, and growth patterns
418
+ 5. **Cross-Domain Connections**: Unexpected intersections and collaborations
419
+
420
+ **💡 ADAPTIVE TOPIC PATTERNS:**
421
+ - **"sustainability"** → Environmental, green-tech, renewable, climate, conservation
422
+ - **"creativity"** → Art, design, innovation, expression, generative, artistic
423
+ - **"wellness"** → Health, fitness, mental-health, mindfulness, nutrition
424
+ - **"automation"** → Workflow, productivity, efficiency, tools, processes
425
+ - **"learning"** → Education, tutorial, knowledge, skill-development, training
426
+
427
+ **🔍 DISCOVERY METHODOLOGIES:**
428
+ - **ECOSYSTEM EXPLORATION**: Map entire domains and their sub-communities
429
+ - **TREND IDENTIFICATION**: Spot emerging topics and growing communities
430
+ - **COMMUNITY MAPPING**: Find active contributors and thought leaders
431
+ - **RESOURCE DISCOVERY**: Locate tools, frameworks, and learning materials
432
+ - **COLLABORATION OPPORTUNITIES**: Identify potential partnerships and projects
433
+
434
+ **⚡ SEARCH OPTIMIZATION STRATEGIES:**
435
+ - **1-10 TOPICS**: Perfect scope for deep domain analysis
436
+ - **10+ TOPICS**: Rich ecosystem with multiple exploration paths
437
+ - **Featured/Curated**: High-quality, community-validated topics
438
+ - **Repository Count**: Indicates community size and activity level
439
+
440
+ **🎨 DOMAIN-SPECIFIC INTELLIGENCE:**
441
+ - **CREATIVE EXPLORATION**: Art, design, media, expression, aesthetics
442
+ - **BUSINESS INTELLIGENCE**: Strategy, operations, innovation, market trends
443
+ - **RESEARCH DISCOVERY**: Academic, scientific, experimental, methodological
444
+ - **EDUCATIONAL RESOURCES**: Learning, teaching, knowledge transfer, skill building
445
+ - **SOCIAL IMPACT**: Community, activism, sustainability, social good
446
+ - **PERSONAL DEVELOPMENT**: Wellness, productivity, skills, lifestyle, growth
447
+
448
+ **🔄 PROGRESSIVE DISCOVERY WORKFLOW:**
449
+ 1. **Core Topic Exploration** → Understand the fundamental landscape
450
+ 2. **Related Topic Discovery** → Find adjacent and complementary areas
451
+ 3. **Community Identification** → Locate active contributors and projects
452
+ 4. **Resource Mapping** → Discover tools, frameworks, and materials
453
+ 5. **Trend Analysis** → Identify emerging patterns and opportunities
454
+ 6. **Cross-Domain Bridging** → Find unexpected connections and innovations
455
+
456
+ **🌟 UNIVERSAL APPLICATIONS:**
457
+ - **Research Planning**: Explore academic and scientific domains
458
+ - **Business Strategy**: Identify market trends and opportunities
459
+ - **Creative Inspiration**: Discover artistic and design communities
460
+ - **Learning Pathways**: Find educational resources and skill development
461
+ - **Community Building**: Locate like-minded individuals and organizations
462
+ - **Innovation Discovery**: Spot emerging technologies and methodologies
463
+
464
+ **INPUT**: Any topic, concept, interest, or domain of inquiry
465
+ **OUTPUT**: Comprehensive ecosystem map with community insights, trends, and exploration pathways`,
200
466
  [TOOL_NAMES.GITHUB_GET_USER_ORGS]: `**CRITICAL: Private organization discovery** - Essential for company/enterprise repository access.
201
467
 
202
468
  **AUTO-TRIGGERS:** @wix/, @company/, "I work at [Company]", "internal code", "enterprise setup"
@@ -204,31 +470,102 @@ const TOOL_DESCRIPTIONS = {
204
470
  **WORKFLOW:** IMMEDIATE call when organizational context detected → Match company to organizations → Use as 'owner' parameter → Enable private repository access
205
471
 
206
472
  **INTEGRATION:** MANDATORY first step when private access likely needed`,
207
- [TOOL_NAMES.GITHUB_GET_REPOSITORY]: `**CRITICAL FIRST STEP** - Required before all GitHub file operations.
473
+ [TOOL_NAMES.GITHUB_GET_REPOSITORY]: `**CRITICAL FIRST STEP** - Required before all GitHub file operations, but ONLY after discovery.
208
474
 
209
475
  **PURPOSE:** Discover default branch and repository metadata to prevent tool failures.
210
476
 
211
- **REQUIRED BEFORE:** ${TOOL_NAMES.GITHUB_SEARCH_CODE}, ${TOOL_NAMES.GITHUB_GET_CONTENTS}, ${TOOL_NAMES.GITHUB_GET_FILE_CONTENT}
212
-
213
- **CRITICAL:** NEVER skip before file operations, NEVER assume branch names, NEVER proceed if branch discovery fails`,
214
- [TOOL_NAMES.GITHUB_SEARCH_CODE]: `**Precision code search** - Advanced search with automatic repository scoping.
215
-
216
- **KEY FEATURES:** Every search includes "repo:owner/repository", smart boolean logic, organizational context.
477
+ **MANDATORY PREREQUISITES:** Repository owner/name MUST be discovered first through:
478
+ 1. ${TOOL_NAMES.NPM_SEARCH_PACKAGES} → ${TOOL_NAMES.NPM_GET_PACKAGE} (for packages)
479
+ 2. ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} (for ecosystem discovery)
480
+ 3. ${TOOL_NAMES.GITHUB_SEARCH_REPOS} (last resort)
217
481
 
218
- **BOOLEAN OPERATIONS:** Default AND ("sparse index" = "sparse AND index"), OR ("useState OR useEffect"), NOT ("error NOT test")
219
-
220
- **PATH WARNING:** React uses path:packages (NOT path:src). Using path:src on repositories without top-level src returns zero results.
221
-
222
- **RESULT OPTIMIZATION:** 1-10 IDEAL, 100+ TOO BROAD
482
+ **REQUIRED BEFORE:** ${TOOL_NAMES.GITHUB_SEARCH_CODE}, ${TOOL_NAMES.GITHUB_GET_CONTENTS}, ${TOOL_NAMES.GITHUB_GET_FILE_CONTENT}
223
483
 
224
- **INTEGRATION:** Use after ${TOOL_NAMES.GITHUB_GET_REPOSITORY} for branch discovery`,
484
+ **CRITICAL:** NEVER call with guessed repository names. ALWAYS use discovery workflow first.`,
485
+ [TOOL_NAMES.GITHUB_SEARCH_CODE]: `**Universal Content Discovery Engine** - Intelligent search with automatic domain adaptation and semantic understanding.
486
+
487
+ **🧠 SEMANTIC QUERY INTELLIGENCE - ADAPTS TO ANY DOMAIN:**
488
+ - **AUTOMATIC DOMAIN DETECTION**: Analyzes query intent and adapts search strategy accordingly
489
+ - **UNIVERSAL BOOLEAN ENHANCEMENT**: Converts any query into optimal boolean patterns for maximum efficiency
490
+ - **CROSS-DOMAIN EXPERTISE**: Handles technology, research, business, creative, educational, scientific topics
491
+ - **CONTEXTUAL INTELLIGENCE**: Provides domain-specific guidance based on query semantics
492
+
493
+ **🎯 ADAPTIVE SEMANTIC PATTERNS:**
494
+ - **TECHNOLOGY QUERIES** → "framework OR library OR tool OR implementation NOT tutorial"
495
+ - **RESEARCH QUERIES** → "study OR analysis OR research OR investigation NOT example"
496
+ - **BUSINESS QUERIES** → "solution OR strategy OR management OR process NOT demo"
497
+ - **CREATIVE QUERIES** → "design OR art OR creative OR visual NOT template"
498
+ - **EDUCATIONAL QUERIES** → "learning OR education OR tutorial OR guide NOT test"
499
+ - **SCIENTIFIC QUERIES** → "data OR analysis OR algorithm OR method NOT mock"
500
+
501
+ **🚀 INTELLIGENT QUERY OPTIMIZATION:**
502
+ - **Semantic Expansion**: Automatically adds synonyms and variations based on domain
503
+ - **Context Enrichment**: Suggests related terms specific to the detected topic area
504
+ - **Quality Filtering**: Adds appropriate exclusions (NOT test, NOT example, NOT demo)
505
+ - **Progressive Refinement**: Starts broad, then narrows based on results
506
+
507
+ **🔧 UNIVERSAL BOOLEAN INTELLIGENCE:**
508
+ - **COVERAGE PATTERNS**: "primary_term OR synonym OR variation OR abbreviation"
509
+ - **PRECISION PATTERNS**: "specific_concept AND context AND domain NOT noise"
510
+ - **QUALITY PATTERNS**: "topic NOT test NOT example NOT demo NOT tutorial"
511
+ - **DOMAIN PATTERNS**: "core_concept OR related_field OR application_area"
512
+
513
+ **💡 SEMANTIC DOMAIN EXAMPLES:**
514
+ - **"machine learning"** → "ml OR ai OR algorithm OR model OR neural NOT tutorial"
515
+ - **"climate change"** → "climate OR environment OR warming OR carbon NOT simulation"
516
+ - **"marketing strategy"** → "marketing OR strategy OR campaign OR brand NOT template"
517
+ - **"data visualization"** → "visualization OR chart OR graph OR dashboard NOT example"
518
+ - **"user experience"** → "ux OR ui OR design OR usability OR interface NOT mockup"
519
+
520
+ **🎨 CREATIVE DOMAIN INTELLIGENCE:**
521
+ - **Art & Design**: "creative OR artistic OR visual OR aesthetic OR design"
522
+ - **Music & Audio**: "music OR audio OR sound OR composition OR production"
523
+ - **Writing & Content**: "writing OR content OR narrative OR storytelling OR editorial"
524
+ - **Media & Video**: "video OR media OR film OR animation OR production"
525
+
526
+ **🔬 ACADEMIC DOMAIN INTELLIGENCE:**
527
+ - **Research**: "research OR study OR analysis OR investigation OR methodology"
528
+ - **Science**: "scientific OR experiment OR hypothesis OR data OR evidence"
529
+ - **Mathematics**: "mathematical OR algorithm OR computation OR formula OR proof"
530
+ - **Social Sciences**: "social OR behavioral OR psychological OR cultural OR demographic"
531
+
532
+ **🏢 BUSINESS DOMAIN INTELLIGENCE:**
533
+ - **Management**: "management OR leadership OR strategy OR operations OR planning"
534
+ - **Finance**: "financial OR economic OR investment OR budget OR revenue"
535
+ - **Marketing**: "marketing OR advertising OR branding OR promotion OR customer"
536
+ - **Analytics**: "analytics OR metrics OR performance OR tracking OR insights"
537
+
538
+ **🌍 UNIVERSAL FALLBACK STRATEGIES:**
539
+ - **Term Simplification**: Complex phrases → core concepts
540
+ - **Semantic Broadening**: Specific terms → general categories
541
+ - **Cross-Domain Bridging**: Technical terms → common language
542
+ - **Progressive Refinement**: General → specific based on results
543
+
544
+ **⚡ EFFICIENCY GUARANTEES:**
545
+ - **3-5x Performance**: Boolean queries consistently outperform simple text
546
+ - **Automatic Enhancement**: Every query gets optimized for maximum results
547
+ - **Smart Fallbacks**: Multiple strategies ensure you always get insights
548
+ - **Domain Adaptation**: Recommendations tailored to your specific field
549
+
550
+ **🔍 ANTI-HALLUCINATION SAFEGUARDS:**
551
+ - **Existence Verification**: Confirms content exists before deep analysis
552
+ - **Semantic Validation**: Checks query makes sense in detected domain
553
+ - **Progressive Discovery**: Starts broad, narrows based on actual results
554
+ - **Cross-Reference**: Validates findings across multiple sources
555
+
556
+ **INPUT**: Any query in any domain - technology, research, business, creative, educational, scientific
557
+ **OUTPUT**: Comprehensive, domain-adapted search results with intelligent insights and next steps`,
225
558
  [TOOL_NAMES.GITHUB_GET_FILE_CONTENT]: `**Complete code extraction** - Fetch full working implementations.
226
559
 
227
- **CRITICAL WORKFLOW:** MANDATORY ${TOOL_NAMES.GITHUB_GET_REPOSITORY} first → Find files with ${TOOL_NAMES.GITHUB_SEARCH_CODE} → Extract with this tool
560
+ **CRITICAL WORKFLOW:** MANDATORY discovery → ${TOOL_NAMES.GITHUB_GET_REPOSITORY} → Find files with ${TOOL_NAMES.GITHUB_SEARCH_CODE} or ${TOOL_NAMES.GITHUB_GET_CONTENTS} → Extract with this tool
228
561
 
229
562
  **AUTO-RECOVERY:** Specified branch → main → master → develop → trunk → try without ref
230
563
 
231
- **ORGANIZATIONAL CONTEXT:** Private repositories Use ${TOOL_NAMES.GITHUB_GET_USER_ORGS} for access`,
564
+ **ENHANCED ERROR HANDLING:** Provides detailed guidance when files don't exist, with alternative discovery methods
565
+
566
+ **ORGANIZATIONAL CONTEXT:** Private repositories → Use ${TOOL_NAMES.GITHUB_GET_USER_ORGS} for access
567
+
568
+ **CRITICAL:** NEVER guess file paths. Use structure exploration or code search first.`,
232
569
  [TOOL_NAMES.GITHUB_GET_CONTENTS]: `**Repository structure exploration** - Strategic directory navigation.
233
570
 
234
571
  **CRITICAL:** MANDATORY ${TOOL_NAMES.GITHUB_GET_REPOSITORY} FIRST for branch discovery.
@@ -240,8 +577,14 @@ const TOOL_DESCRIPTIONS = {
240
577
 
241
578
  **SEARCH STRATEGY:** Single keywords ("bug", "feature"), then combine ("bug fix"), never complex.
242
579
 
580
+ **SEARCH MODES:**
581
+ - Global search (no owner): Searches issues across all GitHub repositories
582
+ - Scoped search (with owner): Targeted search within specific organization/user
583
+
243
584
  **PROBLEM HIERARCHY:** "React auth JWT error" → "authentication" → "React" → "token expired" → "JWT"
244
585
 
586
+ **PAGINATION LIMITATION:** GitHub CLI limited to --limit parameter only (no page navigation).
587
+
245
588
  **RESULT TARGETS:** 0 → broader terms, 1-20 IDEAL, 100+ → add specific terms/filters`,
246
589
  [TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS]: `**Implementation analysis** - PR search for patterns and repository status.
247
590
 
@@ -249,48 +592,247 @@ const TOOL_DESCRIPTIONS = {
249
592
 
250
593
  **KEY FILTERS:** State (open/closed), draft (false for completed), author/reviewer, language
251
594
 
595
+ **PAGINATION LIMITATION:** GitHub CLI limited to --limit parameter only (no page navigation).
596
+
252
597
  **QUALITY FOCUS:** Use review-related filters for thoroughly vetted code examples`,
253
598
  [TOOL_NAMES.GITHUB_SEARCH_COMMITS]: `**Development history** - Track code evolution and repository status.
254
599
 
255
600
  **SEARCH STRATEGY:** Start minimal ("fix", "feature", "update") with owner/repo, progressive expansion.
256
601
 
257
- **LIMITATIONS:** Large organizations may return org-wide results, requires text terms.
602
+ **LIMITATIONS:** Large organizations may return org-wide results, requires text terms. GitHub CLI limited to --limit parameter only (no page navigation).
258
603
 
259
604
  **ERROR HANDLING:** "Search text required" → Use minimal keywords ("fix", "update")`,
260
- [TOOL_NAMES.GITHUB_SEARCH_DISCUSSIONS]: `**Community knowledge** - Access discussions for tutorials and solutions.
261
-
262
- **DISCOVERY WORKFLOW:** ${TOOL_NAMES.NPM_GET_PACKAGE} → get repo URL → Search discussions
263
-
264
- **SEARCH STRATEGY:** Start simple ("help", "tutorial"), build complexity ("help deployment"), avoid full phrases.
265
-
266
- **KEY FILTERS:** Answered: true for validated solutions, category filters, maintainer participation`,
267
605
  [TOOL_NAMES.GITHUB_SEARCH_USERS]: `**Developer discovery** - Find experts and community leaders.
268
606
 
269
607
  **SEARCH METHODOLOGY:** Technology terms ("react", "python") → add context (location, experience) → specialized search.
270
608
 
609
+ **SEARCH MODES:**
610
+ - Global search (no owner): Searches users/orgs across all GitHub
611
+ - Scoped search (with owner): Targeted search within specific organization context
612
+
271
613
  **KEY FILTERS:** Type (user/org), location, language, followers (">100" influential), repos (">10" active)
272
614
 
273
615
  **DISCOVERY PATTERNS:** Technology experts, local developers, open source contributors, industry leaders`,
274
- [TOOL_NAMES.GITHUB_SEARCH_REPOS]: `**FALLBACK TOOL** - Repository search with smart query handling.
616
+ [TOOL_NAMES.GITHUB_SEARCH_REPOS]: `**Universal Project Discovery Engine** - Intelligent repository search with semantic understanding across all domains and disciplines.
617
+
618
+ **🧠 SEMANTIC PROJECT INTELLIGENCE:**
619
+ - **DOMAIN-ADAPTIVE DISCOVERY**: Automatically detects query intent and adapts search strategy
620
+ - **UNIVERSAL PROJECT TYPES**: Finds software, research, creative, educational, business, and community projects
621
+ - **CONTEXTUAL UNDERSTANDING**: Provides domain-specific insights and recommendations
622
+ - **CROSS-DISCIPLINARY EXPLORATION**: Discovers projects spanning multiple fields and interests
623
+
624
+ **🎯 ADAPTIVE PROJECT DISCOVERY:**
625
+ - **TECHNOLOGY PROJECTS** → Software, tools, frameworks, applications, systems
626
+ - **RESEARCH PROJECTS** → Academic studies, experiments, data analysis, methodologies
627
+ - **CREATIVE PROJECTS** → Art, design, media, content, artistic expressions
628
+ - **EDUCATIONAL PROJECTS** → Learning resources, tutorials, courses, documentation
629
+ - **BUSINESS PROJECTS** → Solutions, automation, analytics, productivity tools
630
+ - **COMMUNITY PROJECTS** → Open source, collaboration, social impact, activism
631
+
632
+ **🚀 INTELLIGENT SEARCH STRATEGIES:**
633
+ 1. **Single Terms**: "visualization", "sustainability", "automation", "creativity"
634
+ 2. **Domain-Specific**: Add context filters based on detected field
635
+ 3. **Quality Indicators**: Star count, activity level, community engagement
636
+ 4. **Scope Management**: Global discovery vs. targeted organizational search
637
+
638
+ **💡 UNIVERSAL PROJECT PATTERNS:**
639
+ - **"data visualization"** → Charts, dashboards, plotting, analytics projects
640
+ - **"sustainability"** → Environmental, green-tech, climate, conservation projects
641
+ - **"education"** → Learning platforms, tutorials, courses, knowledge sharing
642
+ - **"automation"** → Workflow tools, productivity, efficiency, process optimization
643
+ - **"creativity"** → Art tools, design systems, creative coding, expression platforms
644
+
645
+ **🌍 CROSS-DOMAIN PROJECT TYPES:**
646
+ - **RESEARCH REPOSITORIES**: Academic papers, datasets, experiments, methodologies
647
+ - **CREATIVE PORTFOLIOS**: Art projects, design systems, media collections
648
+ - **BUSINESS SOLUTIONS**: Analytics tools, automation scripts, productivity apps
649
+ - **EDUCATIONAL RESOURCES**: Learning materials, tutorials, course content
650
+ - **COMMUNITY INITIATIVES**: Open source projects, social impact, collaboration
651
+ - **PERSONAL PROJECTS**: Individual explorations, experiments, learning journeys
652
+
653
+ **⚡ SEARCH OPTIMIZATION STRATEGIES:**
654
+ - **0 results** → Broader terms, alternative approaches, ecosystem exploration
655
+ - **1-20 results** → IDEAL scope for detailed analysis and comparison
656
+ - **100+ results** → Add filters, narrow scope, focus on quality indicators
657
+ - **Organizational scope** → Private/enterprise project discovery
658
+
659
+ **🔧 INTELLIGENT FILTERING:**
660
+ - **Quality Indicators**: Star count (>100 established, >10 active)
661
+ - **Activity Level**: Recent updates, community engagement
662
+ - **Project Maturity**: Development stage, documentation quality
663
+ - **Domain Relevance**: Topic tags, description matching, content analysis
664
+
665
+ **🔄 PROGRESSIVE DISCOVERY WORKFLOW:**
666
+ 1. **Broad Exploration** → Map the project landscape in your domain
667
+ 2. **Quality Filtering** → Focus on well-maintained, active projects
668
+ 3. **Community Analysis** → Identify key contributors and organizations
669
+ 4. **Feature Comparison** → Analyze capabilities and approaches
670
+ 5. **Ecosystem Understanding** → See how projects relate and complement
671
+ 6. **Selection Criteria** → Choose based on needs, quality, and fit
672
+
673
+ **🎨 DOMAIN-SPECIFIC PROJECT DISCOVERY:**
674
+ - **CREATIVE DOMAIN**: Art tools, design systems, media processing, creative coding
675
+ - **BUSINESS DOMAIN**: Analytics, automation, productivity, management tools
676
+ - **RESEARCH DOMAIN**: Data analysis, visualization, computation, methodology
677
+ - **EDUCATIONAL DOMAIN**: Learning platforms, tutorials, knowledge sharing
678
+ - **SOCIAL DOMAIN**: Community tools, activism, social impact, collaboration
679
+ - **PERSONAL DOMAIN**: Productivity, wellness, lifestyle, skill development
680
+
681
+ **🌟 UNIVERSAL APPLICATIONS:**
682
+ - **Solution Discovery**: Find tools and projects for specific needs
683
+ - **Research Exploration**: Locate academic and experimental projects
684
+ - **Learning Resources**: Discover educational and tutorial projects
685
+ - **Community Building**: Find collaborative and open source initiatives
686
+ - **Innovation Inspiration**: Explore cutting-edge and experimental work
687
+ - **Quality Assessment**: Compare approaches, features, and implementations
688
+
689
+ **🔍 FALLBACK STRATEGIES:**
690
+ When repository search yields insufficient results:
691
+ 1. **Package Discovery** → Find related tools and libraries
692
+ 2. **Topic Exploration** → Understand domain terminology and trends
693
+ 3. **Content Search** → Look for implementations and usage patterns
694
+ 4. **Community Discovery** → Find experts and organizations
695
+ 5. **Discussion Mining** → Explore problems and solutions
696
+ 6. **Cross-Domain Bridging** → Look in adjacent fields and applications
697
+
698
+ **INPUT**: Any project need, concept, or area of interest across any domain
699
+ **OUTPUT**: Comprehensive project landscape with quality insights and recommendations`,
700
+ // Focused NPM tools for minimal token usage
701
+ [TOOL_NAMES.NPM_GET_REPOSITORY]: `**Repository discovery** - Extract GitHub repository URL and project description.
702
+
703
+ **MINIMAL OUTPUT:** Package name, description, repository URL, homepage - optimized for token efficiency.
704
+
705
+ **WHEN TO USE:** When you only need repository location for GitHub operations.
706
+
707
+ **INTEGRATION:** Perfect first step → ${TOOL_NAMES.GITHUB_GET_REPOSITORY} → Code exploration`,
708
+ [TOOL_NAMES.NPM_GET_DEPENDENCIES]: `**Dependency analysis** - Extract package dependencies tree.
709
+
710
+ **MINIMAL OUTPUT:** Dependencies, devDependencies, resolutions - focused dependency data only.
711
+
712
+ **WHEN TO USE:** When analyzing package ecosystem and compatibility.
713
+
714
+ **INTEGRATION:** Combine with ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES} for security audit`,
715
+ [TOOL_NAMES.NPM_GET_BUGS]: `**Issue tracking** - Extract bug reporting information.
716
+
717
+ **MINIMAL OUTPUT:** Package name and bugs URL - direct access to issue tracker.
718
+
719
+ **WHEN TO USE:** When users need to report issues or check known problems.
720
+
721
+ **INTEGRATION:** Links to ${TOOL_NAMES.GITHUB_SEARCH_ISSUES} for problem discovery`,
722
+ [TOOL_NAMES.NPM_GET_README]: `**Documentation access** - Extract README filename information.
723
+
724
+ **MINIMAL OUTPUT:** Package name and readme filename - efficient documentation lookup.
725
+
726
+ **WHEN TO USE:** When users need documentation without full package metadata.
727
+
728
+ **INTEGRATION:** Combine with ${TOOL_NAMES.GITHUB_GET_FILE_CONTENT} for full README content`,
729
+ [TOOL_NAMES.NPM_GET_VERSIONS]: `**Official version tracking** - Extract production-ready semantic versions only.
730
+
731
+ **MINIMAL OUTPUT:** Official versions (major.minor.patch format), latest version, count - excludes alpha/beta/rc versions.
732
+
733
+ **WHEN TO USE:** Find stable versions for production deployment, analyze release cadence of stable releases.
734
+
735
+ **INTEGRATION:** Perfect for production planning - filters out experimental versions for reliable deployment decisions`,
736
+ [TOOL_NAMES.NPM_GET_AUTHOR]: `**Maintainer information** - Extract author and maintainer details.
737
+
738
+ **MINIMAL OUTPUT:** Author and maintainers list - focused ownership data.
739
+
740
+ **WHEN TO USE:** When users need to contact maintainers or assess project ownership.
741
+
742
+ **INTEGRATION:** Links to ${TOOL_NAMES.GITHUB_SEARCH_USERS} for developer discovery`,
743
+ [TOOL_NAMES.NPM_GET_LICENSE]: `**License compliance** - Extract package license information.
744
+
745
+ **MINIMAL OUTPUT:** Package name and license - essential legal compliance data.
746
+
747
+ **WHEN TO USE:** When users need quick license verification for legal compliance.
748
+
749
+ **INTEGRATION:** Essential for enterprise package evaluation workflows`,
750
+ [TOOL_NAMES.NPM_GET_HOMEPAGE]: `**Official documentation gateway** - Extract package homepage for comprehensive project resources.
275
751
 
276
- **MANDATORY PREREQUISITES:** ${TOOL_NAMES.NPM_SEARCH_PACKAGES} and ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} must fail first.
752
+ **MINIMAL OUTPUT:** Package name and homepage URL - direct access to live documentation, tutorials, and demos.
277
753
 
278
- **KEY FEATURES:** Smart multi-term handling, filter validation, fallback strategies.
754
+ **WHEN TO USE:** Access official docs, interactive examples, getting started guides, and project showcases.
279
755
 
280
- **BEST PRACTICES:** Single terms work best ("react", "typescript"), validated combinations (microsoft + typescript ✅), progressive refinement.
756
+ **INTEGRATION:** Complements ${TOOL_NAMES.NPM_GET_REPOSITORY} - homepage often contains better docs than README`,
757
+ [TOOL_NAMES.NPM_GET_ID]: `**Precise package targeting** - Extract exact name@version for dependency management.
281
758
 
282
- **MULTI-TERM HANDLING:** "react hooks auth" structured workflow, primary term extraction, workflow guidance.
759
+ **MINIMAL OUTPUT:** Package name and _id (name@latestVersion format) - canonical package identifier for lockfiles.
283
760
 
284
- **CRITICAL:** npm_search_packages topics workflow provides superior results for 95% of use cases`,
285
- [TOOL_NAMES.NPM_GET_PACKAGE_STATS]: `**Package maturity analysis** - Lifecycle assessment for package evaluation.
761
+ **WHEN TO USE:** Pin exact versions, resolve dependency conflicts, generate package-lock entries, version compatibility checks.
286
762
 
287
- **WHEN TO USE:** ALWAYS after ${TOOL_NAMES.NPM_GET_PACKAGE} for complete assessment.
763
+ **INTEGRATION:** Critical for CI/CD pipelines, dependency auditing, and reproducible builds`,
764
+ [TOOL_NAMES.NPM_GET_RELEASES]: `**Recent releases tracker** - Get latest release activity and timeline data.
288
765
 
289
- **ANALYSIS:** Release timeline, version history, distribution tags, maintenance indicators, organizational context.
766
+ **MINIMAL OUTPUT:** Last modified, created date, version count, and last 10 releases - focused release intelligence.
290
767
 
291
- **MATURITY INDICATORS:** Stable (regular releases, clear versioning), active development (frequent releases, beta/alpha), abandoned (long gaps, no activity).
768
+ **WHEN TO USE:** Track recent package activity, analyze release frequency, check latest versions and release dates.
292
769
 
293
- **INTEGRATION:** MANDATORY with ${TOOL_NAMES.NPM_GET_PACKAGE}, combine with ${TOOL_NAMES.NPM_ANALYZE_DEPENDENCIES}`,
770
+ **INTEGRATION:** Essential for monitoring package updates - combine with ${TOOL_NAMES.NPM_GET_VERSIONS} for comprehensive version analysis`,
771
+ [TOOL_NAMES.NPM_GET_ENGINES]: `**Environment compatibility validator** - Prevent runtime conflicts before installation.
772
+
773
+ **MINIMAL OUTPUT:** Node.js version requirements, npm constraints - environment compatibility matrix.
774
+
775
+ **WHEN TO USE:** Pre-deployment validation, Docker image planning, Node.js upgrade decisions, CI/CD environment setup.
776
+
777
+ **INTEGRATION:** Prevents deployment failures - use before installation in production environments`,
778
+ [TOOL_NAMES.NPM_GET_EXPORTS]: `**Import path intelligence** - Discover available modules and import strategies.
779
+
780
+ **MINIMAL OUTPUT:** Export mappings, entry points, submodule paths - complete import guide for developers.
781
+
782
+ **WHEN TO USE:** Learn correct import syntax, discover tree-shakable exports, find submodules, optimize bundle size.
783
+
784
+ **INTEGRATION:** CRITICAL for ${TOOL_NAMES.GITHUB_SEARCH_CODE} - enables precise code search with accurate import paths`,
785
+ [TOOL_NAMES.API_STATUS_CHECK]: `**🛠️ CRITICAL FIRST STEP** - Comprehensive API readiness verification before research operations.
786
+
787
+ **ESSENTIAL PRE-RESEARCH VALIDATION:**
788
+ - **GitHub CLI Authentication**: Verifies user is logged in (gh auth status)
789
+ - **NPM Registry Connectivity**: Confirms npm ping successful
790
+ - **GitHub API Rate Limits**: Real-time quota analysis across all endpoints
791
+
792
+ **🔍 COMPREHENSIVE HEALTH CHECK:**
793
+ - **Authentication Status**: GitHub CLI login verification with username detection
794
+ - **Network Connectivity**: NPM registry accessibility and response validation
795
+ - **API Quota Analysis**: Core API, Search API, and Code Search remaining limits
796
+ - **Reset Time Tracking**: When exhausted APIs will restore quota
797
+ - **Usage Percentage**: Current consumption across all GitHub endpoints
798
+
799
+ **⚡ INTELLIGENT RESEARCH STRATEGY:**
800
+ - **Ready Status**: All systems operational for comprehensive research
801
+ - **Limited Status**: Reduced capacity - targeted searches recommended
802
+ - **Not Ready Status**: Authentication/quota issues require resolution
803
+
804
+ **🎯 RESEARCH GUIDANCE BASED ON API LIMITS:**
805
+ - **Code Search < 5**: Critical - use repository browsing instead of code search
806
+ - **Search API < 20**: Limited - focus on specific repositories vs broad searches
807
+ - **Core API < 200**: Constrained - minimize repository exploration operations
808
+ - **NPM Disconnected**: GitHub-only research mode activated
809
+
810
+ **🚀 SMART FALLBACK RECOMMENDATIONS:**
811
+ - **Authentication Issues**: Step-by-step gh auth login guidance
812
+ - **NPM Problems**: Alternative research paths using GitHub discovery
813
+ - **Rate Limit Exhaustion**: Wait times and alternative approaches
814
+ - **Network Issues**: Diagnostic commands and troubleshooting steps
815
+
816
+ **📊 REAL-TIME API INTELLIGENCE:**
817
+ - **Primary API**: Repository operations, issues, PRs, users (5000/hour)
818
+ - **Search API**: Repository/user/topic searches (30/minute)
819
+ - **Code Search**: Code content searches (10/minute) - most restrictive
820
+ - **Reset Schedules**: Precise timestamps for quota restoration
821
+
822
+ **✅ RESEARCH READINESS MATRIX:**
823
+ - **READY**: GitHub authenticated + NPM connected + healthy API limits
824
+ - **LIMITED**: Some constraints but research possible with guidance
825
+ - **NOT_READY**: Critical issues blocking research operations
826
+
827
+ **💡 PROACTIVE OPTIMIZATION:**
828
+ - **API Usage Prediction**: Warns before hitting limits during extensive research
829
+ - **Strategy Adaptation**: Automatically suggests efficient research patterns
830
+ - **Resource Conservation**: Identifies when to use cached vs live data
831
+ - **Batch Operation Planning**: Optimal timing for bulk research tasks
832
+
833
+ **WHEN TO USE:** ALWAYS call first before starting any research session to ensure optimal tool usage and prevent operation failures.
834
+
835
+ **INTEGRATION:** Sets research strategy for all subsequent GitHub and NPM tools based on current system status.`,
294
836
  };
295
837
 
296
838
  const cache = new NodeCache({
@@ -463,6 +1005,17 @@ async function executeGitHubCommand(command, args = [], options = {}) {
463
1005
  return executeCommand();
464
1006
  }
465
1007
 
1008
+ /**
1009
+ * Search GitHub code with organizational fallback strategy
1010
+ *
1011
+ * For internal company projects (like "Astra Nova" at Wix):
1012
+ * 1. Try direct code search first
1013
+ * 2. If no results, the calling code should implement fallback chain:
1014
+ * - searchGitHubCommits() for commit message references
1015
+ * - searchGitHubPullRequests() for PR mentions
1016
+ * - searchGitHubIssues() for issue discussions
1017
+ * 3. Extract repository info from any successful results
1018
+ */
466
1019
  async function searchGitHubCode(params) {
467
1020
  const cacheKey = generateCacheKey('gh-code', params);
468
1021
  return withCache(cacheKey, async () => {
@@ -541,6 +1094,18 @@ async function searchGitHubCode(params) {
541
1094
  topMatches: analysis.topMatches.slice(0, 5),
542
1095
  },
543
1096
  };
1097
+ // Add organizational fallback guidance for zero results
1098
+ if (analysis.totalFound === 0 && params.owner) {
1099
+ searchResult.organizationalFallback = {
1100
+ suggestion: `No code matches found for "${params.query}" in ${params.owner}. Try organizational fallback strategy:`,
1101
+ fallbackSteps: [
1102
+ `Search commits: "${params.query}" with owner:${params.owner}`,
1103
+ `Search pull requests: "${params.query}" with owner:${params.owner}`,
1104
+ `Search issues: "${params.query}" with owner:${params.owner}`,
1105
+ 'Extract repository references from any successful results',
1106
+ ],
1107
+ };
1108
+ }
544
1109
  return createSuccessResult$1(searchResult);
545
1110
  }
546
1111
  catch (parseError) {
@@ -686,84 +1251,387 @@ function buildGitHubCodeSearchCommand(params) {
686
1251
  return { command: 'search', args };
687
1252
  }
688
1253
 
689
- // Testing-validated search pattern analysis
1254
+ // Enhanced search pattern analysis with MANDATORY boolean operator suggestions
690
1255
  function analyzeSearchPattern(args) {
691
1256
  const suggestions = [];
692
1257
  const warnings = [];
1258
+ const booleanRecommendations = [];
1259
+ const contextEnrichment = [];
693
1260
  let patternType = 'basic';
694
- // Function signature patterns (TESTING-VALIDATED)
695
- if (args.query.includes('function') || args.query.includes('export')) {
696
- patternType = 'function-discovery';
697
- suggestions.push('PROVEN: "export function" → VSCode functions (localize, getVersion, fixWin32DirectoryPermissions)');
1261
+ const query = args.query.toLowerCase();
1262
+ const hasBoolean = /\b(OR|AND|NOT)\b/i.test(args.query);
1263
+ // CRITICAL: Always recommend boolean operators if not present
1264
+ if (!hasBoolean) {
1265
+ warnings.push('CRITICAL: Query lacks boolean operators - efficiency reduced by 3-5x without them');
1266
+ warnings.push('MANDATORY: Add boolean operators (OR, AND, NOT) for maximum search efficiency');
1267
+ patternType = 'needs-boolean-enhancement';
698
1268
  }
699
- // Boolean operator patterns (TESTING-VALIDATED)
700
- if (args.query.includes(' OR ') || args.query.includes(' NOT ')) {
701
- patternType = 'boolean-search';
702
- suggestions.push('PROVEN: "useState OR useEffect" ✅, "function NOT test"');
1269
+ // CRITICAL: Check for unsupported parentheses
1270
+ if (args.query.includes('(') || args.query.includes(')')) {
1271
+ warnings.push('CRITICAL: GitHub API does not support parentheses () in search queries');
1272
+ warnings.push('SOLUTION: Remove parentheses and use boolean operators: "term1 OR term2 AND term3"');
1273
+ patternType = 'unsupported-syntax';
1274
+ }
1275
+ // Check for overly complex queries
1276
+ const booleanOperatorCount = (args.query.match(/\b(OR|AND|NOT)\b/gi) || [])
1277
+ .length;
1278
+ const termCount = args.query.split(/\s+/).length;
1279
+ if (booleanOperatorCount > 3 || termCount > 8) {
1280
+ warnings.push('COMPLEXITY WARNING: Query may exceed GitHub API limits');
1281
+ warnings.push('RECOMMENDATION: Simplify to essential boolean operators (max 3-4 per query)');
1282
+ patternType = 'overly-complex';
1283
+ }
1284
+ // Enhanced Function signature patterns with MANDATORY boolean operators
1285
+ if (query.includes('function') || query.includes('export')) {
1286
+ patternType = 'function-discovery';
1287
+ suggestions.push('PROVEN BOOLEAN: "export OR function OR method OR class" → Comprehensive function discovery');
1288
+ booleanRecommendations.push('MANDATORY BOOLEAN: "export AND function OR method OR procedure" - captures all function types');
1289
+ booleanRecommendations.push('MANDATORY EXCLUSION: "function OR method NOT test NOT spec NOT mock" - production code only');
1290
+ booleanRecommendations.push('MANDATORY ASYNC: "async AND (function OR method) OR promise NOT example" - async patterns');
1291
+ contextEnrichment.push('BOOLEAN CONTEXT: "arrow OR lambda OR callback OR closure" for function variations');
703
1292
  }
704
- // Class and React patterns (TESTING-VALIDATED)
705
- if (args.query.includes('class') || args.query.includes('React')) {
1293
+ // Enhanced React/Component patterns with MANDATORY boolean operators
1294
+ if (query.includes('react') ||
1295
+ query.includes('component') ||
1296
+ query.includes('jsx')) {
706
1297
  patternType = 'component-discovery';
707
- suggestions.push('PROVEN: "class extends" React class components, "import React" → React usage patterns');
1298
+ suggestions.push('PROVEN BOOLEAN: "react AND (hooks OR components OR jsx) NOT test" → React ecosystem discovery');
1299
+ booleanRecommendations.push('MANDATORY HOOKS: "useState OR useEffect OR useContext OR useReducer" - comprehensive hook coverage');
1300
+ booleanRecommendations.push('MANDATORY COMPONENTS: "component OR jsx OR tsx OR react NOT test NOT story" - component patterns');
1301
+ booleanRecommendations.push('MANDATORY LIFECYCLE: "componentDidMount OR useEffect OR lifecycle NOT mock" - lifecycle methods');
1302
+ contextEnrichment.push('BOOLEAN CONTEXT: "props OR state OR render OR mount" for React-specific patterns');
1303
+ }
1304
+ // Authentication/Security patterns with MANDATORY boolean operators
1305
+ if (query.includes('auth') ||
1306
+ query.includes('login') ||
1307
+ query.includes('password') ||
1308
+ query.includes('token')) {
1309
+ patternType = 'security-discovery';
1310
+ booleanRecommendations.push('MANDATORY AUTH: "authentication OR auth OR login OR signin OR oauth" - comprehensive auth coverage');
1311
+ booleanRecommendations.push('MANDATORY TOKENS: "jwt OR token OR bearer OR session OR cookie" - token handling patterns');
1312
+ booleanRecommendations.push('MANDATORY SECURITY: "password OR hash OR encrypt OR decrypt NOT test NOT mock" - security implementations');
1313
+ contextEnrichment.push('BOOLEAN SECURITY: "middleware OR guard OR interceptor OR validation OR sanitize" for auth context');
1314
+ }
1315
+ // API/HTTP patterns with MANDATORY boolean operators
1316
+ if (query.includes('api') ||
1317
+ query.includes('http') ||
1318
+ query.includes('request') ||
1319
+ query.includes('fetch')) {
1320
+ patternType = 'api-discovery';
1321
+ booleanRecommendations.push('MANDATORY HTTP: "fetch OR axios OR request OR http OR api" - HTTP client coverage');
1322
+ booleanRecommendations.push('MANDATORY ENDPOINTS: "endpoint OR route OR handler OR controller NOT test" - API structure');
1323
+ booleanRecommendations.push('MANDATORY METHODS: "get OR post OR put OR delete OR patch" - HTTP methods');
1324
+ contextEnrichment.push('BOOLEAN API: "cors OR middleware OR validation OR serialization OR response" for API context');
1325
+ }
1326
+ // Database/Storage patterns with MANDATORY boolean operators
1327
+ if (query.includes('database') ||
1328
+ query.includes('db') ||
1329
+ query.includes('sql') ||
1330
+ query.includes('query')) {
1331
+ patternType = 'database-discovery';
1332
+ booleanRecommendations.push('MANDATORY CRUD: "insert OR update OR delete OR select OR create" - database operations');
1333
+ booleanRecommendations.push('MANDATORY DATABASES: "mongodb OR postgresql OR mysql OR sqlite OR redis" - database types');
1334
+ booleanRecommendations.push('MANDATORY ORM: "sequelize OR typeorm OR prisma OR mongoose OR knex" - ORM frameworks');
1335
+ }
1336
+ // Error handling patterns with MANDATORY boolean operators
1337
+ if (query.includes('error') ||
1338
+ query.includes('exception') ||
1339
+ query.includes('try') ||
1340
+ query.includes('catch')) {
1341
+ patternType = 'error-handling';
1342
+ booleanRecommendations.push('MANDATORY ERROR: "error OR exception OR catch OR throw OR reject" - error handling coverage');
1343
+ booleanRecommendations.push('MANDATORY PATTERNS: "try OR catch OR finally OR async OR await" - error patterns');
1344
+ booleanRecommendations.push('MANDATORY HANDLING: "handling OR recovery OR retry OR fallback NOT test" - error management');
1345
+ }
1346
+ // Testing patterns - suggest boolean exclusion
1347
+ if (query.includes('test') ||
1348
+ query.includes('spec') ||
1349
+ query.includes('mock')) {
1350
+ if (!query.includes('NOT')) {
1351
+ booleanRecommendations.push('MANDATORY EXCLUSION: Add "NOT test NOT spec NOT mock" to focus on production code');
1352
+ booleanRecommendations.push('BOOLEAN ALTERNATIVE: Use "production OR live OR deploy NOT test" for real implementations');
1353
+ }
1354
+ }
1355
+ // Generic single-term queries - MANDATORY boolean enhancement
1356
+ const words = query.split(/\s+/).filter(w => w.length > 2);
1357
+ if (words.length === 1 && !hasBoolean && words[0].length > 3) {
1358
+ booleanRecommendations.push(`MANDATORY VARIATIONS: "${words[0]} OR ${words[0]}s OR ${words[0]}ing" - capture all variations`);
1359
+ booleanRecommendations.push(`MANDATORY EXCLUSION: "${words[0]} NOT test NOT spec NOT example" - production focus`);
1360
+ booleanRecommendations.push(`MANDATORY CONTEXT: "${words[0]} OR related_term OR synonym" - comprehensive coverage`);
1361
+ }
1362
+ // Boolean operator patterns (existing logic enhanced)
1363
+ if (hasBoolean) {
1364
+ patternType = 'boolean-search';
1365
+ suggestions.push('EXCELLENT: Boolean operators detected - proven 3-5x more efficient than simple text');
1366
+ suggestions.push('PROVEN PATTERNS: "useState OR useEffect" ✅, "function NOT test" ✅, "async AND await" ✅');
708
1367
  }
709
- // Path filter validation (CRITICAL WARNING BASED ON TESTING)
1368
+ // Path filter validation (enhanced with boolean recommendations)
710
1369
  if (args.path === 'src' && !args.repo) {
711
1370
  warnings.push('CRITICAL: path:src may fail - many repos use path:packages, path:lib instead');
712
- suggestions.push('PROVEN PATHS: React uses "packages", VSCode uses "src/vs", TypeScript uses "src"');
1371
+ suggestions.push('PROVEN BOOLEAN PATHS: "react AND hooks" with path:packages, NOT path:src');
1372
+ contextEnrichment.push('BOOLEAN PATH ALTERNATIVES: Try boolean queries without path filters first');
1373
+ }
1374
+ // Language-specific boolean enhancements
1375
+ if (args.language) {
1376
+ const lang = args.language.toLowerCase();
1377
+ if (lang === 'typescript' || lang === 'javascript') {
1378
+ contextEnrichment.push('BOOLEAN JS/TS: "interface OR type OR class OR function OR const OR let" for comprehensive coverage');
1379
+ }
1380
+ else if (lang === 'python') {
1381
+ contextEnrichment.push('BOOLEAN PYTHON: "def OR class OR import OR async OR lambda" for Python patterns');
1382
+ }
1383
+ else if (lang === 'java') {
1384
+ contextEnrichment.push('BOOLEAN JAVA: "public OR private OR class OR interface OR method" for Java patterns');
1385
+ }
713
1386
  }
714
- // Cross-repository patterns (TESTING-VALIDATED)
1387
+ // Cross-repository patterns (enhanced with boolean emphasis)
715
1388
  if (!args.owner && !args.repo && args.query.includes('async')) {
716
1389
  patternType = 'cross-repo-discovery';
717
- suggestions.push('PROVEN: "async function login" finds 4 TypeScript authentication implementations');
718
- }
719
- return { patternType, suggestions, warnings };
720
- }
721
- // Simplified schema matching official GitHub CLI approach
722
- const searchGitHubCodeSchema = z.object({
723
- query: z
724
- .string()
725
- .min(1, 'Query cannot be empty')
726
- .describe('Search query for code. Use GitHub search syntax like repo:owner/name, language:javascript, path:*.js, or simple keywords.'),
727
- owner: z
728
- .string()
729
- .optional()
730
- .describe('Repository owner/organization (e.g., "facebook", "microsoft"). Leave empty for global searches.'),
731
- repo: z
732
- .string()
733
- .optional()
734
- .describe('Repository name (e.g., "react", "vscode"). Requires owner parameter.'),
735
- extension: z
736
- .string()
737
- .optional()
738
- .describe('File extension to filter by (e.g., "js", "ts", "py").'),
739
- filename: z
740
- .string()
741
- .optional()
742
- .describe('Exact filename to search for (e.g., "package.json", "README.md").'),
743
- language: z
744
- .string()
745
- .optional()
746
- .describe('Programming language to filter by (e.g., "javascript", "typescript", "python").'),
747
- path: z
748
- .string()
749
- .optional()
750
- .describe('Path pattern to filter by (e.g., "src", "lib", "*.js", "/src/**/*.ts").'),
751
- limit: z
752
- .number()
753
- .int()
754
- .min(1)
755
- .max(100)
756
- .optional()
757
- .default(30)
758
- .describe('Maximum number of results to return (default: 30, max: 100).'),
759
- match: z.enum(['file', 'path']).optional().describe('Search scope'),
760
- branch: z
761
- .string()
762
- .optional()
763
- .describe('Branch for workflow documentation (required but not used by CLI)'),
764
- });
1390
+ suggestions.push('PROVEN BOOLEAN GLOBAL: "async AND (function OR method) OR promise" finds comprehensive async patterns');
1391
+ contextEnrichment.push('BOOLEAN CROSS-REPO: Global boolean searches excel for common patterns like "error OR exception"');
1392
+ }
1393
+ // Zero results prediction with boolean solutions
1394
+ if (query.length > 50 || query.split(' ').length > 8) {
1395
+ warnings.push('COMPLEXITY WARNING: Very long/complex queries often return 0 results');
1396
+ booleanRecommendations.push('MANDATORY SIMPLIFICATION: Break into essential boolean terms: "term1 OR term2 NOT test"');
1397
+ booleanRecommendations.push('BOOLEAN STRATEGY: Use progressive boolean refinement instead of complex phrases');
1398
+ }
1399
+ // ALWAYS add mandatory boolean recommendations if none exist
1400
+ if (booleanRecommendations.length === 0) {
1401
+ booleanRecommendations.push('MANDATORY: Add boolean operators for 3-5x better efficiency: "term1 OR term2 NOT test"');
1402
+ booleanRecommendations.push('PROVEN PATTERN: Use "primary_term OR synonym OR variation NOT noise" structure');
1403
+ }
1404
+ return {
1405
+ patternType,
1406
+ suggestions,
1407
+ warnings,
1408
+ booleanRecommendations,
1409
+ contextEnrichment,
1410
+ };
1411
+ }
1412
+ // NEW: Smart query simplification for GitHub API compatibility
1413
+ function simplifyComplexQuery(query) {
1414
+ const fallbackQueries = [];
1415
+ // Remove parentheses - GitHub doesn't support them
1416
+ const simplified = query.replace(/[()]/g, '');
1417
+ // If query has parentheses, create simplified version
1418
+ if (query.includes('(') || query.includes(')')) {
1419
+ fallbackQueries.push(simplified);
1420
+ }
1421
+ // Extract main terms and create progressive simplifications
1422
+ const terms = simplified
1423
+ .split(/\s+/)
1424
+ .filter(term => !['AND', 'OR', 'NOT'].includes(term.toUpperCase()));
1425
+ // Strategy 1: Keep only OR operations (most permissive)
1426
+ const orTerms = [];
1427
+ const parts = simplified.split(/\s+/);
1428
+ for (let i = 0; i < parts.length; i++) {
1429
+ if (parts[i].toUpperCase() === 'OR' && i > 0 && i < parts.length - 1) {
1430
+ orTerms.push(parts[i - 1], 'OR', parts[i + 1]);
1431
+ }
1432
+ }
1433
+ if (orTerms.length > 0) {
1434
+ fallbackQueries.push(orTerms.join(' '));
1435
+ }
1436
+ // Strategy 2: Take first 2-3 most important terms
1437
+ if (terms.length >= 2) {
1438
+ fallbackQueries.push(`${terms[0]} OR ${terms[1]}`);
1439
+ }
1440
+ // Strategy 3: Single most specific term
1441
+ const specificTerms = terms.filter(term => term.length > 4 &&
1442
+ !['function', 'class', 'import', 'export'].includes(term.toLowerCase()));
1443
+ if (specificTerms.length > 0) {
1444
+ fallbackQueries.push(specificTerms[0]);
1445
+ }
1446
+ // Strategy 4: Fallback to first term
1447
+ if (terms.length > 0) {
1448
+ fallbackQueries.push(terms[0]);
1449
+ }
1450
+ // Remove duplicates and return unique fallbacks
1451
+ return [...new Set(fallbackQueries)];
1452
+ }
1453
+ // NEW: Safe JSON parsing with error recovery
1454
+ function safeParseJSON(text) {
1455
+ try {
1456
+ const parsed = JSON.parse(text);
1457
+ return { success: true, data: parsed };
1458
+ }
1459
+ catch (error) {
1460
+ try {
1461
+ // Try parsing as double-encoded JSON
1462
+ const doubleParsed = JSON.parse(JSON.parse(text));
1463
+ return { success: true, data: doubleParsed };
1464
+ }
1465
+ catch (secondError) {
1466
+ return {
1467
+ success: false,
1468
+ error: error instanceof Error ? error.message : 'JSON parsing failed',
1469
+ };
1470
+ }
1471
+ }
1472
+ }
1473
+ // Enhanced query optimization for better results - BOOLEAN OPERATORS ALWAYS REQUIRED
1474
+ function optimizeQuery(args) {
1475
+ const original = args.query;
1476
+ const optimized = [];
1477
+ const rationale = [];
1478
+ const fallbackQueries = [];
1479
+ // Check for unsupported syntax first
1480
+ if (original.includes('(') || original.includes(')')) {
1481
+ const simplified = simplifyComplexQuery(original);
1482
+ fallbackQueries.push(...simplified);
1483
+ rationale.push('Removed unsupported parentheses and created boolean fallback queries');
1484
+ }
1485
+ // MANDATORY: Always ensure boolean operators are used for maximum efficiency
1486
+ const hasBoolean = /\b(OR|AND|NOT)\b/i.test(original);
1487
+ if (!hasBoolean) {
1488
+ // CRITICAL: Inject boolean operators for maximum efficiency
1489
+ const words = original
1490
+ .trim()
1491
+ .split(/\s+/)
1492
+ .filter(w => w.length > 2);
1493
+ if (words.length === 1) {
1494
+ const word = words[0];
1495
+ // Always create boolean variations for single terms
1496
+ optimized.push(`${word} OR ${word}s OR ${word}ing`);
1497
+ rationale.push('MANDATORY: Added boolean variations for comprehensive coverage (3-5x more efficient)');
1498
+ optimized.push(`${word} NOT test NOT spec NOT mock`);
1499
+ rationale.push('MANDATORY: Added boolean exclusions to focus on production code');
1500
+ // Add semantic boolean expansions based on common patterns
1501
+ if (word.toLowerCase().includes('react')) {
1502
+ optimized.push(`${word} OR reactjs OR react.js NOT example`);
1503
+ rationale.push('MANDATORY: Added React-specific boolean variations');
1504
+ }
1505
+ else if (word.toLowerCase().includes('auth')) {
1506
+ optimized.push(`${word} OR authentication OR login OR signin NOT test`);
1507
+ rationale.push('MANDATORY: Added authentication boolean variations');
1508
+ }
1509
+ else if (word.toLowerCase().includes('function')) {
1510
+ optimized.push(`${word} OR method OR procedure OR class NOT test`);
1511
+ rationale.push('MANDATORY: Added function-related boolean variations');
1512
+ }
1513
+ else if (word.toLowerCase().includes('error')) {
1514
+ optimized.push(`${word} OR exception OR catch OR handling NOT mock`);
1515
+ rationale.push('MANDATORY: Added error-handling boolean variations');
1516
+ }
1517
+ }
1518
+ else if (words.length >= 2 && words.length <= 4) {
1519
+ // MANDATORY: Convert multi-word queries to boolean
1520
+ optimized.push(words.join(' OR '));
1521
+ rationale.push('MANDATORY: Converted to OR boolean for comprehensive coverage (proven 3-5x more efficient)');
1522
+ optimized.push(`${words.join(' AND ')} NOT test NOT spec`);
1523
+ rationale.push('MANDATORY: Added AND boolean with exclusions for precise targeting');
1524
+ // Create semantic boolean combinations
1525
+ if (words.some(w => w.toLowerCase().includes('react'))) {
1526
+ const reactTerms = words.filter(w => !w.toLowerCase().includes('react'));
1527
+ optimized.push(`react AND (${reactTerms.join(' OR ')}) NOT example NOT tutorial`);
1528
+ rationale.push('MANDATORY: Created React-specific boolean combination');
1529
+ }
1530
+ }
1531
+ else if (words.length > 4) {
1532
+ // MANDATORY: Simplify complex queries with boolean operators
1533
+ const primaryTerms = words.slice(0, 3);
1534
+ optimized.push(`${primaryTerms.join(' OR ')} NOT test`);
1535
+ rationale.push('MANDATORY: Simplified to essential boolean terms (complex queries often fail)');
1536
+ optimized.push(`${primaryTerms[0]} AND ${primaryTerms[1]} NOT mock NOT spec`);
1537
+ rationale.push('MANDATORY: Created focused boolean combination from key terms');
1538
+ }
1539
+ }
1540
+ else {
1541
+ // Query already has boolean operators - validate and enhance
1542
+ const booleanCount = (original.match(/\b(OR|AND|NOT)\b/gi) || []).length;
1543
+ if (booleanCount > 3) {
1544
+ const simplified = simplifyComplexQuery(original);
1545
+ fallbackQueries.push(...simplified);
1546
+ rationale.push('MANDATORY: Boolean query too complex - created simplified boolean fallbacks');
1547
+ }
1548
+ else {
1549
+ optimized.push(original);
1550
+ rationale.push('MANDATORY: Boolean complexity acceptable - using optimized boolean query');
1551
+ // Always add enhanced boolean variations even for existing boolean queries
1552
+ const words = original
1553
+ .split(/\s+/)
1554
+ .filter(w => w.length > 3 && !['AND', 'OR', 'NOT'].includes(w.toUpperCase()));
1555
+ if (words.length >= 2) {
1556
+ // Add alternative boolean combinations
1557
+ optimized.push(`${words[0]} OR ${words[1]} NOT test NOT example`);
1558
+ rationale.push('MANDATORY: Added alternative boolean combination for broader coverage');
1559
+ }
1560
+ }
1561
+ }
1562
+ // MANDATORY: Always ensure we have boolean fallbacks
1563
+ if (optimized.length === 0 && fallbackQueries.length === 0) {
1564
+ const words = original.split(/\s+/).filter(w => w.length > 2);
1565
+ if (words.length > 0) {
1566
+ optimized.push(`${words[0]} OR ${words[0]}s NOT test`);
1567
+ rationale.push('MANDATORY: Created essential boolean query as fallback');
1568
+ }
1569
+ else {
1570
+ optimized.push(original);
1571
+ rationale.push('MANDATORY: Preserved original query (boolean enhancement not possible)');
1572
+ }
1573
+ }
1574
+ return {
1575
+ originalQuery: original,
1576
+ optimizedQueries: optimized,
1577
+ rationale,
1578
+ fallbackQueries,
1579
+ };
1580
+ }
765
1581
  function registerGitHubSearchCodeTool(server) {
766
- server.tool(TOOL_NAMES.GITHUB_SEARCH_CODE, TOOL_DESCRIPTIONS[TOOL_NAMES.GITHUB_SEARCH_CODE], searchGitHubCodeSchema.shape, {
1582
+ server.tool(TOOL_NAMES.GITHUB_SEARCH_CODE, TOOL_DESCRIPTIONS[TOOL_NAMES.GITHUB_SEARCH_CODE], {
1583
+ query: z
1584
+ .string()
1585
+ .min(1, 'Query cannot be empty')
1586
+ .describe('Search query for code. Use GitHub search syntax like repo:owner/name, language:javascript, path:*.js, or simple keywords. Boolean operators (OR, AND, NOT) are highly recommended for better results.'),
1587
+ owner: z
1588
+ .string()
1589
+ .optional()
1590
+ .describe('Repository owner/organization (e.g., "facebook", "microsoft"). Leave empty for global searches.'),
1591
+ repo: z
1592
+ .array(z.string())
1593
+ .optional()
1594
+ .describe('Repository names (e.g., ["react", "vscode"]). Requires owner parameter.'),
1595
+ extension: z
1596
+ .string()
1597
+ .optional()
1598
+ .describe('File extension to filter by (e.g., "js", "ts", "py").'),
1599
+ filename: z
1600
+ .string()
1601
+ .optional()
1602
+ .describe('Exact filename to search for (e.g., "package.json", "README.md").'),
1603
+ language: z
1604
+ .string()
1605
+ .optional()
1606
+ .describe('Programming language to filter by (e.g., "javascript", "typescript", "python").'),
1607
+ path: z
1608
+ .string()
1609
+ .optional()
1610
+ .describe('Path pattern to filter by (e.g., "src", "lib", "*.js", "/src/**/*.ts").'),
1611
+ limit: z
1612
+ .number()
1613
+ .int()
1614
+ .min(1)
1615
+ .max(100)
1616
+ .optional()
1617
+ .default(30)
1618
+ .describe('Maximum number of results to return (default: 30, max: 100).'),
1619
+ match: z.enum(['file', 'path']).optional().describe('Search scope'),
1620
+ branch: z
1621
+ .string()
1622
+ .optional()
1623
+ .describe('Branch for workflow documentation (required but not used by CLI)'),
1624
+ size: z
1625
+ .string()
1626
+ .optional()
1627
+ .describe('Filter on file size range, in kilobytes (e.g., ">1", "<50")'),
1628
+ // New parameter for query optimization
1629
+ enableQueryOptimization: z
1630
+ .boolean()
1631
+ .optional()
1632
+ .default(true)
1633
+ .describe('Enable automatic query optimization with boolean operators for better results (default: true)'),
1634
+ }, {
767
1635
  title: 'GitHub Code Search',
768
1636
  readOnlyHint: true,
769
1637
  destructiveHint: false,
@@ -771,7 +1639,7 @@ function registerGitHubSearchCodeTool(server) {
771
1639
  openWorldHint: true,
772
1640
  }, async (args) => {
773
1641
  try {
774
- // Simple validation - only check repo requires owner
1642
+ // Enhanced validation
775
1643
  if (args.repo && !args.owner) {
776
1644
  return {
777
1645
  content: [
@@ -783,19 +1651,177 @@ function registerGitHubSearchCodeTool(server) {
783
1651
  isError: true,
784
1652
  };
785
1653
  }
786
- // Analyze search pattern for testing-validated insights
1654
+ // Enhanced pattern analysis
787
1655
  const patternAnalysis = analyzeSearchPattern(args);
788
- const result = await searchGitHubCode(args);
789
- // Enhance result with testing-validated insights
1656
+ // Query optimization with fallbacks
1657
+ const queryOptimization = optimizeQuery(args);
1658
+ let result = null;
1659
+ let usedOptimizedQuery = false;
1660
+ let usedFallbackQuery = false;
1661
+ let finalQuery = args.query;
1662
+ const attemptedQueries = [];
1663
+ // Strategy 1: Try original query first (unless it has known issues)
1664
+ const hasUnsupportedSyntax = args.query.includes('(') || args.query.includes(')');
1665
+ const isOverlyComplex = (args.query.match(/\b(OR|AND|NOT)\b/gi) || []).length > 3;
1666
+ if (!hasUnsupportedSyntax && !isOverlyComplex) {
1667
+ try {
1668
+ result = await searchGitHubCode(args);
1669
+ attemptedQueries.push(args.query);
1670
+ // Validate result with safe JSON parsing
1671
+ if (result.content && result.content[0]) {
1672
+ const parseResult = safeParseJSON(result.content[0].text);
1673
+ if (!parseResult.success) {
1674
+ throw new Error(`JSON parsing failed: ${parseResult.error}`);
1675
+ }
1676
+ }
1677
+ }
1678
+ catch (error) {
1679
+ console.warn(`Original query failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
1680
+ result = null; // Will trigger fallback
1681
+ }
1682
+ }
1683
+ // Strategy 2: Try optimized queries if original failed or returned minimal results
1684
+ if (!result &&
1685
+ args.enableQueryOptimization !== false &&
1686
+ queryOptimization.optimizedQueries.length > 0) {
1687
+ for (const optimizedQuery of queryOptimization.optimizedQueries) {
1688
+ if (optimizedQuery === args.query)
1689
+ continue; // Skip if same as original
1690
+ try {
1691
+ const optimizedArgs = { ...args, query: optimizedQuery };
1692
+ const optimizedResult = await searchGitHubCode(optimizedArgs);
1693
+ attemptedQueries.push(optimizedQuery);
1694
+ if (optimizedResult.content && optimizedResult.content[0]) {
1695
+ const parseResult = safeParseJSON(optimizedResult.content[0].text);
1696
+ if (parseResult.success) {
1697
+ result = optimizedResult;
1698
+ usedOptimizedQuery = true;
1699
+ finalQuery = optimizedQuery;
1700
+ break;
1701
+ }
1702
+ }
1703
+ }
1704
+ catch (error) {
1705
+ console.warn(`Optimized query failed: ${optimizedQuery} - ${error instanceof Error ? error.message : 'Unknown error'}`);
1706
+ continue;
1707
+ }
1708
+ }
1709
+ }
1710
+ // Strategy 3: Try fallback queries for complex/unsupported syntax
1711
+ if (!result && queryOptimization.fallbackQueries.length > 0) {
1712
+ for (const fallbackQuery of queryOptimization.fallbackQueries) {
1713
+ try {
1714
+ const fallbackArgs = { ...args, query: fallbackQuery };
1715
+ const fallbackResult = await searchGitHubCode(fallbackArgs);
1716
+ attemptedQueries.push(fallbackQuery);
1717
+ if (fallbackResult.content && fallbackResult.content[0]) {
1718
+ const parseResult = safeParseJSON(fallbackResult.content[0].text);
1719
+ if (parseResult.success) {
1720
+ result = fallbackResult;
1721
+ usedFallbackQuery = true;
1722
+ finalQuery = fallbackQuery;
1723
+ break;
1724
+ }
1725
+ }
1726
+ }
1727
+ catch (error) {
1728
+ console.warn(`Fallback query failed: ${fallbackQuery} - ${error instanceof Error ? error.message : 'Unknown error'}`);
1729
+ continue;
1730
+ }
1731
+ }
1732
+ }
1733
+ // Strategy 4: Last resort - try single term from original query
1734
+ if (!result) {
1735
+ const terms = args.query
1736
+ .split(/\s+/)
1737
+ .filter(term => term.length > 3 &&
1738
+ !['AND', 'OR', 'NOT'].includes(term.toUpperCase()));
1739
+ if (terms.length > 0) {
1740
+ try {
1741
+ const lastResortArgs = { ...args, query: terms[0] };
1742
+ const lastResortResult = await searchGitHubCode(lastResortArgs);
1743
+ attemptedQueries.push(terms[0]);
1744
+ if (lastResortResult.content && lastResortResult.content[0]) {
1745
+ const parseResult = safeParseJSON(lastResortResult.content[0].text);
1746
+ if (parseResult.success) {
1747
+ result = lastResortResult;
1748
+ usedFallbackQuery = true;
1749
+ finalQuery = terms[0];
1750
+ }
1751
+ }
1752
+ }
1753
+ catch (error) {
1754
+ console.warn(`Last resort query failed: ${terms[0]} - ${error instanceof Error ? error.message : 'Unknown error'}`);
1755
+ }
1756
+ }
1757
+ }
1758
+ // If we still don't have a result, return comprehensive error
1759
+ if (!result) {
1760
+ return {
1761
+ content: [
1762
+ {
1763
+ type: 'text',
1764
+ text: `🚨 ALL QUERY STRATEGIES FAILED
1765
+
1766
+ 📋 ATTEMPTED QUERIES:
1767
+ ${attemptedQueries.map(q => `• "${q}"`).join('\n')}
1768
+
1769
+ 🔧 INTELLIGENT FALLBACK RECOMMENDATIONS:
1770
+ • SIMPLIFY: Try single keywords like "useState", "function", "class"
1771
+ • REMOVE SYNTAX: Avoid parentheses () - GitHub API doesn't support them
1772
+ • REDUCE COMPLEXITY: Use max 2-3 boolean operators (OR, AND, NOT)
1773
+ • SPECIFIC TERMS: Use concrete terms instead of abstract concepts
1774
+ • REPOSITORY SCOPE: Add owner/repo parameters to narrow search
1775
+
1776
+ 💡 PROVEN WORKING PATTERNS:
1777
+ • "useState OR useEffect" ✅
1778
+ • "function NOT test" ✅
1779
+ • "async function" ✅
1780
+ • "export default" ✅
1781
+
1782
+ ⚠️ AVOID THESE PATTERNS:
1783
+ • "(term1 OR term2) AND term3" ❌ (parentheses not supported)
1784
+ • Complex nested boolean logic ❌
1785
+ • Very long queries (>50 characters) ❌`,
1786
+ },
1787
+ ],
1788
+ isError: true,
1789
+ };
1790
+ }
1791
+ // Enhance successful result with comprehensive insights
790
1792
  if (result.content && result.content[0]) {
791
1793
  let responseText = result.content[0].text;
1794
+ // Add query transformation info
1795
+ if (usedOptimizedQuery || usedFallbackQuery) {
1796
+ responseText += `\n\n🔄 QUERY TRANSFORMATION APPLIED:`;
1797
+ responseText += `\n• Original: "${args.query}"`;
1798
+ responseText += `\n• Used: "${finalQuery}"`;
1799
+ responseText += `\n• Strategy: ${usedFallbackQuery ? 'Fallback (syntax/complexity issues)' : 'Optimization'}`;
1800
+ if (attemptedQueries.length > 1) {
1801
+ responseText += `\n• Attempts: ${attemptedQueries.length} queries tried`;
1802
+ }
1803
+ }
792
1804
  // Add pattern-specific insights
793
1805
  if (patternAnalysis.suggestions.length > 0) {
794
- responseText += `\n\n🎯 TESTING-VALIDATED PATTERN INSIGHTS (${patternAnalysis.patternType.toUpperCase()}):`;
1806
+ responseText += `\n\n🎯 PATTERN INSIGHTS (${patternAnalysis.patternType.toUpperCase()}):`;
795
1807
  patternAnalysis.suggestions.forEach(suggestion => {
796
1808
  responseText += `\n• ${suggestion}`;
797
1809
  });
798
1810
  }
1811
+ // Add boolean operator recommendations
1812
+ if (patternAnalysis.booleanRecommendations.length > 0) {
1813
+ responseText += `\n\n🔍 BOOLEAN OPERATOR RECOMMENDATIONS:`;
1814
+ patternAnalysis.booleanRecommendations.forEach(rec => {
1815
+ responseText += `\n• ${rec}`;
1816
+ });
1817
+ }
1818
+ // Add context enrichment suggestions
1819
+ if (patternAnalysis.contextEnrichment.length > 0) {
1820
+ responseText += `\n\n💡 CONTEXT ENRICHMENT SUGGESTIONS:`;
1821
+ patternAnalysis.contextEnrichment.forEach(context => {
1822
+ responseText += `\n• ${context}`;
1823
+ });
1824
+ }
799
1825
  // Add critical warnings
800
1826
  if (patternAnalysis.warnings.length > 0) {
801
1827
  responseText += `\n\n⚠️ CRITICAL WARNINGS:`;
@@ -803,14 +1829,24 @@ function registerGitHubSearchCodeTool(server) {
803
1829
  responseText += `\n• ${warning}`;
804
1830
  });
805
1831
  }
806
- // Add general best practices from testing
807
- responseText += `\n\n📋 TESTING-VALIDATED BEST PRACTICES:`;
808
- responseText += `\n• Boolean operators work: "useState OR useEffect", "error NOT test"`;
809
- responseText += `\n• Path filters effective: "packages/react/src/__tests__" ✅`;
810
- responseText += `\n• Extension filters reliable: .ts, .js, .jsx extensions ✅`;
811
- responseText += `\n• Repository-specific targeting: owner/repo combinations ✅`;
1832
+ // Enhanced best practices with GitHub API limitations
1833
+ responseText += `\n\n📋 GITHUB API SEARCH BEST PRACTICES:`;
1834
+ responseText += `\n• SUPPORTED: "useState OR useEffect", "function NOT test"`;
1835
+ responseText += `\n• NOT SUPPORTED: "(useState OR useEffect) AND typescript" (parentheses)`;
1836
+ responseText += `\n• ⚠️ COMPLEXITY LIMIT: Max 3-4 boolean operators per query`;
1837
+ responseText += `\n• 🎯 PATTERN MATCHING: "async function" vs "function.*async"`;
1838
+ responseText += `\n• 🚫 EXCLUDE NOISE: "auth NOT mock NOT test" for production code`;
1839
+ responseText += `\n• 🔄 VARIATION COVERAGE: "login OR signin OR authenticate"`;
812
1840
  if (!args.owner && !args.repo) {
813
- responseText += `\n• Cross-repository search proven for "async function" patterns`;
1841
+ responseText += `\n• 🌐 GLOBAL SEARCH: Works well for common patterns across repositories`;
1842
+ }
1843
+ // Add alternative query suggestions
1844
+ if (queryOptimization.fallbackQueries.length > 0 &&
1845
+ !usedFallbackQuery) {
1846
+ responseText += `\n\n🔄 ALTERNATIVE QUERY SUGGESTIONS:`;
1847
+ queryOptimization.fallbackQueries.forEach(query => {
1848
+ responseText += `\n• "${query}" - Simplified version for better compatibility`;
1849
+ });
814
1850
  }
815
1851
  return {
816
1852
  content: [
@@ -825,20 +1861,65 @@ function registerGitHubSearchCodeTool(server) {
825
1861
  return result;
826
1862
  }
827
1863
  catch (error) {
828
- // Enhanced error handling with testing insights
1864
+ // Enhanced error handling with intelligent suggestions
829
1865
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
830
- const fallbackSuggestions = `
831
- 🔄 TESTING-VALIDATED FALLBACK STRATEGIES:
832
- Try simpler search terms - complex patterns may fail
833
- • Remove path filters if getting 0 results - many repos don't use 'src'
834
- Use proven patterns: "export function", "useState OR useEffect"
835
- Consider repository-specific search: owner + repo + simple terms
836
- For React: use "packages" not "src" in path filters`;
1866
+ // Detect specific error types
1867
+ let errorType = 'general';
1868
+ let specificSuggestions = '';
1869
+ if (errorMessage.includes('JSON') || errorMessage.includes('parse')) {
1870
+ errorType = 'json-parsing';
1871
+ specificSuggestions = `
1872
+ 🔧 JSON PARSING ERROR SOLUTIONS:
1873
+ • QUERY SIMPLIFICATION: Remove complex boolean logic
1874
+ • SYNTAX CHECK: Avoid parentheses () in queries
1875
+ • RETRY STRATEGY: Try single keywords instead of complex queries`;
1876
+ }
1877
+ else if (errorMessage.includes('API') ||
1878
+ errorMessage.includes('rate')) {
1879
+ errorType = 'api-limit';
1880
+ specificSuggestions = `
1881
+ 🔧 API LIMIT SOLUTIONS:
1882
+ • REDUCE FREQUENCY: Wait before retrying
1883
+ • SIMPLIFY QUERIES: Use fewer boolean operators
1884
+ • SCOPE NARROWING: Add owner/repo parameters`;
1885
+ }
1886
+ else if (errorMessage.includes('syntax') ||
1887
+ errorMessage.includes('invalid')) {
1888
+ errorType = 'syntax-error';
1889
+ specificSuggestions = `
1890
+ 🔧 SYNTAX ERROR SOLUTIONS:
1891
+ • REMOVE PARENTHESES: GitHub API doesn't support () grouping
1892
+ • SIMPLIFY BOOLEAN: Use "term1 OR term2" not "(term1 OR term2)"
1893
+ • CHECK OPERATORS: Only AND, OR, NOT are supported`;
1894
+ }
1895
+ let fallbackSuggestions = `
1896
+ 🔄 INTELLIGENT FALLBACK STRATEGIES:
1897
+ • PROGRESSIVE SIMPLIFICATION: Start with single terms, add complexity gradually
1898
+ • BOOLEAN BASICS: "term1 OR term2" works, "(term1 OR term2) AND term3" doesn't
1899
+ • EXCLUDE NOISE: Add "NOT test NOT spec NOT mock" to focus on production code
1900
+ • REMOVE FILTERS: Try without path/language filters first
1901
+ • REPOSITORY TARGETING: Use owner/repo for focused searches${specificSuggestions}`;
1902
+ // Add pattern-specific fallback suggestions
1903
+ const query = args.query.toLowerCase();
1904
+ if (query.includes('react')) {
1905
+ fallbackSuggestions += `\n• REACT SPECIFIC: Try "useState OR useEffect", avoid complex hook combinations`;
1906
+ }
1907
+ if (query.includes('auth')) {
1908
+ fallbackSuggestions += `\n• AUTH SPECIFIC: Try "login OR authenticate OR signin NOT test"`;
1909
+ }
1910
+ if (query.includes('api')) {
1911
+ fallbackSuggestions += `\n• API SPECIFIC: Try "fetch OR axios OR request NOT mock"`;
1912
+ }
1913
+ // Add the attempted queries for debugging
1914
+ fallbackSuggestions += `\n\n🔍 DEBUGGING INFO:
1915
+ • Original Query: "${args.query}"
1916
+ • Error Type: ${errorType}
1917
+ • Error Message: ${errorMessage}`;
837
1918
  return {
838
1919
  content: [
839
1920
  {
840
1921
  type: 'text',
841
- text: `GitHub Code Search Failed: ${errorMessage}${fallbackSuggestions}`,
1922
+ text: `🚨 GitHub Code Search Failed: ${errorMessage}${fallbackSuggestions}`,
842
1923
  },
843
1924
  ],
844
1925
  isError: true,
@@ -859,31 +1940,127 @@ async function fetchGitHubFileContent(params) {
859
1940
  const args = [apiPath, '--jq', '.content'];
860
1941
  const result = await executeGitHubCommand('api', args, { cache: false });
861
1942
  if (result.isError) {
862
- return result;
1943
+ // Parse the error message to provide better context
1944
+ const errorMsg = result.content[0].text;
1945
+ // Handle common GitHub API errors
1946
+ if (errorMsg.includes('404') || errorMsg.includes('Not Found')) {
1947
+ return createErrorResult$1(`File not found: ${params.filePath}`, new Error(`
1948
+ ❌ FILE NOT FOUND: The file '${params.filePath}' does not exist in ${params.owner}/${params.repo}${params.branch ? ` on branch '${params.branch}'` : ''}.
1949
+
1950
+ 🔍 COMMON CAUSES:
1951
+ • File path is incorrect or has changed
1952
+ • Branch '${params.branch || 'default'}' doesn't contain this file
1953
+ • File may exist in a different directory
1954
+
1955
+ 💡 RECOMMENDED ACTIONS:
1956
+ 1. Use 'github_get_contents' to explore repository structure first
1957
+ 2. Use 'github_search_code' to find files by name or pattern
1958
+ 3. Verify the branch contains the expected files
1959
+
1960
+ 📍 SEARCH ALTERNATIVES:
1961
+ • Search for filename: query="${params.filePath.split('/').pop()}"
1962
+ • Search in repository: repo:${params.owner}/${params.repo}
1963
+ • Explore repository structure starting from root`));
1964
+ }
1965
+ if (errorMsg.includes('403') || errorMsg.includes('Forbidden')) {
1966
+ return createErrorResult$1(`Access denied to file: ${params.filePath}`, new Error(`
1967
+ 🔒 ACCESS DENIED: You don't have permission to access '${params.filePath}' in ${params.owner}/${params.repo}.
1968
+
1969
+ 🔍 POSSIBLE CAUSES:
1970
+ • Repository is private and you lack access
1971
+ • File is in a protected branch
1972
+ • Organization restrictions apply
1973
+
1974
+ 💡 RECOMMENDED ACTIONS:
1975
+ 1. Check if you're authenticated: gh auth status
1976
+ 2. Request repository access from owner
1977
+ 3. Use 'github_get_user_organizations' if this is your organization`));
1978
+ }
1979
+ // Handle rate limiting
1980
+ if (errorMsg.includes('rate limit') || errorMsg.includes('429')) {
1981
+ return createErrorResult$1('GitHub API rate limit exceeded', new Error(`
1982
+ ⏱️ RATE LIMIT: GitHub API rate limit has been exceeded.
1983
+
1984
+ 💡 RECOMMENDED ACTIONS:
1985
+ 1. Wait a few minutes before trying again
1986
+ 2. Use authentication to increase rate limits: gh auth login
1987
+ 3. Try searching for content instead of direct file access`));
1988
+ }
1989
+ // Generic error fallback
1990
+ return createErrorResult$1(`Failed to fetch file content: ${params.filePath}`, new Error(`GitHub API Error: ${errorMsg}
1991
+
1992
+ 🔧 TROUBLESHOOTING:
1993
+ • Verify repository exists: ${params.owner}/${params.repo}
1994
+ • Check file path: ${params.filePath}
1995
+ • Confirm branch: ${params.branch || 'default'}
1996
+ • Use repository exploration tools first`));
863
1997
  }
864
1998
  // Extract the actual content from the exec result
865
1999
  const execResult = JSON.parse(result.content[0].text);
866
2000
  const base64Content = execResult.result.trim().replace(/\n/g, '');
2001
+ // Validate base64 content
2002
+ if (!base64Content || base64Content === 'null') {
2003
+ return createErrorResult$1(`Empty or invalid file content: ${params.filePath}`, new Error(`
2004
+ 📄 EMPTY FILE: The file '${params.filePath}' exists but contains no content or returned invalid data.
2005
+
2006
+ 🔍 POSSIBLE CAUSES:
2007
+ • File is empty or binary
2008
+ • API returned null content
2009
+ • File is too large for API response
2010
+
2011
+ 💡 ALTERNATIVES:
2012
+ • Use 'github_search_code' to find content by pattern
2013
+ • Check file in GitHub web interface
2014
+ • Try accessing a different file in the same directory`));
2015
+ }
867
2016
  // Decode base64 content using Node.js Buffer
868
2017
  let decodedContent;
869
2018
  try {
870
2019
  decodedContent = Buffer.from(base64Content, 'base64').toString('utf-8');
871
2020
  }
872
2021
  catch (decodeError) {
873
- throw new Error(`Failed to decode base64 content: ${decodeError.message}`);
2022
+ return createErrorResult$1(`Failed to decode file content: ${params.filePath}`, new Error(`
2023
+ 🔧 DECODE ERROR: Unable to decode base64 content from GitHub API.
2024
+
2025
+ 📋 DETAILS: ${decodeError.message}
2026
+
2027
+ 💡 POSSIBLE CAUSES:
2028
+ • File contains binary data
2029
+ • Corrupted response from API
2030
+ • Encoding mismatch
2031
+
2032
+ 🔍 ALTERNATIVES:
2033
+ • Use 'github_search_code' to find text-based content
2034
+ • Check if file is binary (images, executables, etc.)
2035
+ • Try accessing a different version of the file`));
874
2036
  }
875
- return {
876
- content: [
877
- {
878
- type: 'text',
879
- text: decodedContent,
880
- },
881
- ],
882
- isError: false,
883
- };
2037
+ return createSuccessResult$1({
2038
+ filePath: params.filePath,
2039
+ owner: params.owner,
2040
+ repo: params.repo,
2041
+ branch: params.branch,
2042
+ content: decodedContent,
2043
+ size: decodedContent.length,
2044
+ encoding: 'utf-8',
2045
+ });
884
2046
  }
885
2047
  catch (error) {
886
- return createErrorResult$1('Failed to retrieve file content', error);
2048
+ return createErrorResult$1(`Unexpected error fetching file content: ${params.filePath}`, new Error(`
2049
+ ❌ UNEXPECTED ERROR: ${error.message}
2050
+
2051
+ 📍 FILE DETAILS:
2052
+ • Repository: ${params.owner}/${params.repo}
2053
+ • File: ${params.filePath}
2054
+ • Branch: ${params.branch || 'default'}
2055
+
2056
+ 🔧 TROUBLESHOOTING STEPS:
2057
+ 1. Verify repository exists with 'github_get_repository'
2058
+ 2. Explore structure with 'github_get_contents'
2059
+ 3. Search for file with 'github_search_code'
2060
+ 4. Check GitHub authentication: gh auth status
2061
+
2062
+ 💡 WORKFLOW RECOMMENDATION:
2063
+ github_get_repository → github_get_contents → github_search_code → github_get_file_content`));
887
2064
  }
888
2065
  });
889
2066
  }
@@ -932,25 +2109,434 @@ async function viewGitHubRepositoryInfo(params) {
932
2109
  const args = ['view', `${owner}/${params.repo}`];
933
2110
  const result = await executeGitHubCommand('repo', args, { cache: false });
934
2111
  if (result.isError) {
935
- return result;
2112
+ // Parse the error message to provide better context
2113
+ const errorMsg = result.content[0].text;
2114
+ // Handle repository not found
2115
+ if (errorMsg.includes('404') ||
2116
+ errorMsg.includes('Not Found') ||
2117
+ errorMsg.includes('could not resolve to a Repository')) {
2118
+ return createErrorResult$1(`Repository not found: ${owner}/${params.repo}`, new Error(`
2119
+ ❌ REPOSITORY NOT FOUND: The repository '${owner}/${params.repo}' does not exist or is not accessible.
2120
+
2121
+ 🔍 COMMON CAUSES:
2122
+ • Repository name is incorrect
2123
+ • Repository is private and you lack access
2124
+ • Owner/organization name is wrong
2125
+ • Repository has been deleted or moved
2126
+
2127
+ 🎯 RECOMMENDED DISCOVERY WORKFLOW (in this order):
2128
+
2129
+ 1️⃣ **NPM PACKAGE DISCOVERY** (if this is a package):
2130
+ • Use 'npm_search_packages' with keywords: "${params.repo}"
2131
+ • Then 'npm_get_package' to find the GitHub repository URL
2132
+ • This automatically discovers the correct owner/repo
2133
+
2134
+ 2️⃣ **GITHUB TOPICS SEARCH** (for broader discovery):
2135
+ • Use 'github_search_topics' with terms: "${params.repo}"
2136
+ • Discover related repositories and ecosystems
2137
+ • Find the correct repository among similar projects
2138
+
2139
+ 3️⃣ **REPOSITORY SEARCH** (last resort):
2140
+ • Use 'github_search_repositories' with query: "${params.repo}"
2141
+ • Add filters like language, stars, etc.
2142
+ • Manual selection from search results
2143
+
2144
+ 💡 ORGANIZATION ACCESS:
2145
+ If this should be a private repository, try:
2146
+ • 'github_get_user_organizations' to see your available orgs
2147
+ • Use the correct organization name as owner
2148
+
2149
+ 🔧 VERIFICATION:
2150
+ • Check repository exists at: https://github.com/${owner}/${params.repo}
2151
+ • Verify spelling and case sensitivity`));
2152
+ }
2153
+ // Handle access denied
2154
+ if (errorMsg.includes('403') || errorMsg.includes('Forbidden')) {
2155
+ return createErrorResult$1(`Access denied to repository: ${owner}/${params.repo}`, new Error(`
2156
+ 🔒 ACCESS DENIED: You don't have permission to access '${owner}/${params.repo}'.
2157
+
2158
+ 🔍 POSSIBLE CAUSES:
2159
+ • Repository is private
2160
+ • Organization restrictions
2161
+ • Invalid authentication
2162
+
2163
+ 💡 RECOMMENDED ACTIONS:
2164
+ 1. Check authentication: gh auth status
2165
+ 2. Request repository access from owner: ${owner}
2166
+ 3. Use 'github_get_user_organizations' if this is your org
2167
+ 4. Verify you're logged into the correct GitHub account
2168
+
2169
+ 🎯 ALTERNATIVE DISCOVERY:
2170
+ If you're looking for similar repositories, try:
2171
+ • 'npm_search_packages' for packages
2172
+ • 'github_search_topics' for general discovery
2173
+ • 'github_search_repositories' with broader terms`));
2174
+ }
2175
+ // Handle rate limiting
2176
+ if (errorMsg.includes('rate limit') || errorMsg.includes('429')) {
2177
+ return createErrorResult$1('GitHub API rate limit exceeded', new Error(`
2178
+ ⏱️ RATE LIMIT: GitHub API rate limit has been exceeded.
2179
+
2180
+ 💡 RECOMMENDED ACTIONS:
2181
+ 1. Wait a few minutes before trying again
2182
+ 2. Use authentication to increase rate limits: gh auth login
2183
+ 3. Try discovery tools instead: npm_search_packages or github_search_topics`));
2184
+ }
2185
+ // Generic error fallback
2186
+ return createErrorResult$1(`Failed to access repository: ${owner}/${params.repo}`, new Error(`GitHub CLI Error: ${errorMsg}
2187
+
2188
+ 🔧 TROUBLESHOOTING:
2189
+ • Verify repository exists: https://github.com/${owner}/${params.repo}
2190
+ • Check spelling and case sensitivity
2191
+ • Confirm authentication: gh auth status
2192
+
2193
+ 🎯 DISCOVERY WORKFLOW:
2194
+ 1. npm_search_packages → npm_get_package
2195
+ 2. github_search_topics
2196
+ 3. github_search_repositories
2197
+ 4. github_get_repository (current step)`));
936
2198
  }
937
2199
  // Extract the actual content from the exec result
938
2200
  const execResult = JSON.parse(result.content[0].text);
939
2201
  const content = execResult.result;
2202
+ // Parse repository info to extract key details
940
2203
  const viewResult = {
941
2204
  owner,
942
2205
  repo: params.repo,
943
2206
  repositoryInfo: content,
944
2207
  rawOutput: content,
945
2208
  };
946
- return createSuccessResult$1(viewResult);
947
- }
948
- catch (error) {
949
- return createErrorResult$1('Failed to view GitHub repository', error);
950
- }
2209
+ // Try to extract branch information from the output
2210
+ let defaultBranch = 'main'; // fallback
2211
+ try {
2212
+ // The content is usually YAML-like output from gh repo view
2213
+ const lines = content.split('\n');
2214
+ for (const line of lines) {
2215
+ if (line.includes('default branch:') ||
2216
+ line.includes('Default branch:')) {
2217
+ const branchMatch = line.split(':')[1]?.trim();
2218
+ if (branchMatch) {
2219
+ defaultBranch = branchMatch;
2220
+ break;
2221
+ }
2222
+ }
2223
+ }
2224
+ }
2225
+ catch (parseError) {
2226
+ // If we can't parse the branch, keep the fallback
2227
+ }
2228
+ return createSuccessResult$1({
2229
+ ...viewResult,
2230
+ defaultBranch,
2231
+ success: true,
2232
+ message: `✅ Repository found: ${owner}/${params.repo}
2233
+
2234
+ 📋 REPOSITORY DETAILS:
2235
+ • Default branch: ${defaultBranch}
2236
+ • Ready for file operations
2237
+
2238
+ 🔄 NEXT RECOMMENDED STEPS:
2239
+ 1. Explore structure: github_get_contents
2240
+ 2. Search for code: github_search_code
2241
+ 3. Fetch specific files: github_get_file_content
2242
+
2243
+ ⚠️ IMPORTANT: Use branch '${defaultBranch}' in subsequent file operations.`,
2244
+ });
2245
+ }
2246
+ catch (error) {
2247
+ return createErrorResult$1(`Unexpected error accessing repository: ${params.owner}/${params.repo}`, new Error(`
2248
+ ❌ UNEXPECTED ERROR: ${error.message}
2249
+
2250
+ 📍 REPOSITORY DETAILS:
2251
+ • Owner: ${params.owner}
2252
+ • Repository: ${params.repo}
2253
+
2254
+ 🔧 TROUBLESHOOTING STEPS:
2255
+ 1. Verify GitHub CLI is installed and authenticated
2256
+ 2. Check network connectivity
2257
+ 3. Try discovery workflow instead:
2258
+
2259
+ 🎯 DISCOVERY WORKFLOW:
2260
+ 1. npm_search_packages "${params.repo}"
2261
+ 2. github_search_topics "${params.repo}"
2262
+ 3. github_search_repositories query="${params.repo}" owner="${params.owner}"
2263
+ 4. github_get_repository (retry after discovery)
2264
+
2265
+ 💡 This ensures you have the correct owner/repo before attempting direct access.`));
2266
+ }
951
2267
  });
952
2268
  }
953
2269
 
2270
+ // Cross-Tool Orchestration Chains
2271
+ const TOOL_FALLBACK_CHAINS = {
2272
+ 'package-discovery': [
2273
+ { tool: TOOL_NAMES.NPM_SEARCH_PACKAGES, reason: 'Primary package search' },
2274
+ {
2275
+ tool: TOOL_NAMES.GITHUB_SEARCH_TOPICS,
2276
+ reason: 'Ecosystem terminology discovery',
2277
+ },
2278
+ {
2279
+ tool: TOOL_NAMES.GITHUB_SEARCH_REPOS,
2280
+ reason: 'Repository-based discovery',
2281
+ },
2282
+ {
2283
+ tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
2284
+ reason: 'Code implementation search',
2285
+ },
2286
+ ],
2287
+ 'code-discovery': [
2288
+ { tool: TOOL_NAMES.GITHUB_SEARCH_CODE, reason: 'Direct code search' },
2289
+ { tool: TOOL_NAMES.GITHUB_SEARCH_REPOS, reason: 'Project-level discovery' },
2290
+ { tool: TOOL_NAMES.NPM_SEARCH_PACKAGES, reason: 'Package-based solutions' },
2291
+ {
2292
+ tool: TOOL_NAMES.GITHUB_SEARCH_ISSUES,
2293
+ reason: 'Problem discussion search',
2294
+ },
2295
+ ],
2296
+ 'repository-discovery': [
2297
+ { tool: TOOL_NAMES.NPM_GET_REPOSITORY, reason: 'Package-to-repo mapping' },
2298
+ {
2299
+ tool: TOOL_NAMES.GITHUB_SEARCH_REPOS,
2300
+ reason: 'Direct repository search',
2301
+ },
2302
+ { tool: TOOL_NAMES.GITHUB_SEARCH_TOPICS, reason: 'Topic-based discovery' },
2303
+ { tool: TOOL_NAMES.GITHUB_SEARCH_USERS, reason: 'Organization discovery' },
2304
+ ],
2305
+ 'issue-discovery': [
2306
+ { tool: TOOL_NAMES.GITHUB_SEARCH_ISSUES, reason: 'Primary issue search' },
2307
+ {
2308
+ tool: TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS,
2309
+ reason: 'Solution implementation search',
2310
+ },
2311
+ { tool: TOOL_NAMES.GITHUB_SEARCH_CODE, reason: 'Code example search' },
2312
+ {
2313
+ tool: TOOL_NAMES.GITHUB_SEARCH_REPOS,
2314
+ reason: 'Related project discovery',
2315
+ },
2316
+ ],
2317
+ 'user-discovery': [
2318
+ { tool: TOOL_NAMES.GITHUB_SEARCH_USERS, reason: 'Primary user search' },
2319
+ {
2320
+ tool: TOOL_NAMES.GITHUB_GET_USER_ORGS,
2321
+ reason: 'Organization membership discovery',
2322
+ },
2323
+ { tool: TOOL_NAMES.GITHUB_SEARCH_REPOS, reason: 'User project discovery' },
2324
+ { tool: TOOL_NAMES.GITHUB_SEARCH_CODE, reason: 'Contribution analysis' },
2325
+ ],
2326
+ };
2327
+ // Query Simplification Utilities
2328
+ class QueryOptimizer {
2329
+ static getProgressiveQueries(originalQuery) {
2330
+ const queries = [];
2331
+ // Original query
2332
+ queries.push(originalQuery);
2333
+ // Remove special characters and clean up
2334
+ const cleaned = originalQuery.replace(/[^\w\s-]/g, ' ').trim();
2335
+ if (cleaned !== originalQuery) {
2336
+ queries.push(cleaned);
2337
+ }
2338
+ // Extract key terms (remove common words)
2339
+ const stopWords = [
2340
+ 'the',
2341
+ 'a',
2342
+ 'an',
2343
+ 'and',
2344
+ 'or',
2345
+ 'but',
2346
+ 'in',
2347
+ 'on',
2348
+ 'at',
2349
+ 'to',
2350
+ 'for',
2351
+ 'of',
2352
+ 'with',
2353
+ 'by',
2354
+ ];
2355
+ const terms = cleaned
2356
+ .split(/\s+/)
2357
+ .filter(term => term.length > 2 && !stopWords.includes(term.toLowerCase()));
2358
+ // Multiple key terms
2359
+ if (terms.length >= 2) {
2360
+ queries.push(terms.slice(0, 2).join(' '));
2361
+ }
2362
+ // Single most important term
2363
+ if (terms.length >= 1) {
2364
+ queries.push(terms[0]);
2365
+ }
2366
+ // Remove duplicates and return
2367
+ return [...new Set(queries)];
2368
+ }
2369
+ static simplifyPackageName(packageName) {
2370
+ const variations = [packageName];
2371
+ // Remove scope if present
2372
+ if (packageName.startsWith('@')) {
2373
+ const withoutScope = packageName.split('/')[1];
2374
+ if (withoutScope) {
2375
+ variations.push(withoutScope);
2376
+ }
2377
+ }
2378
+ // Remove common suffixes
2379
+ const suffixes = ['-js', '-node', '-lib', '-tool', '-cli', '-api'];
2380
+ suffixes.forEach(suffix => {
2381
+ if (packageName.endsWith(suffix)) {
2382
+ variations.push(packageName.slice(0, -suffix.length));
2383
+ }
2384
+ });
2385
+ return [...new Set(variations)];
2386
+ }
2387
+ }
2388
+ // Context Analysis
2389
+ class ContextAnalyzer {
2390
+ static analyzeQuery(query) {
2391
+ const lowerQuery = query.toLowerCase();
2392
+ const keywords = query.split(/\s+/).filter(term => term.length > 2);
2393
+ // Determine query type
2394
+ let type = 'general';
2395
+ if (lowerQuery.includes('npm') ||
2396
+ lowerQuery.includes('package') ||
2397
+ lowerQuery.includes('install')) {
2398
+ type = 'package';
2399
+ }
2400
+ else if (lowerQuery.includes('function') ||
2401
+ lowerQuery.includes('class') ||
2402
+ lowerQuery.includes('import')) {
2403
+ type = 'code';
2404
+ }
2405
+ else if (lowerQuery.includes('repo') ||
2406
+ lowerQuery.includes('project') ||
2407
+ lowerQuery.includes('github')) {
2408
+ type = 'repository';
2409
+ }
2410
+ else if (lowerQuery.includes('bug') ||
2411
+ lowerQuery.includes('issue') ||
2412
+ lowerQuery.includes('problem')) {
2413
+ type = 'issue';
2414
+ }
2415
+ else if (lowerQuery.includes('user') ||
2416
+ lowerQuery.includes('developer') ||
2417
+ lowerQuery.includes('maintainer')) {
2418
+ type = 'user';
2419
+ }
2420
+ // Determine complexity
2421
+ const complexity = keywords.length <= 1
2422
+ ? 'simple'
2423
+ : keywords.length <= 3
2424
+ ? 'medium'
2425
+ : 'complex';
2426
+ // Generate suggestions
2427
+ const suggestions = [];
2428
+ if (complexity === 'complex') {
2429
+ suggestions.push('Try breaking down into simpler terms');
2430
+ suggestions.push('Use 1-2 key words instead of full phrases');
2431
+ }
2432
+ return { type, keywords, complexity, suggestions };
2433
+ }
2434
+ static getToolChain(queryType) {
2435
+ const chainKey = `${queryType}-discovery`;
2436
+ return (TOOL_FALLBACK_CHAINS[chainKey] ||
2437
+ TOOL_FALLBACK_CHAINS['package-discovery']);
2438
+ }
2439
+ }
2440
+ // Enhanced Error Recovery
2441
+ function generateSmartRecovery(options) {
2442
+ const { tool, query, packageName, resultCount, error } = options;
2443
+ const queryAnalysis = query ? ContextAnalyzer.analyzeQuery(query) : null;
2444
+ const simplifiedQueries = query
2445
+ ? QueryOptimizer.getProgressiveQueries(query)
2446
+ : [];
2447
+ const packageVariations = packageName
2448
+ ? QueryOptimizer.simplifyPackageName(packageName)
2449
+ : [];
2450
+ // Determine appropriate tool chain
2451
+ const toolChain = queryAnalysis
2452
+ ? ContextAnalyzer.getToolChain(queryAnalysis.type)
2453
+ : TOOL_FALLBACK_CHAINS['package-discovery'];
2454
+ // Build comprehensive recovery message
2455
+ let recoveryText = `${tool} failed: ${error.message}`;
2456
+ // Context-specific analysis
2457
+ if (queryAnalysis) {
2458
+ recoveryText += `
2459
+
2460
+ 🔍 QUERY ANALYSIS:
2461
+ • Type: ${queryAnalysis.type.toUpperCase()} search
2462
+ • Complexity: ${queryAnalysis.complexity.toUpperCase()}
2463
+ • Keywords: ${queryAnalysis.keywords.join(', ')}`;
2464
+ if (queryAnalysis.suggestions.length > 0) {
2465
+ recoveryText += `
2466
+ • Suggestions: ${queryAnalysis.suggestions.join(', ')}`;
2467
+ }
2468
+ }
2469
+ // Query simplification suggestions
2470
+ if (simplifiedQueries.length > 1) {
2471
+ recoveryText += `
2472
+
2473
+ 🔄 SIMPLIFIED QUERY OPTIONS:
2474
+ ${simplifiedQueries
2475
+ .slice(1)
2476
+ .map((q, i) => `${i + 1}. "${q}"`)
2477
+ .join('\n')}`;
2478
+ }
2479
+ // Package name variations
2480
+ if (packageVariations.length > 1) {
2481
+ recoveryText += `
2482
+
2483
+ 📦 PACKAGE NAME VARIATIONS:
2484
+ ${packageVariations
2485
+ .slice(1)
2486
+ .map((v, i) => `${i + 1}. "${v}"`)
2487
+ .join('\n')}`;
2488
+ }
2489
+ // Cross-tool recommendations
2490
+ recoveryText += `
2491
+
2492
+ 🔗 ALTERNATIVE TOOL CHAIN:
2493
+ ${toolChain.map((t, i) => `${i + 1}. ${t.tool} - ${t.reason}`).join('\n')}`;
2494
+ // Specific error type handling
2495
+ if (error.message.includes('404') || error.message.includes('not found')) {
2496
+ recoveryText += `
2497
+
2498
+ 💡 NOT FOUND RECOVERY:
2499
+ • Check spelling and exact names
2500
+ • Try search tools instead of direct access
2501
+ • Use broader discovery methods first`;
2502
+ }
2503
+ if (error.message.includes('API') || error.message.includes('rate limit')) {
2504
+ recoveryText += `
2505
+
2506
+ ⏱️ API LIMIT RECOVERY:
2507
+ • Wait a moment before retrying
2508
+ • Use simpler queries to reduce API usage
2509
+ • Try different tools that may use different API endpoints`;
2510
+ }
2511
+ // General best practices
2512
+ recoveryText += `
2513
+
2514
+ 📋 PROVEN RECOVERY WORKFLOW:
2515
+ 1. Start with search tools (npm_search_packages, github_search_repos)
2516
+ 2. Use discovery results to guide specific tool usage
2517
+ 3. Progressively simplify queries if needed
2518
+ 4. Try alternative tool chains for different perspectives`;
2519
+ // Context-specific recommendations
2520
+ if (resultCount === 0) {
2521
+ recoveryText += `
2522
+
2523
+ 🎯 ZERO RESULTS STRATEGY:
2524
+ • Broaden search terms
2525
+ • Remove restrictive filters
2526
+ • Try ecosystem discovery tools
2527
+ • Use single keywords instead of phrases`;
2528
+ }
2529
+ return {
2530
+ content: [
2531
+ {
2532
+ type: 'text',
2533
+ text: recoveryText,
2534
+ },
2535
+ ],
2536
+ isError: true,
2537
+ };
2538
+ }
2539
+
954
2540
  function registerViewRepositoryTool(server) {
955
2541
  server.tool(TOOL_NAMES.GITHUB_GET_REPOSITORY, TOOL_DESCRIPTIONS[TOOL_NAMES.GITHUB_GET_REPOSITORY], {
956
2542
  owner: z
@@ -970,88 +2556,12 @@ function registerViewRepositoryTool(server) {
970
2556
  return await viewGitHubRepositoryInfo(args);
971
2557
  }
972
2558
  catch (error) {
973
- return {
974
- content: [
975
- {
976
- type: 'text',
977
- text: `Failed to view repository: ${error.message}`,
978
- },
979
- ],
980
- isError: true,
981
- };
982
- }
983
- });
984
- }
985
-
986
- async function npmView(packageName) {
987
- const cacheKey = generateCacheKey('npm-view', { packageName });
988
- return withCache(cacheKey, async () => {
989
- try {
990
- const result = await executeNpmCommand('view', [packageName, '--json'], {
991
- cache: true,
2559
+ return generateSmartRecovery({
2560
+ tool: 'GitHub Repository View',
2561
+ owner: args.owner,
2562
+ repo: args.repo,
2563
+ error: error,
992
2564
  });
993
- if (result.isError) {
994
- return result;
995
- }
996
- // Parse the result from the executed command
997
- const commandOutput = JSON.parse(result.content[0].text);
998
- const npmData = commandOutput.result;
999
- let popularityData = '';
1000
- try {
1001
- // Get version count as popularity indicator
1002
- const versionsResult = await executeNpmCommand('view', [
1003
- packageName,
1004
- 'time',
1005
- '--json',
1006
- ]);
1007
- if (!versionsResult.isError) {
1008
- const versionsOutput = JSON.parse(versionsResult.content[0].text);
1009
- const timeData = versionsOutput.result;
1010
- const versionCount = Object.keys(timeData).length - 2; // Subtract 'created' and 'modified'
1011
- popularityData = `Package versions released: ${versionCount}`;
1012
- }
1013
- }
1014
- catch {
1015
- // Popularity data is optional
1016
- }
1017
- const enhancedResult = {
1018
- npmData: JSON.parse(JSON.stringify(npmData)),
1019
- popularityInfo: popularityData,
1020
- lastAnalyzed: new Date().toISOString(),
1021
- };
1022
- return createSuccessResult$1(enhancedResult);
1023
- }
1024
- catch (error) {
1025
- return createErrorResult$1('Failed to get npm repository information', error);
1026
- }
1027
- });
1028
- }
1029
-
1030
- function registerNpmViewTool(server) {
1031
- server.tool(TOOL_NAMES.NPM_GET_PACKAGE, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_PACKAGE], {
1032
- packageName: z
1033
- .string()
1034
- .describe("The name of the npm package to analyze (e.g., 'react', '@types/node', 'lodash')"),
1035
- }, {
1036
- title: 'View NPM Package',
1037
- readOnlyHint: true,
1038
- destructiveHint: false,
1039
- idempotentHint: true,
1040
- openWorldHint: true,
1041
- }, async (args) => {
1042
- try {
1043
- return await npmView(args.packageName);
1044
- }
1045
- catch (error) {
1046
- return {
1047
- content: [
1048
- {
1049
- type: 'text',
1050
- text: `Failed to get npm package info: ${error.message}`,
1051
- },
1052
- ],
1053
- isError: true,
1054
- };
1055
2565
  }
1056
2566
  });
1057
2567
  }
@@ -1184,8 +2694,8 @@ function buildGitHubReposSearchCommand(params) {
1184
2694
  args.push(`--include-forks=${params.includeForks}`);
1185
2695
  if (params.language)
1186
2696
  args.push(`--language=${params.language}`);
1187
- if (params.license)
1188
- args.push(`--license=${params.license}`);
2697
+ if (params.license && params.license.length > 0)
2698
+ args.push(`--license=${params.license.join(',')}`);
1189
2699
  if (params.limit)
1190
2700
  args.push(`--limit=${params.limit}`);
1191
2701
  if (params.match)
@@ -1196,15 +2706,15 @@ function buildGitHubReposSearchCommand(params) {
1196
2706
  args.push(`--order=${params.order}`);
1197
2707
  if (params.size)
1198
2708
  args.push(`--size="${params.size}"`);
1199
- // DEFAULT TO UPDATED SORTING for recency prioritization
1200
- const sortBy = params.sort || 'updated';
2709
+ // Use best-match as default, only specify sort if different from default
2710
+ const sortBy = params.sort || 'best-match';
1201
2711
  if (sortBy !== 'best-match') {
1202
2712
  args.push(`--sort=${sortBy}`);
1203
2713
  }
1204
2714
  if (params.stars !== undefined)
1205
- args.push(`--stars=${params.stars}`);
1206
- if (params.topic)
1207
- args.push(`--topic=${params.topic}`);
2715
+ args.push(`--stars="${params.stars}"`);
2716
+ if (params.topic && params.topic.length > 0)
2717
+ args.push(`--topic=${params.topic.join(',')}`);
1208
2718
  if (params.updated)
1209
2719
  args.push(`--updated="${params.updated}"`);
1210
2720
  if (params.visibility)
@@ -1264,7 +2774,13 @@ function validateFilterCombinations(args) {
1264
2774
  suggestion: 'PROVEN: owner=facebook + query=react without language filter → React (236K⭐), React Native (119K⭐), Create React App',
1265
2775
  },
1266
2776
  {
1267
- condition: args.language && args.stars !== undefined && args.stars > 10000,
2777
+ condition: args.language &&
2778
+ args.stars &&
2779
+ ((args.stars.includes('>') &&
2780
+ parseInt(args.stars.replace(/[><]/g, '')) > 10000) ||
2781
+ (!args.stars.includes('>') &&
2782
+ !args.stars.includes('<') &&
2783
+ parseInt(args.stars) > 10000)),
1268
2784
  warning: 'High star threshold with specific language may be too restrictive (TESTING-VALIDATED)',
1269
2785
  suggestion: 'PROVEN: Use >1000 stars for established projects, >100 for active ones. Language filters often miss major projects.',
1270
2786
  },
@@ -1298,8 +2814,8 @@ function validateFilterCombinations(args) {
1298
2814
  if (args.limit && (args.limit < 1 || args.limit > 100)) {
1299
2815
  warnings.push('Limit must be between 1 and 100');
1300
2816
  }
1301
- if (args.stars !== undefined && args.stars < 0) {
1302
- warnings.push('Stars filter must be non-negative');
2817
+ if (args.stars && !/^[><]=?\d+$|^\d+$|^\d+\.\.\d+$/.test(args.stars)) {
2818
+ warnings.push('Stars filter must be in format ">100", ">=500", "<1000", "<=200", "50..200" or a simple number');
1303
2819
  }
1304
2820
  if (args.forks !== undefined && args.forks < 0) {
1305
2821
  warnings.push('Forks filter must be non-negative');
@@ -1338,8 +2854,9 @@ function registerSearchGitHubReposTool(server) {
1338
2854
  .describe('Search query for repositories. PRODUCTION TIP: Single terms work best (e.g., "react", "typescript"). Multi-term queries will be auto-decomposed with suggestions.'),
1339
2855
  owner: z
1340
2856
  .string()
1341
- .min(1, 'Owner is required and cannot be empty')
1342
- .describe('Repository owner/organization - REQUIRED for scoped, reliable results'),
2857
+ .min(1)
2858
+ .optional()
2859
+ .describe('Repository owner/organization (e.g., "facebook", "microsoft"). OPTIONAL: Leave empty for global searches across all of GitHub. Recommended for scoped, reliable results.'),
1343
2860
  archived: z.boolean().optional().describe('Filter archived state'),
1344
2861
  created: z
1345
2862
  .string()
@@ -1363,7 +2880,10 @@ function registerSearchGitHubReposTool(server) {
1363
2880
  .string()
1364
2881
  .optional()
1365
2882
  .describe('Filter by programming language - WARNING: Can cause empty results with restrictive combinations'),
1366
- license: z.string().optional().describe('Filter by license type'),
2883
+ license: z
2884
+ .array(z.string())
2885
+ .optional()
2886
+ .describe('Filter based on license type (e.g., ["mit", "apache-2.0"])'),
1367
2887
  limit: z
1368
2888
  .number()
1369
2889
  .optional()
@@ -1373,28 +2893,37 @@ function registerSearchGitHubReposTool(server) {
1373
2893
  .enum(['name', 'description', 'readme'])
1374
2894
  .optional()
1375
2895
  .describe('Search scope restriction'),
1376
- numberTopics: z.number().optional().describe('Filter by topics count'),
2896
+ numberTopics: z
2897
+ .number()
2898
+ .optional()
2899
+ .describe('Filter on number of topics'),
1377
2900
  order: z
1378
2901
  .enum(['asc', 'desc'])
1379
2902
  .optional()
1380
2903
  .default('desc')
1381
2904
  .describe('Result order (default: desc for newest first)'),
1382
- size: z.string().optional().describe('Filter by size in KB'),
2905
+ size: z
2906
+ .string()
2907
+ .optional()
2908
+ .describe('Filter on size range, in kilobytes (e.g., ">1000", "50..120")'),
1383
2909
  sort: z
1384
2910
  .enum(['forks', 'help-wanted-issues', 'stars', 'updated', 'best-match'])
1385
2911
  .optional()
1386
- .default('updated')
1387
- .describe('Sort criteria (default: updated for recent activity)'),
2912
+ .default('best-match')
2913
+ .describe('Sort fetched repositories (default: best-match)'),
1388
2914
  stars: z
1389
- .number()
2915
+ .string()
2916
+ .optional()
2917
+ .describe('Filter by stars count (e.g., ">100", "<1000", ">=500", "50..200" for range queries) - TIP: Use >100 for established projects, >10 for active ones'),
2918
+ topic: z
2919
+ .array(z.string())
1390
2920
  .optional()
1391
- .describe('Filter by stars count - TIP: Use >100 for established projects, >10 for active ones'),
1392
- topic: z.string().optional().describe('Filter by topic/tag'),
2921
+ .describe('Filter on topic (e.g., ["react", "javascript"])'),
1393
2922
  updated: z.string().optional().describe('Filter by last update date'),
1394
2923
  visibility: z
1395
2924
  .enum(['public', 'private', 'internal'])
1396
2925
  .optional()
1397
- .describe('Filter by visibility'),
2926
+ .describe('Filter based on repository visibility'),
1398
2927
  }, {
1399
2928
  title: 'Search GitHub Repositories',
1400
2929
  readOnlyHint: true,
@@ -1420,8 +2949,26 @@ function registerSearchGitHubReposTool(server) {
1420
2949
  const result = await searchGitHubRepos(searchArgs);
1421
2950
  // Check if we got empty results and provide helpful guidance
1422
2951
  const resultText = result.content[0].text;
1423
- const parsedResults = JSON.parse(resultText);
1424
- const resultCount = JSON.parse(parsedResults.rawOutput).length;
2952
+ // Handle non-JSON responses gracefully
2953
+ let parsedResults;
2954
+ let resultCount = 0;
2955
+ try {
2956
+ parsedResults = JSON.parse(resultText);
2957
+ if (parsedResults.rawOutput) {
2958
+ const rawData = JSON.parse(parsedResults.rawOutput);
2959
+ resultCount = Array.isArray(rawData) ? rawData.length : 0;
2960
+ }
2961
+ }
2962
+ catch (parseError) {
2963
+ // If parsing fails, it might be an error message from GitHub CLI
2964
+ if (resultText.includes('Failed to') ||
2965
+ resultText.includes('Error:')) {
2966
+ throw new Error(`GitHub CLI error: ${resultText}`);
2967
+ }
2968
+ // For other parsing issues, set reasonable defaults
2969
+ resultCount = 0;
2970
+ parsedResults = { rawOutput: '[]' };
2971
+ }
1425
2972
  let responseText = resultText;
1426
2973
  // Add guidance for multi-term queries
1427
2974
  if (queryAnalysis.shouldDecompose) {
@@ -1462,6 +3009,10 @@ function registerSearchGitHubReposTool(server) {
1462
3009
  responseText += `\n• SCOPED SEARCH SUCCESS: owner + single term pattern proven effective`;
1463
3010
  responseText += `\n• PROVEN EXAMPLES: microsoft+typescript→VSCode(173K⭐), facebook+react→React(236K⭐)`;
1464
3011
  }
3012
+ else if (!args.owner) {
3013
+ responseText += `\n• GLOBAL SEARCH: Searching across all GitHub repositories`;
3014
+ responseText += `\n• TIP: Add owner filter for more targeted results if you know specific organizations`;
3015
+ }
1465
3016
  // Add caching recommendations for testing-validated popular searches
1466
3017
  const validatedPopularTerms = [
1467
3018
  'react', // 236K⭐ confirmed
@@ -1494,11 +3045,12 @@ function registerSearchGitHubReposTool(server) {
1494
3045
  🔄 RECOMMENDED FALLBACK WORKFLOW:
1495
3046
  ${fallbacks.map(f => `• ${f}`).join('\n')}
1496
3047
 
1497
- 💡 PRODUCTION NOTE: This tool is a last resort. For reliable discovery:
3048
+ 💡 PRODUCTION NOTE: For reliable discovery:
1498
3049
  1. Start with npm_search_packages for package-based discovery
1499
3050
  2. Use github_search_topics for ecosystem terminology
1500
3051
  3. Use npm_get_package to extract repository URLs
1501
- 4. Only use repository search when NPM + Topics completely fail`;
3052
+ 4. Use global repository search (without owner) for broad discovery
3053
+ 5. Use scoped search (with owner) when you know specific organizations`;
1502
3054
  return {
1503
3055
  content: [
1504
3056
  {
@@ -1856,18 +3408,69 @@ function registerSearchGitHubPullRequestsTool(server) {
1856
3408
  openWorldHint: true,
1857
3409
  }, async (args) => {
1858
3410
  try {
1859
- return await searchGitHubPullRequests(args);
3411
+ const result = await searchGitHubPullRequests(args);
3412
+ // Check for empty results and enhance with smart suggestions
3413
+ if (result.content && result.content[0]) {
3414
+ let responseText = result.content[0].text;
3415
+ let resultCount = 0;
3416
+ try {
3417
+ const parsed = JSON.parse(responseText);
3418
+ if (parsed.rawOutput) {
3419
+ const rawData = JSON.parse(parsed.rawOutput);
3420
+ resultCount = Array.isArray(rawData) ? rawData.length : 0;
3421
+ }
3422
+ }
3423
+ catch {
3424
+ const lines = responseText.split('\n').filter(line => line.trim());
3425
+ resultCount = Math.max(0, lines.length - 5);
3426
+ }
3427
+ if (resultCount === 0) {
3428
+ responseText += `
3429
+
3430
+ 🔄 NO RESULTS RECOVERY STRATEGY:
3431
+ • Try broader terms: "${args.query}" → "fix", "feature", "update"
3432
+ • Implementation search: github_search_code for actual code changes
3433
+ • Project discovery: github_search_repos for related projects
3434
+ • Issue tracking: github_search_issues for related problems
3435
+
3436
+ 💡 PR SEARCH OPTIMIZATION:
3437
+ • Focus on action words: "implement", "add", "fix", "update"
3438
+ • Try state filters: state=open vs state=closed
3439
+ • Use review filters: draft=false for completed PRs
3440
+
3441
+ 🔗 RECOMMENDED TOOL CHAIN:
3442
+ 1. github_search_issues - Find problems that needed solutions
3443
+ 2. github_search_code - See actual implementation patterns
3444
+ 3. github_search_repos - Discover projects with similar features`;
3445
+ }
3446
+ else if (resultCount <= 5) {
3447
+ responseText += `
3448
+
3449
+ 💡 FEW RESULTS ENHANCEMENT:
3450
+ • Found ${resultCount} PRs - try removing restrictive filters
3451
+ • Alternative: github_search_code for implementation examples
3452
+ • Cross-reference: github_search_issues for related discussions`;
3453
+ }
3454
+ return {
3455
+ content: [
3456
+ {
3457
+ type: 'text',
3458
+ text: responseText,
3459
+ },
3460
+ ],
3461
+ isError: false,
3462
+ };
3463
+ }
3464
+ return result;
1860
3465
  }
1861
3466
  catch (error) {
1862
- return {
1863
- content: [
1864
- {
1865
- type: 'text',
1866
- text: `Failed to search GitHub pull requests: ${error.message}`,
1867
- },
1868
- ],
1869
- isError: true,
1870
- };
3467
+ return generateSmartRecovery({
3468
+ tool: 'GitHub Pull Requests Search',
3469
+ query: args.query,
3470
+ owner: args.owner,
3471
+ repo: args.repo,
3472
+ error: error,
3473
+ });
1871
3474
  }
1872
3475
  });
1873
3476
  }
@@ -1999,6 +3602,39 @@ async function npmSearch(args) {
1999
3602
  }
2000
3603
  }
2001
3604
 
3605
+ // Analyze NPM search patterns and suggest fallbacks
3606
+ function analyzeNpmSearchPattern(args) {
3607
+ const suggestions = [];
3608
+ const fallbackStrategy = [];
3609
+ const organizationalHints = [];
3610
+ let patternType = 'basic';
3611
+ const query = args.query.toLowerCase();
3612
+ // Detect organizational packages
3613
+ if (query.includes('@') ||
3614
+ query.includes('internal') ||
3615
+ query.includes('private')) {
3616
+ patternType = 'organizational';
3617
+ organizationalHints.push('ORGANIZATIONAL PACKAGE DETECTED: Consider checking GitHub organizations first');
3618
+ fallbackStrategy.push(`Use ${TOOL_NAMES.GITHUB_GET_USER_ORGS} to discover private package access`);
3619
+ }
3620
+ // Complex search patterns
3621
+ if (query.split(' ').length > 2) {
3622
+ patternType = 'complex-multi-term';
3623
+ suggestions.push('PROVEN: Complex phrases often yield zero results - try single terms');
3624
+ fallbackStrategy.push('Break down into primary term → secondary filters');
3625
+ }
3626
+ // Technology-specific patterns
3627
+ if (query.includes('react') ||
3628
+ query.includes('vue') ||
3629
+ query.includes('angular')) {
3630
+ patternType = 'framework-specific';
3631
+ suggestions.push('FRAMEWORK DETECTED: Consider ecosystem-specific searches');
3632
+ fallbackStrategy.push(`Use ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} for framework ecosystem discovery`);
3633
+ }
3634
+ // Generic fallback strategy for all patterns
3635
+ fallbackStrategy.push(`1. ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} - Search ecosystem terms`, `2. ${TOOL_NAMES.GITHUB_SEARCH_REPOS} - Find repositories that might be packages`, `3. ${TOOL_NAMES.GITHUB_SEARCH_CODE} - Search package.json files`, `4. ${TOOL_NAMES.GITHUB_SEARCH_COMMITS} - Search package development history`, `5. ${TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS} - Search package mentions in PRs`, `6. ${TOOL_NAMES.GITHUB_SEARCH_ISSUES} - Search package discussions`);
3636
+ return { patternType, suggestions, fallbackStrategy, organizationalHints };
3637
+ }
2002
3638
  function registerNpmSearchTool(server) {
2003
3639
  server.tool(TOOL_NAMES.NPM_SEARCH_PACKAGES, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_SEARCH_PACKAGES], {
2004
3640
  query: z
@@ -2022,14 +3658,106 @@ function registerNpmSearchTool(server) {
2022
3658
  openWorldHint: true,
2023
3659
  }, async (args) => {
2024
3660
  try {
2025
- return await npmSearch(args);
3661
+ // Analyze search pattern for insights and fallbacks
3662
+ const patternAnalysis = analyzeNpmSearchPattern(args);
3663
+ const result = await npmSearch(args);
3664
+ // Check if we got poor results and enhance with fallback suggestions
3665
+ if (result.content && result.content[0]) {
3666
+ let responseText = result.content[0].text;
3667
+ // Parse result to check quality
3668
+ let resultCount = 0;
3669
+ try {
3670
+ const parsed = JSON.parse(responseText);
3671
+ if (parsed.results && Array.isArray(parsed.results)) {
3672
+ resultCount = parsed.results.length;
3673
+ }
3674
+ }
3675
+ catch {
3676
+ // If not JSON, try to estimate from text
3677
+ const lines = responseText.split('\n').filter(line => line.trim());
3678
+ resultCount = Math.max(0, lines.length - 5); // Rough estimate
3679
+ }
3680
+ // Add organizational hints if detected
3681
+ if (patternAnalysis.organizationalHints.length > 0) {
3682
+ responseText += `\n\n🏢 ORGANIZATIONAL PACKAGE INSIGHTS:`;
3683
+ patternAnalysis.organizationalHints.forEach(hint => {
3684
+ responseText += `\n• ${hint}`;
3685
+ });
3686
+ }
3687
+ // Add pattern-specific suggestions
3688
+ if (patternAnalysis.suggestions.length > 0) {
3689
+ responseText += `\n\n💡 SEARCH PATTERN INSIGHTS (${patternAnalysis.patternType.toUpperCase()}):`;
3690
+ patternAnalysis.suggestions.forEach(suggestion => {
3691
+ responseText += `\n• ${suggestion}`;
3692
+ });
3693
+ }
3694
+ // Add fallback strategy if results are poor (< 5 results or specific patterns)
3695
+ if (resultCount < 5 || patternAnalysis.patternType !== 'basic') {
3696
+ responseText += `\n\n🔄 NPM SEARCH FALLBACK STRATEGY:`;
3697
+ responseText += `\nIf NPM search yields insufficient results, try this validated workflow:`;
3698
+ patternAnalysis.fallbackStrategy.forEach((step, index) => {
3699
+ responseText += `\n${index + 1}. ${step}`;
3700
+ });
3701
+ }
3702
+ // Add general best practices
3703
+ responseText += `\n\n📋 NPM SEARCH BEST PRACTICES:`;
3704
+ responseText += `\n• Single terms work best: "react", "auth", "cli"`;
3705
+ responseText += `\n• Combined terms: "react-hooks", "typescript-cli"`;
3706
+ responseText += `\n• Avoid complex phrases: Break "react auth jwt library" → "react" + "auth"`;
3707
+ responseText += `\n• Organizational packages: @company/ triggers private search workflow`;
3708
+ responseText += `\n• 0 results → broader terms, 1-20 IDEAL, 100+ → more specific`;
3709
+ return {
3710
+ content: [
3711
+ {
3712
+ type: 'text',
3713
+ text: responseText,
3714
+ },
3715
+ ],
3716
+ isError: false,
3717
+ };
3718
+ }
3719
+ return result;
2026
3720
  }
2027
3721
  catch (error) {
3722
+ // Enhanced error handling with fallback suggestions
3723
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
3724
+ const fallbackSuggestions = `
3725
+ 🔄 NPM SEARCH FALLBACK WORKFLOW:
3726
+ When NPM registry search fails, try this proven sequence:
3727
+
3728
+ 1. ${TOOL_NAMES.GITHUB_SEARCH_TOPICS} - Discover ecosystem terminology
3729
+ • Use broader terms: "authentication" instead of "jwt-auth-library"
3730
+ • Find related technologies and packages
3731
+
3732
+ 2. ${TOOL_NAMES.GITHUB_SEARCH_REPOS} - Find package repositories
3733
+ • Search for repositories that might contain packages
3734
+ • Look for package.json indicators
3735
+
3736
+ 3. ${TOOL_NAMES.GITHUB_SEARCH_CODE} - Search package manifests
3737
+ • Query: "package.json" + your terms
3738
+ • Find actual package definitions
3739
+
3740
+ 4. ${TOOL_NAMES.GITHUB_SEARCH_COMMITS} - Development history
3741
+ • Search commit messages for package development
3742
+ • Find package creation/updates
3743
+
3744
+ 5. ${TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS} - Package discussions
3745
+ • Find PRs mentioning package development
3746
+ • Discover package features and issues
3747
+
3748
+ 6. ${TOOL_NAMES.GITHUB_SEARCH_ISSUES} - Community discussions
3749
+ • Find issues discussing packages
3750
+ • Discover alternatives and recommendations
3751
+
3752
+ 💡 PROVEN STRATEGIES:
3753
+ • Try simpler terms if complex search fails
3754
+ • Check organizational access for @company/ packages
3755
+ • Use GitHub ecosystem discovery when NPM fails`;
2028
3756
  return {
2029
3757
  content: [
2030
3758
  {
2031
3759
  type: 'text',
2032
- text: `Failed to search npm packages: ${error.message}`,
3760
+ text: `NPM Search Failed: ${errorMessage}${fallbackSuggestions}`,
2033
3761
  },
2034
3762
  ],
2035
3763
  isError: true,
@@ -2291,8 +4019,9 @@ function registerSearchGitHubIssuesTool(server) {
2291
4019
  .describe("The search query to find issues (e.g., 'bug fix', 'feature request', 'documentation')"),
2292
4020
  owner: z
2293
4021
  .string()
2294
- .min(1, 'Owner is required and cannot be empty')
2295
- .describe("Filter by repository owner/organization (e.g., 'example-org')"),
4022
+ .min(1)
4023
+ .optional()
4024
+ .describe("Filter by repository owner/organization (e.g., 'example-org'). OPTIONAL: Leave empty for global searches across all of GitHub."),
2296
4025
  repo: z
2297
4026
  .string()
2298
4027
  .optional()
@@ -2407,18 +4136,71 @@ function registerSearchGitHubIssuesTool(server) {
2407
4136
  openWorldHint: true,
2408
4137
  }, async (args) => {
2409
4138
  try {
2410
- return await searchGitHubIssues(args);
4139
+ const result = await searchGitHubIssues(args);
4140
+ // Check for empty results and enhance with smart suggestions
4141
+ if (result.content && result.content[0]) {
4142
+ let responseText = result.content[0].text;
4143
+ let resultCount = 0;
4144
+ try {
4145
+ const parsed = JSON.parse(responseText);
4146
+ if (parsed.rawOutput) {
4147
+ const rawData = JSON.parse(parsed.rawOutput);
4148
+ resultCount = Array.isArray(rawData) ? rawData.length : 0;
4149
+ }
4150
+ }
4151
+ catch {
4152
+ // If parsing fails, estimate from text
4153
+ const lines = responseText.split('\n').filter(line => line.trim());
4154
+ resultCount = Math.max(0, lines.length - 5);
4155
+ }
4156
+ // Add smart suggestions for empty or poor results
4157
+ if (resultCount === 0) {
4158
+ responseText += `
4159
+
4160
+ 🔄 NO RESULTS RECOVERY STRATEGY:
4161
+ • Try broader terms: "${args.query}" → single keywords
4162
+ • Alternative discovery: github_search_repos for related projects
4163
+ • Problem context: github_search_code for implementation examples
4164
+ • Solution tracking: github_search_pull_requests for fixes
4165
+
4166
+ 💡 QUERY SIMPLIFICATION:
4167
+ • Remove quotes and special characters
4168
+ • Use single keywords: "bug", "error", "feature"
4169
+ • Try related terms: "issue" → "problem", "bug" → "error"
4170
+
4171
+ 🔗 RECOMMENDED TOOL CHAIN:
4172
+ 1. github_search_repos - Find projects that might have similar issues
4173
+ 2. github_search_code - Search for code patterns related to your problem
4174
+ 3. npm_search_packages - Find packages that solve similar problems`;
4175
+ }
4176
+ else if (resultCount <= 5) {
4177
+ responseText += `
4178
+
4179
+ 💡 FEW RESULTS ENHANCEMENT:
4180
+ • Found ${resultCount} issues - try broader search terms
4181
+ • Alternative: github_search_repos for project-level discovery
4182
+ • Cross-reference: github_search_code for implementation patterns`;
4183
+ }
4184
+ return {
4185
+ content: [
4186
+ {
4187
+ type: 'text',
4188
+ text: responseText,
4189
+ },
4190
+ ],
4191
+ isError: false,
4192
+ };
4193
+ }
4194
+ return result;
2411
4195
  }
2412
4196
  catch (error) {
2413
- return {
2414
- content: [
2415
- {
2416
- type: 'text',
2417
- text: `Failed to search GitHub issues: ${error.message}`,
2418
- },
2419
- ],
2420
- isError: true,
2421
- };
4197
+ return generateSmartRecovery({
4198
+ tool: 'GitHub Issues Search',
4199
+ query: args.query,
4200
+ owner: args.owner,
4201
+ repo: args.repo,
4202
+ error: error,
4203
+ });
2422
4204
  }
2423
4205
  });
2424
4206
  }
@@ -2535,23 +4317,72 @@ function registerSearchGitHubTopicsTool(server) {
2535
4317
  openWorldHint: true,
2536
4318
  }, async (args) => {
2537
4319
  try {
2538
- return await searchGitHubTopics(args);
2539
- }
2540
- catch (error) {
2541
- return {
2542
- content: [
2543
- {
2544
- type: 'text',
2545
- text: `Failed to search GitHub topics: ${error.message}`,
2546
- },
2547
- ],
2548
- isError: true,
2549
- };
2550
- }
2551
- });
2552
- }
2553
-
2554
- async function searchGitHubUsers(params) {
4320
+ const result = await searchGitHubTopics(args);
4321
+ // Check for empty results and enhance with smart suggestions
4322
+ if (result.content && result.content[0]) {
4323
+ let responseText = result.content[0].text;
4324
+ let resultCount = 0;
4325
+ try {
4326
+ const parsed = JSON.parse(responseText);
4327
+ if (parsed.rawOutput) {
4328
+ const rawData = JSON.parse(parsed.rawOutput);
4329
+ resultCount = Array.isArray(rawData) ? rawData.length : 0;
4330
+ }
4331
+ }
4332
+ catch {
4333
+ const lines = responseText.split('\n').filter(line => line.trim());
4334
+ resultCount = Math.max(0, lines.length - 5);
4335
+ }
4336
+ if (resultCount === 0) {
4337
+ responseText += `
4338
+
4339
+ 🔄 NO TOPICS FOUND RECOVERY:
4340
+ • Try simpler terms: "${args.query}" → single technology keywords
4341
+ • Ecosystem discovery: npm_search_packages for related packages
4342
+ • Repository search: github_search_repos for projects using these topics
4343
+ • User community: github_search_users for topic experts
4344
+
4345
+ 💡 TOPIC SEARCH OPTIMIZATION:
4346
+ • Use popular technology terms: "react", "javascript", "python"
4347
+ • Try compound topics: "machine-learning", "web-development"
4348
+ • Focus on featured topics: featured=true
4349
+
4350
+ 🔗 RECOMMENDED DISCOVERY CHAIN:
4351
+ 1. npm_search_packages - Find packages in this domain
4352
+ 2. github_search_repos - Discover projects using these topics
4353
+ 3. github_search_code - Find implementations using topic technologies`;
4354
+ }
4355
+ else if (resultCount <= 3) {
4356
+ responseText += `
4357
+
4358
+ 💡 LIMITED TOPICS ENHANCEMENT:
4359
+ • Found ${resultCount} topics - try broader or more popular terms
4360
+ • Ecosystem expansion: npm_search_packages for related technologies
4361
+ • Project discovery: github_search_repos for topic implementation`;
4362
+ }
4363
+ return {
4364
+ content: [
4365
+ {
4366
+ type: 'text',
4367
+ text: responseText,
4368
+ },
4369
+ ],
4370
+ isError: false,
4371
+ };
4372
+ }
4373
+ return result;
4374
+ }
4375
+ catch (error) {
4376
+ return generateSmartRecovery({
4377
+ tool: 'GitHub Topics Search',
4378
+ query: args.query,
4379
+ error: error,
4380
+ });
4381
+ }
4382
+ });
4383
+ }
4384
+
4385
+ async function searchGitHubUsers(params) {
2555
4386
  const cacheKey = generateCacheKey('gh-users', params);
2556
4387
  return withCache(cacheKey, async () => {
2557
4388
  try {
@@ -2605,6 +4436,8 @@ function buildGitHubUsersAPICommand(params) {
2605
4436
  // Add pagination parameters
2606
4437
  const limit = params.limit || 30;
2607
4438
  queryParams.push(`per_page=${limit}`);
4439
+ const page = params.page || 1;
4440
+ queryParams.push(`page=${page}`);
2608
4441
  if (params.sort)
2609
4442
  queryParams.push(`sort=${params.sort}`);
2610
4443
  if (params.order)
@@ -2623,8 +4456,9 @@ function registerSearchGitHubUsersTool(server) {
2623
4456
  .describe("The search query to find users/organizations (e.g., 'react developer', 'python', 'machine learning')"),
2624
4457
  owner: z
2625
4458
  .string()
2626
- .min(1, 'Owner is required and cannot be empty')
2627
- .describe("Filter by repository owner/organization (e.g., 'example-org') obtained from the appropriate tool for fetching user organizations"),
4459
+ .min(1)
4460
+ .optional()
4461
+ .describe("Filter by repository owner/organization (e.g., 'example-org'). OPTIONAL: Leave empty for global searches across all of GitHub."),
2628
4462
  type: z
2629
4463
  .enum(['user', 'org'])
2630
4464
  .optional()
@@ -2663,6 +4497,11 @@ function registerSearchGitHubUsersTool(server) {
2663
4497
  .optional()
2664
4498
  .default(50)
2665
4499
  .describe('Maximum number of users to return (default: 50)'),
4500
+ page: z
4501
+ .number()
4502
+ .optional()
4503
+ .default(1)
4504
+ .describe('The page number of the results to fetch (default: 1)'),
2666
4505
  }, {
2667
4506
  title: 'Search GitHub Users',
2668
4507
  readOnlyHint: true,
@@ -2671,79 +4510,67 @@ function registerSearchGitHubUsersTool(server) {
2671
4510
  openWorldHint: true,
2672
4511
  }, async (args) => {
2673
4512
  try {
2674
- return await searchGitHubUsers(args);
2675
- }
2676
- catch (error) {
2677
- return {
2678
- content: [
2679
- {
2680
- type: 'text',
2681
- text: `Failed to search GitHub users: ${error.message}`,
2682
- },
2683
- ],
2684
- isError: true,
2685
- };
2686
- }
2687
- });
2688
- }
2689
-
2690
- async function npmPackageStats(packageName) {
2691
- const cacheKey = generateCacheKey('npm-stats', { packageName });
2692
- return withCache(cacheKey, async () => {
2693
- try {
2694
- // Execute multiple commands in parallel using executeNpmCommand
2695
- const commands = [
2696
- executeNpmCommand('view', [packageName, 'time', '--json']),
2697
- executeNpmCommand('view', [packageName, 'versions', '--json']),
2698
- executeNpmCommand('view', [packageName, 'dist-tags', '--json']),
2699
- ];
2700
- const results = await Promise.allSettled(commands);
2701
- const stats = {
2702
- packageName,
2703
- releaseHistory: results[0].status === 'fulfilled' && !results[0].value.isError
2704
- ? JSON.parse(results[0].value.content[0].text).result
2705
- : null,
2706
- versions: results[1].status === 'fulfilled' && !results[1].value.isError
2707
- ? JSON.parse(results[1].value.content[0].text).result
2708
- : null,
2709
- distTags: results[2].status === 'fulfilled' && !results[2].value.isError
2710
- ? JSON.parse(results[2].value.content[0].text).result
2711
- : null,
2712
- analyzedAt: new Date().toISOString(),
2713
- };
2714
- return createSuccessResult$1(stats);
2715
- }
2716
- catch (error) {
2717
- return createErrorResult$1('Failed to get npm package statistics', error);
2718
- }
2719
- });
2720
- }
4513
+ const result = await searchGitHubUsers(args);
4514
+ // Check for empty results and enhance with smart suggestions
4515
+ if (result.content && result.content[0]) {
4516
+ let responseText = result.content[0].text;
4517
+ let resultCount = 0;
4518
+ try {
4519
+ const parsed = JSON.parse(responseText);
4520
+ if (parsed.rawOutput) {
4521
+ const rawData = JSON.parse(parsed.rawOutput);
4522
+ resultCount = Array.isArray(rawData) ? rawData.length : 0;
4523
+ }
4524
+ }
4525
+ catch {
4526
+ const lines = responseText.split('\n').filter(line => line.trim());
4527
+ resultCount = Math.max(0, lines.length - 5);
4528
+ }
4529
+ if (resultCount === 0) {
4530
+ responseText += `
4531
+
4532
+ 🔄 NO RESULTS RECOVERY STRATEGY:
4533
+ Try simpler terms: "${args.query}" technology keywords only
4534
+ Organization discovery: github_get_user_organizations for company access
4535
+ Project-based search: github_search_repos to find user projects
4536
+ Code contribution search: github_search_code for user activity
4537
+
4538
+ 💡 USER SEARCH OPTIMIZATION:
4539
+ Use technology terms: "react", "python", "javascript"
4540
+ Try location filters: location="San Francisco", location="Remote"
4541
+ • Focus on active users: followers>10, repos>5
4542
+
4543
+ 🔗 RECOMMENDED TOOL CHAIN:
4544
+ 1. github_search_repos - Find projects by technology/topic
4545
+ 2. github_get_user_organizations - Discover organizations
4546
+ 3. npm_search_packages - Find package maintainers`;
4547
+ }
4548
+ else if (resultCount <= 5) {
4549
+ responseText += `
2721
4550
 
2722
- function registerNpmPackageStatsTool(server) {
2723
- server.tool(TOOL_NAMES.NPM_GET_PACKAGE_STATS, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_PACKAGE_STATS], {
2724
- packageName: z
2725
- .string()
2726
- .describe("The name of the npm package to analyze (e.g., 'react', '@types/node', 'lodash')"),
2727
- }, {
2728
- title: 'NPM Package Statistics',
2729
- readOnlyHint: true,
2730
- destructiveHint: false,
2731
- idempotentHint: true,
2732
- openWorldHint: true,
2733
- }, async (args) => {
2734
- try {
2735
- return await npmPackageStats(args.packageName);
4551
+ 💡 FEW RESULTS ENHANCEMENT:
4552
+ Found ${resultCount} users - try broader location or technology terms
4553
+ • Alternative: github_search_repos for project discovery
4554
+ • Organization search: github_get_user_organizations`;
4555
+ }
4556
+ return {
4557
+ content: [
4558
+ {
4559
+ type: 'text',
4560
+ text: responseText,
4561
+ },
4562
+ ],
4563
+ isError: false,
4564
+ };
4565
+ }
4566
+ return result;
2736
4567
  }
2737
4568
  catch (error) {
2738
- return {
2739
- content: [
2740
- {
2741
- type: 'text',
2742
- text: `Failed to get npm package statistics: ${error.message}`,
2743
- },
2744
- ],
2745
- isError: true,
2746
- };
4569
+ return generateSmartRecovery({
4570
+ tool: 'GitHub Users Search',
4571
+ query: args.query,
4572
+ error: error,
4573
+ });
2747
4574
  }
2748
4575
  });
2749
4576
  }
@@ -2874,214 +4701,1153 @@ function registerNpmDependencyAnalysisTool(server) {
2874
4701
  });
2875
4702
  }
2876
4703
 
2877
- function registerUsageGuideResource(server) {
2878
- server.resource('usage-guide', 'help://usage', async (uri) => ({
2879
- contents: [
2880
- {
2881
- uri: uri.href,
2882
- mimeType: 'text/markdown',
2883
- text: `# Octocode MCP Quick Start
2884
-
2885
- ## Setup (Required)
2886
- \`\`\`bash
2887
- gh auth login # GitHub CLI authentication
2888
- \`\`\`
2889
-
2890
- ## MANDATORY SEARCH STRATEGY
2891
- 1. **ALWAYS START**: \`search_github_topics\` - **NEVER SKIP** - Maps ecosystem terminology
2892
- 2. **PRIMARY DISCOVERY**: \`npm_search\` and \`npm_view\` - Minimizes GitHub API calls
2893
- 3. **TARGETED EXTRACTION**: \`search_github_code\` with owner/repo from NPM
2894
- 4. **LAST RESORT**: \`search_github_repos\` - Single terms only when NPM insufficient
2895
-
2896
- ## Core Workflow
2897
- 1. **Check Auth**: Read \`github://auth-status\` and \`github://rate-limits\`
2898
- 2. **MANDATORY**: \`search_github_topics\` for ecosystem mapping
2899
- 3. **NPM Discovery**: \`npm_search\` → \`npm_view\` → extract repository URLs
2900
- 4. **Extract**: Get complete implementations from discovered repositories
2901
- 5. **Validate**: Cross-reference multiple NPM packages
2902
-
2903
- ## Essential Tools (Priority Order)
2904
- - **\`search_github_topics\`**: **MANDATORY FIRST STEP** - Find technology ecosystems
2905
- - **\`npm_search\`**: **PRIMARY DISCOVERY** - Find packages by functionality
2906
- - **\`npm_view\`**: **PRIMARY DISCOVERY** - Package metadata and repo links
2907
- - **\`view_repository\`**: Get branch info (required before file operations!)
2908
- - **\`search_github_code\`**: Find specific implementations in discovered repos
2909
- - **\`fetch_github_file_content\`**: Extract complete code
2910
- - **\`search_github_repos\`**: **LAST RESORT ONLY** - Single terms when NPM fails
2911
-
2912
- ## Search Strategy Rules
2913
- - **Topics First**: Every workflow starts with \`search_github_topics\`
2914
- - **NPM Primary**: Use NPM tools before GitHub repo search
2915
- - **Single Terms Only**: NEVER multi-term searches in \`search_github_repos\`
2916
- - **API Conservation**: NPM discovery reduces GitHub API usage by 60%
2917
-
2918
- ## Search Term Strategy
2919
- - **✅ GOOD**: "react", "authentication", "typescript", "deployment"
2920
- - **❌ BAD**: "react hooks", "full-stack app", "react angular auth"
2921
- - **Decompose**: "react typescript auth" → ["react", "typescript", "authentication"]
2922
-
2923
- ## Quick Examples
2924
- - **Package research**: \`search_github_topics\` → \`npm_search\` → \`npm_view\` → \`view_repository\` → \`search_github_code\`
2925
- - **Problem solving**: \`search_github_topics\` → \`npm_search\` → \`search_github_issues\` → \`search_github_code\`
2926
- - **Technology discovery**: \`search_github_topics\` → \`npm_search\` → \`npm_view\` → \`view_repository\` → \`fetch_github_file_content\`
2927
-
2928
- ## CRITICAL REMINDERS
2929
- - **NEVER skip** \`search_github_topics\` - provides essential context
2930
- - **NPM FIRST** - use NPM tools before GitHub repo search
2931
- - **SINGLE TERMS** - never combine multiple concepts in repo searches
2932
- - **REPOS LAST** - \`search_github_repos\` is lowest priority discovery tool
2933
-
2934
- Generated: ${new Date().toISOString()}`,
2935
- },
2936
- ],
2937
- }));
2938
- }
2939
-
2940
- // GitHub Authentication Status Resource
2941
- function registerGithubStatusResource(server) {
2942
- server.resource('github-auth-status', 'github://auth-status', async (uri) => {
2943
- try {
2944
- // For version, we'll use a workaround since --version is not a command
2945
- // We can use 'help' command which shows version info, or skip detailed version check
2946
- const ghVersion = 'Available (GitHub CLI detected)';
2947
- let isAuthenticated = false;
2948
- let authError = null;
2949
- try {
2950
- // Check auth status using safe command
2951
- const authResult = await executeGitHubCommand('auth', ['status'], {
2952
- timeout: 5000,
2953
- cache: false,
2954
- });
2955
- if (!authResult.isError) {
2956
- const content = String(authResult.content[0]?.text || '');
2957
- if (content) {
2958
- try {
2959
- const parsed = JSON.parse(content);
2960
- const output = parsed.result || content;
2961
- // Only check if authenticated, don't expose user details
2962
- isAuthenticated =
2963
- String(output).includes('✓ Logged in') ||
2964
- String(output).includes('Logged in');
2965
- }
2966
- catch {
2967
- isAuthenticated =
2968
- content.includes('✓ Logged in') ||
2969
- content.includes('Logged in');
2970
- }
2971
- }
2972
- }
2973
- else {
2974
- // auth status command failed, check error content for auth info
2975
- const errorContent = String(authResult.content[0]?.text || 'Authentication check failed');
2976
- if (errorContent.includes('✓ Logged in') ||
2977
- errorContent.includes('Logged in')) {
2978
- isAuthenticated = true;
2979
- }
2980
- else {
2981
- authError = 'Not authenticated';
2982
- }
2983
- }
2984
- }
2985
- catch (error) {
2986
- authError = 'Unable to check authentication status';
4704
+ async function checkGitHubAuth() {
4705
+ try {
4706
+ const authResult = await executeGitHubCommand('auth', ['status'], {
4707
+ timeout: 10000,
4708
+ cache: false,
4709
+ });
4710
+ if (authResult.isError) {
4711
+ const errorText = String(authResult.content[0]?.text || '');
4712
+ if (errorText.includes('not logged into') ||
4713
+ errorText.includes('not authenticated')) {
4714
+ return {
4715
+ status: 'not_authenticated',
4716
+ message: 'Not logged into GitHub CLI. Please run: gh auth login',
4717
+ };
2987
4718
  }
2988
4719
  return {
2989
- contents: [
2990
- {
2991
- uri: uri.href,
2992
- mimeType: 'application/json',
2993
- text: JSON.stringify({
2994
- status: 'GitHub Authentication Status - LIVE STATUS',
2995
- description: 'GitHub CLI authentication status and version information',
2996
- gh_version: ghVersion,
2997
- authenticated: isAuthenticated,
2998
- auth_error: authError,
2999
- setup_instructions: {
3000
- not_authenticated: [
3001
- 'Run: gh auth login',
3002
- 'Follow the interactive prompts to authenticate',
3003
- 'Choose your preferred authentication method',
3004
- ],
3005
- verification: [
3006
- 'Run: gh auth status',
3007
- 'Should show "✓ Logged in" if successful',
3008
- ],
3009
- },
3010
- timestamp: new Date().toISOString(),
3011
- }, null, 2),
3012
- },
3013
- ],
4720
+ status: 'error',
4721
+ message: `GitHub CLI error: ${errorText}`,
3014
4722
  };
3015
4723
  }
3016
- catch (error) {
4724
+ const statusText = String(authResult.content[0]?.text || '');
4725
+ // Extract username if present
4726
+ const userMatch = statusText.match(/Logged in to github\.com as ([^\s]+)/);
4727
+ const user = userMatch ? userMatch[1] : undefined;
4728
+ if (statusText.includes('Logged in to github.com')) {
3017
4729
  return {
3018
- contents: [
3019
- {
3020
- uri: uri.href,
3021
- mimeType: 'application/json',
3022
- text: JSON.stringify({
3023
- status: 'GitHub Authentication Status - ERROR',
3024
- error: error.message,
3025
- message: 'GitHub CLI may not be installed or accessible',
3026
- timestamp: new Date().toISOString(),
3027
- }, null, 2),
3028
- },
3029
- ],
4730
+ status: 'authenticated',
4731
+ user,
4732
+ message: user ? `Authenticated as ${user}` : 'Authenticated to GitHub',
3030
4733
  };
3031
4734
  }
3032
- });
4735
+ return {
4736
+ status: 'not_authenticated',
4737
+ message: 'GitHub CLI authentication status unclear. Please run: gh auth login',
4738
+ };
4739
+ }
4740
+ catch (error) {
4741
+ return {
4742
+ status: 'error',
4743
+ message: `Failed to check GitHub auth: ${error.message}`,
4744
+ };
4745
+ }
3033
4746
  }
3034
-
3035
- function registerGithubRateLimitResource(server) {
3036
- server.resource('github-rate-limits', 'github://rate-limits', async (uri) => {
3037
- try {
3038
- // Use safe GitHub command execution for API calls
3039
- const rateLimitResult = await executeGitHubCommand('api', ['rate_limit'], {
3040
- timeout: 10000,
3041
- cache: false,
3042
- });
3043
- if (rateLimitResult.isError) {
3044
- const errorText = String(rateLimitResult.content[0]?.text || 'Failed to fetch rate limits');
3045
- throw new Error(errorText);
3046
- }
3047
- // Extract and parse the rate limit data
3048
- const content = String(rateLimitResult.content[0]?.text || '');
3049
- if (!content) {
3050
- throw new Error('No rate limit data received');
4747
+ async function checkNpmConnectivity() {
4748
+ try {
4749
+ const pingResult = await executeNpmCommand('ping', [], {
4750
+ timeout: 10000,
4751
+ cache: false,
4752
+ });
4753
+ if (pingResult.isError) {
4754
+ const errorText = String(pingResult.content[0]?.text || '');
4755
+ return {
4756
+ status: 'disconnected',
4757
+ message: `NPM registry unreachable: ${errorText}`,
4758
+ };
4759
+ }
4760
+ const pingText = String(pingResult.content[0]?.text || '');
4761
+ if (pingText.includes('npm ping ok') || pingText.includes('Ping success')) {
4762
+ // Extract registry if present
4763
+ const registryMatch = pingText.match(/registry: (.+)/);
4764
+ const registry = registryMatch
4765
+ ? registryMatch[1]
4766
+ : 'https://registry.npmjs.org';
4767
+ return {
4768
+ status: 'connected',
4769
+ registry,
4770
+ message: `Connected to NPM registry: ${registry}`,
4771
+ };
4772
+ }
4773
+ return {
4774
+ status: 'error',
4775
+ message: `NPM ping response unclear: ${pingText}`,
4776
+ };
4777
+ }
4778
+ catch (error) {
4779
+ return {
4780
+ status: 'error',
4781
+ message: `Failed to ping NPM registry: ${error.message}`,
4782
+ };
4783
+ }
4784
+ }
4785
+ async function checkGitHubRateLimits() {
4786
+ try {
4787
+ const rateLimitResult = await executeGitHubCommand('api', ['rate_limit'], {
4788
+ timeout: 10000,
4789
+ cache: false,
4790
+ });
4791
+ if (rateLimitResult.isError) {
4792
+ const errorText = String(rateLimitResult.content[0]?.text || '');
4793
+ return {
4794
+ status: 'error',
4795
+ primary_api: {
4796
+ remaining: 0,
4797
+ limit: 0,
4798
+ reset_time: '',
4799
+ usage_percentage: 100,
4800
+ },
4801
+ search_api: {
4802
+ remaining: 0,
4803
+ limit: 0,
4804
+ reset_time: '',
4805
+ usage_percentage: 100,
4806
+ },
4807
+ code_search: {
4808
+ remaining: 0,
4809
+ limit: 0,
4810
+ reset_time: '',
4811
+ usage_percentage: 100,
4812
+ },
4813
+ message: `Failed to fetch rate limits: ${errorText}`,
4814
+ recommendations: [
4815
+ 'GitHub authentication may be required',
4816
+ 'Run: gh auth login',
4817
+ ],
4818
+ };
4819
+ }
4820
+ const content = String(rateLimitResult.content[0]?.text || '');
4821
+ if (!content) {
4822
+ throw new Error('No rate limit data received');
4823
+ }
4824
+ let rateLimit;
4825
+ try {
4826
+ const parsed = JSON.parse(content);
4827
+ rateLimit = parsed.result || parsed;
4828
+ }
4829
+ catch {
4830
+ rateLimit = JSON.parse(content);
4831
+ }
4832
+ const formatResetTime = (reset) => new Date(reset * 1000).toISOString();
4833
+ const calculateUsage = (used, limit) => Math.round((used / limit) * 100);
4834
+ const core = rateLimit.resources.core;
4835
+ const search = rateLimit.resources.search;
4836
+ const codeSearch = rateLimit.resources.code_search;
4837
+ const primaryApi = {
4838
+ remaining: core.remaining,
4839
+ limit: core.limit,
4840
+ reset_time: formatResetTime(core.reset),
4841
+ usage_percentage: calculateUsage(core.used, core.limit),
4842
+ };
4843
+ const searchApi = {
4844
+ remaining: search.remaining,
4845
+ limit: search.limit,
4846
+ reset_time: formatResetTime(search.reset),
4847
+ usage_percentage: calculateUsage(search.used, search.limit),
4848
+ };
4849
+ const codeSearchApi = {
4850
+ remaining: codeSearch.remaining,
4851
+ limit: codeSearch.limit,
4852
+ reset_time: formatResetTime(codeSearch.reset),
4853
+ usage_percentage: calculateUsage(codeSearch.used, codeSearch.limit),
4854
+ };
4855
+ // Determine overall status
4856
+ const minRemaining = Math.min(core.remaining, search.remaining, codeSearch.remaining);
4857
+ let status;
4858
+ const recommendations = [];
4859
+ if (minRemaining === 0) {
4860
+ status = 'exhausted';
4861
+ recommendations.push('🚨 API limits exhausted - wait for reset or use alternative approaches');
4862
+ recommendations.push('Consider using cached data or reducing API calls');
4863
+ }
4864
+ else if (minRemaining < 10) {
4865
+ status = 'limited';
4866
+ recommendations.push('⚠️ API limits low - prioritize essential requests only');
4867
+ recommendations.push('Avoid extensive searches or bulk operations');
4868
+ }
4869
+ else {
4870
+ status = 'healthy';
4871
+ recommendations.push('✅ All APIs ready for normal operation');
4872
+ }
4873
+ // Add specific API recommendations
4874
+ if (codeSearch.remaining < 5) {
4875
+ recommendations.push('🔍 Code search severely limited - use repository-specific searches');
4876
+ }
4877
+ if (search.remaining < 10) {
4878
+ recommendations.push('🔎 Search API limited - reduce search complexity');
4879
+ }
4880
+ if (core.remaining < 100) {
4881
+ recommendations.push('🏠 Core API limited - avoid bulk repository operations');
4882
+ }
4883
+ return {
4884
+ status,
4885
+ primary_api: primaryApi,
4886
+ search_api: searchApi,
4887
+ code_search: codeSearchApi,
4888
+ message: `Rate limits checked - ${status}`,
4889
+ recommendations,
4890
+ };
4891
+ }
4892
+ catch (error) {
4893
+ return {
4894
+ status: 'error',
4895
+ primary_api: {
4896
+ remaining: 0,
4897
+ limit: 0,
4898
+ reset_time: '',
4899
+ usage_percentage: 100,
4900
+ },
4901
+ search_api: {
4902
+ remaining: 0,
4903
+ limit: 0,
4904
+ reset_time: '',
4905
+ usage_percentage: 100,
4906
+ },
4907
+ code_search: {
4908
+ remaining: 0,
4909
+ limit: 0,
4910
+ reset_time: '',
4911
+ usage_percentage: 100,
4912
+ },
4913
+ message: `Error checking rate limits: ${error.message}`,
4914
+ recommendations: [
4915
+ 'Unable to determine API status',
4916
+ 'Check GitHub authentication',
4917
+ ],
4918
+ };
4919
+ }
4920
+ }
4921
+ async function performApiStatusCheck() {
4922
+ try {
4923
+ console.log('🔍 Performing comprehensive API status check...');
4924
+ // Perform all checks in parallel for efficiency
4925
+ const [githubAuth, npmConnectivity, githubRateLimits] = await Promise.all([
4926
+ checkGitHubAuth(),
4927
+ checkNpmConnectivity(),
4928
+ checkGitHubRateLimits(),
4929
+ ]);
4930
+ // Determine overall status
4931
+ let overallStatus;
4932
+ const researchRecommendations = [];
4933
+ if (githubAuth.status !== 'authenticated') {
4934
+ overallStatus = 'not_ready';
4935
+ researchRecommendations.push('❌ GitHub authentication required before research');
4936
+ researchRecommendations.push('Run: gh auth login');
4937
+ }
4938
+ else if (npmConnectivity.status !== 'connected') {
4939
+ overallStatus = 'limited';
4940
+ researchRecommendations.push('⚠️ NPM unavailable - GitHub research only');
4941
+ }
4942
+ else if (githubRateLimits.status === 'exhausted') {
4943
+ overallStatus = 'not_ready';
4944
+ researchRecommendations.push('❌ GitHub API exhausted - wait for reset');
4945
+ researchRecommendations.push(`Next reset: ${githubRateLimits.code_search.reset_time}`);
4946
+ }
4947
+ else if (githubRateLimits.status === 'limited') {
4948
+ overallStatus = 'limited';
4949
+ researchRecommendations.push('⚠️ Limited API quota - reduce research scope');
4950
+ researchRecommendations.push('Use targeted searches instead of broad exploration');
4951
+ }
4952
+ else {
4953
+ overallStatus = 'ready';
4954
+ researchRecommendations.push('✅ All systems ready for comprehensive research');
4955
+ researchRecommendations.push('NPM package discovery and GitHub analysis available');
4956
+ }
4957
+ // Add research strategy recommendations based on API limits
4958
+ if (githubRateLimits.code_search.remaining < 5) {
4959
+ researchRecommendations.push('🔍 Code search critical - use repository browsing instead');
4960
+ }
4961
+ if (githubRateLimits.search_api.remaining < 20) {
4962
+ researchRecommendations.push('🔎 Search API limited - focus on specific repositories');
4963
+ }
4964
+ if (githubRateLimits.primary_api.remaining < 200) {
4965
+ researchRecommendations.push('🏠 Core API limited - minimize repository exploration');
4966
+ }
4967
+ const result = {
4968
+ github_auth: githubAuth,
4969
+ npm_connectivity: npmConnectivity,
4970
+ github_rate_limits: githubRateLimits,
4971
+ overall_status: overallStatus,
4972
+ research_recommendations: researchRecommendations,
4973
+ timestamp: new Date().toISOString(),
4974
+ };
4975
+ return {
4976
+ content: [
4977
+ {
4978
+ type: 'text',
4979
+ text: JSON.stringify(result, null, 2),
4980
+ },
4981
+ ],
4982
+ isError: false,
4983
+ };
4984
+ }
4985
+ catch (error) {
4986
+ return {
4987
+ content: [
4988
+ {
4989
+ type: 'text',
4990
+ text: `🚨 API Status Check Failed: ${error.message}
4991
+
4992
+ 🔧 Troubleshooting Steps:
4993
+ 1. Check GitHub CLI installation: gh --version
4994
+ 2. Check NPM installation: npm --version
4995
+ 3. Check network connectivity
4996
+ 4. Try: gh auth login
4997
+ 5. Try: npm ping
4998
+
4999
+ 💡 Manual Verification:
5000
+ - GitHub Auth: gh auth status
5001
+ - NPM Registry: npm ping
5002
+ - GitHub API: gh api rate_limit`,
5003
+ },
5004
+ ],
5005
+ isError: true,
5006
+ };
5007
+ }
5008
+ }
5009
+ function registerApiStatusCheckTool(server) {
5010
+ server.tool(TOOL_NAMES.API_STATUS_CHECK, TOOL_DESCRIPTIONS[TOOL_NAMES.API_STATUS_CHECK], {
5011
+ // No parameters needed for status check
5012
+ }, {
5013
+ title: 'API Status Check',
5014
+ readOnlyHint: true,
5015
+ destructiveHint: false,
5016
+ idempotentHint: true,
5017
+ openWorldHint: false,
5018
+ }, async () => {
5019
+ return await performApiStatusCheck();
5020
+ });
5021
+ }
5022
+
5023
+ async function npmGetRepository(packageName) {
5024
+ const cacheKey = generateCacheKey('npm-get-repository', { packageName });
5025
+ return withCache(cacheKey, async () => {
5026
+ try {
5027
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5028
+ cache: true,
5029
+ });
5030
+ if (result.isError) {
5031
+ return result;
5032
+ }
5033
+ // Parse the result from the executed command
5034
+ const commandOutput = JSON.parse(result.content[0].text);
5035
+ // The result is a JSON string from npm that needs to be parsed again
5036
+ const npmData = JSON.parse(commandOutput.result);
5037
+ // Extract only repository-related data
5038
+ const repositoryResult = {
5039
+ packageName: npmData.name,
5040
+ description: npmData.description,
5041
+ repository: npmData.repository,
5042
+ homepage: npmData.homepage,
5043
+ };
5044
+ return createSuccessResult$1(repositoryResult);
5045
+ }
5046
+ catch (error) {
5047
+ return createErrorResult$1('Failed to get npm repository information', error);
5048
+ }
5049
+ });
5050
+ }
5051
+
5052
+ function registerNpmGetRepositoryTool(server) {
5053
+ server.tool(TOOL_NAMES.NPM_GET_REPOSITORY, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_REPOSITORY], {
5054
+ packageName: z
5055
+ .string()
5056
+ .describe("The name of the npm package to get repository information for (e.g., 'react', 'express', 'lodash'). Returns minimal repository data: package name, description, repository URL, and homepage - optimized for token efficiency."),
5057
+ }, {
5058
+ title: 'NPM Repository Discovery - Extract GitHub Repository URL',
5059
+ readOnlyHint: true,
5060
+ destructiveHint: false,
5061
+ idempotentHint: true,
5062
+ openWorldHint: true,
5063
+ }, async (args) => {
5064
+ try {
5065
+ return await npmGetRepository(args.packageName);
5066
+ }
5067
+ catch (error) {
5068
+ const errorMessage = error.message;
5069
+ // Enhanced error handling for package not found
5070
+ if (errorMessage.includes('404') ||
5071
+ errorMessage.includes('not found')) {
5072
+ return generateSmartRecovery({
5073
+ tool: 'NPM Get Repository',
5074
+ packageName: args.packageName,
5075
+ error: error,
5076
+ });
5077
+ }
5078
+ // Generic enhanced error handling
5079
+ return generateSmartRecovery({
5080
+ tool: 'NPM Get Repository',
5081
+ packageName: args.packageName,
5082
+ error: error,
5083
+ });
5084
+ }
5085
+ });
5086
+ }
5087
+
5088
+ async function npmGetDependencies(packageName) {
5089
+ const cacheKey = generateCacheKey('npm-get-dependencies', { packageName });
5090
+ return withCache(cacheKey, async () => {
5091
+ try {
5092
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5093
+ cache: true,
5094
+ });
5095
+ if (result.isError) {
5096
+ return result;
5097
+ }
5098
+ // Parse the result from the executed command
5099
+ const commandOutput = JSON.parse(result.content[0].text);
5100
+ // The result is a JSON string from npm that needs to be parsed again
5101
+ const npmData = JSON.parse(commandOutput.result);
5102
+ // Extract only dependencies data
5103
+ const dependenciesResult = {
5104
+ packageName: npmData.name,
5105
+ dependencies: npmData.dependencies || {},
5106
+ devDependencies: npmData.devDependencies || {},
5107
+ resolutions: npmData.resolutions || {},
5108
+ };
5109
+ return createSuccessResult$1(dependenciesResult);
5110
+ }
5111
+ catch (error) {
5112
+ return createErrorResult$1('Failed to get npm dependencies information', error);
5113
+ }
5114
+ });
5115
+ }
5116
+
5117
+ function registerNpmGetDependenciesTool(server) {
5118
+ server.tool(TOOL_NAMES.NPM_GET_DEPENDENCIES, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_DEPENDENCIES], {
5119
+ packageName: z
5120
+ .string()
5121
+ .describe("The name of the npm package to analyze dependencies for (e.g., 'react', 'express', 'lodash'). Returns focused dependency data: dependencies, devDependencies, and resolutions - optimized for token efficiency."),
5122
+ }, {
5123
+ title: 'NPM Dependency Analysis - Extract Package Dependencies',
5124
+ readOnlyHint: true,
5125
+ destructiveHint: false,
5126
+ idempotentHint: true,
5127
+ openWorldHint: true,
5128
+ }, async (args) => {
5129
+ try {
5130
+ return await npmGetDependencies(args.packageName);
5131
+ }
5132
+ catch (error) {
5133
+ return generateSmartRecovery({
5134
+ tool: 'NPM Get Dependencies',
5135
+ packageName: args.packageName,
5136
+ error: error,
5137
+ });
5138
+ }
5139
+ });
5140
+ }
5141
+
5142
+ async function npmGetBugs(packageName) {
5143
+ const cacheKey = generateCacheKey('npm-get-bugs', { packageName });
5144
+ return withCache(cacheKey, async () => {
5145
+ try {
5146
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5147
+ cache: true,
5148
+ });
5149
+ if (result.isError) {
5150
+ return result;
5151
+ }
5152
+ // Parse the result from the executed command
5153
+ const commandOutput = JSON.parse(result.content[0].text);
5154
+ // The result is a JSON string from npm that needs to be parsed again
5155
+ const npmData = JSON.parse(commandOutput.result);
5156
+ // Extract only bugs data
5157
+ const bugsResult = {
5158
+ packageName: npmData.name,
5159
+ bugs: npmData.bugs,
5160
+ };
5161
+ return createSuccessResult$1(bugsResult);
5162
+ }
5163
+ catch (error) {
5164
+ return createErrorResult$1('Failed to get npm bugs information', error);
5165
+ }
5166
+ });
5167
+ }
5168
+
5169
+ function registerNpmGetBugsTool(server) {
5170
+ server.tool(TOOL_NAMES.NPM_GET_BUGS, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_BUGS], {
5171
+ packageName: z
5172
+ .string()
5173
+ .describe("The name of the npm package to get bug tracking information for (e.g., 'react', 'express', 'lodash'). Returns minimal bug data: package name and bugs URL - optimized for token efficiency."),
5174
+ }, {
5175
+ title: 'NPM Bug Tracking - Extract Issue Tracker URL',
5176
+ readOnlyHint: true,
5177
+ destructiveHint: false,
5178
+ idempotentHint: true,
5179
+ openWorldHint: true,
5180
+ }, async (args) => {
5181
+ try {
5182
+ return await npmGetBugs(args.packageName);
5183
+ }
5184
+ catch (error) {
5185
+ return {
5186
+ content: [
5187
+ {
5188
+ type: 'text',
5189
+ text: `Failed to get npm bugs info: ${error.message}`,
5190
+ },
5191
+ ],
5192
+ isError: true,
5193
+ };
5194
+ }
5195
+ });
5196
+ }
5197
+
5198
+ async function npmGetReadme(packageName) {
5199
+ const cacheKey = generateCacheKey('npm-get-readme', { packageName });
5200
+ return withCache(cacheKey, async () => {
5201
+ try {
5202
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5203
+ cache: true,
5204
+ });
5205
+ if (result.isError) {
5206
+ return result;
5207
+ }
5208
+ // Parse the result from the executed command
5209
+ const commandOutput = JSON.parse(result.content[0].text);
5210
+ // The result is a JSON string from npm that needs to be parsed again
5211
+ const npmData = JSON.parse(commandOutput.result);
5212
+ // Extract only readme data
5213
+ const readmeResult = {
5214
+ packageName: npmData.name,
5215
+ readmeFilename: npmData.readmeFilename,
5216
+ };
5217
+ return createSuccessResult$1(readmeResult);
5218
+ }
5219
+ catch (error) {
5220
+ return createErrorResult$1('Failed to get npm readme information', error);
5221
+ }
5222
+ });
5223
+ }
5224
+
5225
+ function registerNpmGetReadmeTool(server) {
5226
+ server.tool(TOOL_NAMES.NPM_GET_README, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_README], {
5227
+ packageName: z
5228
+ .string()
5229
+ .describe("The name of the npm package to get README information for (e.g., 'react', 'express', 'lodash'). Returns minimal README data: package name and readme filename - optimized for token efficiency."),
5230
+ }, {
5231
+ title: 'NPM Documentation Access - Extract README Filename',
5232
+ readOnlyHint: true,
5233
+ destructiveHint: false,
5234
+ idempotentHint: true,
5235
+ openWorldHint: true,
5236
+ }, async (args) => {
5237
+ try {
5238
+ return await npmGetReadme(args.packageName);
5239
+ }
5240
+ catch (error) {
5241
+ return {
5242
+ content: [
5243
+ {
5244
+ type: 'text',
5245
+ text: `Failed to get npm readme info: ${error.message}`,
5246
+ },
5247
+ ],
5248
+ isError: true,
5249
+ };
5250
+ }
5251
+ });
5252
+ }
5253
+
5254
+ async function npmGetVersions(packageName) {
5255
+ const cacheKey = generateCacheKey('npm-get-versions', { packageName });
5256
+ return withCache(cacheKey, async () => {
5257
+ try {
5258
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5259
+ cache: true,
5260
+ });
5261
+ if (result.isError) {
5262
+ return result;
5263
+ }
5264
+ // Parse the result from the executed command
5265
+ const commandOutput = JSON.parse(result.content[0].text);
5266
+ // The result is a JSON string from npm that needs to be parsed again
5267
+ const npmData = JSON.parse(commandOutput.result);
5268
+ // Filter versions to include only official semantic versions (major.minor.patch)
5269
+ // Excludes pre-release versions like alpha, beta, rc, dev, experimental, etc.
5270
+ const semanticVersionRegex = /^\d+\.\d+\.\d+$/;
5271
+ const officialVersions = npmData.versions.filter(version => semanticVersionRegex.test(version));
5272
+ // Extract only versions data with filtered official versions
5273
+ const versionsResult = {
5274
+ packageName: npmData.name,
5275
+ versions: officialVersions,
5276
+ latestVersion: npmData['dist-tags'].latest,
5277
+ versionCount: officialVersions.length,
5278
+ };
5279
+ return createSuccessResult$1(versionsResult);
5280
+ }
5281
+ catch (error) {
5282
+ return createErrorResult$1('Failed to get npm versions information', error);
5283
+ }
5284
+ });
5285
+ }
5286
+
5287
+ function registerNpmGetVersionsTool(server) {
5288
+ server.tool(TOOL_NAMES.NPM_GET_VERSIONS, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_VERSIONS], {
5289
+ packageName: z
5290
+ .string()
5291
+ .describe("The name of the npm package to get version information for (e.g., 'react', 'express', 'lodash'). Returns only official semantic versions (major.minor.patch format), excluding pre-release versions like alpha, beta, rc - optimized for production planning."),
5292
+ }, {
5293
+ title: 'NPM Version Tracking - Extract Package Versions',
5294
+ readOnlyHint: true,
5295
+ destructiveHint: false,
5296
+ idempotentHint: true,
5297
+ openWorldHint: true,
5298
+ }, async (args) => {
5299
+ try {
5300
+ return await npmGetVersions(args.packageName);
5301
+ }
5302
+ catch (error) {
5303
+ return {
5304
+ content: [
5305
+ {
5306
+ type: 'text',
5307
+ text: `Failed to get npm versions: ${error.message}`,
5308
+ },
5309
+ ],
5310
+ isError: true,
5311
+ };
5312
+ }
5313
+ });
5314
+ }
5315
+
5316
+ async function npmGetAuthor(packageName) {
5317
+ const cacheKey = generateCacheKey('npm-get-author', { packageName });
5318
+ return withCache(cacheKey, async () => {
5319
+ try {
5320
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5321
+ cache: true,
5322
+ });
5323
+ if (result.isError) {
5324
+ return result;
5325
+ }
5326
+ // Parse the result from the executed command
5327
+ const commandOutput = JSON.parse(result.content[0].text);
5328
+ // The result is a JSON string from npm that needs to be parsed again
5329
+ const npmData = JSON.parse(commandOutput.result);
5330
+ // Extract only author data
5331
+ const authorResult = {
5332
+ packageName: npmData.name,
5333
+ author: npmData.author,
5334
+ maintainers: npmData.maintainers,
5335
+ };
5336
+ return createSuccessResult$1(authorResult);
5337
+ }
5338
+ catch (error) {
5339
+ return createErrorResult$1('Failed to get npm author information', error);
5340
+ }
5341
+ });
5342
+ }
5343
+
5344
+ function registerNpmGetAuthorTool(server) {
5345
+ server.tool(TOOL_NAMES.NPM_GET_AUTHOR, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_AUTHOR], {
5346
+ packageName: z
5347
+ .string()
5348
+ .describe("The name of the npm package to get author information for (e.g., 'react', 'express', 'lodash'). Returns focused author data: author and maintainers list - optimized for token efficiency."),
5349
+ }, {
5350
+ title: 'NPM Maintainer Information - Extract Author and Maintainers',
5351
+ readOnlyHint: true,
5352
+ destructiveHint: false,
5353
+ idempotentHint: true,
5354
+ openWorldHint: true,
5355
+ }, async (args) => {
5356
+ try {
5357
+ return await npmGetAuthor(args.packageName);
5358
+ }
5359
+ catch (error) {
5360
+ return {
5361
+ content: [
5362
+ {
5363
+ type: 'text',
5364
+ text: `Failed to get npm author info: ${error.message}`,
5365
+ },
5366
+ ],
5367
+ isError: true,
5368
+ };
5369
+ }
5370
+ });
5371
+ }
5372
+
5373
+ async function npmGetLicense(packageName) {
5374
+ const cacheKey = generateCacheKey('npm-get-license', { packageName });
5375
+ return withCache(cacheKey, async () => {
5376
+ try {
5377
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5378
+ cache: true,
5379
+ });
5380
+ if (result.isError) {
5381
+ return result;
5382
+ }
5383
+ // Parse the result from the executed command
5384
+ const commandOutput = JSON.parse(result.content[0].text);
5385
+ // The result is a JSON string from npm that needs to be parsed again
5386
+ const npmData = JSON.parse(commandOutput.result);
5387
+ // Extract only license data
5388
+ const licenseResult = {
5389
+ packageName: npmData.name,
5390
+ license: npmData.license,
5391
+ };
5392
+ return createSuccessResult$1(licenseResult);
5393
+ }
5394
+ catch (error) {
5395
+ return createErrorResult$1('Failed to get npm license information', error);
5396
+ }
5397
+ });
5398
+ }
5399
+
5400
+ function registerNpmGetLicenseTool(server) {
5401
+ server.tool(TOOL_NAMES.NPM_GET_LICENSE, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_LICENSE], {
5402
+ packageName: z
5403
+ .string()
5404
+ .describe("The name of the npm package to get license information for (e.g., 'react', 'express', 'lodash'). Returns minimal license data: package name and license - optimized for token efficiency."),
5405
+ }, {
5406
+ title: 'NPM License Compliance - Extract Package License',
5407
+ readOnlyHint: true,
5408
+ destructiveHint: false,
5409
+ idempotentHint: true,
5410
+ openWorldHint: true,
5411
+ }, async (args) => {
5412
+ try {
5413
+ return await npmGetLicense(args.packageName);
5414
+ }
5415
+ catch (error) {
5416
+ return {
5417
+ content: [
5418
+ {
5419
+ type: 'text',
5420
+ text: `Failed to get npm license info: ${error.message}`,
5421
+ },
5422
+ ],
5423
+ isError: true,
5424
+ };
5425
+ }
5426
+ });
5427
+ }
5428
+
5429
+ async function npmGetHomepage(packageName) {
5430
+ const cacheKey = generateCacheKey('npm-get-homepage', { packageName });
5431
+ return withCache(cacheKey, async () => {
5432
+ try {
5433
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5434
+ cache: true,
5435
+ });
5436
+ if (result.isError) {
5437
+ return result;
5438
+ }
5439
+ // Parse the result from the executed command
5440
+ const commandOutput = JSON.parse(result.content[0].text);
5441
+ // The result is a JSON string from npm that needs to be parsed again
5442
+ const npmData = JSON.parse(commandOutput.result);
5443
+ // Extract only homepage data
5444
+ const homepageResult = {
5445
+ packageName: npmData.name,
5446
+ homepage: npmData.homepage,
5447
+ };
5448
+ return createSuccessResult$1(homepageResult);
5449
+ }
5450
+ catch (error) {
5451
+ return createErrorResult$1('Failed to get npm homepage information', error);
5452
+ }
5453
+ });
5454
+ }
5455
+
5456
+ function registerNpmGetHomepageTool(server) {
5457
+ server.tool(TOOL_NAMES.NPM_GET_HOMEPAGE, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_HOMEPAGE], {
5458
+ packageName: z
5459
+ .string()
5460
+ .describe("The name of the npm package to get homepage information for (e.g., 'react', 'express', 'lodash'). Returns direct access to official documentation, interactive examples, and comprehensive project resources - optimized for token efficiency."),
5461
+ }, {
5462
+ title: 'NPM Homepage Discovery - Extract Project Website URL',
5463
+ readOnlyHint: true,
5464
+ destructiveHint: false,
5465
+ idempotentHint: true,
5466
+ openWorldHint: true,
5467
+ }, async (args) => {
5468
+ try {
5469
+ return await npmGetHomepage(args.packageName);
5470
+ }
5471
+ catch (error) {
5472
+ return {
5473
+ content: [
5474
+ {
5475
+ type: 'text',
5476
+ text: `Failed to get npm homepage info: ${error.message}`,
5477
+ },
5478
+ ],
5479
+ isError: true,
5480
+ };
5481
+ }
5482
+ });
5483
+ }
5484
+
5485
+ async function npmGetId(packageName) {
5486
+ const cacheKey = generateCacheKey('npm-get-id', { packageName });
5487
+ return withCache(cacheKey, async () => {
5488
+ try {
5489
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5490
+ cache: true,
5491
+ });
5492
+ if (result.isError) {
5493
+ return result;
5494
+ }
5495
+ // Parse the result from the executed command
5496
+ const commandOutput = JSON.parse(result.content[0].text);
5497
+ // The result is a JSON string from npm that needs to be parsed again
5498
+ const npmData = JSON.parse(commandOutput.result);
5499
+ // Extract only _id data (name@latestVersion format)
5500
+ const idResult = {
5501
+ packageName: npmData.name,
5502
+ id: npmData._id,
5503
+ };
5504
+ return createSuccessResult$1(idResult);
5505
+ }
5506
+ catch (error) {
5507
+ return createErrorResult$1('Failed to get npm ID information', error);
5508
+ }
5509
+ });
5510
+ }
5511
+
5512
+ function registerNpmGetIdTool(server) {
5513
+ server.tool(TOOL_NAMES.NPM_GET_ID, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_ID], {
5514
+ packageName: z
5515
+ .string()
5516
+ .describe("The name of the npm package to get ID information for (e.g., 'react', 'express', 'lodash'). Returns precise version identifier for dependency management, lockfiles, and reproducible builds - optimized for token efficiency."),
5517
+ }, {
5518
+ title: 'NPM Package Identification - Extract Name@Version ID',
5519
+ readOnlyHint: true,
5520
+ destructiveHint: false,
5521
+ idempotentHint: true,
5522
+ openWorldHint: true,
5523
+ }, async (args) => {
5524
+ try {
5525
+ return await npmGetId(args.packageName);
5526
+ }
5527
+ catch (error) {
5528
+ return {
5529
+ content: [
5530
+ {
5531
+ type: 'text',
5532
+ text: `Failed to get npm ID info: ${error.message}`,
5533
+ },
5534
+ ],
5535
+ isError: true,
5536
+ };
5537
+ }
5538
+ });
5539
+ }
5540
+
5541
+ async function npmGetReleases(packageName) {
5542
+ const cacheKey = generateCacheKey('npm-get-releases', { packageName });
5543
+ return withCache(cacheKey, async () => {
5544
+ try {
5545
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5546
+ cache: true,
5547
+ });
5548
+ if (result.isError) {
5549
+ return result;
5550
+ }
5551
+ // Parse the result from the executed command
5552
+ const commandOutput = JSON.parse(result.content[0].text);
5553
+ // The result is a JSON string from npm that needs to be parsed again
5554
+ const npmData = JSON.parse(commandOutput.result);
5555
+ // Extract only version entries (exclude 'created' and 'modified')
5556
+ const versionEntries = Object.entries(npmData.time).filter(([key]) => key !== 'created' && key !== 'modified');
5557
+ // Sort by release date (most recent first) and take last 10
5558
+ const sortedVersions = versionEntries
5559
+ .sort(([, dateA], [, dateB]) => new Date(dateB).getTime() - new Date(dateA).getTime())
5560
+ .slice(0, 10)
5561
+ .map(([version, releaseDate]) => ({ version, releaseDate }));
5562
+ // Create efficient result with only requested data
5563
+ const timeResult = {
5564
+ packageName: npmData.name,
5565
+ lastModified: npmData.time.modified,
5566
+ created: npmData.time.created,
5567
+ versionCount: versionEntries.length,
5568
+ last10Releases: sortedVersions,
5569
+ };
5570
+ return createSuccessResult$1(timeResult);
5571
+ }
5572
+ catch (error) {
5573
+ return createErrorResult$1('Failed to get npm time information', error);
5574
+ }
5575
+ });
5576
+ }
5577
+
5578
+ function registerNpmGetReleasesTool(server) {
5579
+ server.tool(TOOL_NAMES.NPM_GET_RELEASES, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_RELEASES], {
5580
+ packageName: z
5581
+ .string()
5582
+ .describe("The name of the npm package to get release information for (e.g., 'react', 'express', 'lodash'). Returns focused release data: last modified, created date, version count, and last 10 releases - optimized for token efficiency."),
5583
+ }, {
5584
+ title: 'NPM Package Releases - Extract Recent Release Data',
5585
+ readOnlyHint: true,
5586
+ destructiveHint: false,
5587
+ idempotentHint: true,
5588
+ openWorldHint: true,
5589
+ }, async (args) => {
5590
+ try {
5591
+ return await npmGetReleases(args.packageName);
5592
+ }
5593
+ catch (error) {
5594
+ return {
5595
+ content: [
5596
+ {
5597
+ type: 'text',
5598
+ text: `Failed to get npm release info: ${error.message}`,
5599
+ },
5600
+ ],
5601
+ isError: true,
5602
+ };
5603
+ }
5604
+ });
5605
+ }
5606
+
5607
+ async function npmGetEngines(packageName) {
5608
+ const cacheKey = generateCacheKey('npm-get-engines', { packageName });
5609
+ return withCache(cacheKey, async () => {
5610
+ try {
5611
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5612
+ cache: true,
5613
+ });
5614
+ if (result.isError) {
5615
+ return result;
5616
+ }
5617
+ // Parse the result from the executed command
5618
+ const commandOutput = JSON.parse(result.content[0].text);
5619
+ // The result is a JSON string from npm that needs to be parsed again
5620
+ const npmData = JSON.parse(commandOutput.result);
5621
+ // Extract only engines data
5622
+ const enginesResult = {
5623
+ packageName: npmData.name,
5624
+ engines: npmData.engines || {},
5625
+ };
5626
+ return createSuccessResult$1(enginesResult);
5627
+ }
5628
+ catch (error) {
5629
+ return createErrorResult$1('Failed to get npm engines information', error);
5630
+ }
5631
+ });
5632
+ }
5633
+
5634
+ function registerNpmGetEnginesTool(server) {
5635
+ server.tool(TOOL_NAMES.NPM_GET_ENGINES, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_ENGINES], {
5636
+ packageName: z
5637
+ .string()
5638
+ .describe("The name of the npm package to get engines information for (e.g., 'react', 'express', 'lodash'). Returns environment compatibility requirements to prevent deployment failures and runtime conflicts - optimized for token efficiency."),
5639
+ }, {
5640
+ title: 'NPM Runtime Compatibility - Extract Engine Requirements',
5641
+ readOnlyHint: true,
5642
+ destructiveHint: false,
5643
+ idempotentHint: true,
5644
+ openWorldHint: true,
5645
+ }, async (args) => {
5646
+ try {
5647
+ return await npmGetEngines(args.packageName);
5648
+ }
5649
+ catch (error) {
5650
+ return {
5651
+ content: [
5652
+ {
5653
+ type: 'text',
5654
+ text: `Failed to get npm engines info: ${error.message}`,
5655
+ },
5656
+ ],
5657
+ isError: true,
5658
+ };
5659
+ }
5660
+ });
5661
+ }
5662
+
5663
+ async function npmGetExports(packageName) {
5664
+ const cacheKey = generateCacheKey('npm-get-exports', { packageName });
5665
+ return withCache(cacheKey, async () => {
5666
+ try {
5667
+ const result = await executeNpmCommand('view', [packageName, '--json'], {
5668
+ cache: true,
5669
+ });
5670
+ if (result.isError) {
5671
+ return result;
3051
5672
  }
3052
- let rateLimit;
5673
+ // Parse the result from the executed command
5674
+ const commandOutput = JSON.parse(result.content[0].text);
5675
+ // The result is a JSON string from npm that needs to be parsed again
5676
+ const npmData = JSON.parse(commandOutput.result);
5677
+ // Extract only exports data
5678
+ const exportsResult = {
5679
+ packageName: npmData.name,
5680
+ exports: npmData.exports || {},
5681
+ };
5682
+ return createSuccessResult$1(exportsResult);
5683
+ }
5684
+ catch (error) {
5685
+ return createErrorResult$1('Failed to get npm exports information', error);
5686
+ }
5687
+ });
5688
+ }
5689
+
5690
+ function registerNpmGetExportsTool(server) {
5691
+ server.tool(TOOL_NAMES.NPM_GET_EXPORTS, TOOL_DESCRIPTIONS[TOOL_NAMES.NPM_GET_EXPORTS], {
5692
+ packageName: z
5693
+ .string()
5694
+ .describe("The name of the npm package to get exports information for (e.g., 'react', 'express', 'lodash'). Returns import path intelligence: available modules, entry points, and tree-shakable exports for optimal code search - optimized for token efficiency."),
5695
+ }, {
5696
+ title: 'NPM Module Structure - Extract Package Export Mappings',
5697
+ readOnlyHint: true,
5698
+ destructiveHint: false,
5699
+ idempotentHint: true,
5700
+ openWorldHint: true,
5701
+ }, async (args) => {
5702
+ try {
5703
+ return await npmGetExports(args.packageName);
5704
+ }
5705
+ catch (error) {
5706
+ return {
5707
+ content: [
5708
+ {
5709
+ type: 'text',
5710
+ text: `Failed to get npm exports info: ${error.message}`,
5711
+ },
5712
+ ],
5713
+ isError: true,
5714
+ };
5715
+ }
5716
+ });
5717
+ }
5718
+
5719
+ function registerUsageGuideResource(server) {
5720
+ server.resource('usage-guide', 'help://usage', async (uri) => ({
5721
+ contents: [
5722
+ {
5723
+ uri: uri.href,
5724
+ mimeType: 'text/markdown',
5725
+ text: `# Octocode MCP Quick Start
5726
+
5727
+ ## Setup (Required)
5728
+ \`\`\`bash
5729
+ gh auth login # GitHub CLI authentication
5730
+ \`\`\`
5731
+
5732
+ ## MANDATORY SEARCH STRATEGY
5733
+ 1. **ALWAYS START**: \`search_github_topics\` - **NEVER SKIP** - Maps ecosystem terminology
5734
+ 2. **PRIMARY DISCOVERY**: \`npm_search\` and \`npm_view\` - Minimizes GitHub API calls
5735
+ 3. **TARGETED EXTRACTION**: \`search_github_code\` with owner/repo from NPM
5736
+ 4. **LAST RESORT**: \`search_github_repos\` - Single terms only when NPM insufficient
5737
+
5738
+ ## Core Workflow
5739
+ 1. **Check Auth**: Read \`github://auth-status\` and \`github://rate-limits\`
5740
+ 2. **MANDATORY**: \`search_github_topics\` for ecosystem mapping
5741
+ 3. **NPM Discovery**: \`npm_search\` → \`npm_view\` → extract repository URLs
5742
+ 4. **Extract**: Get complete implementations from discovered repositories
5743
+ 5. **Validate**: Cross-reference multiple NPM packages
5744
+
5745
+ ## Essential Tools (Priority Order)
5746
+ - **\`search_github_topics\`**: **MANDATORY FIRST STEP** - Find technology ecosystems
5747
+ - **\`npm_search\`**: **PRIMARY DISCOVERY** - Find packages by functionality
5748
+ - **\`npm_view\`**: **PRIMARY DISCOVERY** - Package metadata and repo links
5749
+ - **\`view_repository\`**: Get branch info (required before file operations!)
5750
+ - **\`search_github_code\`**: Find specific implementations in discovered repos
5751
+ - **\`fetch_github_file_content\`**: Extract complete code
5752
+ - **\`search_github_repos\`**: **LAST RESORT ONLY** - Single terms when NPM fails
5753
+
5754
+ ## Search Strategy Rules
5755
+ - **Topics First**: Every workflow starts with \`search_github_topics\`
5756
+ - **NPM Primary**: Use NPM tools before GitHub repo search
5757
+ - **Single Terms Only**: NEVER multi-term searches in \`search_github_repos\`
5758
+ - **API Conservation**: NPM discovery reduces GitHub API usage by 60%
5759
+
5760
+ ## Search Term Strategy
5761
+ - **✅ GOOD**: "react", "authentication", "typescript", "deployment"
5762
+ - **❌ BAD**: "react hooks", "full-stack app", "react angular auth"
5763
+ - **Decompose**: "react typescript auth" → ["react", "typescript", "authentication"]
5764
+
5765
+ ## Quick Examples
5766
+ - **Package research**: \`search_github_topics\` → \`npm_search\` → \`npm_view\` → \`view_repository\` → \`search_github_code\`
5767
+ - **Problem solving**: \`search_github_topics\` → \`npm_search\` → \`search_github_issues\` → \`search_github_code\`
5768
+ - **Technology discovery**: \`search_github_topics\` → \`npm_search\` → \`npm_view\` → \`view_repository\` → \`fetch_github_file_content\`
5769
+
5770
+ ## CRITICAL REMINDERS
5771
+ - **NEVER skip** \`search_github_topics\` - provides essential context
5772
+ - **NPM FIRST** - use NPM tools before GitHub repo search
5773
+ - **SINGLE TERMS** - never combine multiple concepts in repo searches
5774
+ - **REPOS LAST** - \`search_github_repos\` is lowest priority discovery tool
5775
+
5776
+ Generated: ${new Date().toISOString()}`,
5777
+ },
5778
+ ],
5779
+ }));
5780
+ }
5781
+
5782
+ // GitHub Authentication Status Resource
5783
+ function registerGithubStatusResource(server) {
5784
+ server.resource('github-auth-status', 'github://auth-status', async (uri) => {
5785
+ try {
5786
+ // For version, we'll use a workaround since --version is not a command
5787
+ // We can use 'help' command which shows version info, or skip detailed version check
5788
+ const ghVersion = 'Available (GitHub CLI detected)';
5789
+ let isAuthenticated = false;
5790
+ let authError = null;
3053
5791
  try {
3054
- const parsed = JSON.parse(content);
3055
- rateLimit = parsed.result || parsed;
5792
+ // Check auth status using safe command
5793
+ const authResult = await executeGitHubCommand('auth', ['status'], {
5794
+ timeout: 5000,
5795
+ cache: false,
5796
+ });
5797
+ if (!authResult.isError) {
5798
+ const content = String(authResult.content[0]?.text || '');
5799
+ if (content) {
5800
+ try {
5801
+ const parsed = JSON.parse(content);
5802
+ const output = parsed.result || content;
5803
+ // Only check if authenticated, don't expose user details
5804
+ isAuthenticated =
5805
+ String(output).includes('✓ Logged in') ||
5806
+ String(output).includes('Logged in');
5807
+ }
5808
+ catch {
5809
+ isAuthenticated =
5810
+ content.includes('✓ Logged in') ||
5811
+ content.includes('Logged in');
5812
+ }
5813
+ }
5814
+ }
5815
+ else {
5816
+ // auth status command failed, check error content for auth info
5817
+ const errorContent = String(authResult.content[0]?.text || 'Authentication check failed');
5818
+ if (errorContent.includes('✓ Logged in') ||
5819
+ errorContent.includes('Logged in')) {
5820
+ isAuthenticated = true;
5821
+ }
5822
+ else {
5823
+ authError = 'Not authenticated';
5824
+ }
5825
+ }
3056
5826
  }
3057
- catch {
3058
- rateLimit = JSON.parse(content);
5827
+ catch (error) {
5828
+ authError = 'Unable to check authentication status';
3059
5829
  }
3060
- const rateLimitInfo = processRateLimit(rateLimit);
3061
5830
  return {
3062
5831
  contents: [
3063
5832
  {
3064
5833
  uri: uri.href,
3065
5834
  mimeType: 'application/json',
3066
5835
  text: JSON.stringify({
3067
- status: 'GitHub API Rate Limits - LIVE STATUS',
3068
- description: 'Real-time GitHub API rate limit status for all endpoints',
3069
- rate_limits: rateLimitInfo,
3070
- usage_notes: {
3071
- primary_api: 'Used for most GitHub operations (repos, issues, PRs, etc.)',
3072
- search_api: 'Used for searching repositories, code, issues, users',
3073
- code_search: 'Dedicated endpoint for code search operations (most restrictive)',
3074
- graphql_api: 'Used for GraphQL queries',
3075
- status_meanings: {
3076
- healthy: 'All APIs have sufficient remaining requests',
3077
- limited: 'Some APIs are running low on requests (< 10 remaining)',
3078
- exhausted: 'One or more APIs have no remaining requests',
3079
- },
3080
- },
3081
- recommendations: {
3082
- healthy: 'All APIs ready for use',
3083
- limited: 'Consider prioritizing essential requests only',
3084
- exhausted: 'Wait until reset time or use alternative approaches',
5836
+ status: 'GitHub Authentication Status - LIVE STATUS',
5837
+ description: 'GitHub CLI authentication status and version information',
5838
+ gh_version: ghVersion,
5839
+ authenticated: isAuthenticated,
5840
+ auth_error: authError,
5841
+ setup_instructions: {
5842
+ not_authenticated: [
5843
+ 'Run: gh auth login',
5844
+ 'Follow the interactive prompts to authenticate',
5845
+ 'Choose your preferred authentication method',
5846
+ ],
5847
+ verification: [
5848
+ 'Run: gh auth status',
5849
+ 'Should show "✓ Logged in" if successful',
5850
+ ],
3085
5851
  },
3086
5852
  timestamp: new Date().toISOString(),
3087
5853
  }, null, 2),
@@ -3096,9 +5862,9 @@ function registerGithubRateLimitResource(server) {
3096
5862
  uri: uri.href,
3097
5863
  mimeType: 'application/json',
3098
5864
  text: JSON.stringify({
3099
- status: 'GitHub API Rate Limits - ERROR',
5865
+ status: 'GitHub Authentication Status - ERROR',
3100
5866
  error: error.message,
3101
- message: 'Unable to check rate limits - authentication may be required',
5867
+ message: 'GitHub CLI may not be installed or accessible',
3102
5868
  timestamp: new Date().toISOString(),
3103
5869
  }, null, 2),
3104
5870
  },
@@ -3107,56 +5873,6 @@ function registerGithubRateLimitResource(server) {
3107
5873
  }
3108
5874
  });
3109
5875
  }
3110
- function processRateLimit(rateLimit) {
3111
- const formatResetTime = (reset) => new Date(reset * 1000).toISOString();
3112
- const calculateUsage = (used, limit) => Math.round((used / limit) * 100);
3113
- const core = rateLimit.resources.core;
3114
- const search = rateLimit.resources.search;
3115
- const codeSearch = rateLimit.resources.code_search;
3116
- const graphql = rateLimit.resources.graphql;
3117
- // Determine overall status based on most restrictive API
3118
- const minRemaining = Math.min(core.remaining, search.remaining, codeSearch.remaining, graphql.remaining);
3119
- let status;
3120
- if (minRemaining === 0) {
3121
- status = 'exhausted';
3122
- }
3123
- else if (minRemaining < 10) {
3124
- status = 'limited';
3125
- }
3126
- else {
3127
- status = 'healthy';
3128
- }
3129
- // Find the earliest reset time
3130
- const nextReset = Math.min(core.reset, search.reset, codeSearch.reset, graphql.reset);
3131
- return {
3132
- primary_api: {
3133
- remaining: core.remaining,
3134
- limit: core.limit,
3135
- reset_time: formatResetTime(core.reset),
3136
- usage_percentage: calculateUsage(core.used, core.limit),
3137
- },
3138
- search_api: {
3139
- remaining: search.remaining,
3140
- limit: search.limit,
3141
- reset_time: formatResetTime(search.reset),
3142
- usage_percentage: calculateUsage(search.used, search.limit),
3143
- },
3144
- code_search: {
3145
- remaining: codeSearch.remaining,
3146
- limit: codeSearch.limit,
3147
- reset_time: formatResetTime(codeSearch.reset),
3148
- usage_percentage: calculateUsage(codeSearch.used, codeSearch.limit),
3149
- },
3150
- graphql_api: {
3151
- remaining: graphql.remaining,
3152
- limit: graphql.limit,
3153
- reset_time: formatResetTime(graphql.reset),
3154
- usage_percentage: calculateUsage(graphql.used, graphql.limit),
3155
- },
3156
- status,
3157
- next_reset: formatResetTime(nextReset),
3158
- };
3159
- }
3160
5876
 
3161
5877
  // Sanitize output to remove potential tokens
3162
5878
  function sanitizeOutput(output) {
@@ -3598,10 +6314,12 @@ process.stdin.on('close', async () => {
3598
6314
  });
3599
6315
  // Register all tools
3600
6316
  function registerAllTools(server) {
6317
+ // System & API Status - CRITICAL FIRST STEP
6318
+ registerApiStatusCheckTool(server);
3601
6319
  registerGitHubSearchCodeTool(server);
3602
6320
  registerFetchGitHubFileContentTool(server);
3603
6321
  registerViewRepositoryTool(server);
3604
- registerNpmViewTool(server);
6322
+ //Tools.registerNpmViewTool(server);
3605
6323
  registerSearchGitHubReposTool(server);
3606
6324
  registerSearchGitHubCommitsTool(server);
3607
6325
  registerSearchGitHubPullRequestsTool(server);
@@ -3609,18 +6327,27 @@ function registerAllTools(server) {
3609
6327
  registerNpmSearchTool(server);
3610
6328
  registerViewRepositoryStructureTool(server);
3611
6329
  registerSearchGitHubIssuesTool(server);
3612
- // TODO: add discussions tool after fixing API
3613
- //Tools.registerSearchGitHubDiscussionsTool(server);
3614
6330
  registerSearchGitHubTopicsTool(server);
3615
6331
  registerSearchGitHubUsersTool(server);
3616
- registerNpmPackageStatsTool(server);
6332
+ // Focused NPM tools for minimal token usage
3617
6333
  registerNpmDependencyAnalysisTool(server);
6334
+ registerNpmGetRepositoryTool(server);
6335
+ registerNpmGetDependenciesTool(server);
6336
+ registerNpmGetBugsTool(server);
6337
+ registerNpmGetReadmeTool(server);
6338
+ registerNpmGetVersionsTool(server);
6339
+ registerNpmGetAuthorTool(server);
6340
+ registerNpmGetLicenseTool(server);
6341
+ registerNpmGetHomepageTool(server);
6342
+ registerNpmGetIdTool(server);
6343
+ registerNpmGetReleasesTool(server);
6344
+ registerNpmGetEnginesTool(server);
6345
+ registerNpmGetExportsTool(server);
3618
6346
  }
3619
6347
  // Register all resources
3620
6348
  function registerResources(server) {
3621
6349
  registerUsageGuideResource(server);
3622
6350
  registerGithubStatusResource(server);
3623
- registerGithubRateLimitResource(server);
3624
6351
  registerNpmStatusResource(server);
3625
6352
  registerRepositoryIntelligenceResource(server);
3626
6353
  }