@pkgseer/cli 0.5.0 → 0.5.2
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/dist/cli.js +427 -164
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-kh5enjt9.js → chunk-a0vv3x03.js} +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
version
|
|
4
|
-
} from "./shared/chunk-
|
|
4
|
+
} from "./shared/chunk-a0vv3x03.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -335,6 +335,8 @@ var FetchCodeContextDocument = gql`
|
|
|
335
335
|
endLine
|
|
336
336
|
repoUrl
|
|
337
337
|
gitRef
|
|
338
|
+
indexingStatus
|
|
339
|
+
indexingRef
|
|
338
340
|
}
|
|
339
341
|
}
|
|
340
342
|
`;
|
|
@@ -363,6 +365,16 @@ var TriggerIndexingDocument = gql`
|
|
|
363
365
|
}
|
|
364
366
|
}
|
|
365
367
|
`;
|
|
368
|
+
var IndexingProgressDocument = gql`
|
|
369
|
+
query IndexingProgress($ref: String!) {
|
|
370
|
+
indexingProgress(ref: $ref) {
|
|
371
|
+
status
|
|
372
|
+
filesIndexed
|
|
373
|
+
chunksCreated
|
|
374
|
+
elapsedMs
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
`;
|
|
366
378
|
var CreateProjectDocument = gql`
|
|
367
379
|
mutation CreateProject($input: CreateProjectInput!) {
|
|
368
380
|
createProject(input: $input) {
|
|
@@ -699,6 +711,8 @@ var FindSymbolDocument = gql`
|
|
|
699
711
|
indexedAt
|
|
700
712
|
hint
|
|
701
713
|
}
|
|
714
|
+
indexingStatus
|
|
715
|
+
indexingRef
|
|
702
716
|
}
|
|
703
717
|
}
|
|
704
718
|
`;
|
|
@@ -747,6 +761,8 @@ var SearchSymbolsDocument = gql`
|
|
|
747
761
|
hint
|
|
748
762
|
}
|
|
749
763
|
warning
|
|
764
|
+
indexingStatus
|
|
765
|
+
indexingRef
|
|
750
766
|
}
|
|
751
767
|
}
|
|
752
768
|
`;
|
|
@@ -786,6 +802,8 @@ var ListSymbolsDocument = gql`
|
|
|
786
802
|
path
|
|
787
803
|
language
|
|
788
804
|
}
|
|
805
|
+
indexingStatus
|
|
806
|
+
indexingRef
|
|
789
807
|
}
|
|
790
808
|
}
|
|
791
809
|
`;
|
|
@@ -825,6 +843,8 @@ var SymbolDependenciesDocument = gql`
|
|
|
825
843
|
missingPackages
|
|
826
844
|
total
|
|
827
845
|
hasMore
|
|
846
|
+
indexingStatus
|
|
847
|
+
indexingRef
|
|
828
848
|
}
|
|
829
849
|
}
|
|
830
850
|
`;
|
|
@@ -854,6 +874,8 @@ var SymbolDependentsDocument = gql`
|
|
|
854
874
|
}
|
|
855
875
|
total
|
|
856
876
|
hasMore
|
|
877
|
+
indexingStatus
|
|
878
|
+
indexingRef
|
|
857
879
|
}
|
|
858
880
|
}
|
|
859
881
|
`;
|
|
@@ -888,6 +910,8 @@ var PackageImportsDocument = gql`
|
|
|
888
910
|
}
|
|
889
911
|
uniqueDependencies
|
|
890
912
|
unresolvedCount
|
|
913
|
+
indexingStatus
|
|
914
|
+
indexingRef
|
|
891
915
|
}
|
|
892
916
|
}
|
|
893
917
|
`;
|
|
@@ -921,6 +945,8 @@ var CallPathDocument = gql`
|
|
|
921
945
|
callLine
|
|
922
946
|
}
|
|
923
947
|
}
|
|
948
|
+
indexingStatus
|
|
949
|
+
indexingRef
|
|
924
950
|
}
|
|
925
951
|
}
|
|
926
952
|
`;
|
|
@@ -981,6 +1007,8 @@ var ListRepoFilesDocument = gql`
|
|
|
981
1007
|
indexedAt
|
|
982
1008
|
hint
|
|
983
1009
|
}
|
|
1010
|
+
indexingStatus
|
|
1011
|
+
indexingRef
|
|
984
1012
|
}
|
|
985
1013
|
}
|
|
986
1014
|
`;
|
|
@@ -1017,6 +1045,8 @@ var GrepRepoFileDocument = gql`
|
|
|
1017
1045
|
indexedAt
|
|
1018
1046
|
hint
|
|
1019
1047
|
}
|
|
1048
|
+
indexingStatus
|
|
1049
|
+
indexingRef
|
|
1020
1050
|
}
|
|
1021
1051
|
}
|
|
1022
1052
|
`;
|
|
@@ -1074,6 +1104,8 @@ var VersionDiffDocument = gql`
|
|
|
1074
1104
|
}
|
|
1075
1105
|
}
|
|
1076
1106
|
hasMore
|
|
1107
|
+
indexingStatus
|
|
1108
|
+
indexingRef
|
|
1077
1109
|
}
|
|
1078
1110
|
}
|
|
1079
1111
|
`;
|
|
@@ -1092,6 +1124,7 @@ var SearchResultsDocumentString = print(SearchResultsDocument);
|
|
|
1092
1124
|
var FetchCodeContextDocumentString = print(FetchCodeContextDocument);
|
|
1093
1125
|
var CliDocsGetDocumentString = print(CliDocsGetDocument);
|
|
1094
1126
|
var TriggerIndexingDocumentString = print(TriggerIndexingDocument);
|
|
1127
|
+
var IndexingProgressDocumentString = print(IndexingProgressDocument);
|
|
1095
1128
|
var CreateProjectDocumentString = print(CreateProjectDocument);
|
|
1096
1129
|
var PackageSummaryDocumentString = print(PackageSummaryDocument);
|
|
1097
1130
|
var PackageVulnerabilitiesDocumentString = print(PackageVulnerabilitiesDocument);
|
|
@@ -1157,6 +1190,9 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
1157
1190
|
TriggerIndexing(variables, requestHeaders) {
|
|
1158
1191
|
return withWrapper((wrappedRequestHeaders) => client.rawRequest(TriggerIndexingDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "TriggerIndexing", "mutation", variables);
|
|
1159
1192
|
},
|
|
1193
|
+
IndexingProgress(variables, requestHeaders) {
|
|
1194
|
+
return withWrapper((wrappedRequestHeaders) => client.rawRequest(IndexingProgressDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "IndexingProgress", "query", variables);
|
|
1195
|
+
},
|
|
1160
1196
|
CreateProject(variables, requestHeaders) {
|
|
1161
1197
|
return withWrapper((wrappedRequestHeaders) => client.rawRequest(CreateProjectDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateProject", "mutation", variables);
|
|
1162
1198
|
},
|
|
@@ -1671,6 +1707,7 @@ var TOOL_NAMES = [
|
|
|
1671
1707
|
"list_imports",
|
|
1672
1708
|
"call_path",
|
|
1673
1709
|
"trigger_indexing",
|
|
1710
|
+
"indexing_status",
|
|
1674
1711
|
"version_diff"
|
|
1675
1712
|
];
|
|
1676
1713
|
var TOOL_NAME_MIGRATION = {
|
|
@@ -2405,6 +2442,10 @@ class PkgseerServiceImpl {
|
|
|
2405
2442
|
});
|
|
2406
2443
|
return { data: result.data, errors: result.errors };
|
|
2407
2444
|
}
|
|
2445
|
+
async getIndexingProgress(ref) {
|
|
2446
|
+
const result = await this.client.IndexingProgress({ ref });
|
|
2447
|
+
return { data: result.data, errors: result.errors };
|
|
2448
|
+
}
|
|
2408
2449
|
async triggerIndexing(input) {
|
|
2409
2450
|
const result = await this.client.TriggerIndexing({ input });
|
|
2410
2451
|
return { data: result.data, errors: result.errors };
|
|
@@ -2822,6 +2863,14 @@ function handleErrors(errors, json) {
|
|
|
2822
2863
|
const hint = CLI_HINTS[classifyError(combined)];
|
|
2823
2864
|
outputError(`${combined}${hint}`, json);
|
|
2824
2865
|
}
|
|
2866
|
+
function handleIndexingInProgress(data, json) {
|
|
2867
|
+
if (data.indexingStatus === "INDEXING") {
|
|
2868
|
+
const refInfo = data.indexingRef ? ` (ref: ${data.indexingRef})` : "";
|
|
2869
|
+
outputError(`Target is being indexed${refInfo}. Retry with a longer --wait value or try again later.`, json);
|
|
2870
|
+
return true;
|
|
2871
|
+
}
|
|
2872
|
+
return false;
|
|
2873
|
+
}
|
|
2825
2874
|
function formatNumber(num) {
|
|
2826
2875
|
if (num == null)
|
|
2827
2876
|
return "N/A";
|
|
@@ -3036,7 +3085,8 @@ function formatDependencyEntry(entry) {
|
|
|
3036
3085
|
// src/commands/code/callees.ts
|
|
3037
3086
|
function formatCalleesResult(data) {
|
|
3038
3087
|
const lines = [];
|
|
3039
|
-
|
|
3088
|
+
const rootLabel = data.root ? `${data.root.qualifiedPath ?? data.root.name} (ref:${data.root.symbolRef})` : "unknown";
|
|
3089
|
+
lines.push(`Callees of ${rootLabel}`);
|
|
3040
3090
|
lines.push(`${data.total} callee(s)${data.hasMore ? " (more available)" : ""}`);
|
|
3041
3091
|
if (data.externalPackages && data.externalPackages.length > 0) {
|
|
3042
3092
|
lines.push(`External packages: ${data.externalPackages.join(", ")}`);
|
|
@@ -3067,10 +3117,13 @@ async function codeCalleesAction(symbolArg, options, deps) {
|
|
|
3067
3117
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3068
3118
|
});
|
|
3069
3119
|
handleErrors(result.errors, options.json ?? false);
|
|
3120
|
+
const data = result.data.symbolDependencies;
|
|
3121
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3122
|
+
return;
|
|
3070
3123
|
if (options.json) {
|
|
3071
|
-
output(
|
|
3124
|
+
output(data, true);
|
|
3072
3125
|
} else {
|
|
3073
|
-
console.log(formatCalleesResult(
|
|
3126
|
+
console.log(formatCalleesResult(data));
|
|
3074
3127
|
}
|
|
3075
3128
|
}
|
|
3076
3129
|
var CALLEES_DESCRIPTION = `Find what a symbol calls.
|
|
@@ -3093,7 +3146,8 @@ function registerCodeCalleesCommand(program) {
|
|
|
3093
3146
|
// src/commands/code/callers.ts
|
|
3094
3147
|
function formatCallersResult(data) {
|
|
3095
3148
|
const lines = [];
|
|
3096
|
-
|
|
3149
|
+
const targetLabel = data.target ? `${data.target.qualifiedPath ?? data.target.name} (ref:${data.target.symbolRef})` : "unknown";
|
|
3150
|
+
lines.push(`Callers of ${targetLabel}`);
|
|
3097
3151
|
lines.push(`${data.total} caller(s)${data.hasMore ? " (more available)" : ""}`);
|
|
3098
3152
|
lines.push("");
|
|
3099
3153
|
for (const dep of data.dependents) {
|
|
@@ -3114,10 +3168,13 @@ async function codeCallersAction(symbolArg, options, deps) {
|
|
|
3114
3168
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3115
3169
|
});
|
|
3116
3170
|
handleErrors(result.errors, options.json ?? false);
|
|
3171
|
+
const data = result.data.symbolDependents;
|
|
3172
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3173
|
+
return;
|
|
3117
3174
|
if (options.json) {
|
|
3118
|
-
output(
|
|
3175
|
+
output(data, true);
|
|
3119
3176
|
} else {
|
|
3120
|
-
console.log(formatCallersResult(
|
|
3177
|
+
console.log(formatCallersResult(data));
|
|
3121
3178
|
}
|
|
3122
3179
|
}
|
|
3123
3180
|
var CALLERS_DESCRIPTION = `Find what calls a symbol.
|
|
@@ -3140,12 +3197,14 @@ function registerCodeCallersCommand(program) {
|
|
|
3140
3197
|
// src/commands/code/diff.ts
|
|
3141
3198
|
function formatDiffResult(data) {
|
|
3142
3199
|
const lines = [];
|
|
3143
|
-
lines.push(`Version diff: ${data.fromVersion} → ${data.toVersion}`);
|
|
3200
|
+
lines.push(`Version diff: ${data.fromVersion ?? "unknown"} → ${data.toVersion ?? "unknown"}`);
|
|
3144
3201
|
lines.push("");
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3202
|
+
if (data.summary) {
|
|
3203
|
+
const s = data.summary;
|
|
3204
|
+
lines.push("Summary:");
|
|
3205
|
+
lines.push(` Added: ${s.added} Removed: ${s.removed} Modified: ${s.modified} Moved: ${s.moved}`);
|
|
3206
|
+
lines.push(` Breaking: ${s.breaking} Behavior changes: ${s.behaviorChange}`);
|
|
3207
|
+
}
|
|
3149
3208
|
if (data.hasMore) {
|
|
3150
3209
|
lines.push(" (more changes available, increase --limit)");
|
|
3151
3210
|
}
|
|
@@ -3182,10 +3241,13 @@ async function codeDiffAction(packageArg, fromVersion, toVersion, options, deps)
|
|
|
3182
3241
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3183
3242
|
});
|
|
3184
3243
|
handleErrors(result.errors, options.json ?? false);
|
|
3244
|
+
const data = result.data.versionDiff;
|
|
3245
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3246
|
+
return;
|
|
3185
3247
|
if (options.json) {
|
|
3186
|
-
output(
|
|
3248
|
+
output(data, true);
|
|
3187
3249
|
} else {
|
|
3188
|
-
console.log(formatDiffResult(
|
|
3250
|
+
console.log(formatDiffResult(data));
|
|
3189
3251
|
}
|
|
3190
3252
|
}
|
|
3191
3253
|
var DIFF_DESCRIPTION = `Compare symbols between two package versions.
|
|
@@ -3239,6 +3301,8 @@ async function codeFilesAction(packageArg, options, deps) {
|
|
|
3239
3301
|
});
|
|
3240
3302
|
handleErrors(result.errors, options.json ?? false);
|
|
3241
3303
|
const data = result.data.listRepoFiles;
|
|
3304
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3305
|
+
return;
|
|
3242
3306
|
if (options.json) {
|
|
3243
3307
|
output(data, true);
|
|
3244
3308
|
} else {
|
|
@@ -3300,6 +3364,8 @@ async function codeFindAction(packageArg, nameArg, options, deps) {
|
|
|
3300
3364
|
});
|
|
3301
3365
|
handleErrors(result.errors, options.json ?? false);
|
|
3302
3366
|
const data = result.data.findSymbol;
|
|
3367
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3368
|
+
return;
|
|
3303
3369
|
if (options.json) {
|
|
3304
3370
|
output(data, true);
|
|
3305
3371
|
} else {
|
|
@@ -3370,6 +3436,8 @@ async function codeGrepAction(packageArg, filePath, pattern, options, deps) {
|
|
|
3370
3436
|
});
|
|
3371
3437
|
handleErrors(result.errors, options.json ?? false);
|
|
3372
3438
|
const data = result.data.grepRepoFile;
|
|
3439
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3440
|
+
return;
|
|
3373
3441
|
if (options.json) {
|
|
3374
3442
|
output(data, true);
|
|
3375
3443
|
} else {
|
|
@@ -3452,10 +3520,13 @@ async function codeImportsAction(packageArg, options, deps) {
|
|
|
3452
3520
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3453
3521
|
});
|
|
3454
3522
|
handleErrors(result.errors, options.json ?? false);
|
|
3523
|
+
const data = result.data.packageImports;
|
|
3524
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3525
|
+
return;
|
|
3455
3526
|
if (options.json) {
|
|
3456
|
-
output(
|
|
3527
|
+
output(data, true);
|
|
3457
3528
|
} else {
|
|
3458
|
-
console.log(formatImportsResult(
|
|
3529
|
+
console.log(formatImportsResult(data));
|
|
3459
3530
|
}
|
|
3460
3531
|
}
|
|
3461
3532
|
var IMPORTS_DESCRIPTION = `List import statements in a package.
|
|
@@ -3517,10 +3588,13 @@ async function codeListAction(packageArg, options, deps) {
|
|
|
3517
3588
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3518
3589
|
});
|
|
3519
3590
|
handleErrors(result.errors, options.json ?? false);
|
|
3591
|
+
const data = result.data.listSymbols;
|
|
3592
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3593
|
+
return;
|
|
3520
3594
|
if (options.json) {
|
|
3521
|
-
output(
|
|
3595
|
+
output(data, true);
|
|
3522
3596
|
} else {
|
|
3523
|
-
console.log(formatListResult(
|
|
3597
|
+
console.log(formatListResult(data));
|
|
3524
3598
|
}
|
|
3525
3599
|
}
|
|
3526
3600
|
var LIST_DESCRIPTION = `Browse symbols in a package.
|
|
@@ -3544,8 +3618,8 @@ function registerCodeListCommand(program) {
|
|
|
3544
3618
|
// src/commands/code/path.ts
|
|
3545
3619
|
function formatPathResult(data) {
|
|
3546
3620
|
const lines = [];
|
|
3547
|
-
const fromName = data.fromSymbol.qualifiedPath ?? data.fromSymbol.name;
|
|
3548
|
-
const toName = data.toSymbol.qualifiedPath ?? data.toSymbol.name;
|
|
3621
|
+
const fromName = data.fromSymbol ? data.fromSymbol.qualifiedPath ?? data.fromSymbol.name : "unknown";
|
|
3622
|
+
const toName = data.toSymbol ? data.toSymbol.qualifiedPath ?? data.toSymbol.name : "unknown";
|
|
3549
3623
|
lines.push(`Call path: ${fromName} -> ${toName}`);
|
|
3550
3624
|
if (!data.pathFound) {
|
|
3551
3625
|
lines.push("No path found between these symbols.");
|
|
@@ -3578,10 +3652,13 @@ async function codePathAction(fromArg, toArg, options, deps) {
|
|
|
3578
3652
|
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3579
3653
|
});
|
|
3580
3654
|
handleErrors(result.errors, options.json ?? false);
|
|
3655
|
+
const data = result.data.callPath;
|
|
3656
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3657
|
+
return;
|
|
3581
3658
|
if (options.json) {
|
|
3582
|
-
output(
|
|
3659
|
+
output(data, true);
|
|
3583
3660
|
} else {
|
|
3584
|
-
console.log(formatPathResult(
|
|
3661
|
+
console.log(formatPathResult(data));
|
|
3585
3662
|
}
|
|
3586
3663
|
}
|
|
3587
3664
|
var PATH_DESCRIPTION = `Find call path between two symbols.
|
|
@@ -3655,6 +3732,8 @@ async function codeSearchAction(packageArg, query, options, deps) {
|
|
|
3655
3732
|
});
|
|
3656
3733
|
handleErrors(result.errors, options.json ?? false);
|
|
3657
3734
|
const data = result.data.searchSymbols;
|
|
3735
|
+
if (handleIndexingInProgress(data, options.json ?? false))
|
|
3736
|
+
return;
|
|
3658
3737
|
if (options.json) {
|
|
3659
3738
|
output(data, true);
|
|
3660
3739
|
} else {
|
|
@@ -6804,7 +6883,7 @@ var schemas = {
|
|
|
6804
6883
|
packageName: z2.string().max(255).describe("Name of the package"),
|
|
6805
6884
|
version: z2.string().max(100).optional().describe("Specific version, e.g. '4.18.2' (defaults to latest)"),
|
|
6806
6885
|
navigationMode: z2.enum(["summary", "detailed"]).optional().describe("Response detail level. summary (default) returns core fields; detailed adds all optional fields."),
|
|
6807
|
-
waitTimeoutMs: z2.coerce.number().int().min(0).max(
|
|
6886
|
+
waitTimeoutMs: z2.coerce.number().int().min(0).max(60000).optional().describe("Max milliseconds to wait for indexing (0-60000, default 10000). Set 0 to error immediately if not indexed."),
|
|
6808
6887
|
symbolReference: z2.object({
|
|
6809
6888
|
symbol_ref: z2.string().optional().describe("Compound symbol reference (registry:package:version:id) from find_symbol or list_symbols results. Self-contained — no additional fields needed."),
|
|
6810
6889
|
registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry. For package-scoped lookup (with package_name + symbol_name)."),
|
|
@@ -6893,7 +6972,7 @@ function buildCodeTargetVars(resolved) {
|
|
|
6893
6972
|
}
|
|
6894
6973
|
var DEFAULT_WAIT_TIMEOUT_MS2 = 1e4;
|
|
6895
6974
|
var MCP_HINTS = {
|
|
6896
|
-
being_indexed: "Hint:
|
|
6975
|
+
being_indexed: "Hint: target is being indexed. Retry with a longer wait_timeout_ms (e.g., 30000) or use indexing_status to poll progress.",
|
|
6897
6976
|
timeout: "Hint: this may be transient — retry the same query. If the issue persists, try simplifying the query."
|
|
6898
6977
|
};
|
|
6899
6978
|
function buildHintedMessage(operation, message) {
|
|
@@ -6922,14 +7001,50 @@ function buildHintedMessage(operation, message) {
|
|
|
6922
7001
|
return `Failed to ${operation}: ${message}`;
|
|
6923
7002
|
}
|
|
6924
7003
|
var MCP_GRAPHQL_HINTS = {
|
|
6925
|
-
not_found: "Hint: verify the package name
|
|
6926
|
-
being_indexed: "Hint:
|
|
7004
|
+
not_found: "Hint: verify the package name, registry, or repository URL are correct.",
|
|
7005
|
+
being_indexed: "Hint: target is being indexed. Retry with a longer wait_timeout_ms (e.g., 30000) or use indexing_status to poll progress.",
|
|
6927
7006
|
timeout: "Hint: this may be transient — retry the same query. If the issue persists, try simplifying the query."
|
|
6928
7007
|
};
|
|
7008
|
+
function getExtensionCode(errors) {
|
|
7009
|
+
for (const error2 of errors) {
|
|
7010
|
+
const ext = error2.extensions;
|
|
7011
|
+
if (ext?.code && typeof ext.code === "string") {
|
|
7012
|
+
return ext.code;
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
return;
|
|
7016
|
+
}
|
|
7017
|
+
function getExtensionIndexingRef(errors) {
|
|
7018
|
+
for (const error2 of errors) {
|
|
7019
|
+
const ext = error2.extensions;
|
|
7020
|
+
const ref = ext?.indexing_ref ?? ext?.indexingRef;
|
|
7021
|
+
if (ref && typeof ref === "string") {
|
|
7022
|
+
return ref;
|
|
7023
|
+
}
|
|
7024
|
+
}
|
|
7025
|
+
return;
|
|
7026
|
+
}
|
|
7027
|
+
var EXTENSION_CODE_HINTS = {
|
|
7028
|
+
PACKAGE_INDEXING: "Hint: target is being indexed. Use indexing_status to poll progress, or retry with a longer wait_timeout_ms.",
|
|
7029
|
+
NOT_FOUND: "Hint: verify the package name, registry, or repository URL are correct."
|
|
7030
|
+
};
|
|
6929
7031
|
function handleGraphQLErrors(errors) {
|
|
6930
7032
|
if (errors && errors.length > 0) {
|
|
6931
7033
|
const combined = errors.map((e) => e.message).filter(Boolean).join(", ");
|
|
6932
|
-
const
|
|
7034
|
+
const extensionCode = getExtensionCode(errors);
|
|
7035
|
+
const indexingRef = getExtensionIndexingRef(errors);
|
|
7036
|
+
if (extensionCode === "PACKAGE_INDEXING" && indexingRef) {
|
|
7037
|
+
return errorResult(JSON.stringify({
|
|
7038
|
+
error: combined,
|
|
7039
|
+
indexingStatus: "INDEXING",
|
|
7040
|
+
indexingRef,
|
|
7041
|
+
message: "Target is being indexed. Use indexing_status tool with this indexingRef to poll progress, " + "or retry the original query after indexing completes."
|
|
7042
|
+
}));
|
|
7043
|
+
}
|
|
7044
|
+
if (extensionCode === "PACKAGE_INDEXING") {
|
|
7045
|
+
return errorResult(`Error: ${combined}. ` + "Hint: target is being indexed (background refresh). Retry the query in a few seconds.");
|
|
7046
|
+
}
|
|
7047
|
+
const hint = extensionCode ? EXTENSION_CODE_HINTS[extensionCode] : MCP_GRAPHQL_HINTS[classifyError(combined)];
|
|
6933
7048
|
const suffix = hint ? `. ${hint}` : "";
|
|
6934
7049
|
return errorResult(`Error: ${combined}${suffix}`);
|
|
6935
7050
|
}
|
|
@@ -6943,6 +7058,19 @@ async function withErrorHandling(operation, fn) {
|
|
|
6943
7058
|
return errorResult(buildHintedMessage(operation, message));
|
|
6944
7059
|
}
|
|
6945
7060
|
}
|
|
7061
|
+
function handleIndexingStatus(data) {
|
|
7062
|
+
if (data.indexingStatus === "INDEXING") {
|
|
7063
|
+
const response = {
|
|
7064
|
+
indexingStatus: "INDEXING",
|
|
7065
|
+
message: "Target is being indexed. Use indexing_status tool with this indexingRef to poll progress, " + "or retry the original query after indexing completes."
|
|
7066
|
+
};
|
|
7067
|
+
if (data.indexingRef) {
|
|
7068
|
+
response.indexingRef = data.indexingRef;
|
|
7069
|
+
}
|
|
7070
|
+
return errorResult(JSON.stringify(response));
|
|
7071
|
+
}
|
|
7072
|
+
return null;
|
|
7073
|
+
}
|
|
6946
7074
|
function notFoundError(packageName, registry) {
|
|
6947
7075
|
return errorResult(`Package not found: ${packageName} in ${registry}. Verify the package name and registry are correct.`);
|
|
6948
7076
|
}
|
|
@@ -6979,7 +7107,11 @@ function createCallPathTool(pkgseerService) {
|
|
|
6979
7107
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
6980
7108
|
if (graphqlError)
|
|
6981
7109
|
return graphqlError;
|
|
6982
|
-
|
|
7110
|
+
const data = result.data.callPath;
|
|
7111
|
+
const indexingError = handleIndexingStatus(data);
|
|
7112
|
+
if (indexingError)
|
|
7113
|
+
return indexingError;
|
|
7114
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
6983
7115
|
});
|
|
6984
7116
|
}
|
|
6985
7117
|
};
|
|
@@ -7094,6 +7226,9 @@ function createFindSymbolTool(pkgseerService) {
|
|
|
7094
7226
|
if (graphqlError)
|
|
7095
7227
|
return graphqlError;
|
|
7096
7228
|
const data = result.data.findSymbol;
|
|
7229
|
+
const indexingError = handleIndexingStatus(data);
|
|
7230
|
+
if (indexingError)
|
|
7231
|
+
return indexingError;
|
|
7097
7232
|
if (data.symbols.length === 0 && data.diagnostics?.hint) {
|
|
7098
7233
|
return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
|
|
7099
7234
|
}
|
|
@@ -7136,6 +7271,9 @@ function createGrepFileTool(pkgseerService) {
|
|
|
7136
7271
|
if (graphqlError)
|
|
7137
7272
|
return graphqlError;
|
|
7138
7273
|
const data = result.data.grepRepoFile;
|
|
7274
|
+
const indexingError = handleIndexingStatus(data);
|
|
7275
|
+
if (indexingError)
|
|
7276
|
+
return indexingError;
|
|
7139
7277
|
if (data.matches.length === 0 && data.diagnostics?.hint) {
|
|
7140
7278
|
return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
|
|
7141
7279
|
}
|
|
@@ -7144,19 +7282,67 @@ function createGrepFileTool(pkgseerService) {
|
|
|
7144
7282
|
}
|
|
7145
7283
|
};
|
|
7146
7284
|
}
|
|
7147
|
-
// src/tools/
|
|
7285
|
+
// src/tools/indexing-status.ts
|
|
7148
7286
|
import { z as z8 } from "zod";
|
|
7149
7287
|
var argsSchema6 = {
|
|
7288
|
+
ref: z8.string().min(1).describe("Indexing reference from a previous tool result (returned when indexing times out).")
|
|
7289
|
+
};
|
|
7290
|
+
function createIndexingStatusTool(pkgseerService) {
|
|
7291
|
+
return {
|
|
7292
|
+
name: "indexing_status",
|
|
7293
|
+
description: "Check indexing progress for a code navigation target. " + "Use after any code navigation tool returns an indexingRef (when indexing exceeded wait_timeout_ms). " + "Returns status (PENDING, INDEXING, INDEXED, FAILED, NOT_FOUND) with progress details. " + "When status is INDEXED, retry the original query to get results.",
|
|
7294
|
+
schema: argsSchema6,
|
|
7295
|
+
annotations: { readOnlyHint: true },
|
|
7296
|
+
handler: async ({ ref }, _extra) => {
|
|
7297
|
+
return withErrorHandling("check indexing status", async () => {
|
|
7298
|
+
const result = await pkgseerService.getIndexingProgress(ref);
|
|
7299
|
+
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7300
|
+
if (graphqlError)
|
|
7301
|
+
return graphqlError;
|
|
7302
|
+
const progress = result.data?.indexingProgress;
|
|
7303
|
+
if (!progress) {
|
|
7304
|
+
return errorResult("Indexing session not found. The reference may be invalid or the session may have expired.");
|
|
7305
|
+
}
|
|
7306
|
+
const response = {
|
|
7307
|
+
status: progress.status,
|
|
7308
|
+
ref
|
|
7309
|
+
};
|
|
7310
|
+
if (progress.filesIndexed != null) {
|
|
7311
|
+
response.filesIndexed = progress.filesIndexed;
|
|
7312
|
+
}
|
|
7313
|
+
if (progress.chunksCreated != null) {
|
|
7314
|
+
response.chunksCreated = progress.chunksCreated;
|
|
7315
|
+
}
|
|
7316
|
+
if (progress.elapsedMs != null) {
|
|
7317
|
+
response.elapsedMs = progress.elapsedMs;
|
|
7318
|
+
}
|
|
7319
|
+
if (progress.status === "INDEXED") {
|
|
7320
|
+
response.message = "Indexing is complete. Retry your original query to get results.";
|
|
7321
|
+
} else if (progress.status === "INDEXING" || progress.status === "PENDING") {
|
|
7322
|
+
response.message = "Indexing is in progress. Poll again to check status.";
|
|
7323
|
+
} else if (progress.status === "FAILED") {
|
|
7324
|
+
response.message = "Indexing failed.";
|
|
7325
|
+
} else if (progress.status === "NOT_FOUND") {
|
|
7326
|
+
response.message = "Indexing reference not found. The ref may be invalid or the session may have expired.";
|
|
7327
|
+
}
|
|
7328
|
+
return textResult(JSON.stringify(response, null, 2));
|
|
7329
|
+
});
|
|
7330
|
+
}
|
|
7331
|
+
};
|
|
7332
|
+
}
|
|
7333
|
+
// src/tools/list-files.ts
|
|
7334
|
+
import { z as z9 } from "zod";
|
|
7335
|
+
var argsSchema7 = {
|
|
7150
7336
|
target: schemas.codeTarget,
|
|
7151
|
-
path_prefix:
|
|
7152
|
-
limit:
|
|
7337
|
+
path_prefix: z9.string().optional().describe("Filter to files under this path (e.g., 'src/')"),
|
|
7338
|
+
limit: z9.coerce.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
|
|
7153
7339
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7154
7340
|
};
|
|
7155
7341
|
function createListFilesTool(pkgseerService) {
|
|
7156
7342
|
return {
|
|
7157
7343
|
name: "list_files",
|
|
7158
7344
|
description: "Explore a dependency's file structure — " + "see what source files, configs, and docs exist. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns file paths, names, languages, types (source/doc/config), and sizes. " + "Use path_prefix to filter by directory (e.g., 'src/'). " + "Good first step when investigating unfamiliar package internals. " + "In monorepos with package scope, returns only files within this package's subdirectory. " + "Requires code indexing.",
|
|
7159
|
-
schema:
|
|
7345
|
+
schema: argsSchema7,
|
|
7160
7346
|
annotations: { readOnlyHint: true },
|
|
7161
7347
|
handler: async (args, _extra) => {
|
|
7162
7348
|
return withErrorHandling("list files", async () => {
|
|
@@ -7176,6 +7362,9 @@ function createListFilesTool(pkgseerService) {
|
|
|
7176
7362
|
if (graphqlError)
|
|
7177
7363
|
return graphqlError;
|
|
7178
7364
|
const data = result.data.listRepoFiles;
|
|
7365
|
+
const indexingError = handleIndexingStatus(data);
|
|
7366
|
+
if (indexingError)
|
|
7367
|
+
return indexingError;
|
|
7179
7368
|
if (data.files.length === 0 && data.diagnostics?.hint) {
|
|
7180
7369
|
return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
|
|
7181
7370
|
}
|
|
@@ -7185,12 +7374,12 @@ function createListFilesTool(pkgseerService) {
|
|
|
7185
7374
|
};
|
|
7186
7375
|
}
|
|
7187
7376
|
// src/tools/list-imports.ts
|
|
7188
|
-
import { z as
|
|
7189
|
-
var
|
|
7377
|
+
import { z as z10 } from "zod";
|
|
7378
|
+
var argsSchema8 = {
|
|
7190
7379
|
target: schemas.codeTarget,
|
|
7191
|
-
file_path:
|
|
7192
|
-
resolved_only:
|
|
7193
|
-
limit:
|
|
7380
|
+
file_path: z10.string().max(1000).optional().describe("Filter to a specific file path"),
|
|
7381
|
+
resolved_only: z10.boolean().optional().describe("Only return imports resolved to a known package"),
|
|
7382
|
+
limit: z10.coerce.number().int().min(1).max(500).optional().describe("Max imports to return"),
|
|
7194
7383
|
mode: schemas.navigationMode,
|
|
7195
7384
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7196
7385
|
};
|
|
@@ -7198,7 +7387,7 @@ function createListImportsTool(pkgseerService) {
|
|
|
7198
7387
|
return {
|
|
7199
7388
|
name: "list_imports",
|
|
7200
7389
|
description: "See what a dependency imports — understand its internal dependencies and external package usage. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns parsed import/require/use statements with optional resolution to known packages. " + "Use resolved_only=true to see only imports that map to packages in the PkgSeer registry. " + "Includes: source path, imported names, and de-duplicated dependency list.",
|
|
7201
|
-
schema:
|
|
7390
|
+
schema: argsSchema8,
|
|
7202
7391
|
annotations: { readOnlyHint: true },
|
|
7203
7392
|
handler: async (args, _extra) => {
|
|
7204
7393
|
return withErrorHandling("list imports", async () => {
|
|
@@ -7219,13 +7408,17 @@ function createListImportsTool(pkgseerService) {
|
|
|
7219
7408
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7220
7409
|
if (graphqlError)
|
|
7221
7410
|
return graphqlError;
|
|
7222
|
-
|
|
7411
|
+
const data = result.data.packageImports;
|
|
7412
|
+
const indexingError = handleIndexingStatus(data);
|
|
7413
|
+
if (indexingError)
|
|
7414
|
+
return indexingError;
|
|
7415
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
7223
7416
|
});
|
|
7224
7417
|
}
|
|
7225
7418
|
};
|
|
7226
7419
|
}
|
|
7227
7420
|
// src/tools/list-package-docs.ts
|
|
7228
|
-
var
|
|
7421
|
+
var argsSchema9 = {
|
|
7229
7422
|
registry: schemas.registry,
|
|
7230
7423
|
package_name: schemas.packageName.describe("Name of the package to list documentation for"),
|
|
7231
7424
|
version: schemas.version
|
|
@@ -7234,7 +7427,7 @@ function createListPackageDocsTool(pkgseerService) {
|
|
|
7234
7427
|
return {
|
|
7235
7428
|
name: "list_package_docs",
|
|
7236
7429
|
description: "Discover available documentation pages for a package. Start here before fetching or searching docs. " + "Returns: page titles, unique IDs (needed for fetch_package_doc), word counts, and update timestamps. " + "Workflow: list_package_docs → fetch_package_doc for full content, or search(mode='docs') to find specific topics. " + "Requires documentation to have been crawled — if results are empty, use trigger_indexing first, then retry.",
|
|
7237
|
-
schema:
|
|
7430
|
+
schema: argsSchema9,
|
|
7238
7431
|
annotations: { readOnlyHint: true },
|
|
7239
7432
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7240
7433
|
return withErrorHandling("list package documentation", async () => {
|
|
@@ -7251,15 +7444,15 @@ function createListPackageDocsTool(pkgseerService) {
|
|
|
7251
7444
|
};
|
|
7252
7445
|
}
|
|
7253
7446
|
// src/tools/list-symbols.ts
|
|
7254
|
-
import { z as
|
|
7255
|
-
var
|
|
7447
|
+
import { z as z11 } from "zod";
|
|
7448
|
+
var argsSchema10 = {
|
|
7256
7449
|
target: schemas.codeTarget,
|
|
7257
|
-
scope:
|
|
7258
|
-
file_path:
|
|
7259
|
-
namespace:
|
|
7260
|
-
public_only:
|
|
7261
|
-
include_popularity:
|
|
7262
|
-
limit:
|
|
7450
|
+
scope: z11.enum(["exports", "file"]).describe("Browsing scope: 'exports' for public API, 'file' for all symbols in a specific file"),
|
|
7451
|
+
file_path: z11.string().max(1000).optional().describe("File path within the repo (required when scope=file)"),
|
|
7452
|
+
namespace: z11.string().max(500).optional().describe("Filter by namespace prefix (e.g., 'React' to see React.*)"),
|
|
7453
|
+
public_only: z11.boolean().optional().describe("Only return public symbols"),
|
|
7454
|
+
include_popularity: z11.boolean().optional().describe("Include callerCount for each symbol (slightly slower)"),
|
|
7455
|
+
limit: z11.coerce.number().int().min(1).max(100).optional().describe("Max symbols to return (max 100)"),
|
|
7263
7456
|
mode: schemas.navigationMode,
|
|
7264
7457
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7265
7458
|
};
|
|
@@ -7267,7 +7460,7 @@ function createListSymbolsTool(pkgseerService) {
|
|
|
7267
7460
|
return {
|
|
7268
7461
|
name: "list_symbols",
|
|
7269
7462
|
description: "Browse a dependency's public API or file-level symbols. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Use scope='exports' for the public API with optional popularity ranking. " + "Use scope='file' with file_path for all symbols in a specific file. " + "Returns symbol refs, names, qualified paths, kinds, and file locations. " + "Use find_symbol(name=<symbol>, include_code=true) to read source for any result.",
|
|
7270
|
-
schema:
|
|
7463
|
+
schema: argsSchema10,
|
|
7271
7464
|
annotations: { readOnlyHint: true },
|
|
7272
7465
|
handler: async (args, _extra) => {
|
|
7273
7466
|
return withErrorHandling("list symbols", async () => {
|
|
@@ -7302,19 +7495,23 @@ function createListSymbolsTool(pkgseerService) {
|
|
|
7302
7495
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7303
7496
|
if (graphqlError)
|
|
7304
7497
|
return graphqlError;
|
|
7305
|
-
|
|
7498
|
+
const data = result.data.listSymbols;
|
|
7499
|
+
const indexingError = handleIndexingStatus(data);
|
|
7500
|
+
if (indexingError)
|
|
7501
|
+
return indexingError;
|
|
7502
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
7306
7503
|
});
|
|
7307
7504
|
}
|
|
7308
7505
|
};
|
|
7309
7506
|
}
|
|
7310
7507
|
// src/tools/package-dependencies.ts
|
|
7311
|
-
import { z as
|
|
7312
|
-
var
|
|
7508
|
+
import { z as z12 } from "zod";
|
|
7509
|
+
var argsSchema11 = {
|
|
7313
7510
|
registry: schemas.registry,
|
|
7314
7511
|
package_name: schemas.packageName.describe("Name of the package to retrieve dependencies for"),
|
|
7315
7512
|
version: schemas.version,
|
|
7316
|
-
include_transitive:
|
|
7317
|
-
max_depth:
|
|
7513
|
+
include_transitive: z12.boolean().optional().describe("Whether to include transitive dependency DAG"),
|
|
7514
|
+
max_depth: z12.coerce.number().int().min(1).max(10).optional().describe("Maximum depth for transitive traversal (1-10)")
|
|
7318
7515
|
};
|
|
7319
7516
|
function decodeDag(rawDag) {
|
|
7320
7517
|
if (!rawDag || typeof rawDag !== "object")
|
|
@@ -7392,7 +7589,7 @@ function createPackageDependenciesTool(pkgseerService) {
|
|
|
7392
7589
|
return {
|
|
7393
7590
|
name: "package_dependencies",
|
|
7394
7591
|
description: "Analyze package dependencies. By default returns direct dependencies only. " + "Set include_transitive=true to get the full dependency tree (use max_depth to limit large trees). " + "Returns: dependency names, version constraints, and for transitive deps, a graph with depth levels. " + "Use this to understand complexity before adding a package, or to find nested dependencies.",
|
|
7395
|
-
schema:
|
|
7592
|
+
schema: argsSchema11,
|
|
7396
7593
|
annotations: { readOnlyHint: true },
|
|
7397
7594
|
handler: async ({ registry, package_name, version: version2, include_transitive, max_depth }, _extra) => {
|
|
7398
7595
|
return withErrorHandling("fetch package dependencies", async () => {
|
|
@@ -7431,7 +7628,7 @@ function createPackageDependenciesTool(pkgseerService) {
|
|
|
7431
7628
|
};
|
|
7432
7629
|
}
|
|
7433
7630
|
// src/tools/package-quality.ts
|
|
7434
|
-
var
|
|
7631
|
+
var argsSchema12 = {
|
|
7435
7632
|
registry: schemas.registry,
|
|
7436
7633
|
package_name: schemas.packageName.describe("Name of the package to analyze"),
|
|
7437
7634
|
version: schemas.version
|
|
@@ -7440,7 +7637,7 @@ function createPackageQualityTool(pkgseerService) {
|
|
|
7440
7637
|
return {
|
|
7441
7638
|
name: "package_quality",
|
|
7442
7639
|
description: "Evaluate package maintenance health and code quality (available immediately — no indexing required). " + "Use this to assess if a package is well-maintained " + "before adding it as a dependency. Returns: overall score (0-100), category scores (documentation, " + "testing, community, maintenance), and individual rule results with pass/fail status. " + "Useful for comparing quality between alternative packages.",
|
|
7443
|
-
schema:
|
|
7640
|
+
schema: argsSchema12,
|
|
7444
7641
|
annotations: { readOnlyHint: true },
|
|
7445
7642
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7446
7643
|
return withErrorHandling("fetch package quality", async () => {
|
|
@@ -7457,7 +7654,7 @@ function createPackageQualityTool(pkgseerService) {
|
|
|
7457
7654
|
};
|
|
7458
7655
|
}
|
|
7459
7656
|
// src/tools/package-summary.ts
|
|
7460
|
-
var
|
|
7657
|
+
var argsSchema13 = {
|
|
7461
7658
|
registry: schemas.registry,
|
|
7462
7659
|
package_name: schemas.packageName.describe("Name of the package to retrieve summary for")
|
|
7463
7660
|
};
|
|
@@ -7465,7 +7662,7 @@ function createPackageSummaryTool(pkgseerService) {
|
|
|
7465
7662
|
return {
|
|
7466
7663
|
name: "package_summary",
|
|
7467
7664
|
description: "Get a comprehensive overview of a package (available immediately — no indexing required). " + "Use this as your first tool when researching a package. " + "Returns: description, latest version, license, repository URL, download stats, " + "active security advisories count, and quickstart/installation instructions. " + "For deeper analysis, follow up with package_quality (maintenance health) or " + "package_vulnerabilities (security details). " + "Use package.repositoryUrl + package.latestVersion as git_ref with fetch_code_context to read source files.",
|
|
7468
|
-
schema:
|
|
7665
|
+
schema: argsSchema13,
|
|
7469
7666
|
annotations: { readOnlyHint: true },
|
|
7470
7667
|
handler: async ({ registry, package_name }, _extra) => {
|
|
7471
7668
|
return withErrorHandling("fetch package summary", async () => {
|
|
@@ -7482,7 +7679,7 @@ function createPackageSummaryTool(pkgseerService) {
|
|
|
7482
7679
|
};
|
|
7483
7680
|
}
|
|
7484
7681
|
// src/tools/package-vulnerabilities.ts
|
|
7485
|
-
var
|
|
7682
|
+
var argsSchema14 = {
|
|
7486
7683
|
registry: schemas.registry,
|
|
7487
7684
|
package_name: schemas.packageName.describe("Name of the package to inspect for vulnerabilities"),
|
|
7488
7685
|
version: schemas.version
|
|
@@ -7491,7 +7688,7 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
|
|
|
7491
7688
|
return {
|
|
7492
7689
|
name: "package_vulnerabilities",
|
|
7493
7690
|
description: "Check security vulnerabilities for a package (available immediately — no indexing required). " + "Use this before adding dependencies or when auditing existing ones. " + "Returns: list of CVEs/advisories with severity levels, affected version ranges, fixed versions, " + "and upgrade recommendations. If version is specified, shows only vulnerabilities affecting that version.",
|
|
7494
|
-
schema:
|
|
7691
|
+
schema: argsSchema14,
|
|
7495
7692
|
annotations: { readOnlyHint: true },
|
|
7496
7693
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7497
7694
|
return withErrorHandling("fetch package vulnerabilities", async () => {
|
|
@@ -7508,21 +7705,21 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
|
|
|
7508
7705
|
};
|
|
7509
7706
|
}
|
|
7510
7707
|
// src/tools/read-file.ts
|
|
7511
|
-
import { z as
|
|
7512
|
-
var
|
|
7708
|
+
import { z as z13 } from "zod";
|
|
7709
|
+
var argsSchema15 = {
|
|
7513
7710
|
target: schemas.codeTarget,
|
|
7514
|
-
file_path:
|
|
7711
|
+
file_path: z13.string({
|
|
7515
7712
|
error: "file_path is required. Get file paths from find_symbol (returns file locations) " + "or list_files (browse file structure)."
|
|
7516
7713
|
}).min(1).describe("Path to file in repository. Example: src/router/index.js"),
|
|
7517
|
-
start_line:
|
|
7518
|
-
end_line:
|
|
7714
|
+
start_line: z13.coerce.number().int().positive().optional().describe("Starting line (1-indexed). If omitted, starts from line 1."),
|
|
7715
|
+
end_line: z13.coerce.number().int().positive().optional().describe("Ending line. If omitted, returns to end of file."),
|
|
7519
7716
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7520
7717
|
};
|
|
7521
7718
|
function createReadFileTool(pkgseerService) {
|
|
7522
7719
|
return {
|
|
7523
7720
|
name: "read_file",
|
|
7524
7721
|
description: "Read source code from a dependency's repository by file path and line range — " + "use when you have a file path from a stack trace or symbol lookup. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns full file or a specific line range. " + "Prefer find_symbol(include_code=true) for function/class lookup. " + "Use list_files to discover file paths. " + "With repo scope, operates on the full repository. " + "With package scope, scoped to the package subdirectory in monorepos.",
|
|
7525
|
-
schema:
|
|
7722
|
+
schema: argsSchema15,
|
|
7526
7723
|
annotations: { readOnlyHint: true },
|
|
7527
7724
|
handler: async (args, _extra) => {
|
|
7528
7725
|
return withErrorHandling("read file", async () => {
|
|
@@ -7541,31 +7738,39 @@ function createReadFileTool(pkgseerService) {
|
|
|
7541
7738
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7542
7739
|
if (graphqlError)
|
|
7543
7740
|
return graphqlError;
|
|
7544
|
-
|
|
7741
|
+
const codeContext = result.data?.fetchCodeContext;
|
|
7742
|
+
if (codeContext) {
|
|
7743
|
+
const indexingError = handleIndexingStatus(codeContext);
|
|
7744
|
+
if (indexingError)
|
|
7745
|
+
return indexingError;
|
|
7746
|
+
}
|
|
7747
|
+
if (!codeContext) {
|
|
7545
7748
|
return errorResult(`File not found: ${args.file_path}. ` + "Check that the file path and target are correct. " + "Use list_files to discover available files.");
|
|
7546
7749
|
}
|
|
7547
|
-
return textResult(JSON.stringify(
|
|
7750
|
+
return textResult(JSON.stringify(codeContext, null, 2));
|
|
7548
7751
|
});
|
|
7549
7752
|
}
|
|
7550
7753
|
};
|
|
7551
7754
|
}
|
|
7552
7755
|
// src/tools/search.ts
|
|
7553
|
-
import { z as
|
|
7554
|
-
var
|
|
7555
|
-
registry:
|
|
7556
|
-
|
|
7557
|
-
version:
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7756
|
+
import { z as z14 } from "zod";
|
|
7757
|
+
var targetInputSchema = z14.object({
|
|
7758
|
+
registry: z14.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry (npm, pypi, hex, etc.). Required for package scope."),
|
|
7759
|
+
package_name: z14.string().min(1).optional().describe("Package name. Required for package scope."),
|
|
7760
|
+
version: z14.string().optional().describe("Specific version (defaults to latest). Package scope only."),
|
|
7761
|
+
repo_url: z14.string().optional().describe("Repository URL (GitHub). Required for repo scope. Example: https://github.com/expressjs/express"),
|
|
7762
|
+
git_ref: z14.string().optional().describe("Git ref — tag, branch, or commit. Required for repo scope. Use HEAD for latest.")
|
|
7763
|
+
}).describe("Search target: provide registry + package_name (package scope) OR repo_url + git_ref (repo scope).");
|
|
7764
|
+
var argsSchema16 = {
|
|
7765
|
+
targets: z14.array(targetInputSchema, {
|
|
7766
|
+
error: 'targets is required. Provide 1-20 targets as [{registry: "npm", package_name: "express"}] ' + 'or [{repo_url: "https://github.com/user/repo", git_ref: "HEAD"}]. ' + "Use package_summary to verify a package exists. " + "For project-wide doc search without specifying targets, use search_project_docs instead."
|
|
7767
|
+
}).min(1).max(20).describe("Targets to search (1-20). Each uses registry + package_name (package scope) or repo_url + git_ref (repo scope)."),
|
|
7768
|
+
query: z14.string({
|
|
7564
7769
|
error: "query is required. Provide search terms as natural language or keywords, " + "e.g., 'error handling middleware'."
|
|
7565
7770
|
}).min(1).describe("Search query - natural language or keywords"),
|
|
7566
|
-
mode:
|
|
7567
|
-
limit:
|
|
7568
|
-
|
|
7771
|
+
mode: z14.enum(["all", "code", "docs"]).optional().describe('Search mode: "all" (default), "code" only, or "docs" only'),
|
|
7772
|
+
limit: z14.coerce.number().int().min(1).max(100).optional().describe("Maximum results (default: 20)"),
|
|
7773
|
+
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7569
7774
|
};
|
|
7570
7775
|
function toSearchMode2(mode) {
|
|
7571
7776
|
if (!mode)
|
|
@@ -7577,6 +7782,47 @@ function toSearchMode2(mode) {
|
|
|
7577
7782
|
};
|
|
7578
7783
|
return map[mode.toLowerCase()];
|
|
7579
7784
|
}
|
|
7785
|
+
function validateAndConvertTargets(targets) {
|
|
7786
|
+
const inputs = [];
|
|
7787
|
+
for (let i = 0;i < targets.length; i++) {
|
|
7788
|
+
const t = targets[i];
|
|
7789
|
+
const hasPackage = t.registry || t.package_name;
|
|
7790
|
+
const hasRepo = t.repo_url || t.git_ref;
|
|
7791
|
+
if (hasPackage && hasRepo) {
|
|
7792
|
+
return {
|
|
7793
|
+
error: `Target ${i + 1}: provide either registry + package_name or repo_url + git_ref, not both.`
|
|
7794
|
+
};
|
|
7795
|
+
}
|
|
7796
|
+
if (!hasPackage && !hasRepo) {
|
|
7797
|
+
return {
|
|
7798
|
+
error: `Target ${i + 1}: provide registry + package_name (package scope) or repo_url + git_ref (repo scope).`
|
|
7799
|
+
};
|
|
7800
|
+
}
|
|
7801
|
+
if (hasPackage) {
|
|
7802
|
+
if (!t.registry || !t.package_name) {
|
|
7803
|
+
return {
|
|
7804
|
+
error: `Target ${i + 1}: both registry and package_name are required for package scope.`
|
|
7805
|
+
};
|
|
7806
|
+
}
|
|
7807
|
+
inputs.push({
|
|
7808
|
+
registry: toGraphQLRegistry(t.registry),
|
|
7809
|
+
name: t.package_name,
|
|
7810
|
+
version: t.version
|
|
7811
|
+
});
|
|
7812
|
+
} else {
|
|
7813
|
+
if (!t.repo_url || !t.git_ref) {
|
|
7814
|
+
return {
|
|
7815
|
+
error: `Target ${i + 1}: both repo_url and git_ref are required for repo scope.`
|
|
7816
|
+
};
|
|
7817
|
+
}
|
|
7818
|
+
inputs.push({
|
|
7819
|
+
repoUrl: t.repo_url,
|
|
7820
|
+
gitRef: t.git_ref
|
|
7821
|
+
});
|
|
7822
|
+
}
|
|
7823
|
+
}
|
|
7824
|
+
return { inputs };
|
|
7825
|
+
}
|
|
7580
7826
|
function formatIndexingWarnings2(indexingStatus) {
|
|
7581
7827
|
if (!indexingStatus || indexingStatus.length === 0)
|
|
7582
7828
|
return null;
|
|
@@ -7595,7 +7841,7 @@ function formatIndexingWarnings2(indexingStatus) {
|
|
|
7595
7841
|
if (warnings.length === 0)
|
|
7596
7842
|
return null;
|
|
7597
7843
|
return `
|
|
7598
|
-
Note: Some
|
|
7844
|
+
Note: Some targets are not fully indexed:
|
|
7599
7845
|
` + warnings.join(`
|
|
7600
7846
|
`) + `
|
|
7601
7847
|
Results may be incomplete. Retry later for more complete results.`;
|
|
@@ -7603,38 +7849,37 @@ Results may be incomplete. Retry later for more complete results.`;
|
|
|
7603
7849
|
function createSearchTool(pkgseerService) {
|
|
7604
7850
|
return {
|
|
7605
7851
|
name: "search",
|
|
7606
|
-
description: "Search code and documentation across packages using full-text search. " + "Returns code chunks and doc pages matching your query with relevance scores and snippets. " + "Use mode='code' for code only, mode='docs' for docs only, or mode='all' (default). " + "Provide 1-20
|
|
7607
|
-
schema:
|
|
7852
|
+
description: "Search code and documentation across packages or repositories using full-text search. " + "Returns code chunks and doc pages matching your query with relevance scores and snippets. " + "Each target can use package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "Use mode='code' for code only, mode='docs' for docs only, or mode='all' (default). " + "Provide 1-20 targets. For symbol-level results that feed into symbol_callers/symbol_callees, " + "use search_symbols instead. " + "For full source of code results, use find_symbol(name=<title>, include_code=true). " + "Code results include repoUrl and filePath for use with fetch_code_context. " + "If targets need indexing, waits up to wait_timeout_ms (default 10s) or returns searchRef — use search_status to poll.",
|
|
7853
|
+
schema: argsSchema16,
|
|
7608
7854
|
annotations: { readOnlyHint: true },
|
|
7609
|
-
handler: async ({
|
|
7610
|
-
return withErrorHandling("search
|
|
7855
|
+
handler: async ({ targets, query, mode, limit, wait_timeout_ms }, _extra) => {
|
|
7856
|
+
return withErrorHandling("search", async () => {
|
|
7611
7857
|
const normalizedQuery = query.trim();
|
|
7612
7858
|
if (normalizedQuery.length === 0) {
|
|
7613
7859
|
return errorResult("Search query is required.");
|
|
7614
7860
|
}
|
|
7615
|
-
const
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
const result = await pkgseerService.combinedSearch(graphqlPackages, normalizedQuery, {
|
|
7861
|
+
const validated = validateAndConvertTargets(targets);
|
|
7862
|
+
if ("error" in validated) {
|
|
7863
|
+
return errorResult(validated.error);
|
|
7864
|
+
}
|
|
7865
|
+
const result = await pkgseerService.combinedSearch(validated.inputs, normalizedQuery, {
|
|
7621
7866
|
mode: toSearchMode2(mode),
|
|
7622
7867
|
limit,
|
|
7623
|
-
waitTimeoutMs:
|
|
7868
|
+
waitTimeoutMs: wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
|
|
7624
7869
|
});
|
|
7625
7870
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7626
7871
|
if (graphqlError)
|
|
7627
7872
|
return graphqlError;
|
|
7628
7873
|
const asyncResult = result.data?.combinedSearch;
|
|
7629
7874
|
if (!asyncResult) {
|
|
7630
|
-
return errorResult("No search results returned. Check
|
|
7875
|
+
return errorResult("No search results returned. Check target names and registries.");
|
|
7631
7876
|
}
|
|
7632
7877
|
if (!asyncResult.completed) {
|
|
7633
7878
|
const progressInfo = {
|
|
7634
7879
|
completed: false,
|
|
7635
7880
|
searchRef: asyncResult.searchRef,
|
|
7636
7881
|
progress: asyncResult.progress,
|
|
7637
|
-
message: "Search is still indexing.
|
|
7882
|
+
message: "Search is still indexing. Use search_status with the searchRef to poll, " + "or retry with a longer wait_timeout_ms."
|
|
7638
7883
|
};
|
|
7639
7884
|
return textResult(JSON.stringify(progressInfo, null, 2));
|
|
7640
7885
|
}
|
|
@@ -7644,7 +7889,7 @@ function createSearchTool(pkgseerService) {
|
|
|
7644
7889
|
}
|
|
7645
7890
|
const entries = searchResult.entries ?? [];
|
|
7646
7891
|
if (entries.length === 0) {
|
|
7647
|
-
return errorResult(`No results found for "${normalizedQuery}". ` + "Try broader terms or different
|
|
7892
|
+
return errorResult(`No results found for "${normalizedQuery}". ` + "Try broader terms or different targets.");
|
|
7648
7893
|
}
|
|
7649
7894
|
let response = JSON.stringify(searchResult, null, 2);
|
|
7650
7895
|
const indexingWarning = formatIndexingWarnings2(searchResult.indexingStatus);
|
|
@@ -7657,21 +7902,21 @@ function createSearchTool(pkgseerService) {
|
|
|
7657
7902
|
};
|
|
7658
7903
|
}
|
|
7659
7904
|
// src/tools/search-project-docs.ts
|
|
7660
|
-
import { z as
|
|
7661
|
-
var
|
|
7662
|
-
project_directory:
|
|
7663
|
-
project:
|
|
7664
|
-
terms:
|
|
7665
|
-
match_mode:
|
|
7666
|
-
include_snippets:
|
|
7667
|
-
limit:
|
|
7905
|
+
import { z as z15 } from "zod";
|
|
7906
|
+
var argsSchema17 = {
|
|
7907
|
+
project_directory: z15.string().optional().describe("Directory to search for pkgseer.yml configuration. " + "Use this to specify which project's context to use when the MCP server " + "is installed at user level. Defaults to MCP server's working directory."),
|
|
7908
|
+
project: z15.string().optional().describe("Project name to search. Overrides value from pkgseer.yml if provided."),
|
|
7909
|
+
terms: z15.array(z15.string()).optional().describe("Search terms to match. Provide a few key words or phrases that should appear in results."),
|
|
7910
|
+
match_mode: z15.enum(["any", "or", "all", "and"]).optional().describe('How to combine terms: "any" (OR) or "all" (AND).'),
|
|
7911
|
+
include_snippets: z15.boolean().optional().describe("Include content excerpts around matches"),
|
|
7912
|
+
limit: z15.coerce.number().int().min(1).max(100).optional().describe("Maximum number of results to return")
|
|
7668
7913
|
};
|
|
7669
7914
|
function createSearchProjectDocsTool(deps) {
|
|
7670
7915
|
const { pkgseerService, configService, defaultProjectDir } = deps;
|
|
7671
7916
|
return {
|
|
7672
7917
|
name: "search_project_docs",
|
|
7673
7918
|
description: "Search documentation across all dependencies in a PkgSeer project — " + "use when you need to find information but don't know which dependency has it. " + "Requires a pkgseer.yml project config (or pass project name directly). " + "Returns ranked results with snippets from multiple packages. " + "Use project_directory to specify which project's context to use. " + "For single-package doc search, use search(mode='docs') instead.",
|
|
7674
|
-
schema:
|
|
7919
|
+
schema: argsSchema17,
|
|
7675
7920
|
annotations: { readOnlyHint: true },
|
|
7676
7921
|
handler: async ({
|
|
7677
7922
|
project_directory,
|
|
@@ -7720,15 +7965,15 @@ function createSearchProjectDocsTool(deps) {
|
|
|
7720
7965
|
};
|
|
7721
7966
|
}
|
|
7722
7967
|
// src/tools/search-status.ts
|
|
7723
|
-
import { z as
|
|
7724
|
-
var
|
|
7725
|
-
searchRef:
|
|
7968
|
+
import { z as z16 } from "zod";
|
|
7969
|
+
var argsSchema18 = {
|
|
7970
|
+
searchRef: z16.string().min(1).describe("Search reference from a previous incomplete search")
|
|
7726
7971
|
};
|
|
7727
7972
|
function createSearchStatusTool(pkgseerService) {
|
|
7728
7973
|
return {
|
|
7729
7974
|
name: "search_status",
|
|
7730
7975
|
description: "Check the status of an async search and get results if complete. " + "Use after search returns completed=false with a searchRef. Sessions expire after 1 hour. " + "Returns status (PENDING, INDEXING, SEARCHING, COMPLETED, TIMEOUT, FAILED), " + "progress info (packagesReady/packagesTotal), and results when COMPLETED.",
|
|
7731
|
-
schema:
|
|
7976
|
+
schema: argsSchema18,
|
|
7732
7977
|
annotations: { readOnlyHint: true },
|
|
7733
7978
|
handler: async ({ searchRef }, _extra) => {
|
|
7734
7979
|
return withErrorHandling("check search status", async () => {
|
|
@@ -7770,13 +8015,13 @@ function createSearchStatusTool(pkgseerService) {
|
|
|
7770
8015
|
};
|
|
7771
8016
|
}
|
|
7772
8017
|
// src/tools/search-symbols.ts
|
|
7773
|
-
import { z as
|
|
7774
|
-
var
|
|
8018
|
+
import { z as z17 } from "zod";
|
|
8019
|
+
var argsSchema19 = {
|
|
7775
8020
|
target: schemas.codeTarget,
|
|
7776
|
-
query:
|
|
7777
|
-
keywords:
|
|
7778
|
-
match_mode:
|
|
7779
|
-
kind:
|
|
8021
|
+
query: z17.string().max(500).optional().describe("Search query for full-text code search (max 500 chars). Required if keywords not provided."),
|
|
8022
|
+
keywords: z17.array(z17.string()).max(20).optional().describe("Search keywords (max 20). Combined using match_mode. Alternative to query."),
|
|
8023
|
+
match_mode: z17.enum(["or", "and"]).optional().describe("How to combine keywords: or (any match) or and (all must match)"),
|
|
8024
|
+
kind: z17.enum([
|
|
7780
8025
|
"function",
|
|
7781
8026
|
"method",
|
|
7782
8027
|
"class",
|
|
@@ -7785,8 +8030,8 @@ var argsSchema18 = {
|
|
|
7785
8030
|
"type",
|
|
7786
8031
|
"doc_section"
|
|
7787
8032
|
]).optional().describe("Filter results by code chunk type"),
|
|
7788
|
-
file_path:
|
|
7789
|
-
limit:
|
|
8033
|
+
file_path: z17.string().optional().describe("Filter results to files whose path starts with this value (e.g., 'src/' for a directory)"),
|
|
8034
|
+
limit: z17.coerce.number().int().min(1).max(50).optional().describe("Max results to return (max 50)"),
|
|
7790
8035
|
mode: schemas.navigationMode,
|
|
7791
8036
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7792
8037
|
};
|
|
@@ -7794,7 +8039,7 @@ function createSearchSymbolsTool(pkgseerService) {
|
|
|
7794
8039
|
return {
|
|
7795
8040
|
name: "search_symbols",
|
|
7796
8041
|
description: "Search a dependency's source code by text using the code navigation index — " + "find where error messages, exceptions, or patterns appear across functions, classes, and modules. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Supports query string or keyword list with match_mode. " + "Use file_path to filter by directory (e.g., 'src/'). " + "Returns symbol-level results that can feed directly into symbol_callers, symbol_callees, or call_path. " + "Follow up with find_symbol(name=<result.name>, include_code=true) for full source. " + "For free-form text search across multiple packages, use search(mode='code') instead.",
|
|
7797
|
-
schema:
|
|
8042
|
+
schema: argsSchema19,
|
|
7798
8043
|
annotations: { readOnlyHint: true },
|
|
7799
8044
|
handler: async (args, _extra) => {
|
|
7800
8045
|
return withErrorHandling("search symbols", async () => {
|
|
@@ -7819,6 +8064,9 @@ function createSearchSymbolsTool(pkgseerService) {
|
|
|
7819
8064
|
if (graphqlError)
|
|
7820
8065
|
return graphqlError;
|
|
7821
8066
|
const data = result.data.searchSymbols;
|
|
8067
|
+
const indexingError = handleIndexingStatus(data);
|
|
8068
|
+
if (indexingError)
|
|
8069
|
+
return indexingError;
|
|
7822
8070
|
const extra = {};
|
|
7823
8071
|
if (data.results.length === 0 && data.diagnostics?.hint) {
|
|
7824
8072
|
extra._hint = data.diagnostics.hint;
|
|
@@ -7835,13 +8083,13 @@ function createSearchSymbolsTool(pkgseerService) {
|
|
|
7835
8083
|
};
|
|
7836
8084
|
}
|
|
7837
8085
|
// src/tools/symbol-callees.ts
|
|
7838
|
-
import { z as
|
|
7839
|
-
var
|
|
8086
|
+
import { z as z18 } from "zod";
|
|
8087
|
+
var argsSchema20 = {
|
|
7840
8088
|
symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
|
|
7841
|
-
max_depth:
|
|
7842
|
-
limit:
|
|
7843
|
-
include_external:
|
|
7844
|
-
include_builtins:
|
|
8089
|
+
max_depth: z18.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
|
|
8090
|
+
limit: z18.coerce.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
|
|
8091
|
+
include_external: z18.boolean().optional().describe("Include calls to symbols in other indexed packages. " + "Default (false) shows only calls within the same package."),
|
|
8092
|
+
include_builtins: z18.boolean().optional().describe("Include calls to built-in/standard library functions (console, Math, etc.)"),
|
|
7845
8093
|
mode: schemas.navigationMode,
|
|
7846
8094
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7847
8095
|
};
|
|
@@ -7849,7 +8097,7 @@ function createSymbolCalleesTool(pkgseerService) {
|
|
|
7849
8097
|
return {
|
|
7850
8098
|
name: "symbol_callees",
|
|
7851
8099
|
description: "Trace what a function calls internally — " + "understand dependency behavior by following its execution path. " + "Returns direct callees at max_depth=1, or transitive call chains at higher depths. " + "Includes callee names, qualified paths, file locations, call lines, and external package references. " + "Supports package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callers for the reverse.",
|
|
7852
|
-
schema:
|
|
8100
|
+
schema: argsSchema20,
|
|
7853
8101
|
annotations: { readOnlyHint: true },
|
|
7854
8102
|
handler: async (args, _extra) => {
|
|
7855
8103
|
return withErrorHandling("find symbol callees", async () => {
|
|
@@ -7868,18 +8116,22 @@ function createSymbolCalleesTool(pkgseerService) {
|
|
|
7868
8116
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7869
8117
|
if (graphqlError)
|
|
7870
8118
|
return graphqlError;
|
|
7871
|
-
|
|
8119
|
+
const data = result.data.symbolDependencies;
|
|
8120
|
+
const indexingError = handleIndexingStatus(data);
|
|
8121
|
+
if (indexingError)
|
|
8122
|
+
return indexingError;
|
|
8123
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
7872
8124
|
});
|
|
7873
8125
|
}
|
|
7874
8126
|
};
|
|
7875
8127
|
}
|
|
7876
8128
|
// src/tools/symbol-callers.ts
|
|
7877
|
-
import { z as
|
|
7878
|
-
var
|
|
8129
|
+
import { z as z19 } from "zod";
|
|
8130
|
+
var argsSchema21 = {
|
|
7879
8131
|
symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
|
|
7880
|
-
same_package_only:
|
|
7881
|
-
max_depth:
|
|
7882
|
-
limit:
|
|
8132
|
+
same_package_only: z19.boolean().optional().describe("Only return callers from the same package. " + "Default (false) includes callers from other indexed packages."),
|
|
8133
|
+
max_depth: z19.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callers only, 2+ = transitive, max 5)"),
|
|
8134
|
+
limit: z19.coerce.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
|
|
7883
8135
|
mode: schemas.navigationMode,
|
|
7884
8136
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7885
8137
|
};
|
|
@@ -7887,7 +8139,7 @@ function createSymbolCallersTool(pkgseerService) {
|
|
|
7887
8139
|
return {
|
|
7888
8140
|
name: "symbol_callers",
|
|
7889
8141
|
description: "Trace what calls a function in a dependency's source code — " + "find entry points or debug why behavior triggers. " + "Returns callers with file locations and call line numbers. " + "Supports package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "Use same_package_only for within-package callers only. " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callees for the reverse. " + "Use find_symbol(include_code=true) on any caller to read its source.",
|
|
7890
|
-
schema:
|
|
8142
|
+
schema: argsSchema21,
|
|
7891
8143
|
annotations: { readOnlyHint: true },
|
|
7892
8144
|
handler: async (args, _extra) => {
|
|
7893
8145
|
return withErrorHandling("find symbol callers", async () => {
|
|
@@ -7905,32 +8157,36 @@ function createSymbolCallersTool(pkgseerService) {
|
|
|
7905
8157
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7906
8158
|
if (graphqlError)
|
|
7907
8159
|
return graphqlError;
|
|
7908
|
-
|
|
8160
|
+
const data = result.data.symbolDependents;
|
|
8161
|
+
const indexingError = handleIndexingStatus(data);
|
|
8162
|
+
if (indexingError)
|
|
8163
|
+
return indexingError;
|
|
8164
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
7909
8165
|
});
|
|
7910
8166
|
}
|
|
7911
8167
|
};
|
|
7912
8168
|
}
|
|
7913
8169
|
// src/tools/trigger-indexing.ts
|
|
7914
|
-
import { z as
|
|
7915
|
-
var
|
|
8170
|
+
import { z as z20 } from "zod";
|
|
8171
|
+
var packageInputSchema2 = z20.object({
|
|
7916
8172
|
registry: schemas.registry,
|
|
7917
|
-
name:
|
|
7918
|
-
version:
|
|
8173
|
+
name: z20.string().max(255).describe("Package name"),
|
|
8174
|
+
version: z20.string().max(100).optional().describe("Specific version to index")
|
|
7919
8175
|
});
|
|
7920
|
-
var repositoryInputSchema =
|
|
7921
|
-
url:
|
|
7922
|
-
ref:
|
|
7923
|
-
discover_packages:
|
|
8176
|
+
var repositoryInputSchema = z20.object({
|
|
8177
|
+
url: z20.string().max(2000).describe("GitHub repository URL"),
|
|
8178
|
+
ref: z20.string().max(200).optional().describe("Git ref to index (tag, branch, commit). Defaults to HEAD"),
|
|
8179
|
+
discover_packages: z20.boolean().optional().describe("If true, discover packages published from this repo and trigger their metadata fetch")
|
|
7924
8180
|
});
|
|
7925
|
-
var
|
|
7926
|
-
packages:
|
|
7927
|
-
repositories:
|
|
8181
|
+
var argsSchema22 = {
|
|
8182
|
+
packages: z20.array(packageInputSchema2).max(100).optional().describe("Package versions to index (max 100)"),
|
|
8183
|
+
repositories: z20.array(repositoryInputSchema).max(50).optional().describe("Repository URLs to index (max 50)")
|
|
7928
8184
|
};
|
|
7929
8185
|
function createTriggerIndexingTool(pkgseerService) {
|
|
7930
8186
|
return {
|
|
7931
8187
|
name: "trigger_indexing",
|
|
7932
8188
|
description: "Pre-warm PkgSeer indexes by triggering indexing for packages and/or repositories. " + "Fire-and-forget: triggers jobs and returns immediately with accepted/skipped counts. " + "Use before search or doc requests to ensure packages are indexed. " + "Code tools auto-wait via wait_timeout_ms on subsequent calls. Most packages index within 10-30s. " + "Rate limited to 10 requests per minute.",
|
|
7933
|
-
schema:
|
|
8189
|
+
schema: argsSchema22,
|
|
7934
8190
|
annotations: { readOnlyHint: false, idempotentHint: true },
|
|
7935
8191
|
handler: async (args, _extra) => {
|
|
7936
8192
|
return withErrorHandling("trigger indexing", async () => {
|
|
@@ -7968,13 +8224,13 @@ function createTriggerIndexingTool(pkgseerService) {
|
|
|
7968
8224
|
};
|
|
7969
8225
|
}
|
|
7970
8226
|
// src/tools/version-diff.ts
|
|
7971
|
-
import { z as
|
|
7972
|
-
var
|
|
8227
|
+
import { z as z21 } from "zod";
|
|
8228
|
+
var argsSchema23 = {
|
|
7973
8229
|
target: schemas.codeTarget,
|
|
7974
|
-
from_version:
|
|
7975
|
-
to_version:
|
|
7976
|
-
include_private:
|
|
7977
|
-
kind:
|
|
8230
|
+
from_version: z21.string().max(100).describe("Source version (git ref, e.g., 'v4.18.2')"),
|
|
8231
|
+
to_version: z21.string().max(100).describe("Target version (git ref, e.g., 'v5.0.0')"),
|
|
8232
|
+
include_private: z21.boolean().optional().describe("Include private/non-exported symbols in the diff"),
|
|
8233
|
+
kind: z21.enum([
|
|
7978
8234
|
"function",
|
|
7979
8235
|
"method",
|
|
7980
8236
|
"class",
|
|
@@ -7983,14 +8239,14 @@ var argsSchema22 = {
|
|
|
7983
8239
|
"type",
|
|
7984
8240
|
"doc_section"
|
|
7985
8241
|
]).optional().describe("Filter by symbol kind"),
|
|
7986
|
-
limit:
|
|
8242
|
+
limit: z21.coerce.number().int().min(1).max(500).optional().describe("Max changes to return (max 500). Summary always reflects full counts."),
|
|
7987
8243
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7988
8244
|
};
|
|
7989
8245
|
function createVersionDiffTool(pkgseerService) {
|
|
7990
8246
|
return {
|
|
7991
8247
|
name: "version_diff",
|
|
7992
8248
|
description: "Compare two versions of a dependency to understand what changed — " + "use when debugging issues after upgrades or planning migrations. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "With repo scope, from_version and to_version are literal git refs (tags, branches, commits) — " + "the backend does not normalize them. Use target.git_ref=HEAD to identify the repository. " + "Detects added, removed, moved, and modified symbols with severity " + "(breaking, behavior_change, non_breaking, internal). " + "Returns summary counts and per-symbol changes with file locations.",
|
|
7993
|
-
schema:
|
|
8249
|
+
schema: argsSchema23,
|
|
7994
8250
|
annotations: { readOnlyHint: true },
|
|
7995
8251
|
handler: async (args, _extra) => {
|
|
7996
8252
|
return withErrorHandling("version diff", async () => {
|
|
@@ -8009,7 +8265,11 @@ function createVersionDiffTool(pkgseerService) {
|
|
|
8009
8265
|
const graphqlError = handleGraphQLErrors(result.errors);
|
|
8010
8266
|
if (graphqlError)
|
|
8011
8267
|
return graphqlError;
|
|
8012
|
-
|
|
8268
|
+
const data = result.data.versionDiff;
|
|
8269
|
+
const indexingError = handleIndexingStatus(data);
|
|
8270
|
+
if (indexingError)
|
|
8271
|
+
return indexingError;
|
|
8272
|
+
return textResult(JSON.stringify(data, null, 2));
|
|
8013
8273
|
});
|
|
8014
8274
|
}
|
|
8015
8275
|
};
|
|
@@ -8049,7 +8309,7 @@ Data availability — tools are grouped by what backend data they need:
|
|
|
8049
8309
|
3. Code navigation (requires code repo indexing, dual addressing via target):
|
|
8050
8310
|
find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path,
|
|
8051
8311
|
list_imports, version_diff, list_files, grep_file, read_file, search(mode='code')
|
|
8052
|
-
These wait up to wait_timeout_ms (default 10s) for indexing. If indexing takes longer,
|
|
8312
|
+
These wait up to wait_timeout_ms (default 10s) for indexing. If indexing takes longer, the response includes an indexingRef — use indexing_status to poll progress, then retry the original query when status is INDEXED.
|
|
8053
8313
|
|
|
8054
8314
|
Symbol reference tools (symbol_callers, symbol_callees, call_path) accept a symbol object with either:
|
|
8055
8315
|
- symbol_ref from a previous find_symbol/search_symbols result (preferred, fastest)
|
|
@@ -8062,7 +8322,7 @@ Choosing a code search tool:
|
|
|
8062
8322
|
- search(mode='code'): multi-package, full-text → code chunks with snippets
|
|
8063
8323
|
- grep_file: single file, pattern match → when you know the file path
|
|
8064
8324
|
|
|
8065
|
-
Utility: trigger_indexing (pre-warm indexes), search_status (poll async search).
|
|
8325
|
+
Utility: trigger_indexing (pre-warm indexes), search_status (poll async search), indexing_status (poll navigation indexing).
|
|
8066
8326
|
|
|
8067
8327
|
Quick start: find_symbol(target={registry:"npm", package_name:"<pkg>"}, name="<function>", include_code=true) often answers the question in one call.
|
|
8068
8328
|
|
|
@@ -8071,7 +8331,7 @@ Common workflows (pass symbolRef between tools for chaining):
|
|
|
8071
8331
|
- Trace calls: find_symbol → symbol_callees(symbol={symbol_ref: <symbolRef>})
|
|
8072
8332
|
- Find callers: find_symbol → symbol_callers(symbol={symbol_ref: <symbolRef>})
|
|
8073
8333
|
- Read file: read_file(target={registry, package_name}, file_path=<path>) or read_file(target={repo_url, git_ref}, file_path=<path>)
|
|
8074
|
-
- Search code: search_symbols (single pkg, feeds callers/callees) or search(mode='code',
|
|
8334
|
+
- Search code: search_symbols (single pkg, feeds callers/callees) or search(mode='code', targets=[...]) (multi-target)
|
|
8075
8335
|
- Browse docs: list_package_docs → fetch_package_doc(page_id)`;
|
|
8076
8336
|
var TOOL_FACTORIES = {
|
|
8077
8337
|
package_summary: ({ pkgseerService }) => createPackageSummaryTool(pkgseerService),
|
|
@@ -8097,6 +8357,7 @@ var TOOL_FACTORIES = {
|
|
|
8097
8357
|
list_imports: ({ pkgseerService }) => createListImportsTool(pkgseerService),
|
|
8098
8358
|
call_path: ({ pkgseerService }) => createCallPathTool(pkgseerService),
|
|
8099
8359
|
trigger_indexing: ({ pkgseerService }) => createTriggerIndexingTool(pkgseerService),
|
|
8360
|
+
indexing_status: ({ pkgseerService }) => createIndexingStatusTool(pkgseerService),
|
|
8100
8361
|
list_files: ({ pkgseerService }) => createListFilesTool(pkgseerService),
|
|
8101
8362
|
grep_file: ({ pkgseerService }) => createGrepFileTool(pkgseerService),
|
|
8102
8363
|
version_diff: ({ pkgseerService }) => createVersionDiffTool(pkgseerService)
|
|
@@ -8120,6 +8381,7 @@ var PUBLIC_READ_TOOLS = [
|
|
|
8120
8381
|
"list_imports",
|
|
8121
8382
|
"call_path",
|
|
8122
8383
|
"trigger_indexing",
|
|
8384
|
+
"indexing_status",
|
|
8123
8385
|
"list_files",
|
|
8124
8386
|
"grep_file",
|
|
8125
8387
|
"version_diff"
|
|
@@ -8188,19 +8450,20 @@ function showMcpSetupInstructions(deps) {
|
|
|
8188
8450
|
console.log("Alternative: Use CLI directly (no MCP setup needed)");
|
|
8189
8451
|
console.log(` ${highlight("pkgseer pkg info <package>", useColors)}`);
|
|
8190
8452
|
}
|
|
8191
|
-
|
|
8192
|
-
const mcpCommand = program.command("mcp").summary("Show setup instructions or start MCP server").description(`Start the Model Context Protocol (MCP) server using STDIO transport.
|
|
8453
|
+
var MCP_COMMAND_DESCRIPTION = `Start the Model Context Protocol (MCP) server using STDIO transport.
|
|
8193
8454
|
|
|
8194
8455
|
When run interactively (TTY), shows setup instructions.
|
|
8195
8456
|
When run via stdio (non-TTY), starts the MCP server.
|
|
8196
8457
|
|
|
8197
|
-
Available tools (
|
|
8458
|
+
Available tools (23):
|
|
8198
8459
|
Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
|
|
8199
8460
|
Browse files: list_files, grep_file, read_file
|
|
8200
8461
|
Search: search, search_project_docs
|
|
8201
8462
|
Docs: list_package_docs, fetch_package_doc
|
|
8202
8463
|
Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
|
|
8203
|
-
Utility: trigger_indexing, search_status, list_imports
|
|
8464
|
+
Utility: trigger_indexing, indexing_status, search_status, list_imports`;
|
|
8465
|
+
function registerMcpCommand(program) {
|
|
8466
|
+
const mcpCommand = program.command("mcp").summary("Show setup instructions or start MCP server").description(MCP_COMMAND_DESCRIPTION).action(async () => {
|
|
8204
8467
|
const deps = await createContainer();
|
|
8205
8468
|
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
8206
8469
|
showMcpSetupInstructions(deps);
|
package/dist/index.js
CHANGED