octocode-mcp 2.3.8 → 2.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +1080 -290
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -168,11 +168,13 @@ function escapeWindowsCmdArg(arg) {
|
|
|
168
168
|
* Preserves AND search logic by not over-escaping space-separated terms
|
|
169
169
|
*/
|
|
170
170
|
function escapeUnixShellArg(arg, isGitHubQuery) {
|
|
171
|
-
// For GitHub search queries, we need to preserve AND logic
|
|
171
|
+
// For GitHub search queries, we need to preserve AND logic and quoted phrases
|
|
172
172
|
if (isGitHubQuery) {
|
|
173
|
-
// If the query contains quotes, preserve them for
|
|
173
|
+
// If the query contains quotes, we need to preserve them for GitHub CLI
|
|
174
|
+
// but escape the entire argument for the shell
|
|
174
175
|
if (arg.includes('"')) {
|
|
175
176
|
// Use single quotes to wrap the entire query while preserving internal quotes
|
|
177
|
+
// This allows GitHub CLI to see: "quoted phrase" other terms
|
|
176
178
|
return `'${arg.replace(/'/g, "'\"'\"'")}'`;
|
|
177
179
|
}
|
|
178
180
|
// For space-separated terms (AND search), only escape if absolutely necessary
|
|
@@ -230,14 +232,21 @@ async function executeGitHubCommand(command, args = [], options = {}) {
|
|
|
230
232
|
// Get shell configuration
|
|
231
233
|
const shellConfig = getShellConfig(options.windowsShell);
|
|
232
234
|
// Build command with validated prefix and properly escaped arguments
|
|
233
|
-
// For GitHub search commands,
|
|
234
|
-
//
|
|
235
|
+
// For GitHub search commands, we need to distinguish between:
|
|
236
|
+
// 1. Main query (index 1) - needs special escaping for AND logic
|
|
237
|
+
// 2. CLI flags (--flag=value) - standard escaping
|
|
238
|
+
// 3. Search qualifiers (key:value) - minimal escaping
|
|
235
239
|
const escapedArgs = args.map((arg, index) => {
|
|
236
240
|
const isMainQueryArgument = command === 'search' && index === 1;
|
|
241
|
+
const isCliFlag = arg.startsWith('--');
|
|
237
242
|
const isGitHubQualifier = command === 'search' &&
|
|
238
243
|
index > 1 &&
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
!isCliFlag &&
|
|
245
|
+
(arg.includes(':') || arg.startsWith('('));
|
|
246
|
+
// CLI flags like --language=javascript, --repo=owner/repo need standard escaping
|
|
247
|
+
if (isCliFlag) {
|
|
248
|
+
return escapeShellArg(arg, shellConfig.type, false);
|
|
249
|
+
}
|
|
241
250
|
// GitHub search qualifiers need special handling
|
|
242
251
|
// Most qualifiers can be passed as-is, but those with shell metacharacters need escaping
|
|
243
252
|
if (isGitHubQualifier) {
|
|
@@ -458,24 +467,16 @@ const ERROR_MESSAGES = {
|
|
|
458
467
|
ISSUE_SEARCH_FAILED: 'Issue search failed - check auth or simplify query',
|
|
459
468
|
PR_SEARCH_FAILED: 'PR search failed - check access and query syntax',
|
|
460
469
|
PACKAGE_SEARCH_FAILED: 'Package search failed - try different keywords',
|
|
461
|
-
// GitHub CLI errors
|
|
462
|
-
CLI_INVALID_RESPONSE: 'GitHub CLI invalid response - check "gh version" and update',
|
|
463
|
-
// Timeout errors
|
|
464
|
-
SEARCH_TIMEOUT: 'Search timed out - add filters (language, owner) or use specific terms',
|
|
465
470
|
// Query validation errors
|
|
466
471
|
QUERY_TOO_LONG: 'Query too long (max 256 chars) - simplify search terms',
|
|
467
472
|
QUERY_REQUIRED: 'Query required - provide search keywords',
|
|
468
|
-
EMPTY_QUERY: 'Empty query - try "useState", "authentication", or language:python',
|
|
469
|
-
QUERY_TOO_LONG_1000: 'Query too long (max 1000 chars) - use key terms like "error handling"',
|
|
470
|
-
REPO_OR_OWNER_NOT_FOUND: 'Repository/owner not found - check spelling, visibility, and permissions',
|
|
471
|
-
// Query syntax errors
|
|
472
|
-
INVALID_QUERY_SYNTAX: 'Invalid syntax - Boolean operators not supported, use quotes for phrases',
|
|
473
|
-
// Size/format validation errors
|
|
474
|
-
INVALID_SIZE_FORMAT: 'Invalid size format - use >N, <N, or N..M without quotes',
|
|
475
|
-
INVALID_SEARCH_SCOPE: 'Invalid scope - use "file" for content, "path" for filenames',
|
|
476
473
|
// API Status check errors
|
|
477
474
|
API_STATUS_CHECK_FAILED: 'API Status Check Failed',
|
|
478
|
-
|
|
475
|
+
// NPM Errors
|
|
476
|
+
NPM_PACKAGE_NOT_FOUND: 'Package not found on NPM registry',
|
|
477
|
+
NPM_CONNECTION_FAILED: 'NPM registry connection failed',
|
|
478
|
+
NPM_CLI_ERROR: 'NPM CLI issue detected',
|
|
479
|
+
NPM_PERMISSION_ERROR: 'NPM permission issue'};
|
|
479
480
|
const SUGGESTIONS = {
|
|
480
481
|
// Code search suggestions
|
|
481
482
|
CODE_SEARCH_NO_RESULTS: `No results found. Try this progression:
|
|
@@ -499,6 +500,31 @@ const SUGGESTIONS = {
|
|
|
499
500
|
2. Break compound words: "authlib" → "auth"
|
|
500
501
|
3. Search by use case: "user login" vs "authentication"
|
|
501
502
|
4. Try category terms: "framework", "tool", "library"`,
|
|
503
|
+
// File Content Suggestions
|
|
504
|
+
FILE_NOT_FOUND_RECOVERY: `Quick fixes:
|
|
505
|
+
• Use github_view_repo_structure to verify path exists
|
|
506
|
+
• Check for typos in file path
|
|
507
|
+
• Try different branch (main/master/develop)`,
|
|
508
|
+
FILE_TOO_LARGE_RECOVERY: `Alternative strategies:
|
|
509
|
+
• Use github_search_code to search within the file
|
|
510
|
+
• Download directly from GitHub
|
|
511
|
+
• Use github_view_repo_structure to find smaller related files
|
|
512
|
+
• Look for configuration or summary files instead`,
|
|
513
|
+
// Repository Suggestions
|
|
514
|
+
REPOSITORY_NOT_FOUND_RECOVERY: `This is often due to incorrect repository name. Steps to resolve:
|
|
515
|
+
1. Use github_search_repositories to find the correct repository
|
|
516
|
+
2. Verify the exact repository name
|
|
517
|
+
3. Check if the repository might have been renamed or moved`,
|
|
518
|
+
// NPM Suggestions
|
|
519
|
+
NPM_DISCOVERY_STRATEGIES: `Discovery strategies:
|
|
520
|
+
• Functional search: "validation", "testing", "charts"
|
|
521
|
+
• Ecosystem search: "react", "typescript", "node"
|
|
522
|
+
• Use github_search_repositories for related projects`,
|
|
523
|
+
NPM_PACKAGE_NAME_ALTERNATIVES: `Try these alternatives:
|
|
524
|
+
• Try with dashes instead of underscores
|
|
525
|
+
• Try without dashes
|
|
526
|
+
• Try scoped package format
|
|
527
|
+
• Use npm_package_search for discovery`,
|
|
502
528
|
};
|
|
503
529
|
// Helper function to get error message with context-specific suggestions
|
|
504
530
|
function getErrorWithSuggestion(options) {
|
|
@@ -556,9 +582,348 @@ function createSearchFailedError(type = 'code') {
|
|
|
556
582
|
return ERROR_MESSAGES.SEARCH_FAILED;
|
|
557
583
|
}
|
|
558
584
|
}
|
|
585
|
+
function createNpmPackageNotFoundError(packageName) {
|
|
586
|
+
const suggestions = [];
|
|
587
|
+
if (packageName.includes('_')) {
|
|
588
|
+
suggestions.push(`• Try with dashes: "${packageName.replace(/_/g, '-')}"`);
|
|
589
|
+
}
|
|
590
|
+
if (packageName.includes('-')) {
|
|
591
|
+
suggestions.push(`• Try without dashes: "${packageName.replace(/-/g, '')}"`);
|
|
592
|
+
}
|
|
593
|
+
if (!packageName.includes('/') && packageName.length > 2) {
|
|
594
|
+
suggestions.push(`• Try scoped format: "@${packageName.slice(0, 3)}/${packageName}"`);
|
|
595
|
+
}
|
|
596
|
+
return `${ERROR_MESSAGES.NPM_PACKAGE_NOT_FOUND}: "${packageName}"
|
|
597
|
+
|
|
598
|
+
${suggestions.length > 0 ? suggestions.join('\n') + '\n\n' : ''}${SUGGESTIONS.NPM_PACKAGE_NAME_ALTERNATIVES}
|
|
599
|
+
|
|
600
|
+
${SUGGESTIONS.NPM_DISCOVERY_STRATEGIES}`;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Tool relationship map for standardized cross-tool suggestions
|
|
605
|
+
* Defines how tools connect and when to suggest alternatives
|
|
606
|
+
*/
|
|
607
|
+
const TOOL_NAMES = {
|
|
608
|
+
API_STATUS_CHECK: 'api_status_check',
|
|
609
|
+
GITHUB_FETCH_CONTENT: 'github_fetch_content',
|
|
610
|
+
GITHUB_SEARCH_CODE: 'github_search_code',
|
|
611
|
+
GITHUB_SEARCH_COMMITS: 'github_search_commits',
|
|
612
|
+
GITHUB_SEARCH_ISSUES: 'github_search_issues',
|
|
613
|
+
GITHUB_SEARCH_PULL_REQUESTS: 'github_search_pull_requests',
|
|
614
|
+
GITHUB_SEARCH_REPOSITORIES: 'github_search_repositories',
|
|
615
|
+
GITHUB_VIEW_REPO_STRUCTURE: 'github_view_repo_structure',
|
|
616
|
+
NPM_PACKAGE_SEARCH: 'npm_package_search',
|
|
617
|
+
NPM_VIEW_PACKAGE: 'npm_view_package',
|
|
618
|
+
};
|
|
619
|
+
const TOOL_RELATIONSHIPS = {
|
|
620
|
+
[TOOL_NAMES.NPM_PACKAGE_SEARCH]: {
|
|
621
|
+
fallbackTools: [
|
|
622
|
+
{
|
|
623
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
624
|
+
reason: 'to find repositories by topic or language',
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
628
|
+
reason: 'to search for package usage examples',
|
|
629
|
+
},
|
|
630
|
+
],
|
|
631
|
+
nextSteps: [
|
|
632
|
+
{
|
|
633
|
+
tool: TOOL_NAMES.NPM_VIEW_PACKAGE,
|
|
634
|
+
reason: 'to get detailed package information and repository URL',
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
638
|
+
reason: 'to explore the package source code structure',
|
|
639
|
+
},
|
|
640
|
+
],
|
|
641
|
+
},
|
|
642
|
+
[TOOL_NAMES.NPM_VIEW_PACKAGE]: {
|
|
643
|
+
fallbackTools: [
|
|
644
|
+
{
|
|
645
|
+
tool: TOOL_NAMES.NPM_PACKAGE_SEARCH,
|
|
646
|
+
reason: 'to discover similar packages',
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
650
|
+
reason: 'to find the repository directly',
|
|
651
|
+
},
|
|
652
|
+
],
|
|
653
|
+
nextSteps: [
|
|
654
|
+
{
|
|
655
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
656
|
+
reason: 'to explore repository structure',
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
tool: TOOL_NAMES.GITHUB_FETCH_CONTENT,
|
|
660
|
+
reason: 'to read specific files like README or package.json',
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
664
|
+
reason: 'to find usage examples',
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
},
|
|
668
|
+
[TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES]: {
|
|
669
|
+
fallbackTools: [
|
|
670
|
+
{
|
|
671
|
+
tool: TOOL_NAMES.NPM_PACKAGE_SEARCH,
|
|
672
|
+
reason: 'if searching for packages or libraries',
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
676
|
+
reason: 'to search within repository contents',
|
|
677
|
+
},
|
|
678
|
+
],
|
|
679
|
+
nextSteps: [
|
|
680
|
+
{
|
|
681
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
682
|
+
reason: 'to explore repository contents',
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_ISSUES,
|
|
686
|
+
reason: 'to check open issues and discussions',
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
tool: TOOL_NAMES.NPM_VIEW_PACKAGE,
|
|
690
|
+
reason: 'if repository is an NPM package',
|
|
691
|
+
},
|
|
692
|
+
],
|
|
693
|
+
},
|
|
694
|
+
[TOOL_NAMES.GITHUB_SEARCH_CODE]: {
|
|
695
|
+
fallbackTools: [
|
|
696
|
+
{
|
|
697
|
+
tool: TOOL_NAMES.NPM_PACKAGE_SEARCH,
|
|
698
|
+
reason: 'if searching for package implementations',
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
702
|
+
reason: 'to find repositories by topic',
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
tool: TOOL_NAMES.API_STATUS_CHECK,
|
|
706
|
+
reason: 'if no results (might be private repos)',
|
|
707
|
+
condition: 'no_results',
|
|
708
|
+
},
|
|
709
|
+
],
|
|
710
|
+
nextSteps: [
|
|
711
|
+
{
|
|
712
|
+
tool: TOOL_NAMES.GITHUB_FETCH_CONTENT,
|
|
713
|
+
reason: 'to view full file contents',
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
717
|
+
reason: 'to explore repository structure',
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
prerequisites: [
|
|
721
|
+
{
|
|
722
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
723
|
+
reason: 'to verify file paths before searching',
|
|
724
|
+
},
|
|
725
|
+
],
|
|
726
|
+
},
|
|
727
|
+
[TOOL_NAMES.GITHUB_FETCH_CONTENT]: {
|
|
728
|
+
fallbackTools: [
|
|
729
|
+
{
|
|
730
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
731
|
+
reason: 'to verify correct file path',
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
735
|
+
reason: 'to search for similar files',
|
|
736
|
+
},
|
|
737
|
+
],
|
|
738
|
+
nextSteps: [
|
|
739
|
+
{
|
|
740
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
741
|
+
reason: 'to explore related files',
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
745
|
+
reason: 'to find usage examples',
|
|
746
|
+
},
|
|
747
|
+
],
|
|
748
|
+
prerequisites: [
|
|
749
|
+
{
|
|
750
|
+
tool: TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE,
|
|
751
|
+
reason: 'to verify file exists and get correct path',
|
|
752
|
+
},
|
|
753
|
+
],
|
|
754
|
+
},
|
|
755
|
+
[TOOL_NAMES.GITHUB_VIEW_REPO_STRUCTURE]: {
|
|
756
|
+
fallbackTools: [
|
|
757
|
+
{
|
|
758
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
759
|
+
reason: 'to find the correct repository',
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
tool: TOOL_NAMES.API_STATUS_CHECK,
|
|
763
|
+
reason: 'if access denied (check authentication)',
|
|
764
|
+
condition: 'access_denied',
|
|
765
|
+
},
|
|
766
|
+
],
|
|
767
|
+
nextSteps: [
|
|
768
|
+
{
|
|
769
|
+
tool: TOOL_NAMES.GITHUB_FETCH_CONTENT,
|
|
770
|
+
reason: 'to read specific files',
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
774
|
+
reason: 'to search within the repository',
|
|
775
|
+
},
|
|
776
|
+
],
|
|
777
|
+
},
|
|
778
|
+
[TOOL_NAMES.GITHUB_SEARCH_COMMITS]: {
|
|
779
|
+
fallbackTools: [
|
|
780
|
+
{
|
|
781
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
782
|
+
reason: 'to find repositories first',
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_ISSUES,
|
|
786
|
+
reason: 'to find related discussions',
|
|
787
|
+
},
|
|
788
|
+
],
|
|
789
|
+
nextSteps: [
|
|
790
|
+
{
|
|
791
|
+
tool: TOOL_NAMES.GITHUB_FETCH_CONTENT,
|
|
792
|
+
reason: 'to view files changed in commits',
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
796
|
+
reason: 'to find current implementation',
|
|
797
|
+
},
|
|
798
|
+
],
|
|
799
|
+
},
|
|
800
|
+
[TOOL_NAMES.GITHUB_SEARCH_ISSUES]: {
|
|
801
|
+
fallbackTools: [
|
|
802
|
+
{
|
|
803
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS,
|
|
804
|
+
reason: 'to find related PRs',
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
808
|
+
reason: 'to find the repository first',
|
|
809
|
+
},
|
|
810
|
+
],
|
|
811
|
+
nextSteps: [
|
|
812
|
+
{
|
|
813
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS,
|
|
814
|
+
reason: 'to find solutions or implementations',
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
818
|
+
reason: 'to find related code',
|
|
819
|
+
},
|
|
820
|
+
],
|
|
821
|
+
},
|
|
822
|
+
[TOOL_NAMES.GITHUB_SEARCH_PULL_REQUESTS]: {
|
|
823
|
+
fallbackTools: [
|
|
824
|
+
{
|
|
825
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_ISSUES,
|
|
826
|
+
reason: 'to find related issues',
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_COMMITS,
|
|
830
|
+
reason: 'to find related commits',
|
|
831
|
+
},
|
|
832
|
+
],
|
|
833
|
+
nextSteps: [
|
|
834
|
+
{
|
|
835
|
+
tool: TOOL_NAMES.GITHUB_FETCH_CONTENT,
|
|
836
|
+
reason: 'to view PR changes',
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_CODE,
|
|
840
|
+
reason: 'to find current implementation',
|
|
841
|
+
},
|
|
842
|
+
],
|
|
843
|
+
},
|
|
844
|
+
[TOOL_NAMES.API_STATUS_CHECK]: {
|
|
845
|
+
fallbackTools: [],
|
|
846
|
+
nextSteps: [
|
|
847
|
+
{
|
|
848
|
+
tool: TOOL_NAMES.GITHUB_SEARCH_REPOSITORIES,
|
|
849
|
+
reason: 'to search accessible repositories',
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
tool: TOOL_NAMES.NPM_PACKAGE_SEARCH,
|
|
853
|
+
reason: 'to search public packages',
|
|
854
|
+
},
|
|
855
|
+
],
|
|
856
|
+
},
|
|
857
|
+
};
|
|
858
|
+
/**
|
|
859
|
+
* Get tool suggestions based on current context
|
|
860
|
+
*/
|
|
861
|
+
function getToolSuggestions(currentTool, context) {
|
|
862
|
+
const relationships = TOOL_RELATIONSHIPS[currentTool];
|
|
863
|
+
if (!relationships) {
|
|
864
|
+
return { fallback: [], nextSteps: [], prerequisites: [] };
|
|
865
|
+
}
|
|
866
|
+
// Filter fallback tools based on context
|
|
867
|
+
const fallback = relationships.fallbackTools.filter(item => {
|
|
868
|
+
if (!item.condition)
|
|
869
|
+
return true;
|
|
870
|
+
switch (item.condition) {
|
|
871
|
+
case 'no_results':
|
|
872
|
+
return context.errorType === 'no_results';
|
|
873
|
+
case 'access_denied':
|
|
874
|
+
return context.errorType === 'access_denied';
|
|
875
|
+
default:
|
|
876
|
+
return true;
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
// Return next steps only if operation was successful
|
|
880
|
+
const nextSteps = context.hasResults ? relationships.nextSteps : [];
|
|
881
|
+
return {
|
|
882
|
+
fallback,
|
|
883
|
+
nextSteps,
|
|
884
|
+
prerequisites: relationships.prerequisites || [],
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Shared validation utilities for MCP tools
|
|
890
|
+
* Centralized validation logic to reduce duplication across tools
|
|
891
|
+
*/
|
|
892
|
+
/**
|
|
893
|
+
* Extracts owner/repo from various query formats
|
|
894
|
+
* Handles: owner/repo, https://github.com/owner/repo, github.com/owner/repo
|
|
895
|
+
*/
|
|
896
|
+
/**
|
|
897
|
+
* Creates a standardized tool suggestion message
|
|
898
|
+
*/
|
|
899
|
+
function createToolSuggestion(currentTool, suggestedTools) {
|
|
900
|
+
if (suggestedTools.length === 0) {
|
|
901
|
+
return '';
|
|
902
|
+
}
|
|
903
|
+
const suggestions = suggestedTools
|
|
904
|
+
.map(({ tool, reason }) => `• Use ${tool} ${reason}`)
|
|
905
|
+
.join('\n');
|
|
906
|
+
return `\n\nCurrent tool: ${currentTool}\nAlternative tools:\n${suggestions}`;
|
|
907
|
+
}
|
|
559
908
|
|
|
560
909
|
const API_STATUS_CHECK_TOOL_NAME = 'apiStatusCheck';
|
|
561
|
-
const DESCRIPTION$9 = `
|
|
910
|
+
const DESCRIPTION$9 = `Verify API connections and discover available organizations. FIRST STEP for private repository research.
|
|
911
|
+
|
|
912
|
+
AUTHENTICATION VERIFICATION:
|
|
913
|
+
- Check GitHub and NPM CLI authentication status
|
|
914
|
+
- Troubleshoot access issues before extensive searches
|
|
915
|
+
- Verify API connectivity and permissions
|
|
916
|
+
|
|
917
|
+
ORGANIZATION DISCOVERY:
|
|
918
|
+
- List available GitHub organizations for scoped searches
|
|
919
|
+
- Identify accessible private repositories
|
|
920
|
+
- Guide repository search strategy based on permissions
|
|
921
|
+
|
|
922
|
+
WORKFLOW OPTIMIZATION:
|
|
923
|
+
- Run first when dealing with private/organizational repositories
|
|
924
|
+
- Prevents access errors in subsequent tool usage
|
|
925
|
+
- Informs search scope and strategy decisions
|
|
926
|
+
- Essential for comprehensive organizational research`;
|
|
562
927
|
// Helper function to parse execution results with proper typing
|
|
563
928
|
function parseExecResult(result) {
|
|
564
929
|
if (!result.isError && result.content?.[0]?.text) {
|
|
@@ -664,6 +1029,19 @@ function registerApiStatusCheckTool(server) {
|
|
|
664
1029
|
}
|
|
665
1030
|
npmConnected = false;
|
|
666
1031
|
}
|
|
1032
|
+
const { nextSteps } = getToolSuggestions(TOOL_NAMES.API_STATUS_CHECK, {
|
|
1033
|
+
hasResults: true,
|
|
1034
|
+
});
|
|
1035
|
+
const hints = [
|
|
1036
|
+
'Use user organizations to search private repositories when requested - verify access by checking query and repository structure',
|
|
1037
|
+
];
|
|
1038
|
+
// Add tool suggestions as hints
|
|
1039
|
+
if (nextSteps.length > 0) {
|
|
1040
|
+
hints.push('Next steps:');
|
|
1041
|
+
nextSteps.forEach(({ tool, reason }) => {
|
|
1042
|
+
hints.push(`- ${tool}: ${reason}`);
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
667
1045
|
return createResult({
|
|
668
1046
|
data: {
|
|
669
1047
|
login: {
|
|
@@ -675,23 +1053,48 @@ function registerApiStatusCheckTool(server) {
|
|
|
675
1053
|
connected: npmConnected,
|
|
676
1054
|
registry: registry || 'https://registry.npmjs.org/',
|
|
677
1055
|
},
|
|
678
|
-
hints
|
|
679
|
-
'Use user organizations to search private repositories when requested - verify access by checking query and repository structure',
|
|
680
|
-
],
|
|
1056
|
+
hints,
|
|
681
1057
|
},
|
|
682
1058
|
},
|
|
683
1059
|
});
|
|
684
1060
|
}
|
|
685
1061
|
catch (error) {
|
|
1062
|
+
const { nextSteps } = getToolSuggestions(TOOL_NAMES.API_STATUS_CHECK, {
|
|
1063
|
+
});
|
|
1064
|
+
const toolSuggestions = createToolSuggestion(TOOL_NAMES.API_STATUS_CHECK, nextSteps);
|
|
686
1065
|
return createResult({
|
|
687
|
-
error:
|
|
1066
|
+
error: getErrorWithSuggestion({
|
|
1067
|
+
baseError: [
|
|
1068
|
+
ERROR_MESSAGES.API_STATUS_CHECK_FAILED,
|
|
1069
|
+
`Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1070
|
+
'',
|
|
1071
|
+
'This usually indicates a system configuration issue. Please verify GitHub CLI and NPM are properly installed.',
|
|
1072
|
+
],
|
|
1073
|
+
suggestion: toolSuggestions,
|
|
1074
|
+
}),
|
|
688
1075
|
});
|
|
689
1076
|
}
|
|
690
1077
|
});
|
|
691
1078
|
}
|
|
692
1079
|
|
|
693
1080
|
const GITHUB_GET_FILE_CONTENT_TOOL_NAME = 'githubGetFileContent';
|
|
694
|
-
const DESCRIPTION$8 = `
|
|
1081
|
+
const DESCRIPTION$8 = `Access GitHub file content for implementation analysis. USE AFTER repository structure validation.
|
|
1082
|
+
|
|
1083
|
+
IMPLEMENTATION ANALYSIS:
|
|
1084
|
+
- Examine configuration files, documentation, key source code
|
|
1085
|
+
- Understand actual implementations and patterns
|
|
1086
|
+
- Extract technical details and architecture decisions
|
|
1087
|
+
|
|
1088
|
+
VALIDATION REQUIREMENTS:
|
|
1089
|
+
- ALWAYS verify repository structure first with githubViewRepoStructure
|
|
1090
|
+
- Confirm file paths exist before accessing
|
|
1091
|
+
- Navigate from known structure to specific files
|
|
1092
|
+
|
|
1093
|
+
CONTENT CAPABILITIES:
|
|
1094
|
+
- Handles text files up to 300KB efficiently
|
|
1095
|
+
- Automatic branch fallback (main/master)
|
|
1096
|
+
- Provides decoded content with metadata
|
|
1097
|
+
- Optimized for code analysis workflows`;
|
|
695
1098
|
function registerFetchGitHubFileContentTool(server) {
|
|
696
1099
|
server.registerTool(GITHUB_GET_FILE_CONTENT_TOOL_NAME, {
|
|
697
1100
|
description: DESCRIPTION$8,
|
|
@@ -793,24 +1196,61 @@ async function fetchGitHubFileContent(params) {
|
|
|
793
1196
|
if (errorMsg.includes('404')) {
|
|
794
1197
|
const searchSuggestion = await suggestCodeSearchFallback(owner, filePath);
|
|
795
1198
|
return createResult({
|
|
796
|
-
error: `File "${filePath}" not found in branch "${branch}".
|
|
1199
|
+
error: `File "${filePath}" not found in branch "${branch}".
|
|
1200
|
+
|
|
1201
|
+
Quick fixes:
|
|
1202
|
+
• Use github_view_repo_structure to verify path exists
|
|
1203
|
+
• Check for typos in file path
|
|
1204
|
+
• Try different branch (main/master/develop)${searchSuggestion}
|
|
1205
|
+
|
|
1206
|
+
Alternative strategies:
|
|
1207
|
+
• Use github_search_code with query="filename:${filePath.split('/').pop()}" owner="${owner}"
|
|
1208
|
+
• Use github_search_code with query="path:${filePath}" to find similar paths`,
|
|
797
1209
|
});
|
|
798
1210
|
}
|
|
799
1211
|
else if (errorMsg.includes('403')) {
|
|
800
1212
|
return createResult({
|
|
801
|
-
error: `Access denied to "${filePath}" in "${owner}/${repo}".
|
|
1213
|
+
error: `Access denied to "${filePath}" in "${owner}/${repo}".
|
|
1214
|
+
|
|
1215
|
+
Possible causes & solutions:
|
|
1216
|
+
• Private repository: use api_status_check to verify permissions
|
|
1217
|
+
• File in private directory: check repository access level
|
|
1218
|
+
• Rate limiting: wait 5-10 minutes and retry
|
|
1219
|
+
• Authentication: run gh auth login
|
|
1220
|
+
|
|
1221
|
+
Alternative approaches:
|
|
1222
|
+
• Use github_search_code with query="path:${filePath}" owner="${owner}"
|
|
1223
|
+
• Use github_view_repo_structure to explore accessible paths
|
|
1224
|
+
• Check repository on GitHub.com for public access`,
|
|
802
1225
|
});
|
|
803
1226
|
}
|
|
804
1227
|
else if (errorMsg.includes('maxBuffer') ||
|
|
805
1228
|
errorMsg.includes('stdout maxBuffer length exceeded')) {
|
|
806
1229
|
return createResult({
|
|
807
|
-
error: `File "${filePath}" is too large (>300KB).
|
|
1230
|
+
error: `File "${filePath}" is too large (>300KB).
|
|
1231
|
+
|
|
1232
|
+
Alternative strategies:
|
|
1233
|
+
• Use github_search_code to search within the file
|
|
1234
|
+
• Download directly from: https://github.com/${owner}/${repo}/blob/${branch}/${filePath}
|
|
1235
|
+
• Use github_view_repo_structure to find smaller related files
|
|
1236
|
+
• Look for configuration or summary files instead`,
|
|
808
1237
|
});
|
|
809
1238
|
}
|
|
810
1239
|
else {
|
|
811
1240
|
const searchSuggestion = await suggestCodeSearchFallback(owner, filePath);
|
|
812
1241
|
return createResult({
|
|
813
|
-
error: `Failed to fetch "${filePath}"
|
|
1242
|
+
error: `Failed to fetch "${filePath}": ${errorMsg}
|
|
1243
|
+
|
|
1244
|
+
Troubleshooting steps:
|
|
1245
|
+
1. Verify repository exists: github_view_repo_structure
|
|
1246
|
+
2. Check network connection and GitHub status
|
|
1247
|
+
3. Verify authentication: gh auth status
|
|
1248
|
+
4. Try different branch names${searchSuggestion}
|
|
1249
|
+
|
|
1250
|
+
Recovery strategies:
|
|
1251
|
+
• Use github_search_code for content discovery
|
|
1252
|
+
• Try github_search_repos to find similar repositories
|
|
1253
|
+
• Check file on GitHub.com: https://github.com/${owner}/${repo}/blob/${branch}/${filePath}`,
|
|
814
1254
|
});
|
|
815
1255
|
}
|
|
816
1256
|
}
|
|
@@ -909,24 +1349,36 @@ async function suggestCodeSearchFallback(owner, filePath) {
|
|
|
909
1349
|
}
|
|
910
1350
|
|
|
911
1351
|
const GITHUB_SEARCH_CODE_TOOL_NAME = 'githubSearchCode';
|
|
912
|
-
const DESCRIPTION$7 = `Search code across GitHub repositories using GitHub's code search API.
|
|
1352
|
+
const DESCRIPTION$7 = `Search code across GitHub repositories using GitHub's code search API via GitHub CLI.
|
|
913
1353
|
|
|
914
|
-
|
|
915
|
-
Use filters and flags on subsequent searches when you know what to search for or if the user asks for it explicitly.
|
|
916
|
-
Using too many flags might make miss relevant results. Use filters and flags to narrow down the results when getting too many.
|
|
1354
|
+
SEARCH STRATEGY FOR BEST RESULTS:
|
|
917
1355
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
-
|
|
921
|
-
-
|
|
922
|
-
-
|
|
923
|
-
- Additional filters: Language, owner, repository, filename, extension, size and other flags supported
|
|
1356
|
+
TERM OPTIMIZATION (IMPORTANT):
|
|
1357
|
+
- BEST: Single terms for maximum coverage and relevance
|
|
1358
|
+
- GOOD: 2 terms when you need both to be present
|
|
1359
|
+
- RESTRICTIVE: 3+ terms - very specific but may miss relevant results
|
|
1360
|
+
- Example: "useState" (best coverage) vs "react hook useState" (specific but restrictive)
|
|
924
1361
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1362
|
+
MULTI-SEARCH STRATEGY:
|
|
1363
|
+
- Use SEPARATE searches for different aspects instead of complex single queries
|
|
1364
|
+
- Example: Search "authentication" separately, then "login" separately
|
|
1365
|
+
- Separate searches provide broader coverage than restrictive AND logic
|
|
928
1366
|
|
|
929
|
-
|
|
1367
|
+
Search Logic:
|
|
1368
|
+
- Multiple terms = ALL must be present (AND logic) - very restrictive
|
|
1369
|
+
- Single terms = maximum results and coverage
|
|
1370
|
+
- Quoted phrases = exact phrase matching
|
|
1371
|
+
- Mixed queries: "exact phrase" additional_term (phrase + term)
|
|
1372
|
+
|
|
1373
|
+
Quote Usage:
|
|
1374
|
+
- Single terms: NO quotes (useState, authentication)
|
|
1375
|
+
- Multi-word phrases: WITH quotes ("error handling", "user authentication")
|
|
1376
|
+
- Mixed queries: "exact phrase" single_term another_term
|
|
1377
|
+
|
|
1378
|
+
Filter Usage:
|
|
1379
|
+
- All filters use GitHub CLI flags (--language, --owner, --repo, etc.)
|
|
1380
|
+
- Combine filters to narrow scope: language + owner, repo + filename
|
|
1381
|
+
- Never use filters on exploratory searches - use to refine when too many results`;
|
|
930
1382
|
function registerGitHubSearchCodeTool(server) {
|
|
931
1383
|
server.registerTool(GITHUB_SEARCH_CODE_TOOL_NAME, {
|
|
932
1384
|
description: DESCRIPTION$7,
|
|
@@ -934,36 +1386,36 @@ function registerGitHubSearchCodeTool(server) {
|
|
|
934
1386
|
query: z
|
|
935
1387
|
.string()
|
|
936
1388
|
.min(1)
|
|
937
|
-
.describe('Search query with AND logic between terms. Multiple words require ALL to be present. Use quotes for exact phrases.'),
|
|
1389
|
+
.describe('Search query with AND logic between terms. OPTIMIZATION: Single terms give best coverage, 2 terms when both needed, 3+ terms very restrictive. Multiple words require ALL to be present. Use quotes for exact phrases. Examples: "useState" (best coverage), "error handling" (exact phrase), "react hook useState" (specific but restrictive).'),
|
|
938
1390
|
language: z
|
|
939
1391
|
.string()
|
|
940
1392
|
.optional()
|
|
941
|
-
.describe('Programming language filter. Narrows search to specific language files. Use for language-specific searches.'),
|
|
1393
|
+
.describe('Programming language filter. Uses --language CLI flag. Narrows search to specific language files. Use for language-specific searches.'),
|
|
942
1394
|
owner: z
|
|
943
1395
|
.union([z.string(), z.array(z.string())])
|
|
944
1396
|
.optional()
|
|
945
|
-
.describe('Repository owner/organization name(s) to search within (e.g., "facebook", ["google", "microsoft"]).
|
|
1397
|
+
.describe('Repository owner/organization name(s) to search within (e.g., "facebook", ["google", "microsoft"]). Uses --owner CLI flag for organization-wide search. Can be combined with repo parameter for specific repository search. Do NOT use owner/repo format - just the organization/username.'),
|
|
946
1398
|
repo: z
|
|
947
1399
|
.union([z.string(), z.array(z.string())])
|
|
948
1400
|
.optional()
|
|
949
|
-
.describe('Filter on specific repository(ies).
|
|
1401
|
+
.describe('Filter on specific repository(ies). Uses --repo CLI flag. Two usage patterns: (1) Use with owner parameter - provide just repo name (e.g., owner="facebook", repo="react" → --repo=facebook/react), or (2) Use alone - provide full "owner/repo" format (e.g., "facebook/react" → --repo=facebook/react).'),
|
|
950
1402
|
filename: z
|
|
951
1403
|
.string()
|
|
952
1404
|
.optional()
|
|
953
|
-
.describe('Target specific filename or pattern. Use for file-specific searches.'),
|
|
1405
|
+
.describe('Target specific filename or pattern. Uses --filename CLI flag. Use for file-specific searches.'),
|
|
954
1406
|
extension: z
|
|
955
1407
|
.string()
|
|
956
1408
|
.optional()
|
|
957
|
-
.describe('File extension filter. Alternative to language parameter.'),
|
|
1409
|
+
.describe('File extension filter. Uses --extension CLI flag. Alternative to language parameter.'),
|
|
958
1410
|
match: z
|
|
959
|
-
.
|
|
1411
|
+
.enum(['file', 'path'])
|
|
960
1412
|
.optional()
|
|
961
|
-
.describe('Search scope: "file" for file content (default), "path" for filenames/paths
|
|
1413
|
+
.describe('Search scope: "file" for file content (default), "path" for filenames/paths. Uses --match CLI flag. Single value only - multiple scopes not supported by GitHub CLI.'),
|
|
962
1414
|
size: z
|
|
963
1415
|
.string()
|
|
964
1416
|
.regex(/^(>=?\d+|<=?\d+|\d+\.\.\d+|\d+)$/, 'Invalid size format. Use: ">10", ">=5", "<100", "<=50", "10..100", or exact number "50"')
|
|
965
1417
|
.optional()
|
|
966
|
-
.describe('File size filter in KB. Format: ">N" (larger than), "<N" (smaller than), "N..M" (range), "N" (exact).'),
|
|
1418
|
+
.describe('File size filter in KB. Uses --size CLI flag. Format: ">N" (larger than), "<N" (smaller than), "N..M" (range), "N" (exact).'),
|
|
967
1419
|
limit: z
|
|
968
1420
|
.number()
|
|
969
1421
|
.int()
|
|
@@ -982,11 +1434,6 @@ function registerGitHubSearchCodeTool(server) {
|
|
|
982
1434
|
},
|
|
983
1435
|
}, async (args) => {
|
|
984
1436
|
try {
|
|
985
|
-
// Validate parameter combinations
|
|
986
|
-
const validationError = validateSearchParameters(args);
|
|
987
|
-
if (validationError) {
|
|
988
|
-
return createResult({ error: validationError });
|
|
989
|
-
}
|
|
990
1437
|
const result = await searchGitHubCode(args);
|
|
991
1438
|
if (result.isError) {
|
|
992
1439
|
return result;
|
|
@@ -1021,45 +1468,79 @@ function registerGitHubSearchCodeTool(server) {
|
|
|
1021
1468
|
});
|
|
1022
1469
|
}
|
|
1023
1470
|
/**
|
|
1024
|
-
* Handles various search errors and returns a formatted CallToolResult.
|
|
1471
|
+
* Handles various search errors and returns a formatted CallToolResult with smart fallbacks.
|
|
1025
1472
|
*/
|
|
1026
1473
|
function handleSearchError(errorMessage) {
|
|
1027
|
-
//
|
|
1028
|
-
if (errorMessage.includes('
|
|
1474
|
+
// Rate limit with smart timing guidance
|
|
1475
|
+
if (errorMessage.includes('rate limit') || errorMessage.includes('403')) {
|
|
1029
1476
|
return createResult({
|
|
1030
|
-
error:
|
|
1477
|
+
error: `GitHub API rate limit reached. Try again in 5-10 minutes, or use these strategies:
|
|
1478
|
+
• Search fewer terms per query
|
|
1479
|
+
• Use owner/repo filters to narrow scope
|
|
1480
|
+
• Try npm package search for package-related queries
|
|
1481
|
+
• Use separate searches instead of complex queries`,
|
|
1031
1482
|
});
|
|
1032
1483
|
}
|
|
1033
|
-
|
|
1484
|
+
// Authentication with clear next steps
|
|
1485
|
+
if (errorMessage.includes('authentication') || errorMessage.includes('401')) {
|
|
1034
1486
|
return createResult({
|
|
1035
|
-
error:
|
|
1487
|
+
error: `GitHub authentication required. Fix with:
|
|
1488
|
+
1. Run: gh auth login
|
|
1489
|
+
2. Verify access: gh auth status
|
|
1490
|
+
3. For private repos: use api_status_check to verify org access`,
|
|
1036
1491
|
});
|
|
1037
1492
|
}
|
|
1038
|
-
|
|
1493
|
+
// Network/timeout with fallback suggestions
|
|
1494
|
+
if (errorMessage.includes('timed out') || errorMessage.includes('network')) {
|
|
1039
1495
|
return createResult({
|
|
1040
|
-
error:
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
error: ERROR_MESSAGES.SEARCH_TIMEOUT,
|
|
1496
|
+
error: `Network timeout. Try these alternatives:
|
|
1497
|
+
• Reduce search scope with owner or language filters
|
|
1498
|
+
• Use github_search_repos to find repositories first
|
|
1499
|
+
• Try npm package search for package discovery
|
|
1500
|
+
• Check network connection and retry`,
|
|
1046
1501
|
});
|
|
1047
1502
|
}
|
|
1503
|
+
// Invalid query with specific fixes
|
|
1048
1504
|
if (errorMessage.includes('validation failed') ||
|
|
1049
1505
|
errorMessage.includes('Invalid query')) {
|
|
1050
1506
|
return createResult({
|
|
1051
|
-
error:
|
|
1507
|
+
error: `Invalid search query. Common fixes:
|
|
1508
|
+
• Remove special characters: ()[]{}*?^$|.\\
|
|
1509
|
+
• Use quotes only for exact phrases: "error handling"
|
|
1510
|
+
• Avoid escaped quotes: use term instead of "term"
|
|
1511
|
+
• Try broader terms: "react" instead of "React.Component"`,
|
|
1052
1512
|
});
|
|
1053
1513
|
}
|
|
1514
|
+
// Repository not found with discovery suggestions
|
|
1054
1515
|
if (errorMessage.includes('repository not found') ||
|
|
1055
1516
|
errorMessage.includes('owner not found')) {
|
|
1056
1517
|
return createResult({
|
|
1057
|
-
error:
|
|
1518
|
+
error: `Repository/owner not found. Discovery strategies:
|
|
1519
|
+
• Use github_search_repos to find correct names
|
|
1520
|
+
• Check for typos in owner/repo names
|
|
1521
|
+
• Try without owner filter for broader search
|
|
1522
|
+
• Use npm package search if looking for packages`,
|
|
1058
1523
|
});
|
|
1059
1524
|
}
|
|
1060
|
-
//
|
|
1525
|
+
// JSON parsing with system guidance
|
|
1526
|
+
if (errorMessage.includes('JSON')) {
|
|
1527
|
+
return createResult({
|
|
1528
|
+
error: `GitHub CLI response parsing failed. System issue - try:
|
|
1529
|
+
• Update GitHub CLI: gh extension upgrade
|
|
1530
|
+
• Retry in a few moments
|
|
1531
|
+
• Use github_search_repos as alternative
|
|
1532
|
+
• Check gh auth status for authentication`,
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
// Generic fallback with progressive strategy
|
|
1061
1536
|
return createResult({
|
|
1062
|
-
error: `Code search failed: ${errorMessage}
|
|
1537
|
+
error: `Code search failed: ${errorMessage}
|
|
1538
|
+
|
|
1539
|
+
Progressive recovery strategy:
|
|
1540
|
+
1. Try broader search terms
|
|
1541
|
+
2. Use github_search_repos to find repositories
|
|
1542
|
+
3. Use npm package search for package-related queries
|
|
1543
|
+
4. Check github CLI status: gh auth status`,
|
|
1063
1544
|
});
|
|
1064
1545
|
}
|
|
1065
1546
|
/**
|
|
@@ -1106,8 +1587,8 @@ function extractSingleRepository$1(items) {
|
|
|
1106
1587
|
return allSameRepo ? firstRepo : null;
|
|
1107
1588
|
}
|
|
1108
1589
|
/**
|
|
1109
|
-
* Build command line arguments for GitHub CLI
|
|
1110
|
-
*
|
|
1590
|
+
* Build command line arguments for GitHub CLI following the exact CLI format.
|
|
1591
|
+
* Uses proper flags (--flag=value) instead of qualifiers where appropriate.
|
|
1111
1592
|
*/
|
|
1112
1593
|
function buildGitHubCliArgs(params) {
|
|
1113
1594
|
const args = ['code'];
|
|
@@ -1117,39 +1598,52 @@ function buildGitHubCliArgs(params) {
|
|
|
1117
1598
|
if (searchQuery) {
|
|
1118
1599
|
args.push(searchQuery);
|
|
1119
1600
|
}
|
|
1120
|
-
// Add extracted qualifiers from the query
|
|
1601
|
+
// Add extracted qualifiers from the query (these should remain as qualifiers)
|
|
1121
1602
|
extractedQualifiers.forEach(qualifier => {
|
|
1122
1603
|
args.push(qualifier);
|
|
1123
1604
|
});
|
|
1124
|
-
// Add explicit parameters as
|
|
1605
|
+
// Add explicit parameters as CLI flags (following GitHub CLI format)
|
|
1125
1606
|
if (params.language && !params.query.includes('language:')) {
|
|
1126
|
-
args.push(
|
|
1607
|
+
args.push(`--language=${params.language}`);
|
|
1608
|
+
}
|
|
1609
|
+
// Handle owner and repo parameters properly
|
|
1610
|
+
if (params.repo && !params.query.includes('repo:')) {
|
|
1611
|
+
const repos = Array.isArray(params.repo) ? params.repo : [params.repo];
|
|
1612
|
+
repos.forEach(repo => {
|
|
1613
|
+
// If both owner and repo are provided, combine them for --repo flag
|
|
1614
|
+
if (params.owner && !repo.includes('/')) {
|
|
1615
|
+
const owners = Array.isArray(params.owner)
|
|
1616
|
+
? params.owner
|
|
1617
|
+
: [params.owner];
|
|
1618
|
+
owners.forEach(owner => args.push(`--repo=${owner}/${repo}`));
|
|
1619
|
+
}
|
|
1620
|
+
else {
|
|
1621
|
+
// Repo is already in owner/repo format or no owner provided
|
|
1622
|
+
args.push(`--repo=${repo}`);
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1127
1625
|
}
|
|
1128
|
-
if (params.owner &&
|
|
1626
|
+
else if (params.owner &&
|
|
1129
1627
|
!params.query.includes('org:') &&
|
|
1130
1628
|
!params.query.includes('user:')) {
|
|
1629
|
+
// Only owner provided, no repo - use --owner flag for organization-wide search
|
|
1131
1630
|
const owners = Array.isArray(params.owner) ? params.owner : [params.owner];
|
|
1132
|
-
owners.forEach(owner => args.push(
|
|
1133
|
-
}
|
|
1134
|
-
if (params.repo && !params.query.includes('repo:')) {
|
|
1135
|
-
const repos = Array.isArray(params.repo) ? params.repo : [params.repo];
|
|
1136
|
-
repos.forEach(repo => args.push(`repo:${repo}`));
|
|
1631
|
+
owners.forEach(owner => args.push(`--owner=${owner}`));
|
|
1137
1632
|
}
|
|
1138
1633
|
if (params.filename && !params.query.includes('filename:')) {
|
|
1139
|
-
args.push(
|
|
1634
|
+
args.push(`--filename=${params.filename}`);
|
|
1140
1635
|
}
|
|
1141
1636
|
if (params.extension && !params.query.includes('extension:')) {
|
|
1142
|
-
args.push(
|
|
1637
|
+
args.push(`--extension=${params.extension}`);
|
|
1143
1638
|
}
|
|
1144
1639
|
if (params.size && !params.query.includes('size:')) {
|
|
1145
|
-
args.push(
|
|
1640
|
+
args.push(`--size=${params.size}`);
|
|
1146
1641
|
}
|
|
1147
|
-
// Handle match parameter
|
|
1642
|
+
// Handle match parameter - use --match flag
|
|
1148
1643
|
if (params.match) {
|
|
1149
|
-
|
|
1150
|
-
args.push(`in:${matches.join(',')}`);
|
|
1644
|
+
args.push(`--match=${params.match}`);
|
|
1151
1645
|
}
|
|
1152
|
-
// Add limit
|
|
1646
|
+
// Add limit flag
|
|
1153
1647
|
if (params.limit) {
|
|
1154
1648
|
args.push(`--limit=${params.limit}`);
|
|
1155
1649
|
}
|
|
@@ -1169,54 +1663,10 @@ async function searchGitHubCode(params) {
|
|
|
1169
1663
|
}
|
|
1170
1664
|
catch (error) {
|
|
1171
1665
|
const errorMessage = error.message || '';
|
|
1172
|
-
return handleSearchError(errorMessage);
|
|
1666
|
+
return handleSearchError(errorMessage);
|
|
1173
1667
|
}
|
|
1174
1668
|
});
|
|
1175
1669
|
}
|
|
1176
|
-
/**
|
|
1177
|
-
* Enhanced validation with helpful suggestions
|
|
1178
|
-
*/
|
|
1179
|
-
function validateSearchParameters(params) {
|
|
1180
|
-
// Query validation
|
|
1181
|
-
if (!params.query.trim()) {
|
|
1182
|
-
return ERROR_MESSAGES.EMPTY_QUERY;
|
|
1183
|
-
}
|
|
1184
|
-
if (params.query.length > 1000) {
|
|
1185
|
-
return ERROR_MESSAGES.QUERY_TOO_LONG_1000;
|
|
1186
|
-
}
|
|
1187
|
-
// Repository validation - ensure owner is provided correctly
|
|
1188
|
-
if (params.owner &&
|
|
1189
|
-
typeof params.owner === 'string' &&
|
|
1190
|
-
params.owner.includes('/')) {
|
|
1191
|
-
return 'Owner parameter should contain only the username/org name, not owner/repo format. For repository-specific searches, use org: or user: qualifiers in the query.';
|
|
1192
|
-
}
|
|
1193
|
-
if (Array.isArray(params.owner)) {
|
|
1194
|
-
const hasSlashFormat = params.owner.some(owner => owner.includes('/'));
|
|
1195
|
-
if (hasSlashFormat) {
|
|
1196
|
-
return 'Owner parameter should contain only usernames/org names, not owner/repo format. For repository-specific searches, use repo: qualifier in the query.';
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
// Add validation for file size limit
|
|
1200
|
-
if (params.size) {
|
|
1201
|
-
if (!/^([<>]\d+|\d+\.\.\d+)$/.test(params.size)) {
|
|
1202
|
-
return ERROR_MESSAGES.INVALID_SIZE_FORMAT;
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
// Validate search scope
|
|
1206
|
-
if (params.match) {
|
|
1207
|
-
const validScopes = ['file', 'path'];
|
|
1208
|
-
const scopes = Array.isArray(params.match) ? params.match : [params.match];
|
|
1209
|
-
if (!scopes.every(scope => validScopes.includes(scope))) {
|
|
1210
|
-
return ERROR_MESSAGES.INVALID_SEARCH_SCOPE;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
// Note about repository limitations (This is a note, not a hard error)
|
|
1214
|
-
// This return statement was returning null before, so it shouldn't be an issue
|
|
1215
|
-
// if (params.repo || params.owner) {
|
|
1216
|
-
// return null; // Return warning about repository limitations
|
|
1217
|
-
// }
|
|
1218
|
-
return null; // No validation errors
|
|
1219
|
-
}
|
|
1220
1670
|
/**
|
|
1221
1671
|
* Parse search query to preserve quoted phrases and extract qualifiers.
|
|
1222
1672
|
* Handles:
|
|
@@ -1224,14 +1674,27 @@ function validateSearchParameters(params) {
|
|
|
1224
1674
|
* - Multiple terms: react lifecycle -> both terms for AND search
|
|
1225
1675
|
* - Mixed: "error handling" debug -> phrase + term
|
|
1226
1676
|
* - Qualifiers: language:javascript -> extracted separately
|
|
1677
|
+
* - Quote escaping issues: automatically fixes common mistakes
|
|
1227
1678
|
*/
|
|
1228
1679
|
function parseSearchQuery(query) {
|
|
1229
1680
|
const qualifiers = [];
|
|
1230
1681
|
const searchTerms = [];
|
|
1682
|
+
// Clean up common quote escaping issues
|
|
1683
|
+
let cleanedQuery = query;
|
|
1684
|
+
// Fix escaped quotes that shouldn't be escaped
|
|
1685
|
+
if (cleanedQuery.includes('\\"') && !cleanedQuery.includes(' ')) {
|
|
1686
|
+
cleanedQuery = cleanedQuery.replace(/\\"/g, '');
|
|
1687
|
+
}
|
|
1688
|
+
// Fix single-word queries wrapped in quotes unnecessarily
|
|
1689
|
+
if (cleanedQuery.startsWith('"') &&
|
|
1690
|
+
cleanedQuery.endsWith('"') &&
|
|
1691
|
+
!cleanedQuery.slice(1, -1).includes(' ')) {
|
|
1692
|
+
cleanedQuery = cleanedQuery.slice(1, -1);
|
|
1693
|
+
}
|
|
1231
1694
|
// Regular expression to match quoted strings or individual words/qualifiers
|
|
1232
1695
|
const tokenRegex = /"([^"]+)"|([^\s]+)/g;
|
|
1233
1696
|
let match;
|
|
1234
|
-
while ((match = tokenRegex.exec(
|
|
1697
|
+
while ((match = tokenRegex.exec(cleanedQuery)) !== null) {
|
|
1235
1698
|
const token = match[1] || match[2]; // match[1] is quoted content, match[2] is unquoted
|
|
1236
1699
|
// Check if it's a qualifier (contains : but not inside quotes)
|
|
1237
1700
|
if (!match[1] && token.includes(':') && /^[a-zA-Z]+:/.test(token)) {
|
|
@@ -1734,6 +2197,51 @@ async function searchGitHubIssues(params) {
|
|
|
1734
2197
|
comments: issue.comments,
|
|
1735
2198
|
reactions: issue.reactions?.total_count || 0,
|
|
1736
2199
|
}));
|
|
2200
|
+
// Smart fallback suggestions for no results
|
|
2201
|
+
if (cleanIssues.length === 0) {
|
|
2202
|
+
const fallbackSuggestions = [];
|
|
2203
|
+
// Analyze search parameters for specific suggestions
|
|
2204
|
+
if (params.state === 'closed') {
|
|
2205
|
+
fallbackSuggestions.push('• Try state:open or remove state filter');
|
|
2206
|
+
}
|
|
2207
|
+
if (params.author) {
|
|
2208
|
+
fallbackSuggestions.push('• Remove author filter for broader search');
|
|
2209
|
+
fallbackSuggestions.push(`• Use github_search_code to find ${params.author}'s contributions`);
|
|
2210
|
+
}
|
|
2211
|
+
if (params.label) {
|
|
2212
|
+
const labels = Array.isArray(params.label)
|
|
2213
|
+
? params.label
|
|
2214
|
+
: [params.label];
|
|
2215
|
+
fallbackSuggestions.push(`• Try broader labels or remove label filter`);
|
|
2216
|
+
fallbackSuggestions.push(`• Search for label variations: ${labels.map(l => `"${l}"`).join(', ')}`);
|
|
2217
|
+
}
|
|
2218
|
+
if (params.owner && params.repo) {
|
|
2219
|
+
fallbackSuggestions.push('• Check repository name spelling');
|
|
2220
|
+
fallbackSuggestions.push('• Use github_view_repo_structure to verify repository exists');
|
|
2221
|
+
}
|
|
2222
|
+
else if (params.owner) {
|
|
2223
|
+
fallbackSuggestions.push('• Remove owner filter for global search');
|
|
2224
|
+
fallbackSuggestions.push('• Use github_search_repos to find organization repositories');
|
|
2225
|
+
}
|
|
2226
|
+
if (params.created || params.updated) {
|
|
2227
|
+
fallbackSuggestions.push('• Expand date range or remove date filters');
|
|
2228
|
+
}
|
|
2229
|
+
// Add general alternatives
|
|
2230
|
+
fallbackSuggestions.push('• Try broader search terms');
|
|
2231
|
+
fallbackSuggestions.push('• Use github_search_pull_requests for related development activity');
|
|
2232
|
+
fallbackSuggestions.push('• Use github_search_code to find implementation patterns');
|
|
2233
|
+
return createResult({
|
|
2234
|
+
error: `No issues found for query: "${params.query}"
|
|
2235
|
+
|
|
2236
|
+
Try these alternatives:
|
|
2237
|
+
${fallbackSuggestions.join('\n')}
|
|
2238
|
+
|
|
2239
|
+
Discovery strategies:
|
|
2240
|
+
• Broader terms: "error" instead of "TypeError"
|
|
2241
|
+
• Remove filters: state, labels, author
|
|
2242
|
+
• Related searches: pull requests, code implementations`,
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
1737
2245
|
const searchResult = {
|
|
1738
2246
|
results: cleanIssues,
|
|
1739
2247
|
};
|
|
@@ -2195,11 +2703,22 @@ function buildGitHubPullRequestsAPICommand(params) {
|
|
|
2195
2703
|
* TIP: Use limit parameter instead of adding more filters
|
|
2196
2704
|
*/
|
|
2197
2705
|
const GITHUB_SEARCH_REPOSITORIES_TOOL_NAME = 'githubSearchRepositories';
|
|
2198
|
-
const DESCRIPTION$3 = `Search GitHub repositories
|
|
2706
|
+
const DESCRIPTION$3 = `Search GitHub repositories for project discovery and ecosystem analysis. TOPICS are the most powerful discovery feature.
|
|
2707
|
+
|
|
2708
|
+
TOPIC-DRIVEN DISCOVERY:
|
|
2709
|
+
- Topics reveal ecosystem relationships and quality indicators
|
|
2710
|
+
- Combine topics for targeted discovery: ["framework", "use-case", "language"]
|
|
2711
|
+
- Topics beat keyword searches for unknown project exploration
|
|
2712
|
+
|
|
2713
|
+
PROGRESSIVE SEARCH STRATEGY:
|
|
2714
|
+
- Start with topic combinations for broad discovery
|
|
2715
|
+
- Add quality filters (stars, activity) for refinement
|
|
2716
|
+
- Use multiple separate searches vs complex single queries
|
|
2199
2717
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2718
|
+
RESEARCH INTEGRATION:
|
|
2719
|
+
- Repository discovery → structure analysis → implementation patterns
|
|
2720
|
+
- Quality assessment via community metrics and activity
|
|
2721
|
+
- Bridge to code search and file analysis tools`;
|
|
2203
2722
|
/**
|
|
2204
2723
|
* Extract owner/repo information from various query formats
|
|
2205
2724
|
*/
|
|
@@ -2411,34 +2930,87 @@ function registerSearchGitHubReposTool(server) {
|
|
|
2411
2930
|
enhancedArgs.forks;
|
|
2412
2931
|
if (!hasPrimaryFilter) {
|
|
2413
2932
|
return createResult({
|
|
2414
|
-
error:
|
|
2933
|
+
error: `Repository search requires at least one filter. Try these patterns:
|
|
2934
|
+
• Topic discovery: { topic: ["react", "typescript"] }
|
|
2935
|
+
• Quality search: { stars: ">1000", language: "javascript" }
|
|
2936
|
+
• Organization: { owner: "microsoft", language: "python" }
|
|
2937
|
+
• Recent projects: { created: ">2023-01-01", stars: ">100" }`,
|
|
2415
2938
|
});
|
|
2416
2939
|
}
|
|
2417
2940
|
// First attempt: Search with current parameters
|
|
2418
2941
|
const result = await searchGitHubRepos(enhancedArgs);
|
|
2942
|
+
if (result.isError) {
|
|
2943
|
+
const errorMsg = result.content?.[0]?.text || '';
|
|
2944
|
+
// Smart fallbacks based on error type
|
|
2945
|
+
if (errorMsg.includes('rate limit')) {
|
|
2946
|
+
return createResult({
|
|
2947
|
+
error: `GitHub API rate limit. Smart alternatives:
|
|
2948
|
+
• Try npm package search for package discovery
|
|
2949
|
+
• Use broader filters (remove stars/forks constraints)
|
|
2950
|
+
• Search fewer organizations at once
|
|
2951
|
+
• Wait 5-10 minutes and retry`,
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
if (errorMsg.includes('authentication')) {
|
|
2955
|
+
return createResult({
|
|
2956
|
+
error: `Authentication required. Quick fix:
|
|
2957
|
+
1. Run: gh auth login
|
|
2958
|
+
2. For private repos: use api_status_check to verify access
|
|
2959
|
+
3. Public repos should work without auth - check query`,
|
|
2960
|
+
});
|
|
2961
|
+
}
|
|
2962
|
+
return result; // Return original error for other cases
|
|
2963
|
+
}
|
|
2964
|
+
// Check if we got results
|
|
2965
|
+
const resultData = JSON.parse(result.content[0].text);
|
|
2966
|
+
const hasResults = resultData.total_count > 0;
|
|
2967
|
+
// Smart fallback strategies for no results
|
|
2968
|
+
if (!hasResults) {
|
|
2969
|
+
const fallbackSuggestions = [];
|
|
2970
|
+
if (enhancedArgs.query) {
|
|
2971
|
+
fallbackSuggestions.push('• Try broader search terms or remove query filter');
|
|
2972
|
+
}
|
|
2973
|
+
if (enhancedArgs.language) {
|
|
2974
|
+
fallbackSuggestions.push('• Remove language filter for broader discovery');
|
|
2975
|
+
}
|
|
2976
|
+
if (enhancedArgs.stars || enhancedArgs.forks) {
|
|
2977
|
+
fallbackSuggestions.push('• Lower quality thresholds (stars/forks)');
|
|
2978
|
+
}
|
|
2979
|
+
if (!enhancedArgs.topic) {
|
|
2980
|
+
fallbackSuggestions.push('• Try topic-based search: { topic: ["web", "api"] }');
|
|
2981
|
+
}
|
|
2982
|
+
if (enhancedArgs.owner) {
|
|
2983
|
+
fallbackSuggestions.push('• Search without owner filter for global discovery');
|
|
2984
|
+
fallbackSuggestions.push('• Use npm package search if looking for packages');
|
|
2985
|
+
}
|
|
2986
|
+
return createResult({
|
|
2987
|
+
error: `No repositories found. Try these alternatives:
|
|
2988
|
+
${fallbackSuggestions.join('\n')}
|
|
2989
|
+
|
|
2990
|
+
Discovery patterns:
|
|
2991
|
+
• Topic exploration: { topic: ["react"] }
|
|
2992
|
+
• Quality discovery: { stars: ">100", language: "python" }
|
|
2993
|
+
• Recent activity: { updated: ">2024-01-01" }`,
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2419
2996
|
// Fallback for private repositories: If no results and owner is specified, try with private visibility
|
|
2420
|
-
if (!
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
enhancedArgs
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
...privateData,
|
|
2438
|
-
note: 'Found results in private repositories within the specified organization.',
|
|
2439
|
-
},
|
|
2440
|
-
});
|
|
2441
|
-
}
|
|
2997
|
+
if (enhancedArgs.owner && !enhancedArgs.visibility) {
|
|
2998
|
+
// Try searching with private visibility for organization repos
|
|
2999
|
+
const privateSearchArgs = {
|
|
3000
|
+
...enhancedArgs,
|
|
3001
|
+
visibility: 'private',
|
|
3002
|
+
};
|
|
3003
|
+
const privateResult = await searchGitHubRepos(privateSearchArgs);
|
|
3004
|
+
if (!privateResult.isError) {
|
|
3005
|
+
const privateData = JSON.parse(privateResult.content[0].text);
|
|
3006
|
+
if (privateData.total_count > 0) {
|
|
3007
|
+
// Return private results with note
|
|
3008
|
+
return createResult({
|
|
3009
|
+
data: {
|
|
3010
|
+
...privateData,
|
|
3011
|
+
note: 'Found results in private repositories within the specified organization.',
|
|
3012
|
+
},
|
|
3013
|
+
});
|
|
2442
3014
|
}
|
|
2443
3015
|
}
|
|
2444
3016
|
}
|
|
@@ -2593,17 +3165,35 @@ function buildGitHubReposSearchCommand(params) {
|
|
|
2593
3165
|
// SEARCH SCOPE
|
|
2594
3166
|
addArg('match', 'match');
|
|
2595
3167
|
// SORTING AND LIMITS
|
|
2596
|
-
addArg('limit', 'limit');
|
|
2597
|
-
addArg('order', 'order');
|
|
2598
3168
|
const sortBy = params.sort || 'best-match';
|
|
2599
3169
|
if (sortBy !== 'best-match') {
|
|
2600
3170
|
args.push(`--sort=${sortBy}`);
|
|
2601
3171
|
}
|
|
3172
|
+
addArg('order', 'order');
|
|
3173
|
+
// Always add limit with default of 30
|
|
3174
|
+
const limit = params.limit || 30;
|
|
3175
|
+
args.push(`--limit=${limit}`);
|
|
2602
3176
|
return { command: 'search', args };
|
|
2603
3177
|
}
|
|
2604
3178
|
|
|
2605
3179
|
const GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME = 'githubViewRepoStructure';
|
|
2606
|
-
const DESCRIPTION$2 = `
|
|
3180
|
+
const DESCRIPTION$2 = `Explore GitHub repository structure and validate repository access. ESSENTIAL for understanding project organization.
|
|
3181
|
+
|
|
3182
|
+
REPOSITORY VALIDATION:
|
|
3183
|
+
- Verify repository existence and accessibility
|
|
3184
|
+
- Navigate from root to understand project layout
|
|
3185
|
+
- Identify key directories and file patterns
|
|
3186
|
+
|
|
3187
|
+
PROJECT UNDERSTANDING:
|
|
3188
|
+
- Discover configuration files, documentation, source structure
|
|
3189
|
+
- Validate paths before accessing specific files
|
|
3190
|
+
- Understand architecture and organization patterns
|
|
3191
|
+
|
|
3192
|
+
WORKFLOW INTEGRATION:
|
|
3193
|
+
- First step after repository discovery
|
|
3194
|
+
- Guides subsequent file access and code search
|
|
3195
|
+
- Prevents "file not found" errors through validation
|
|
3196
|
+
- Essential for comprehensive repository analysis`;
|
|
2607
3197
|
function registerViewRepositoryStructureTool(server) {
|
|
2608
3198
|
server.registerTool(GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME, {
|
|
2609
3199
|
description: DESCRIPTION$2,
|
|
@@ -2853,7 +3443,22 @@ async function suggestPathSearchFallback(owner, path) {
|
|
|
2853
3443
|
}
|
|
2854
3444
|
|
|
2855
3445
|
const NPM_PACKAGE_SEARCH_TOOL_NAME = 'npmPackageSearch';
|
|
2856
|
-
const DESCRIPTION$1 = `Search NPM packages by
|
|
3446
|
+
const DESCRIPTION$1 = `Search NPM packages by functionality keywords. PRIMARY ENTRY POINT for package-related queries.
|
|
3447
|
+
|
|
3448
|
+
PACKAGE-FIRST STRATEGY:
|
|
3449
|
+
- Start here when users mention: libraries, dependencies, installations, alternatives
|
|
3450
|
+
- Use broad functional terms for discovery (not exact package names)
|
|
3451
|
+
- Bridge to GitHub tools via repository URLs from results
|
|
3452
|
+
|
|
3453
|
+
SEARCH APPROACH:
|
|
3454
|
+
- Single functional terms work best for discovery
|
|
3455
|
+
- Multiple searches for different aspects/use-cases
|
|
3456
|
+
- Reveals ecosystem alternatives and quality indicators
|
|
3457
|
+
|
|
3458
|
+
INTEGRATION WORKFLOW:
|
|
3459
|
+
- Package Discovery → Repository Analysis → Implementation Patterns
|
|
3460
|
+
- npmPackageSearch → npmViewPackage → GitHub repository tools
|
|
3461
|
+
- Compare alternatives by searching different functional terms`;
|
|
2857
3462
|
const MAX_DESCRIPTION_LENGTH = 100;
|
|
2858
3463
|
const MAX_KEYWORDS = 10;
|
|
2859
3464
|
function registerNpmSearchTool(server) {
|
|
@@ -2888,28 +3493,136 @@ function registerNpmSearchTool(server) {
|
|
|
2888
3493
|
const allPackages = [];
|
|
2889
3494
|
// Search for each query term
|
|
2890
3495
|
for (const query of queries) {
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
3496
|
+
try {
|
|
3497
|
+
const result = await executeNpmCommand('search', [query, `--searchlimit=${searchLimit}`, '--json'], { cache: true });
|
|
3498
|
+
if (!result.isError && result.content?.[0]?.text) {
|
|
3499
|
+
const packages = parseNpmSearchOutput(result.content[0].text);
|
|
3500
|
+
allPackages.push(...packages);
|
|
3501
|
+
}
|
|
3502
|
+
else if (result.isError) {
|
|
3503
|
+
// Individual query failures are handled silently, continue with others
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
catch (queryError) {
|
|
3507
|
+
// Continue with other queries even if one fails
|
|
2895
3508
|
}
|
|
2896
3509
|
}
|
|
2897
3510
|
const deduplicatedPackages = deduplicatePackages(allPackages);
|
|
2898
3511
|
if (deduplicatedPackages.length > 0) {
|
|
3512
|
+
const { nextSteps } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, { hasResults: true });
|
|
3513
|
+
const hints = [];
|
|
3514
|
+
if (nextSteps.length > 0) {
|
|
3515
|
+
hints.push('Next steps:');
|
|
3516
|
+
nextSteps.forEach(({ tool, reason }) => {
|
|
3517
|
+
hints.push(`• Use ${tool} ${reason}`);
|
|
3518
|
+
});
|
|
3519
|
+
}
|
|
2899
3520
|
return createResult({
|
|
2900
3521
|
data: {
|
|
2901
3522
|
total_count: deduplicatedPackages.length,
|
|
2902
3523
|
results: deduplicatedPackages,
|
|
3524
|
+
hints: hints.length > 0 ? hints : undefined,
|
|
2903
3525
|
},
|
|
2904
3526
|
});
|
|
2905
3527
|
}
|
|
3528
|
+
// Smart fallback suggestions based on query patterns
|
|
3529
|
+
const hasSpecificTerms = queries.some(q => q.includes('-') || q.includes('@') || q.length > 15);
|
|
3530
|
+
const hasFrameworkTerms = queries.some(q => ['react', 'vue', 'angular', 'express', 'fastify'].some(fw => q.toLowerCase().includes(fw)));
|
|
3531
|
+
let fallbackSuggestions = [
|
|
3532
|
+
'• Try broader functional terms: "testing" instead of "jest-unit-test"',
|
|
3533
|
+
'• Remove version numbers or specific constraints',
|
|
3534
|
+
'• Use single keywords: "http" instead of "http-client-library"',
|
|
3535
|
+
];
|
|
3536
|
+
if (hasSpecificTerms) {
|
|
3537
|
+
fallbackSuggestions = [
|
|
3538
|
+
'• Use simpler terms: "validation" instead of "schema-validation-library"',
|
|
3539
|
+
'• Try category terms: "database", "testing", "auth"',
|
|
3540
|
+
...fallbackSuggestions.slice(1),
|
|
3541
|
+
];
|
|
3542
|
+
}
|
|
3543
|
+
if (hasFrameworkTerms) {
|
|
3544
|
+
fallbackSuggestions.unshift('• Try specific framework searches: "react hooks", "vue components"');
|
|
3545
|
+
}
|
|
3546
|
+
// Add GitHub integration suggestions
|
|
3547
|
+
fallbackSuggestions.push('• Use github_search_repos with topic filters for project discovery');
|
|
3548
|
+
fallbackSuggestions.push('• Check npm registry status: https://status.npmjs.org');
|
|
3549
|
+
const { fallback } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, {
|
|
3550
|
+
errorType: 'no_results',
|
|
3551
|
+
});
|
|
3552
|
+
const toolSuggestions = createToolSuggestion(TOOL_NAMES.NPM_PACKAGE_SEARCH, fallback);
|
|
2906
3553
|
return createResult({
|
|
2907
|
-
error:
|
|
3554
|
+
error: getErrorWithSuggestion({
|
|
3555
|
+
baseError: createNpmPackageNotFoundError(queries.join(', ')),
|
|
3556
|
+
suggestion: [fallbackSuggestions.join('\n'), toolSuggestions],
|
|
3557
|
+
}),
|
|
2908
3558
|
});
|
|
2909
3559
|
}
|
|
2910
3560
|
catch (error) {
|
|
3561
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3562
|
+
// Network/connectivity issues
|
|
3563
|
+
if (errorMsg.includes('network') ||
|
|
3564
|
+
errorMsg.includes('timeout') ||
|
|
3565
|
+
errorMsg.includes('ENOTFOUND')) {
|
|
3566
|
+
const { fallback } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, { });
|
|
3567
|
+
return createResult({
|
|
3568
|
+
error: getErrorWithSuggestion({
|
|
3569
|
+
baseError: ERROR_MESSAGES.NPM_CONNECTION_FAILED,
|
|
3570
|
+
suggestion: [
|
|
3571
|
+
'• Check internet connection and npm registry status',
|
|
3572
|
+
'• Try fewer search terms to reduce load',
|
|
3573
|
+
'• Retry in a few moments',
|
|
3574
|
+
createToolSuggestion(TOOL_NAMES.NPM_PACKAGE_SEARCH, fallback),
|
|
3575
|
+
],
|
|
3576
|
+
}),
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
// NPM CLI issues
|
|
3580
|
+
if (errorMsg.includes('command not found') ||
|
|
3581
|
+
errorMsg.includes('npm')) {
|
|
3582
|
+
const { fallback } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, { });
|
|
3583
|
+
return createResult({
|
|
3584
|
+
error: getErrorWithSuggestion({
|
|
3585
|
+
baseError: ERROR_MESSAGES.NPM_CLI_ERROR,
|
|
3586
|
+
suggestion: [
|
|
3587
|
+
'• Verify NPM installation: npm --version',
|
|
3588
|
+
'• Update NPM: npm install -g npm@latest',
|
|
3589
|
+
'• Check PATH environment variable',
|
|
3590
|
+
createToolSuggestion(TOOL_NAMES.NPM_PACKAGE_SEARCH, fallback),
|
|
3591
|
+
],
|
|
3592
|
+
}),
|
|
3593
|
+
});
|
|
3594
|
+
}
|
|
3595
|
+
// Permission/auth issues
|
|
3596
|
+
if (errorMsg.includes('permission') ||
|
|
3597
|
+
errorMsg.includes('403') ||
|
|
3598
|
+
errorMsg.includes('401')) {
|
|
3599
|
+
const { fallback } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, { errorType: 'access_denied' });
|
|
3600
|
+
return createResult({
|
|
3601
|
+
error: getErrorWithSuggestion({
|
|
3602
|
+
baseError: ERROR_MESSAGES.NPM_PERMISSION_ERROR,
|
|
3603
|
+
suggestion: [
|
|
3604
|
+
'• Check npm login status: npm whoami',
|
|
3605
|
+
'• Use public registry search without auth',
|
|
3606
|
+
'• Verify npm registry configuration',
|
|
3607
|
+
createToolSuggestion(TOOL_NAMES.NPM_PACKAGE_SEARCH, fallback),
|
|
3608
|
+
],
|
|
3609
|
+
}),
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
const { fallback } = getToolSuggestions(TOOL_NAMES.NPM_PACKAGE_SEARCH, {
|
|
3613
|
+
});
|
|
2911
3614
|
return createResult({
|
|
2912
|
-
error:
|
|
3615
|
+
error: getErrorWithSuggestion({
|
|
3616
|
+
baseError: ERROR_MESSAGES.PACKAGE_SEARCH_FAILED,
|
|
3617
|
+
suggestion: [
|
|
3618
|
+
`Error details: ${errorMsg}`,
|
|
3619
|
+
'',
|
|
3620
|
+
'Fallback strategies:',
|
|
3621
|
+
'• Check npm status and retry',
|
|
3622
|
+
'• Use broader search terms',
|
|
3623
|
+
createToolSuggestion(TOOL_NAMES.NPM_PACKAGE_SEARCH, fallback),
|
|
3624
|
+
],
|
|
3625
|
+
}),
|
|
2913
3626
|
});
|
|
2914
3627
|
}
|
|
2915
3628
|
});
|
|
@@ -2961,7 +3674,25 @@ function parseNpmSearchOutput(output) {
|
|
|
2961
3674
|
}
|
|
2962
3675
|
|
|
2963
3676
|
const NPM_VIEW_PACKAGE_TOOL_NAME = 'npmViewPackage';
|
|
2964
|
-
const DESCRIPTION = `
|
|
3677
|
+
const DESCRIPTION = `Analyze NPM packages for repository discovery and dependency insights. BRIDGE to GitHub ecosystem.
|
|
3678
|
+
|
|
3679
|
+
PACKAGE ANALYSIS CAPABILITIES:
|
|
3680
|
+
- Repository URL discovery for GitHub exploration
|
|
3681
|
+
- Version history and release patterns
|
|
3682
|
+
- Export analysis for implementation understanding
|
|
3683
|
+
- Dependency metadata for ecosystem mapping
|
|
3684
|
+
|
|
3685
|
+
GITHUB INTEGRATION:
|
|
3686
|
+
- Provides repository links for GitHub repository tools
|
|
3687
|
+
- Connects package metadata to source code analysis
|
|
3688
|
+
- Enables package-to-implementation research workflows
|
|
3689
|
+
- Essential for dependency and alternative evaluation
|
|
3690
|
+
|
|
3691
|
+
USE CASES:
|
|
3692
|
+
- Repository discovery from package names
|
|
3693
|
+
- Version analysis and security assessment
|
|
3694
|
+
- Export structure for integration planning
|
|
3695
|
+
- Dependency research and ecosystem exploration`;
|
|
2965
3696
|
function registerNpmViewPackageTool(server) {
|
|
2966
3697
|
server.registerTool(NPM_VIEW_PACKAGE_TOOL_NAME, {
|
|
2967
3698
|
description: DESCRIPTION,
|
|
@@ -2992,18 +3723,87 @@ function registerNpmViewPackageTool(server) {
|
|
|
2992
3723
|
}
|
|
2993
3724
|
catch (error) {
|
|
2994
3725
|
const errorMessage = error.message || '';
|
|
2995
|
-
|
|
3726
|
+
// Package not found with smart discovery
|
|
3727
|
+
if (errorMessage.includes('not found') ||
|
|
3728
|
+
errorMessage.includes('404')) {
|
|
3729
|
+
const packageName = args.packageName;
|
|
3730
|
+
const suggestions = [];
|
|
3731
|
+
// Check for common naming patterns
|
|
3732
|
+
if (packageName.includes('_')) {
|
|
3733
|
+
suggestions.push(`• Try with dashes: "${packageName.replace(/_/g, '-')}"`);
|
|
3734
|
+
}
|
|
3735
|
+
if (packageName.includes('-')) {
|
|
3736
|
+
suggestions.push(`• Try without dashes: "${packageName.replace(/-/g, '')}"`);
|
|
3737
|
+
}
|
|
3738
|
+
if (!packageName.startsWith('@') && packageName.includes('/')) {
|
|
3739
|
+
suggestions.push(`• Try scoped package: "@${packageName}"`);
|
|
3740
|
+
}
|
|
3741
|
+
if (packageName.startsWith('@')) {
|
|
3742
|
+
suggestions.push(`• Try without scope: "${packageName.split('/')[1]}"`);
|
|
3743
|
+
}
|
|
3744
|
+
// Add discovery alternatives
|
|
3745
|
+
suggestions.push('• Use npm_package_search for discovery');
|
|
3746
|
+
suggestions.push('• Use github_search_repos to find source repository');
|
|
3747
|
+
suggestions.push('• Check exact spelling on npmjs.com');
|
|
2996
3748
|
return createResult({
|
|
2997
|
-
error:
|
|
3749
|
+
error: `Package "${packageName}" not found on NPM registry.
|
|
3750
|
+
|
|
3751
|
+
Try these alternatives:
|
|
3752
|
+
${suggestions.join('\n')}
|
|
3753
|
+
|
|
3754
|
+
Discovery workflow:
|
|
3755
|
+
1. Use npm_package_search with functional terms
|
|
3756
|
+
2. Use github_search_repos for related projects
|
|
3757
|
+
3. Verify exact package name on npmjs.com`,
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3760
|
+
// Network issues with fallback strategies
|
|
3761
|
+
if (errorMessage.includes('network') ||
|
|
3762
|
+
errorMessage.includes('timeout') ||
|
|
3763
|
+
errorMessage.includes('ENOTFOUND')) {
|
|
3764
|
+
return createResult({
|
|
3765
|
+
error: `NPM registry connection failed. Alternative strategies:
|
|
3766
|
+
• Check internet connection and npm registry status
|
|
3767
|
+
• Use github_search_repos to find package repository
|
|
3768
|
+
• Try npm_package_search for broader discovery
|
|
3769
|
+
• Visit https://npmjs.com/${args.packageName} directly
|
|
3770
|
+
• Retry in a few moments`,
|
|
3771
|
+
});
|
|
3772
|
+
}
|
|
3773
|
+
// NPM CLI issues
|
|
3774
|
+
if (errorMessage.includes('command not found') ||
|
|
3775
|
+
errorMessage.includes('npm')) {
|
|
3776
|
+
return createResult({
|
|
3777
|
+
error: `NPM CLI issue. Quick fixes:
|
|
3778
|
+
• Verify NPM installation: npm --version
|
|
3779
|
+
• Update NPM: npm install -g npm@latest
|
|
3780
|
+
• Use github_search_repos to find package repository
|
|
3781
|
+
• Check PATH environment variable
|
|
3782
|
+
• Try web interface: https://npmjs.com/${args.packageName}`,
|
|
2998
3783
|
});
|
|
2999
3784
|
}
|
|
3000
|
-
|
|
3785
|
+
// Permission/registry issues
|
|
3786
|
+
if (errorMessage.includes('permission') ||
|
|
3787
|
+
errorMessage.includes('403') ||
|
|
3788
|
+
errorMessage.includes('401')) {
|
|
3001
3789
|
return createResult({
|
|
3002
|
-
error:
|
|
3790
|
+
error: `NPM registry access issue. Try these solutions:
|
|
3791
|
+
• Check npm configuration: npm config get registry
|
|
3792
|
+
• Use public registry: npm config set registry https://registry.npmjs.org/
|
|
3793
|
+
• Try github_search_repos for package source code
|
|
3794
|
+
• Visit package page: https://npmjs.com/${args.packageName}`,
|
|
3003
3795
|
});
|
|
3004
3796
|
}
|
|
3797
|
+
// Generic error with comprehensive fallbacks
|
|
3005
3798
|
return createResult({
|
|
3006
|
-
error:
|
|
3799
|
+
error: `Failed to fetch package "${args.packageName}": ${errorMessage}
|
|
3800
|
+
|
|
3801
|
+
Fallback strategies:
|
|
3802
|
+
• Use npm_package_search for similar packages
|
|
3803
|
+
• Use github_search_repos with package name as query
|
|
3804
|
+
• Check package on web: https://npmjs.com/${args.packageName}
|
|
3805
|
+
• Verify npm status: https://status.npmjs.org
|
|
3806
|
+
• Try alternative package managers (yarn info, pnpm view)`,
|
|
3007
3807
|
});
|
|
3008
3808
|
}
|
|
3009
3809
|
});
|
|
@@ -3114,130 +3914,120 @@ async function viewNpmPackage(packageName) {
|
|
|
3114
3914
|
});
|
|
3115
3915
|
}
|
|
3116
3916
|
|
|
3117
|
-
const PROMPT_SYSTEM_PROMPT = `You are an expert code research assistant
|
|
3118
|
-
using gh cli for github and npm cli for packages.
|
|
3119
|
-
|
|
3120
|
-
CRITICAL SEARCH PRINCIPLES:
|
|
3121
|
-
|
|
3122
|
-
PROGRESSIVE SEARCH STRATEGY (MOST IMPORTANT):
|
|
3123
|
-
a) START BROAD: Begin with simple, general queries and terms (1-2 words max)
|
|
3124
|
-
b) ANALYZE RESULTS: Learn from what you find
|
|
3125
|
-
c) REFINE GRADUALLY: Add filters only after understanding the landscape and if needed (only if the user asks for it explicitly)
|
|
3126
|
-
d) MULTIPLE ANGLES: Try different search terms if first approach yields no results
|
|
3127
|
-
|
|
3128
|
-
HANDLING NO RESULTS:
|
|
3129
|
-
- NEVER give up after one failed search.
|
|
3130
|
-
- Act on fallbacks messages and try to understand the user's intent.
|
|
3131
|
-
- Try progressively BROADER terms (simplify queries and remove filters)
|
|
3132
|
-
|
|
3133
|
-
SMART FILTER USAGE:
|
|
3134
|
-
- NO FILTERS on first search (unless user specifies)
|
|
3135
|
-
- Add ONE filter at a time based on results
|
|
3136
|
-
- Common progression: query → +language → +stars → +owner (only if user asks for it explicitly)
|
|
3137
|
-
- Reserve complex filters for final refinement
|
|
3138
|
-
|
|
3139
|
-
RESEARCH BEST PRACTICES:
|
|
3140
|
-
- Conduct COMPREHENSIVE research with multiple searches
|
|
3141
|
-
- Learn from each search to improve the next
|
|
3142
|
-
- Provide context about your search strategy
|
|
3143
|
-
- Always verify technical details with actual code
|
|
3144
|
-
|
|
3145
|
-
COMPLEX ANALYSIS PATTERNS:
|
|
3146
|
-
|
|
3147
|
-
Multi-terms Comparison
|
|
3148
|
-
1. Search repos separately: "repoA", then "repoB"
|
|
3149
|
-
2. Review repositories structure and files
|
|
3150
|
-
3. Review code and documentation
|
|
3151
|
-
4. Compare similar functionalities across repos
|
|
3152
|
-
5. Use filters and flags to narrow down the results
|
|
3153
|
-
|
|
3154
|
-
Evolution Tracking (e.g., Feature History):
|
|
3155
|
-
1. Use commit search with broad terms first
|
|
3156
|
-
2. Narrow by date ranges progressively
|
|
3157
|
-
3. Track changes in specific files over time
|
|
3158
|
-
4. Identify key contributors and their patterns
|
|
3159
|
-
|
|
3160
|
-
CROSS-REPOSITORY INTELLIGENCE:
|
|
3161
|
-
- When comparing frameworks, search EACH separately first
|
|
3162
|
-
- Build mental model of each codebase structure
|
|
3163
|
-
- Use discovered patterns to refine searches and connect findings across repositories for insights
|
|
3164
|
-
|
|
3165
|
-
RESEARCH WORKFLOW BEST PRACTICES:
|
|
3166
|
-
|
|
3167
|
-
Discovery Phase (Unknown Projects/Topics):
|
|
3168
|
-
- START with ${GITHUB_SEARCH_REPOSITORIES_TOOL_NAME} using TOPICS
|
|
3169
|
-
- Topics are underutilized but extremely powerful for discovery
|
|
3170
|
-
- Example: { topic: ["react", "typescript", "testing"], stars: ">500" }
|
|
3171
|
-
|
|
3172
|
-
Understanding Phase
|
|
3173
|
-
- ALWAYS use ${GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME} first to verify repository exists
|
|
3174
|
-
- CRITICAL: Many failures are due to incorrect repository names - verify before proceeding
|
|
3175
|
-
- Check README.md, docs/, configuration files
|
|
3176
|
-
- Understand project structure before searching code
|
|
3177
|
-
- Never make assumptions about repository names or file locations - always verify
|
|
3178
|
-
|
|
3179
|
-
Implementation Search (Specific Code):
|
|
3180
|
-
- Fetch importnat files using ${GITHUB_GET_FILE_CONTENT_TOOL_NAME}
|
|
3181
|
-
- Use ${GITHUB_SEARCH_CODE_TOOL_NAME} with NARROW queries
|
|
3182
|
-
- Start precise, broaden only if needed
|
|
3183
|
-
- Use exact phrases when you know patterns
|
|
3184
|
-
- Verify dependences and imports
|
|
3185
|
-
|
|
3186
|
-
File Access Validation Workflow:
|
|
3187
|
-
1. VERIFY repository name first with ${GITHUB_SEARCH_CODE_TOOL_NAME} if unsure
|
|
3188
|
-
2. Use ${GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME} to confirm repository structure
|
|
3189
|
-
3. Navigate to parent directory first to understand layout
|
|
3190
|
-
4. Only then use ${GITHUB_GET_FILE_CONTENT_TOOL_NAME} with confirmed paths
|
|
3191
|
-
5. Most "file not found" errors are due to incorrect repository names
|
|
3192
|
-
|
|
3193
|
-
TOOL-SPECIFIC BEST PRACTICES:
|
|
3917
|
+
const PROMPT_SYSTEM_PROMPT = `You are an expert code research assistant specialized in comprehensive package and repository analysis using GitHub CLI and NPM CLI.
|
|
3194
3918
|
|
|
3195
|
-
|
|
3196
|
-
-
|
|
3197
|
-
-
|
|
3198
|
-
-
|
|
3919
|
+
CORE RESEARCH PHILOSOPHY:
|
|
3920
|
+
- PACKAGE-FIRST: When packages mentioned → start with NPM tools → bridge to GitHub
|
|
3921
|
+
- REPOSITORY-FIRST: When repos mentioned → start with GitHub tools → explore dependencies
|
|
3922
|
+
- CROSS-REFERENCE: Always connect packages to repositories and repositories to packages
|
|
3923
|
+
- PROGRESSIVE: Start broad, refine gradually, use multiple separate searches
|
|
3924
|
+
|
|
3925
|
+
CRITICAL SEARCH STRATEGIES:
|
|
3926
|
+
|
|
3927
|
+
MULTI-SEARCH APPROACH (MOST EFFECTIVE):
|
|
3928
|
+
a) SEPARATE SEARCHES: Individual terms beat complex queries
|
|
3929
|
+
b) PROGRESSIVE REFINEMENT: Start broad → analyze → narrow down
|
|
3930
|
+
c) CROSS-TOOL VALIDATION: Verify findings across GitHub and NPM
|
|
3931
|
+
d) TOPIC DISCOVERY: Use topics as primary discovery mechanism
|
|
3932
|
+
|
|
3933
|
+
PACKAGE-CENTRIC WORKFLOWS:
|
|
3934
|
+
When users mention: libraries, dependencies, packages, installations, versions
|
|
3935
|
+
→ START with ${NPM_PACKAGE_SEARCH_TOOL_NAME} → ${NPM_VIEW_PACKAGE_TOOL_NAME} → GitHub tools
|
|
3936
|
+
|
|
3937
|
+
NPM-TO-GITHUB INTEGRATION PATTERNS:
|
|
3938
|
+
1. Package Discovery: ${NPM_PACKAGE_SEARCH_TOOL_NAME} → get repository URLs → ${GITHUB_SEARCH_REPOSITORIES_TOOL_NAME}
|
|
3939
|
+
2. Dependency Analysis: ${NPM_VIEW_PACKAGE_TOOL_NAME} → repository structure → implementation patterns
|
|
3940
|
+
3. Alternative Research: Multiple ${NPM_PACKAGE_SEARCH_TOOL_NAME} → compare repositories → evaluate quality
|
|
3941
|
+
4. Version Investigation: ${NPM_VIEW_PACKAGE_TOOL_NAME} → commit history → feature evolution
|
|
3942
|
+
|
|
3943
|
+
REPOSITORY-CENTRIC WORKFLOWS:
|
|
3944
|
+
When users mention: codebases, implementations, source code, organizations
|
|
3945
|
+
→ START with ${GITHUB_SEARCH_REPOSITORIES_TOOL_NAME} using TOPICS → drill down to specifics
|
|
3946
|
+
|
|
3947
|
+
COMPREHENSIVE RESEARCH PATTERNS:
|
|
3948
|
+
|
|
3949
|
+
Discovery Phase (Unknown Territory):
|
|
3950
|
+
- TOPICS FIRST: ${GITHUB_SEARCH_REPOSITORIES_TOOL_NAME} with topic combinations
|
|
3951
|
+
- Topics reveal ecosystems, relationships, quality indicators
|
|
3952
|
+
- Example topics: ["framework-name", "use-case", "language"]
|
|
3953
|
+
|
|
3954
|
+
Understanding Phase:
|
|
3955
|
+
- Repository Structure: ${GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME} for project layout
|
|
3956
|
+
- Package Metadata: ${NPM_VIEW_PACKAGE_TOOL_NAME} for dependencies and exports
|
|
3957
|
+
- Cross-validation: Verify package-repo connections
|
|
3958
|
+
|
|
3959
|
+
Implementation Phase:
|
|
3960
|
+
- Code Patterns: ${GITHUB_SEARCH_CODE_TOOL_NAME} with SEPARATE single-term searches
|
|
3961
|
+
- File Access: ${GITHUB_GET_FILE_CONTENT_TOOL_NAME} for specific implementations
|
|
3962
|
+
- Historical Context: ${GITHUB_SEARCH_COMMITS_TOOL_NAME} for feature evolution
|
|
3963
|
+
|
|
3964
|
+
TOOL INTEGRATION BEST PRACTICES:
|
|
3965
|
+
|
|
3966
|
+
${NPM_PACKAGE_SEARCH_TOOL_NAME}:
|
|
3967
|
+
- Primary entry for package-related queries
|
|
3968
|
+
- Use broad functional terms, not exact package names
|
|
3969
|
+
- Bridge to GitHub via repository URLs
|
|
3970
|
+
|
|
3971
|
+
${NPM_VIEW_PACKAGE_TOOL_NAME}:
|
|
3972
|
+
- Essential for repository discovery and dependency analysis
|
|
3973
|
+
- Provides GitHub repository links for further exploration
|
|
3974
|
+
- Critical for version and export analysis
|
|
3199
3975
|
|
|
3200
3976
|
${GITHUB_SEARCH_REPOSITORIES_TOOL_NAME}:
|
|
3201
|
-
-
|
|
3202
|
-
-
|
|
3203
|
-
-
|
|
3977
|
+
- TOPICS are the most powerful discovery feature
|
|
3978
|
+
- Start with topic/language combinations
|
|
3979
|
+
- Quality indicators: stars, activity, community
|
|
3204
3980
|
|
|
3205
3981
|
${GITHUB_SEARCH_CODE_TOOL_NAME}:
|
|
3206
|
-
-
|
|
3207
|
-
-
|
|
3208
|
-
-
|
|
3982
|
+
- SEPARATE searches outperform complex queries
|
|
3983
|
+
- Single terms without quotes for broad discovery
|
|
3984
|
+
- Multi-word phrases WITH quotes for exact patterns
|
|
3209
3985
|
|
|
3210
3986
|
${GITHUB_VIEW_REPO_STRUCTURE_TOOL_NAME}:
|
|
3211
|
-
-
|
|
3212
|
-
-
|
|
3213
|
-
-
|
|
3987
|
+
- Always verify repository existence and structure first
|
|
3988
|
+
- Navigate from root to understand project organization
|
|
3989
|
+
- Essential before accessing specific files
|
|
3214
3990
|
|
|
3215
3991
|
${GITHUB_GET_FILE_CONTENT_TOOL_NAME}:
|
|
3216
|
-
-
|
|
3217
|
-
-
|
|
3992
|
+
- Use AFTER structure verification
|
|
3993
|
+
- Focus on configuration, documentation, key implementations
|
|
3994
|
+
- Validate paths through structure exploration
|
|
3218
3995
|
|
|
3219
3996
|
${GITHUB_SEARCH_COMMITS_TOOL_NAME}:
|
|
3220
|
-
-
|
|
3221
|
-
-
|
|
3997
|
+
- Feature evolution and implementation history
|
|
3998
|
+
- Author patterns and development activity
|
|
3999
|
+
- Date ranges for tracking changes
|
|
3222
4000
|
|
|
3223
4001
|
${GITHUB_SEARCH_ISSUES_TOOL_NAME} & ${GITHUB_SEARCH_PULL_REQUESTS_TOOL_NAME}:
|
|
3224
|
-
-
|
|
3225
|
-
-
|
|
4002
|
+
- Problem-solution discovery
|
|
4003
|
+
- Implementation discussions and decisions
|
|
4004
|
+
- Community feedback and feature requests
|
|
3226
4005
|
|
|
3227
|
-
${
|
|
3228
|
-
-
|
|
4006
|
+
${API_STATUS_CHECK_TOOL_NAME}:
|
|
4007
|
+
- First step for private repository access
|
|
4008
|
+
- Organization discovery for scoped searches
|
|
4009
|
+
- Authentication troubleshooting
|
|
3229
4010
|
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
-
|
|
3235
|
-
-
|
|
3236
|
-
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
-
|
|
3240
|
-
-
|
|
4011
|
+
INTELLIGENT SEARCH PROGRESSION:
|
|
4012
|
+
|
|
4013
|
+
No Results Strategy:
|
|
4014
|
+
- BROADEN search terms (remove filters)
|
|
4015
|
+
- Try ALTERNATIVE tool (NPM ↔ GitHub)
|
|
4016
|
+
- Use TOPICS for discovery
|
|
4017
|
+
- Check SPELLING and exact names
|
|
4018
|
+
|
|
4019
|
+
Quality Research Indicators:
|
|
4020
|
+
- Cross-tool consistency (NPM package ↔ GitHub repo)
|
|
4021
|
+
- Community metrics (stars, downloads, issues)
|
|
4022
|
+
- Recent activity (commits, releases, discussions)
|
|
4023
|
+
- Documentation quality and completeness
|
|
4024
|
+
|
|
4025
|
+
CHAIN OF RESEARCH OPTIMIZATION:
|
|
4026
|
+
- Plan multi-tool sequences before execution
|
|
4027
|
+
- Connect findings across NPM and GitHub ecosystems
|
|
4028
|
+
- Build comprehensive understanding progressively
|
|
4029
|
+
- Validate technical details with actual code
|
|
4030
|
+
- Provide actionable insights based on data patterns
|
|
3241
4031
|
`;
|
|
3242
4032
|
|
|
3243
4033
|
const SERVER_CONFIG = {
|