@pkgseer/cli 0.4.1 → 0.4.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 +631 -95
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-d340pysc.js → chunk-w4ht5me5.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-w4ht5me5.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -689,12 +689,15 @@ var FindSymbolDocument = gql`
|
|
|
689
689
|
}
|
|
690
690
|
`;
|
|
691
691
|
var SearchSymbolsDocument = gql`
|
|
692
|
-
query SearchSymbols($registry: Registry!, $packageName: String!, $query: String
|
|
692
|
+
query SearchSymbols($registry: Registry!, $packageName: String!, $query: String, $keywords: [String!], $matchMode: MatchMode, $kind: SymbolKind, $filePath: String, $version: String, $limit: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
|
|
693
693
|
searchSymbols(
|
|
694
694
|
registry: $registry
|
|
695
695
|
packageName: $packageName
|
|
696
696
|
query: $query
|
|
697
|
+
keywords: $keywords
|
|
698
|
+
matchMode: $matchMode
|
|
697
699
|
kind: $kind
|
|
700
|
+
filePath: $filePath
|
|
698
701
|
version: $version
|
|
699
702
|
limit: $limit
|
|
700
703
|
mode: $mode
|
|
@@ -708,11 +711,25 @@ var SearchSymbolsDocument = gql`
|
|
|
708
711
|
endLine
|
|
709
712
|
preview
|
|
710
713
|
contentPreview
|
|
714
|
+
code
|
|
711
715
|
language
|
|
716
|
+
symbolId
|
|
717
|
+
qualifiedPath
|
|
718
|
+
kind
|
|
719
|
+
arity
|
|
720
|
+
isPublic
|
|
721
|
+
containedSymbols
|
|
712
722
|
}
|
|
713
723
|
totalMatches
|
|
714
724
|
hasMore
|
|
715
725
|
indexedVersion
|
|
726
|
+
diagnostics {
|
|
727
|
+
indexed
|
|
728
|
+
chunkCount
|
|
729
|
+
fileCount
|
|
730
|
+
indexedAt
|
|
731
|
+
hint
|
|
732
|
+
}
|
|
716
733
|
}
|
|
717
734
|
}
|
|
718
735
|
`;
|
|
@@ -913,6 +930,112 @@ var SearchProjectDocsDocument = gql`
|
|
|
913
930
|
}
|
|
914
931
|
}
|
|
915
932
|
`;
|
|
933
|
+
var ListRepoFilesDocument = gql`
|
|
934
|
+
query ListRepoFiles($registry: Registry!, $packageName: String!, $version: String, $pathPrefix: String, $limit: Int, $waitTimeoutMs: Int) {
|
|
935
|
+
listRepoFiles(
|
|
936
|
+
registry: $registry
|
|
937
|
+
packageName: $packageName
|
|
938
|
+
version: $version
|
|
939
|
+
pathPrefix: $pathPrefix
|
|
940
|
+
limit: $limit
|
|
941
|
+
waitTimeoutMs: $waitTimeoutMs
|
|
942
|
+
) {
|
|
943
|
+
files {
|
|
944
|
+
path
|
|
945
|
+
name
|
|
946
|
+
language
|
|
947
|
+
fileType
|
|
948
|
+
byteSize
|
|
949
|
+
}
|
|
950
|
+
total
|
|
951
|
+
hasMore
|
|
952
|
+
indexedVersion
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
`;
|
|
956
|
+
var GrepRepoFileDocument = gql`
|
|
957
|
+
query GrepRepoFile($registry: Registry!, $packageName: String!, $filePath: String!, $pattern: String!, $contextLines: Int, $maxMatches: Int, $version: String, $waitTimeoutMs: Int) {
|
|
958
|
+
grepRepoFile(
|
|
959
|
+
registry: $registry
|
|
960
|
+
packageName: $packageName
|
|
961
|
+
filePath: $filePath
|
|
962
|
+
pattern: $pattern
|
|
963
|
+
contextLines: $contextLines
|
|
964
|
+
maxMatches: $maxMatches
|
|
965
|
+
version: $version
|
|
966
|
+
waitTimeoutMs: $waitTimeoutMs
|
|
967
|
+
) {
|
|
968
|
+
matches {
|
|
969
|
+
lineNumber
|
|
970
|
+
lineContent
|
|
971
|
+
contextBefore
|
|
972
|
+
contextAfter
|
|
973
|
+
}
|
|
974
|
+
totalMatches
|
|
975
|
+
hasMore
|
|
976
|
+
filePath
|
|
977
|
+
language
|
|
978
|
+
totalLines
|
|
979
|
+
indexedVersion
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
`;
|
|
983
|
+
var VersionDiffDocument = gql`
|
|
984
|
+
query VersionDiff($registry: Registry!, $packageName: String!, $fromVersion: String!, $toVersion: String!, $includePrivate: Boolean, $kind: SymbolKind, $limit: Int, $waitTimeoutMs: Int) {
|
|
985
|
+
versionDiff(
|
|
986
|
+
registry: $registry
|
|
987
|
+
packageName: $packageName
|
|
988
|
+
fromVersion: $fromVersion
|
|
989
|
+
toVersion: $toVersion
|
|
990
|
+
includePrivate: $includePrivate
|
|
991
|
+
kind: $kind
|
|
992
|
+
limit: $limit
|
|
993
|
+
waitTimeoutMs: $waitTimeoutMs
|
|
994
|
+
) {
|
|
995
|
+
fromVersion
|
|
996
|
+
toVersion
|
|
997
|
+
summary {
|
|
998
|
+
added
|
|
999
|
+
removed
|
|
1000
|
+
moved
|
|
1001
|
+
modified
|
|
1002
|
+
unchanged
|
|
1003
|
+
breaking
|
|
1004
|
+
behaviorChange
|
|
1005
|
+
}
|
|
1006
|
+
changes {
|
|
1007
|
+
qualifiedPath
|
|
1008
|
+
kind
|
|
1009
|
+
arity
|
|
1010
|
+
name
|
|
1011
|
+
changeType
|
|
1012
|
+
severity
|
|
1013
|
+
changedFields
|
|
1014
|
+
from {
|
|
1015
|
+
contentHash
|
|
1016
|
+
filePath
|
|
1017
|
+
arity
|
|
1018
|
+
startLine
|
|
1019
|
+
endLine
|
|
1020
|
+
isPublic
|
|
1021
|
+
minArity
|
|
1022
|
+
symbolId
|
|
1023
|
+
}
|
|
1024
|
+
to {
|
|
1025
|
+
contentHash
|
|
1026
|
+
filePath
|
|
1027
|
+
arity
|
|
1028
|
+
startLine
|
|
1029
|
+
endLine
|
|
1030
|
+
isPublic
|
|
1031
|
+
minArity
|
|
1032
|
+
symbolId
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
hasMore
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
`;
|
|
916
1039
|
var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
|
|
917
1040
|
var CliPackageInfoDocumentString = print(CliPackageInfoDocument);
|
|
918
1041
|
var CliPackageVulnsDocumentString = print(CliPackageVulnsDocument);
|
|
@@ -946,6 +1069,9 @@ var SymbolDependentsDocumentString = print(SymbolDependentsDocument);
|
|
|
946
1069
|
var PackageImportsDocumentString = print(PackageImportsDocument);
|
|
947
1070
|
var CallPathDocumentString = print(CallPathDocument);
|
|
948
1071
|
var SearchProjectDocsDocumentString = print(SearchProjectDocsDocument);
|
|
1072
|
+
var ListRepoFilesDocumentString = print(ListRepoFilesDocument);
|
|
1073
|
+
var GrepRepoFileDocumentString = print(GrepRepoFileDocument);
|
|
1074
|
+
var VersionDiffDocumentString = print(VersionDiffDocument);
|
|
949
1075
|
function getSdk(client, withWrapper = defaultWrapper) {
|
|
950
1076
|
return {
|
|
951
1077
|
CliPackageInfo(variables, requestHeaders) {
|
|
@@ -1043,6 +1169,15 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
1043
1169
|
},
|
|
1044
1170
|
SearchProjectDocs(variables, requestHeaders) {
|
|
1045
1171
|
return withWrapper((wrappedRequestHeaders) => client.rawRequest(SearchProjectDocsDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "SearchProjectDocs", "query", variables);
|
|
1172
|
+
},
|
|
1173
|
+
ListRepoFiles(variables, requestHeaders) {
|
|
1174
|
+
return withWrapper((wrappedRequestHeaders) => client.rawRequest(ListRepoFilesDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "ListRepoFiles", "query", variables);
|
|
1175
|
+
},
|
|
1176
|
+
GrepRepoFile(variables, requestHeaders) {
|
|
1177
|
+
return withWrapper((wrappedRequestHeaders) => client.rawRequest(GrepRepoFileDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "GrepRepoFile", "query", variables);
|
|
1178
|
+
},
|
|
1179
|
+
VersionDiff(variables, requestHeaders) {
|
|
1180
|
+
return withWrapper((wrappedRequestHeaders) => client.rawRequest(VersionDiffDocumentString, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "VersionDiff", "query", variables);
|
|
1046
1181
|
}
|
|
1047
1182
|
};
|
|
1048
1183
|
}
|
|
@@ -1381,7 +1516,10 @@ var TOOL_NAMES = [
|
|
|
1381
1516
|
"symbol_callees",
|
|
1382
1517
|
"package_imports",
|
|
1383
1518
|
"call_path",
|
|
1384
|
-
"trigger_indexing"
|
|
1519
|
+
"trigger_indexing",
|
|
1520
|
+
"list_repo_files",
|
|
1521
|
+
"grep_repo_file",
|
|
1522
|
+
"version_diff"
|
|
1385
1523
|
];
|
|
1386
1524
|
var ToolNameSchema = z.enum(TOOL_NAMES);
|
|
1387
1525
|
var SharedConfigFields = {
|
|
@@ -1820,12 +1958,15 @@ class PkgseerServiceImpl {
|
|
|
1820
1958
|
});
|
|
1821
1959
|
return { data: result.data, errors: result.errors };
|
|
1822
1960
|
}
|
|
1823
|
-
async searchSymbols(registry, packageName,
|
|
1961
|
+
async searchSymbols(registry, packageName, options) {
|
|
1824
1962
|
const result = await this.client.SearchSymbols({
|
|
1825
1963
|
registry,
|
|
1826
1964
|
packageName,
|
|
1827
|
-
query,
|
|
1965
|
+
query: options?.query,
|
|
1966
|
+
keywords: options?.keywords,
|
|
1967
|
+
matchMode: options?.matchMode,
|
|
1828
1968
|
kind: options?.kind,
|
|
1969
|
+
filePath: options?.filePath,
|
|
1829
1970
|
version: options?.version,
|
|
1830
1971
|
limit: options?.limit,
|
|
1831
1972
|
mode: options?.mode,
|
|
@@ -1894,6 +2035,43 @@ class PkgseerServiceImpl {
|
|
|
1894
2035
|
});
|
|
1895
2036
|
return { data: result.data, errors: result.errors };
|
|
1896
2037
|
}
|
|
2038
|
+
async listRepoFiles(registry, packageName, options) {
|
|
2039
|
+
const result = await this.client.ListRepoFiles({
|
|
2040
|
+
registry,
|
|
2041
|
+
packageName,
|
|
2042
|
+
version: options?.version,
|
|
2043
|
+
pathPrefix: options?.pathPrefix,
|
|
2044
|
+
limit: options?.limit,
|
|
2045
|
+
waitTimeoutMs: options?.waitTimeoutMs
|
|
2046
|
+
});
|
|
2047
|
+
return { data: result.data, errors: result.errors };
|
|
2048
|
+
}
|
|
2049
|
+
async grepRepoFile(registry, packageName, filePath, pattern, options) {
|
|
2050
|
+
const result = await this.client.GrepRepoFile({
|
|
2051
|
+
registry,
|
|
2052
|
+
packageName,
|
|
2053
|
+
filePath,
|
|
2054
|
+
pattern,
|
|
2055
|
+
contextLines: options?.contextLines,
|
|
2056
|
+
maxMatches: options?.maxMatches,
|
|
2057
|
+
version: options?.version,
|
|
2058
|
+
waitTimeoutMs: options?.waitTimeoutMs
|
|
2059
|
+
});
|
|
2060
|
+
return { data: result.data, errors: result.errors };
|
|
2061
|
+
}
|
|
2062
|
+
async versionDiff(registry, packageName, fromVersion, toVersion, options) {
|
|
2063
|
+
const result = await this.client.VersionDiff({
|
|
2064
|
+
registry,
|
|
2065
|
+
packageName,
|
|
2066
|
+
fromVersion,
|
|
2067
|
+
toVersion,
|
|
2068
|
+
includePrivate: options?.includePrivate,
|
|
2069
|
+
kind: options?.kind,
|
|
2070
|
+
limit: options?.limit,
|
|
2071
|
+
waitTimeoutMs: options?.waitTimeoutMs
|
|
2072
|
+
});
|
|
2073
|
+
return { data: result.data, errors: result.errors };
|
|
2074
|
+
}
|
|
1897
2075
|
async triggerIndexing(input) {
|
|
1898
2076
|
const result = await this.client.TriggerIndexing({ input });
|
|
1899
2077
|
return { data: result.data, errors: result.errors };
|
|
@@ -2599,6 +2777,138 @@ function registerCodeCallersCommand(program) {
|
|
|
2599
2777
|
});
|
|
2600
2778
|
});
|
|
2601
2779
|
}
|
|
2780
|
+
// src/commands/code/diff.ts
|
|
2781
|
+
function formatDiffResult(data) {
|
|
2782
|
+
const lines = [];
|
|
2783
|
+
lines.push(`Version diff: ${data.fromVersion} → ${data.toVersion}`);
|
|
2784
|
+
lines.push("");
|
|
2785
|
+
const s = data.summary;
|
|
2786
|
+
lines.push("Summary:");
|
|
2787
|
+
lines.push(` Added: ${s.added} Removed: ${s.removed} Modified: ${s.modified} Moved: ${s.moved}`);
|
|
2788
|
+
lines.push(` Unchanged: ${s.unchanged} Breaking: ${s.breaking} Behavior changes: ${s.behaviorChange}`);
|
|
2789
|
+
if (data.hasMore) {
|
|
2790
|
+
lines.push(" (more changes available, increase --limit)");
|
|
2791
|
+
}
|
|
2792
|
+
lines.push("");
|
|
2793
|
+
for (const change of data.changes) {
|
|
2794
|
+
const severity = change.severity ? ` [${change.severity}]` : "";
|
|
2795
|
+
const kindLabel = change.kind ? `[${change.kind}]` : "";
|
|
2796
|
+
const name = change.qualifiedPath ?? change.name ?? "unknown";
|
|
2797
|
+
lines.push(`${change.changeType}${severity} ${kindLabel} ${name}`.trim());
|
|
2798
|
+
if (change.from?.filePath) {
|
|
2799
|
+
const loc = change.from.startLine ? `${change.from.filePath}:${change.from.startLine}` : change.from.filePath;
|
|
2800
|
+
lines.push(` From: ${loc}`);
|
|
2801
|
+
}
|
|
2802
|
+
if (change.to?.filePath) {
|
|
2803
|
+
const loc = change.to.startLine ? `${change.to.filePath}:${change.to.startLine}` : change.to.filePath;
|
|
2804
|
+
lines.push(` To: ${loc}`);
|
|
2805
|
+
}
|
|
2806
|
+
if (change.changedFields?.length) {
|
|
2807
|
+
lines.push(` Changed: ${change.changedFields.join(", ")}`);
|
|
2808
|
+
}
|
|
2809
|
+
lines.push("");
|
|
2810
|
+
}
|
|
2811
|
+
return lines.join(`
|
|
2812
|
+
`).trimEnd();
|
|
2813
|
+
}
|
|
2814
|
+
async function codeDiffAction(packageArg, fromVersion, toVersion, options, deps) {
|
|
2815
|
+
const { pkgseerService } = deps;
|
|
2816
|
+
const parsed = parsePackageSpec(packageArg);
|
|
2817
|
+
const registry = toGraphQLRegistry(parsed.registry);
|
|
2818
|
+
const result = await pkgseerService.versionDiff(registry, parsed.name, fromVersion, toVersion, {
|
|
2819
|
+
includePrivate: options.includePrivate,
|
|
2820
|
+
kind: options.kind?.toUpperCase(),
|
|
2821
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
2822
|
+
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
2823
|
+
});
|
|
2824
|
+
handleErrors(result.errors, options.json ?? false);
|
|
2825
|
+
if (!result.data.versionDiff) {
|
|
2826
|
+
outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
if (options.json) {
|
|
2830
|
+
output(result.data.versionDiff, true);
|
|
2831
|
+
} else {
|
|
2832
|
+
console.log(formatDiffResult(result.data.versionDiff));
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
var DIFF_DESCRIPTION = `Compare symbols between two package versions.
|
|
2836
|
+
|
|
2837
|
+
Detects added, removed, moved, and modified symbols with severity classification.
|
|
2838
|
+
Returns summary counts and per-symbol changes with file locations.
|
|
2839
|
+
|
|
2840
|
+
Examples:
|
|
2841
|
+
pkgseer code diff npm:express v4.18.2 v5.0.0
|
|
2842
|
+
pkgseer code diff npm:lodash 4.17.20 4.17.21 --include-private
|
|
2843
|
+
pkgseer code diff pypi:requests 2.30.0 2.31.0 --kind function`;
|
|
2844
|
+
function registerCodeDiffCommand(program) {
|
|
2845
|
+
program.command("diff <package> <from> <to>").summary("Compare symbols between versions").description(DIFF_DESCRIPTION).option("--include-private", "Include private/non-exported symbols").option("--kind <kind>", "Filter by symbol kind").option("--limit <n>", "Max changes to return (max 500)").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (packageArg, fromVersion, toVersion, options) => {
|
|
2846
|
+
await withCliErrorHandling(options.json ?? false, async () => {
|
|
2847
|
+
const deps = await createContainer();
|
|
2848
|
+
await codeDiffAction(packageArg, fromVersion, toVersion, options, deps);
|
|
2849
|
+
});
|
|
2850
|
+
});
|
|
2851
|
+
}
|
|
2852
|
+
// src/commands/code/files.ts
|
|
2853
|
+
function formatFilesResult(data) {
|
|
2854
|
+
const lines = [];
|
|
2855
|
+
lines.push(`${data.total} file(s)${data.hasMore ? " (more available)" : ""}`);
|
|
2856
|
+
if (data.indexedVersion) {
|
|
2857
|
+
lines.push(`Indexed version: ${data.indexedVersion}`);
|
|
2858
|
+
}
|
|
2859
|
+
lines.push("");
|
|
2860
|
+
for (const file of data.files) {
|
|
2861
|
+
const meta = [];
|
|
2862
|
+
if (file.language)
|
|
2863
|
+
meta.push(file.language);
|
|
2864
|
+
if (file.fileType)
|
|
2865
|
+
meta.push(file.fileType);
|
|
2866
|
+
if (file.byteSize != null)
|
|
2867
|
+
meta.push(`${file.byteSize}B`);
|
|
2868
|
+
const suffix = meta.length > 0 ? ` (${meta.join(", ")})` : "";
|
|
2869
|
+
lines.push(`${file.path}${suffix}`);
|
|
2870
|
+
}
|
|
2871
|
+
return lines.join(`
|
|
2872
|
+
`).trimEnd();
|
|
2873
|
+
}
|
|
2874
|
+
async function codeFilesAction(packageArg, options, deps) {
|
|
2875
|
+
const { pkgseerService } = deps;
|
|
2876
|
+
const parsed = parsePackageSpec(packageArg);
|
|
2877
|
+
const registry = toGraphQLRegistry(parsed.registry);
|
|
2878
|
+
const result = await pkgseerService.listRepoFiles(registry, parsed.name, {
|
|
2879
|
+
version: parsed.version,
|
|
2880
|
+
pathPrefix: options.pathPrefix,
|
|
2881
|
+
limit: parseIntOption(options.limit, "--limit"),
|
|
2882
|
+
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
2883
|
+
});
|
|
2884
|
+
handleErrors(result.errors, options.json ?? false);
|
|
2885
|
+
if (!result.data.listRepoFiles) {
|
|
2886
|
+
outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
|
|
2887
|
+
return;
|
|
2888
|
+
}
|
|
2889
|
+
if (options.json) {
|
|
2890
|
+
output(result.data.listRepoFiles, true);
|
|
2891
|
+
} else {
|
|
2892
|
+
console.log(formatFilesResult(result.data.listRepoFiles));
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
var FILES_DESCRIPTION = `List files in a package's indexed repository.
|
|
2896
|
+
|
|
2897
|
+
Returns file paths, names, languages, types, and sizes.
|
|
2898
|
+
Use --path-prefix to filter by directory.
|
|
2899
|
+
|
|
2900
|
+
Examples:
|
|
2901
|
+
pkgseer code files npm:express
|
|
2902
|
+
pkgseer code files npm:express --path-prefix src/
|
|
2903
|
+
pkgseer code files pypi:requests --limit 50`;
|
|
2904
|
+
function registerCodeFilesCommand(program) {
|
|
2905
|
+
program.command("files <package>").summary("List files in package repository").description(FILES_DESCRIPTION).option("--path-prefix <prefix>", "Filter to files under this path").option("--limit <n>", "Max files to return (max 1000)").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (packageArg, options) => {
|
|
2906
|
+
await withCliErrorHandling(options.json ?? false, async () => {
|
|
2907
|
+
const deps = await createContainer();
|
|
2908
|
+
await codeFilesAction(packageArg, options, deps);
|
|
2909
|
+
});
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2602
2912
|
// src/commands/code/find.ts
|
|
2603
2913
|
function formatFindResult(data) {
|
|
2604
2914
|
const lines = [];
|
|
@@ -2658,6 +2968,72 @@ function registerCodeFindCommand(program) {
|
|
|
2658
2968
|
});
|
|
2659
2969
|
});
|
|
2660
2970
|
}
|
|
2971
|
+
// src/commands/code/grep.ts
|
|
2972
|
+
function formatGrepResult(data) {
|
|
2973
|
+
const lines = [];
|
|
2974
|
+
lines.push(`${data.totalMatches} match(es) in ${data.filePath ?? "unknown"}${data.hasMore ? " (more available)" : ""}`);
|
|
2975
|
+
if (data.language)
|
|
2976
|
+
lines.push(`Language: ${data.language}`);
|
|
2977
|
+
if (data.totalLines != null)
|
|
2978
|
+
lines.push(`Total lines: ${data.totalLines}`);
|
|
2979
|
+
if (data.indexedVersion)
|
|
2980
|
+
lines.push(`Indexed version: ${data.indexedVersion}`);
|
|
2981
|
+
lines.push("");
|
|
2982
|
+
for (const match of data.matches) {
|
|
2983
|
+
if (match.contextBefore) {
|
|
2984
|
+
for (const line of match.contextBefore) {
|
|
2985
|
+
lines.push(` ${line}`);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
lines.push(`${match.lineNumber}: ${match.lineContent}`);
|
|
2989
|
+
if (match.contextAfter) {
|
|
2990
|
+
for (const line of match.contextAfter) {
|
|
2991
|
+
lines.push(` ${line}`);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
lines.push("");
|
|
2995
|
+
}
|
|
2996
|
+
return lines.join(`
|
|
2997
|
+
`).trimEnd();
|
|
2998
|
+
}
|
|
2999
|
+
async function codeGrepAction(packageArg, filePath, pattern, options, deps) {
|
|
3000
|
+
const { pkgseerService } = deps;
|
|
3001
|
+
const parsed = parsePackageSpec(packageArg);
|
|
3002
|
+
const registry = toGraphQLRegistry(parsed.registry);
|
|
3003
|
+
const result = await pkgseerService.grepRepoFile(registry, parsed.name, filePath, pattern, {
|
|
3004
|
+
contextLines: parseIntOption(options.contextLines, "--context-lines"),
|
|
3005
|
+
maxMatches: parseIntOption(options.maxMatches, "--max-matches"),
|
|
3006
|
+
version: parsed.version,
|
|
3007
|
+
waitTimeoutMs: parseWaitTimeout(options.wait)
|
|
3008
|
+
});
|
|
3009
|
+
handleErrors(result.errors, options.json ?? false);
|
|
3010
|
+
if (!result.data.grepRepoFile) {
|
|
3011
|
+
outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
if (options.json) {
|
|
3015
|
+
output(result.data.grepRepoFile, true);
|
|
3016
|
+
} else {
|
|
3017
|
+
console.log(formatGrepResult(result.data.grepRepoFile));
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
var GREP_DESCRIPTION = `Search for a pattern within a file in a package's repository.
|
|
3021
|
+
|
|
3022
|
+
Case-insensitive substring matching. Returns matching lines with context.
|
|
3023
|
+
Use 'code files' to discover available file paths.
|
|
3024
|
+
|
|
3025
|
+
Examples:
|
|
3026
|
+
pkgseer code grep npm:express "lib/router/index.js" "middleware"
|
|
3027
|
+
pkgseer code grep pypi:requests "requests/api.py" "timeout" --context-lines 3
|
|
3028
|
+
pkgseer code grep npm:lodash "lodash.js" "cloneDeep" --max-matches 5`;
|
|
3029
|
+
function registerCodeGrepCommand(program) {
|
|
3030
|
+
program.command("grep <package> <file> <pattern>").summary("Search for pattern in a package file").description(GREP_DESCRIPTION).option("--context-lines <n>", "Lines of context around each match (max 10)").option("--max-matches <n>", "Maximum matches to return (max 200)").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (packageArg, filePath, pattern, options) => {
|
|
3031
|
+
await withCliErrorHandling(options.json ?? false, async () => {
|
|
3032
|
+
const deps = await createContainer();
|
|
3033
|
+
await codeGrepAction(packageArg, filePath, pattern, options, deps);
|
|
3034
|
+
});
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
2661
3037
|
// src/commands/code/imports.ts
|
|
2662
3038
|
function formatImport(entry) {
|
|
2663
3039
|
const parts = [];
|
|
@@ -2899,12 +3275,29 @@ function formatSearchResult(data) {
|
|
|
2899
3275
|
return lines.join(`
|
|
2900
3276
|
`).trimEnd();
|
|
2901
3277
|
}
|
|
3278
|
+
function parseMatchMode(mode) {
|
|
3279
|
+
if (!mode)
|
|
3280
|
+
return;
|
|
3281
|
+
const upper = mode.toUpperCase();
|
|
3282
|
+
if (upper === "OR" || upper === "AND")
|
|
3283
|
+
return upper;
|
|
3284
|
+
throw new Error("--match-mode must be 'or' or 'and'");
|
|
3285
|
+
}
|
|
2902
3286
|
async function codeSearchAction(packageArg, query, options, deps) {
|
|
2903
3287
|
const { pkgseerService } = deps;
|
|
2904
3288
|
const parsed = parsePackageSpec(packageArg);
|
|
2905
3289
|
const registry = toGraphQLRegistry(parsed.registry);
|
|
2906
|
-
const
|
|
3290
|
+
const keywords = options.keywords ? options.keywords.split(",").map((k) => k.trim()).filter(Boolean) : undefined;
|
|
3291
|
+
if (!query && !keywords?.length) {
|
|
3292
|
+
outputError("Either a query argument or --keywords must be provided", options.json ?? false);
|
|
3293
|
+
return;
|
|
3294
|
+
}
|
|
3295
|
+
const result = await pkgseerService.searchSymbols(registry, parsed.name, {
|
|
3296
|
+
query: query || undefined,
|
|
3297
|
+
keywords,
|
|
3298
|
+
matchMode: parseMatchMode(options.matchMode),
|
|
2907
3299
|
kind: options.kind?.toUpperCase(),
|
|
3300
|
+
filePath: options.filePath,
|
|
2908
3301
|
version: parsed.version,
|
|
2909
3302
|
limit: parseIntOption(options.limit, "--limit"),
|
|
2910
3303
|
mode: parseNavigationMode(options.mode),
|
|
@@ -2924,14 +3317,16 @@ async function codeSearchAction(packageArg, query, options, deps) {
|
|
|
2924
3317
|
var SEARCH_DESCRIPTION = `Full-text search within package code.
|
|
2925
3318
|
|
|
2926
3319
|
Searches across functions, classes, modules, and doc sections.
|
|
3320
|
+
Supports query string or keyword list with match mode.
|
|
2927
3321
|
Returns matching code chunks with names, types, and previews.
|
|
2928
3322
|
|
|
2929
3323
|
Examples:
|
|
2930
3324
|
pkgseer code search npm:express "middleware"
|
|
2931
3325
|
pkgseer code search pypi:requests "timeout" --kind function
|
|
2932
|
-
pkgseer code search npm:lodash "deep
|
|
3326
|
+
pkgseer code search npm:lodash --keywords "deep,clone" --match-mode and
|
|
3327
|
+
pkgseer code search npm:express "router" --file-path src/`;
|
|
2933
3328
|
function registerCodeSearchCommand(program) {
|
|
2934
|
-
program.command("search <package>
|
|
3329
|
+
program.command("search <package> [query]").summary("Full-text search in package code").description(SEARCH_DESCRIPTION).option("--kind <kind>", "Filter by chunk type (function, class, module, etc.)").option("--limit <n>", "Max results (default: 25, max: 50)").option("--keywords <words>", "Comma-separated keywords (alternative to query)").option("--match-mode <mode>", "How to combine keywords: or (any) or and (all)").option("--file-path <prefix>", "Filter to files matching path prefix").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (packageArg, query, options) => {
|
|
2935
3330
|
await withCliErrorHandling(options.json ?? false, async () => {
|
|
2936
3331
|
const deps = await createContainer();
|
|
2937
3332
|
await codeSearchAction(packageArg, query, options, deps);
|
|
@@ -6006,6 +6401,14 @@ function toSymbolKind(kind) {
|
|
|
6006
6401
|
return upper;
|
|
6007
6402
|
return;
|
|
6008
6403
|
}
|
|
6404
|
+
function toMatchMode(mode) {
|
|
6405
|
+
if (!mode)
|
|
6406
|
+
return;
|
|
6407
|
+
const upper = mode.toUpperCase();
|
|
6408
|
+
if (upper === "OR" || upper === "AND")
|
|
6409
|
+
return upper;
|
|
6410
|
+
return;
|
|
6411
|
+
}
|
|
6009
6412
|
function toListScope(scope) {
|
|
6010
6413
|
if (!scope)
|
|
6011
6414
|
return;
|
|
@@ -6252,8 +6655,44 @@ function createFindSymbolTool(pkgseerService) {
|
|
|
6252
6655
|
}
|
|
6253
6656
|
};
|
|
6254
6657
|
}
|
|
6255
|
-
// src/tools/
|
|
6658
|
+
// src/tools/grep-repo-file.ts
|
|
6659
|
+
import { z as z8 } from "zod";
|
|
6256
6660
|
var argsSchema6 = {
|
|
6661
|
+
registry: schemas.registry,
|
|
6662
|
+
package_name: schemas.packageName.describe("Name of the package to search within"),
|
|
6663
|
+
file_path: z8.string().describe("Path to the file (relative to package root)"),
|
|
6664
|
+
pattern: z8.string().max(200).describe("Case-insensitive substring to search for (max 200 chars)"),
|
|
6665
|
+
context_lines: z8.number().int().min(0).max(10).optional().describe("Lines of context around each match (max 10)"),
|
|
6666
|
+
max_matches: z8.number().int().min(1).max(200).optional().describe("Maximum matches to return (max 200)"),
|
|
6667
|
+
version: schemas.version,
|
|
6668
|
+
wait_timeout_ms: schemas.waitTimeoutMs
|
|
6669
|
+
};
|
|
6670
|
+
function createGrepRepoFileTool(pkgseerService) {
|
|
6671
|
+
return {
|
|
6672
|
+
name: "grep_repo_file",
|
|
6673
|
+
description: "Search for a pattern within a file in a package's repository. " + "Case-insensitive substring matching. Returns matching lines with context. " + "Faster than fetch_code_context for large files. " + "Use list_repo_files to discover available file paths.",
|
|
6674
|
+
schema: argsSchema6,
|
|
6675
|
+
handler: async (args, _extra) => {
|
|
6676
|
+
return withErrorHandling("grep repo file", async () => {
|
|
6677
|
+
const result = await pkgseerService.grepRepoFile(toGraphQLRegistry2(args.registry), args.package_name, args.file_path, args.pattern, {
|
|
6678
|
+
contextLines: args.context_lines,
|
|
6679
|
+
maxMatches: args.max_matches,
|
|
6680
|
+
version: args.version,
|
|
6681
|
+
waitTimeoutMs: args.wait_timeout_ms
|
|
6682
|
+
});
|
|
6683
|
+
const graphqlError = handleGraphQLErrors(result.errors);
|
|
6684
|
+
if (graphqlError)
|
|
6685
|
+
return graphqlError;
|
|
6686
|
+
if (!result.data.grepRepoFile) {
|
|
6687
|
+
return notFoundError(args.package_name, args.registry);
|
|
6688
|
+
}
|
|
6689
|
+
return textResult(JSON.stringify(result.data.grepRepoFile, null, 2));
|
|
6690
|
+
});
|
|
6691
|
+
}
|
|
6692
|
+
};
|
|
6693
|
+
}
|
|
6694
|
+
// src/tools/list-package-docs.ts
|
|
6695
|
+
var argsSchema7 = {
|
|
6257
6696
|
registry: schemas.registry,
|
|
6258
6697
|
package_name: schemas.packageName.describe("Name of the package to list documentation for"),
|
|
6259
6698
|
version: schemas.version
|
|
@@ -6262,7 +6701,7 @@ function createListPackageDocsTool(pkgseerService) {
|
|
|
6262
6701
|
return {
|
|
6263
6702
|
name: "list_package_docs",
|
|
6264
6703
|
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_package_docs to find specific topics.",
|
|
6265
|
-
schema:
|
|
6704
|
+
schema: argsSchema7,
|
|
6266
6705
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
6267
6706
|
return withErrorHandling("list package documentation", async () => {
|
|
6268
6707
|
const result = await pkgseerService.listPackageDocs(toGraphQLRegistry2(registry), package_name, version2);
|
|
@@ -6277,17 +6716,51 @@ function createListPackageDocsTool(pkgseerService) {
|
|
|
6277
6716
|
}
|
|
6278
6717
|
};
|
|
6279
6718
|
}
|
|
6719
|
+
// src/tools/list-repo-files.ts
|
|
6720
|
+
import { z as z9 } from "zod";
|
|
6721
|
+
var argsSchema8 = {
|
|
6722
|
+
registry: schemas.registry,
|
|
6723
|
+
package_name: schemas.packageName.describe("Name of the package to list files for"),
|
|
6724
|
+
version: schemas.version,
|
|
6725
|
+
path_prefix: z9.string().optional().describe("Filter to files under this path (e.g., 'src/')"),
|
|
6726
|
+
limit: z9.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
|
|
6727
|
+
wait_timeout_ms: schemas.waitTimeoutMs
|
|
6728
|
+
};
|
|
6729
|
+
function createListRepoFilesTool(pkgseerService) {
|
|
6730
|
+
return {
|
|
6731
|
+
name: "list_repo_files",
|
|
6732
|
+
description: "List files in a package's indexed repository. " + "Returns file paths, names, languages, types (source/doc/config), and sizes. " + "Use path_prefix to filter by directory (e.g., 'src/'). " + "Useful for exploring package structure before searching or reading code.",
|
|
6733
|
+
schema: argsSchema8,
|
|
6734
|
+
handler: async (args, _extra) => {
|
|
6735
|
+
return withErrorHandling("list repo files", async () => {
|
|
6736
|
+
const result = await pkgseerService.listRepoFiles(toGraphQLRegistry2(args.registry), args.package_name, {
|
|
6737
|
+
version: args.version,
|
|
6738
|
+
pathPrefix: args.path_prefix,
|
|
6739
|
+
limit: args.limit,
|
|
6740
|
+
waitTimeoutMs: args.wait_timeout_ms
|
|
6741
|
+
});
|
|
6742
|
+
const graphqlError = handleGraphQLErrors(result.errors);
|
|
6743
|
+
if (graphqlError)
|
|
6744
|
+
return graphqlError;
|
|
6745
|
+
if (!result.data.listRepoFiles) {
|
|
6746
|
+
return notFoundError(args.package_name, args.registry);
|
|
6747
|
+
}
|
|
6748
|
+
return textResult(JSON.stringify(result.data.listRepoFiles, null, 2));
|
|
6749
|
+
});
|
|
6750
|
+
}
|
|
6751
|
+
};
|
|
6752
|
+
}
|
|
6280
6753
|
// src/tools/list-symbols.ts
|
|
6281
|
-
import { z as
|
|
6282
|
-
var
|
|
6754
|
+
import { z as z10 } from "zod";
|
|
6755
|
+
var argsSchema9 = {
|
|
6283
6756
|
registry: schemas.registry,
|
|
6284
6757
|
package_name: schemas.packageName.describe("Name of the package to browse symbols for"),
|
|
6285
|
-
scope:
|
|
6286
|
-
file_path:
|
|
6287
|
-
namespace:
|
|
6288
|
-
public_only:
|
|
6289
|
-
include_popularity:
|
|
6290
|
-
limit:
|
|
6758
|
+
scope: z10.enum(["exports", "file"]).describe("Browsing scope: 'exports' for public API, 'file' for all symbols in a specific file"),
|
|
6759
|
+
file_path: z10.string().max(1000).optional().describe("File path within the repo (required when scope=file)"),
|
|
6760
|
+
namespace: z10.string().max(500).optional().describe("Filter by namespace prefix (e.g., 'React' to see React.*)"),
|
|
6761
|
+
public_only: z10.boolean().optional().describe("Only return public symbols"),
|
|
6762
|
+
include_popularity: z10.boolean().optional().describe("Include callerCount for each symbol (slightly slower)"),
|
|
6763
|
+
limit: z10.number().int().min(1).max(100).optional().describe("Max symbols to return (max 100)"),
|
|
6291
6764
|
version: schemas.version,
|
|
6292
6765
|
mode: schemas.navigationMode,
|
|
6293
6766
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
@@ -6296,7 +6769,7 @@ function createListSymbolsTool(pkgseerService) {
|
|
|
6296
6769
|
return {
|
|
6297
6770
|
name: "list_symbols",
|
|
6298
6771
|
description: "Browse symbols in a package by scope. " + "Use scope='exports' for public API with namespace grouping and optional popularity. " + "Use scope='file' with file_path for all symbols in a specific file. " + "Returns symbols with IDs, names, qualified paths, kinds, and file locations. " + "Use find_symbol(name=<symbol>, include_code=true) to get source for any listed symbol.",
|
|
6299
|
-
schema:
|
|
6772
|
+
schema: argsSchema9,
|
|
6300
6773
|
handler: async (args, _extra) => {
|
|
6301
6774
|
return withErrorHandling("list symbols", async () => {
|
|
6302
6775
|
const scope = toListScope(args.scope);
|
|
@@ -6333,13 +6806,13 @@ function createListSymbolsTool(pkgseerService) {
|
|
|
6333
6806
|
};
|
|
6334
6807
|
}
|
|
6335
6808
|
// src/tools/package-dependencies.ts
|
|
6336
|
-
import { z as
|
|
6337
|
-
var
|
|
6809
|
+
import { z as z11 } from "zod";
|
|
6810
|
+
var argsSchema10 = {
|
|
6338
6811
|
registry: schemas.registry,
|
|
6339
6812
|
package_name: schemas.packageName.describe("Name of the package to retrieve dependencies for"),
|
|
6340
6813
|
version: schemas.version,
|
|
6341
|
-
include_transitive:
|
|
6342
|
-
max_depth:
|
|
6814
|
+
include_transitive: z11.boolean().optional().describe("Whether to include transitive dependency DAG"),
|
|
6815
|
+
max_depth: z11.number().int().min(1).max(10).optional().describe("Maximum depth for transitive traversal (1-10)")
|
|
6343
6816
|
};
|
|
6344
6817
|
function decodeDag(rawDag) {
|
|
6345
6818
|
if (!rawDag || typeof rawDag !== "object")
|
|
@@ -6417,7 +6890,7 @@ function createPackageDependenciesTool(pkgseerService) {
|
|
|
6417
6890
|
return {
|
|
6418
6891
|
name: "package_dependencies",
|
|
6419
6892
|
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.",
|
|
6420
|
-
schema:
|
|
6893
|
+
schema: argsSchema10,
|
|
6421
6894
|
handler: async ({ registry, package_name, version: version2, include_transitive, max_depth }, _extra) => {
|
|
6422
6895
|
return withErrorHandling("fetch package dependencies", async () => {
|
|
6423
6896
|
const result = await pkgseerService.getPackageDependencies(toGraphQLRegistry2(registry), package_name, version2, include_transitive, max_depth);
|
|
@@ -6455,13 +6928,13 @@ function createPackageDependenciesTool(pkgseerService) {
|
|
|
6455
6928
|
};
|
|
6456
6929
|
}
|
|
6457
6930
|
// src/tools/package-imports.ts
|
|
6458
|
-
import { z as
|
|
6459
|
-
var
|
|
6931
|
+
import { z as z12 } from "zod";
|
|
6932
|
+
var argsSchema11 = {
|
|
6460
6933
|
registry: schemas.registry,
|
|
6461
6934
|
package_name: schemas.packageName.describe("Name of the package to get imports for"),
|
|
6462
|
-
file_path:
|
|
6463
|
-
resolved_only:
|
|
6464
|
-
limit:
|
|
6935
|
+
file_path: z12.string().max(1000).optional().describe("Filter to a specific file path"),
|
|
6936
|
+
resolved_only: z12.boolean().optional().describe("Only return imports resolved to a known package"),
|
|
6937
|
+
limit: z12.number().int().min(1).max(500).optional().describe("Max imports to return"),
|
|
6465
6938
|
version: schemas.version,
|
|
6466
6939
|
mode: schemas.navigationMode,
|
|
6467
6940
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
@@ -6470,7 +6943,7 @@ function createPackageImportsTool(pkgseerService) {
|
|
|
6470
6943
|
return {
|
|
6471
6944
|
name: "package_imports",
|
|
6472
6945
|
description: "Get import statements in a package. " + "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.",
|
|
6473
|
-
schema:
|
|
6946
|
+
schema: argsSchema11,
|
|
6474
6947
|
handler: async (args, _extra) => {
|
|
6475
6948
|
return withErrorHandling("fetch package imports", async () => {
|
|
6476
6949
|
const result = await pkgseerService.packageImports(toGraphQLRegistry2(args.registry), args.package_name, {
|
|
@@ -6493,7 +6966,7 @@ function createPackageImportsTool(pkgseerService) {
|
|
|
6493
6966
|
};
|
|
6494
6967
|
}
|
|
6495
6968
|
// src/tools/package-quality.ts
|
|
6496
|
-
var
|
|
6969
|
+
var argsSchema12 = {
|
|
6497
6970
|
registry: schemas.registry,
|
|
6498
6971
|
package_name: schemas.packageName.describe("Name of the package to analyze"),
|
|
6499
6972
|
version: schemas.version
|
|
@@ -6502,7 +6975,7 @@ function createPackageQualityTool(pkgseerService) {
|
|
|
6502
6975
|
return {
|
|
6503
6976
|
name: "package_quality",
|
|
6504
6977
|
description: "Evaluate package maintenance health and code quality. 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.",
|
|
6505
|
-
schema:
|
|
6978
|
+
schema: argsSchema12,
|
|
6506
6979
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
6507
6980
|
return withErrorHandling("fetch package quality", async () => {
|
|
6508
6981
|
const result = await pkgseerService.getPackageQuality(toGraphQLRegistry2(registry), package_name, version2);
|
|
@@ -6518,7 +6991,7 @@ function createPackageQualityTool(pkgseerService) {
|
|
|
6518
6991
|
};
|
|
6519
6992
|
}
|
|
6520
6993
|
// src/tools/package-summary.ts
|
|
6521
|
-
var
|
|
6994
|
+
var argsSchema13 = {
|
|
6522
6995
|
registry: schemas.registry,
|
|
6523
6996
|
package_name: schemas.packageName.describe("Name of the package to retrieve summary for")
|
|
6524
6997
|
};
|
|
@@ -6526,7 +6999,7 @@ function createPackageSummaryTool(pkgseerService) {
|
|
|
6526
6999
|
return {
|
|
6527
7000
|
name: "package_summary",
|
|
6528
7001
|
description: "Get a comprehensive overview of a package. 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).",
|
|
6529
|
-
schema:
|
|
7002
|
+
schema: argsSchema13,
|
|
6530
7003
|
handler: async ({ registry, package_name }, _extra) => {
|
|
6531
7004
|
return withErrorHandling("fetch package summary", async () => {
|
|
6532
7005
|
const result = await pkgseerService.getPackageSummary(toGraphQLRegistry2(registry), package_name);
|
|
@@ -6542,7 +7015,7 @@ function createPackageSummaryTool(pkgseerService) {
|
|
|
6542
7015
|
};
|
|
6543
7016
|
}
|
|
6544
7017
|
// src/tools/package-vulnerabilities.ts
|
|
6545
|
-
var
|
|
7018
|
+
var argsSchema14 = {
|
|
6546
7019
|
registry: schemas.registry,
|
|
6547
7020
|
package_name: schemas.packageName.describe("Name of the package to inspect for vulnerabilities"),
|
|
6548
7021
|
version: schemas.version
|
|
@@ -6551,7 +7024,7 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
|
|
|
6551
7024
|
return {
|
|
6552
7025
|
name: "package_vulnerabilities",
|
|
6553
7026
|
description: "Check security vulnerabilities for a package. 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.",
|
|
6554
|
-
schema:
|
|
7027
|
+
schema: argsSchema14,
|
|
6555
7028
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
6556
7029
|
return withErrorHandling("fetch package vulnerabilities", async () => {
|
|
6557
7030
|
const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry2(registry), package_name, version2);
|
|
@@ -6567,19 +7040,19 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
|
|
|
6567
7040
|
};
|
|
6568
7041
|
}
|
|
6569
7042
|
// src/tools/search.ts
|
|
6570
|
-
import { z as
|
|
6571
|
-
var packageInputSchema2 =
|
|
7043
|
+
import { z as z13 } from "zod";
|
|
7044
|
+
var packageInputSchema2 = z13.object({
|
|
6572
7045
|
registry: schemas.registry,
|
|
6573
|
-
name:
|
|
6574
|
-
version:
|
|
7046
|
+
name: z13.string().min(1).describe("Package name"),
|
|
7047
|
+
version: z13.string().optional().describe("Specific version (defaults to latest)")
|
|
6575
7048
|
});
|
|
6576
7049
|
var DEFAULT_AGENT_WAIT_TIMEOUT_MS = 1e4;
|
|
6577
|
-
var
|
|
6578
|
-
packages:
|
|
6579
|
-
query:
|
|
6580
|
-
mode:
|
|
6581
|
-
limit:
|
|
6582
|
-
waitTimeoutMs:
|
|
7050
|
+
var argsSchema15 = {
|
|
7051
|
+
packages: z13.array(packageInputSchema2).min(1).max(20).describe("Packages to search (1-20). Each package needs registry and name."),
|
|
7052
|
+
query: z13.string().min(1).describe("Search query - natural language or keywords"),
|
|
7053
|
+
mode: z13.enum(["all", "code", "docs"]).optional().describe('Search mode: "all" (default), "code" only, or "docs" only'),
|
|
7054
|
+
limit: z13.number().int().min(1).max(100).optional().describe("Maximum results (default: 20)"),
|
|
7055
|
+
waitTimeoutMs: z13.number().int().min(0).max(60000).optional().describe("Max milliseconds to wait for indexing (default: 10000, 0=immediate)")
|
|
6583
7056
|
};
|
|
6584
7057
|
function toSearchMode2(mode) {
|
|
6585
7058
|
if (!mode)
|
|
@@ -6618,7 +7091,7 @@ function createSearchTool(pkgseerService) {
|
|
|
6618
7091
|
return {
|
|
6619
7092
|
name: "search",
|
|
6620
7093
|
description: "Search code and documentation across packages. Returns functions, classes, and doc pages " + "matching your query. Use mode='code' for code only, mode='docs' for docs only, or " + "mode='all' (default). Provide 1-20 packages. Results include relevance scores and snippets. " + "For full source of code results, use find_symbol(name=<title>, include_code=true). " + "If packages need indexing, waits up to waitTimeoutMs (default 10s) or returns searchRef — use search_status to poll.",
|
|
6621
|
-
schema:
|
|
7094
|
+
schema: argsSchema15,
|
|
6622
7095
|
handler: async ({ packages, query, mode, limit, waitTimeoutMs }, _extra) => {
|
|
6623
7096
|
return withErrorHandling("search packages", async () => {
|
|
6624
7097
|
const normalizedQuery = query.trim();
|
|
@@ -6670,21 +7143,21 @@ function createSearchTool(pkgseerService) {
|
|
|
6670
7143
|
};
|
|
6671
7144
|
}
|
|
6672
7145
|
// src/tools/search-project-docs.ts
|
|
6673
|
-
import { z as
|
|
6674
|
-
var
|
|
6675
|
-
project_directory:
|
|
6676
|
-
project:
|
|
6677
|
-
terms:
|
|
6678
|
-
match_mode:
|
|
6679
|
-
include_snippets:
|
|
6680
|
-
limit:
|
|
7146
|
+
import { z as z14 } from "zod";
|
|
7147
|
+
var argsSchema16 = {
|
|
7148
|
+
project_directory: z14.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."),
|
|
7149
|
+
project: z14.string().optional().describe("Project name to search. Overrides value from pkgseer.yml if provided."),
|
|
7150
|
+
terms: z14.array(z14.string()).optional().describe("Search terms to match. Provide a few key words or phrases that should appear in results."),
|
|
7151
|
+
match_mode: z14.enum(["any", "or", "all", "and"]).optional().describe('How to combine terms: "any" (OR) or "all" (AND).'),
|
|
7152
|
+
include_snippets: z14.boolean().optional().describe("Include content excerpts around matches"),
|
|
7153
|
+
limit: z14.number().int().min(1).max(100).optional().describe("Maximum number of results to return")
|
|
6681
7154
|
};
|
|
6682
7155
|
function createSearchProjectDocsTool(deps) {
|
|
6683
7156
|
const { pkgseerService, configService, defaultProjectDir } = deps;
|
|
6684
7157
|
return {
|
|
6685
7158
|
name: "search_project_docs",
|
|
6686
7159
|
description: "Searches documentation across all dependencies in a PkgSeer project using search terms and match modes (any/all). Returns ranked results from multiple packages. Use project_directory to specify which project's context to use, or project to search a specific project directly.",
|
|
6687
|
-
schema:
|
|
7160
|
+
schema: argsSchema16,
|
|
6688
7161
|
handler: async ({
|
|
6689
7162
|
project_directory,
|
|
6690
7163
|
project,
|
|
@@ -6730,15 +7203,15 @@ function createSearchProjectDocsTool(deps) {
|
|
|
6730
7203
|
};
|
|
6731
7204
|
}
|
|
6732
7205
|
// src/tools/search-status.ts
|
|
6733
|
-
import { z as
|
|
6734
|
-
var
|
|
6735
|
-
searchRef:
|
|
7206
|
+
import { z as z15 } from "zod";
|
|
7207
|
+
var argsSchema17 = {
|
|
7208
|
+
searchRef: z15.string().min(1).describe("Search reference from a previous incomplete search")
|
|
6736
7209
|
};
|
|
6737
7210
|
function createSearchStatusTool(pkgseerService) {
|
|
6738
7211
|
return {
|
|
6739
7212
|
name: "search_status",
|
|
6740
7213
|
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.",
|
|
6741
|
-
schema:
|
|
7214
|
+
schema: argsSchema17,
|
|
6742
7215
|
handler: async ({ searchRef }, _extra) => {
|
|
6743
7216
|
return withErrorHandling("check search status", async () => {
|
|
6744
7217
|
const progressResult = await pkgseerService.getSearchProgress(searchRef);
|
|
@@ -6779,12 +7252,14 @@ function createSearchStatusTool(pkgseerService) {
|
|
|
6779
7252
|
};
|
|
6780
7253
|
}
|
|
6781
7254
|
// src/tools/search-symbols.ts
|
|
6782
|
-
import { z as
|
|
6783
|
-
var
|
|
7255
|
+
import { z as z16 } from "zod";
|
|
7256
|
+
var argsSchema18 = {
|
|
6784
7257
|
registry: schemas.registry,
|
|
6785
7258
|
package_name: schemas.packageName.describe("Name of the package to search within"),
|
|
6786
|
-
query:
|
|
6787
|
-
|
|
7259
|
+
query: z16.string().max(500).optional().describe("Search query for full-text code search (max 500 chars). Required if keywords not provided."),
|
|
7260
|
+
keywords: z16.array(z16.string()).max(20).optional().describe("Search keywords (max 20). Combined using match_mode. Alternative to query."),
|
|
7261
|
+
match_mode: z16.enum(["or", "and"]).optional().describe("How to combine keywords: or (any match) or and (all must match)"),
|
|
7262
|
+
kind: z16.enum([
|
|
6788
7263
|
"function",
|
|
6789
7264
|
"method",
|
|
6790
7265
|
"class",
|
|
@@ -6793,20 +7268,25 @@ var argsSchema16 = {
|
|
|
6793
7268
|
"type",
|
|
6794
7269
|
"doc_section"
|
|
6795
7270
|
]).optional().describe("Filter results by code chunk type"),
|
|
7271
|
+
file_path: z16.string().optional().describe("Filter results to files whose path starts with this value (e.g., 'src/' for a directory)"),
|
|
6796
7272
|
version: schemas.version,
|
|
6797
|
-
limit:
|
|
7273
|
+
limit: z16.number().int().min(1).max(50).optional().describe("Max results to return (max 50)"),
|
|
6798
7274
|
mode: schemas.navigationMode,
|
|
6799
7275
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
6800
7276
|
};
|
|
6801
7277
|
function createSearchSymbolsTool(pkgseerService) {
|
|
6802
7278
|
return {
|
|
6803
7279
|
name: "search_symbols",
|
|
6804
|
-
description: "Full-text search within package code. " + "Searches across functions, classes, modules, and doc sections. " + "Returns matching code chunks with name, type, file path, line numbers, and content previews. " + "Follow-up: use find_symbol(name=<result.name>, include_code=true) to get full source.",
|
|
6805
|
-
schema:
|
|
7280
|
+
description: "Full-text search within package code. " + "Searches across functions, classes, modules, and doc sections. " + "Supports query string or keyword list with match_mode. " + "Use file_path to filter by directory (e.g., 'src/'). " + "Returns matching code chunks with name, type, file path, line numbers, and content previews. " + "Follow-up: use find_symbol(name=<result.name>, include_code=true) to get full source.",
|
|
7281
|
+
schema: argsSchema18,
|
|
6806
7282
|
handler: async (args, _extra) => {
|
|
6807
7283
|
return withErrorHandling("search symbols", async () => {
|
|
6808
|
-
const result = await pkgseerService.searchSymbols(toGraphQLRegistry2(args.registry), args.package_name,
|
|
7284
|
+
const result = await pkgseerService.searchSymbols(toGraphQLRegistry2(args.registry), args.package_name, {
|
|
7285
|
+
query: args.query,
|
|
7286
|
+
keywords: args.keywords,
|
|
7287
|
+
matchMode: toMatchMode(args.match_mode),
|
|
6809
7288
|
kind: toSymbolKind(args.kind),
|
|
7289
|
+
filePath: args.file_path,
|
|
6810
7290
|
version: args.version,
|
|
6811
7291
|
limit: args.limit,
|
|
6812
7292
|
mode: toNavigationMode(args.mode),
|
|
@@ -6824,13 +7304,13 @@ function createSearchSymbolsTool(pkgseerService) {
|
|
|
6824
7304
|
};
|
|
6825
7305
|
}
|
|
6826
7306
|
// src/tools/symbol-callees.ts
|
|
6827
|
-
import { z as
|
|
6828
|
-
var
|
|
7307
|
+
import { z as z17 } from "zod";
|
|
7308
|
+
var argsSchema19 = {
|
|
6829
7309
|
symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide either symbol_id or registry + package_name + symbol_name."),
|
|
6830
|
-
max_depth:
|
|
6831
|
-
limit:
|
|
6832
|
-
include_external:
|
|
6833
|
-
include_builtins:
|
|
7310
|
+
max_depth: z17.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
|
|
7311
|
+
limit: z17.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
|
|
7312
|
+
include_external: z17.boolean().optional().describe("Include calls to symbols in other packages"),
|
|
7313
|
+
include_builtins: z17.boolean().optional().describe("Include calls to built-in/standard library functions (console, Math, etc.)"),
|
|
6834
7314
|
mode: schemas.navigationMode,
|
|
6835
7315
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
6836
7316
|
};
|
|
@@ -6838,7 +7318,7 @@ function createSymbolCalleesTool(pkgseerService) {
|
|
|
6838
7318
|
return {
|
|
6839
7319
|
name: "symbol_callees",
|
|
6840
7320
|
description: "Find what a symbol calls (its dependencies). " + "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. " + "Get symbol_id from find_symbol or list_symbols results. See symbol_callers for the reverse.",
|
|
6841
|
-
schema:
|
|
7321
|
+
schema: argsSchema19,
|
|
6842
7322
|
handler: async (args, _extra) => {
|
|
6843
7323
|
return withErrorHandling("find symbol callees", async () => {
|
|
6844
7324
|
const symbolInput = toSymbolReferenceInput(args.symbol);
|
|
@@ -6865,11 +7345,11 @@ function createSymbolCalleesTool(pkgseerService) {
|
|
|
6865
7345
|
};
|
|
6866
7346
|
}
|
|
6867
7347
|
// src/tools/symbol-callers.ts
|
|
6868
|
-
import { z as
|
|
6869
|
-
var
|
|
7348
|
+
import { z as z18 } from "zod";
|
|
7349
|
+
var argsSchema20 = {
|
|
6870
7350
|
symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide either symbol_id or registry + package_name + symbol_name."),
|
|
6871
|
-
same_package_only:
|
|
6872
|
-
limit:
|
|
7351
|
+
same_package_only: z18.boolean().optional().describe("Only return callers from the same package"),
|
|
7352
|
+
limit: z18.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
|
|
6873
7353
|
mode: schemas.navigationMode,
|
|
6874
7354
|
wait_timeout_ms: schemas.waitTimeoutMs
|
|
6875
7355
|
};
|
|
@@ -6877,7 +7357,7 @@ function createSymbolCallersTool(pkgseerService) {
|
|
|
6877
7357
|
return {
|
|
6878
7358
|
name: "symbol_callers",
|
|
6879
7359
|
description: "Find what calls a symbol (its dependents/callers). " + "Returns the target symbol and a list of callers with file locations and call line numbers. " + "Use same_package_only to limit to callers within the same package. " + "Get symbol_id from find_symbol or list_symbols results. See symbol_callees for the reverse.",
|
|
6880
|
-
schema:
|
|
7360
|
+
schema: argsSchema20,
|
|
6881
7361
|
handler: async (args, _extra) => {
|
|
6882
7362
|
return withErrorHandling("find symbol callers", async () => {
|
|
6883
7363
|
const symbolInput = toSymbolReferenceInput(args.symbol);
|
|
@@ -6902,26 +7382,26 @@ function createSymbolCallersTool(pkgseerService) {
|
|
|
6902
7382
|
};
|
|
6903
7383
|
}
|
|
6904
7384
|
// src/tools/trigger-indexing.ts
|
|
6905
|
-
import { z as
|
|
6906
|
-
var packageInputSchema3 =
|
|
7385
|
+
import { z as z19 } from "zod";
|
|
7386
|
+
var packageInputSchema3 = z19.object({
|
|
6907
7387
|
registry: schemas.registry,
|
|
6908
|
-
name:
|
|
6909
|
-
version:
|
|
7388
|
+
name: z19.string().max(255).describe("Package name"),
|
|
7389
|
+
version: z19.string().max(100).optional().describe("Specific version to index")
|
|
6910
7390
|
});
|
|
6911
|
-
var repositoryInputSchema =
|
|
6912
|
-
url:
|
|
6913
|
-
ref:
|
|
6914
|
-
discover_packages:
|
|
7391
|
+
var repositoryInputSchema = z19.object({
|
|
7392
|
+
url: z19.string().max(2000).describe("GitHub repository URL"),
|
|
7393
|
+
ref: z19.string().max(200).optional().describe("Git ref to index (tag, branch, commit). Defaults to HEAD"),
|
|
7394
|
+
discover_packages: z19.boolean().optional().describe("If true, discover packages published from this repo and trigger their metadata fetch")
|
|
6915
7395
|
});
|
|
6916
|
-
var
|
|
6917
|
-
packages:
|
|
6918
|
-
repositories:
|
|
7396
|
+
var argsSchema21 = {
|
|
7397
|
+
packages: z19.array(packageInputSchema3).max(100).optional().describe("Package versions to index (max 100)"),
|
|
7398
|
+
repositories: z19.array(repositoryInputSchema).max(50).optional().describe("Repository URLs to index (max 50)")
|
|
6919
7399
|
};
|
|
6920
7400
|
function createTriggerIndexingTool(pkgseerService) {
|
|
6921
7401
|
return {
|
|
6922
7402
|
name: "trigger_indexing",
|
|
6923
7403
|
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 requests to ensure packages are indexed. " + "Rate limited to 10 requests per minute.",
|
|
6924
|
-
schema:
|
|
7404
|
+
schema: argsSchema21,
|
|
6925
7405
|
handler: async (args, _extra) => {
|
|
6926
7406
|
return withErrorHandling("trigger indexing", async () => {
|
|
6927
7407
|
const packages = args.packages?.map((p) => ({
|
|
@@ -6957,6 +7437,50 @@ function createTriggerIndexingTool(pkgseerService) {
|
|
|
6957
7437
|
}
|
|
6958
7438
|
};
|
|
6959
7439
|
}
|
|
7440
|
+
// src/tools/version-diff.ts
|
|
7441
|
+
import { z as z20 } from "zod";
|
|
7442
|
+
var argsSchema22 = {
|
|
7443
|
+
registry: schemas.registry,
|
|
7444
|
+
package_name: schemas.packageName.describe("Name of the package to compare versions for"),
|
|
7445
|
+
from_version: z20.string().max(100).describe("Source version (git ref, e.g., 'v4.18.2')"),
|
|
7446
|
+
to_version: z20.string().max(100).describe("Target version (git ref, e.g., 'v5.0.0')"),
|
|
7447
|
+
include_private: z20.boolean().optional().describe("Include private/non-exported symbols in the diff"),
|
|
7448
|
+
kind: z20.enum([
|
|
7449
|
+
"function",
|
|
7450
|
+
"method",
|
|
7451
|
+
"class",
|
|
7452
|
+
"module",
|
|
7453
|
+
"interface",
|
|
7454
|
+
"type",
|
|
7455
|
+
"doc_section"
|
|
7456
|
+
]).optional().describe("Filter by symbol kind"),
|
|
7457
|
+
limit: z20.number().int().min(1).max(500).optional().describe("Max changes to return (max 500). Summary always reflects full counts."),
|
|
7458
|
+
wait_timeout_ms: schemas.waitTimeoutMs
|
|
7459
|
+
};
|
|
7460
|
+
function createVersionDiffTool(pkgseerService) {
|
|
7461
|
+
return {
|
|
7462
|
+
name: "version_diff",
|
|
7463
|
+
description: "Compare symbols between two package versions. " + "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.",
|
|
7464
|
+
schema: argsSchema22,
|
|
7465
|
+
handler: async (args, _extra) => {
|
|
7466
|
+
return withErrorHandling("version diff", async () => {
|
|
7467
|
+
const result = await pkgseerService.versionDiff(toGraphQLRegistry2(args.registry), args.package_name, args.from_version, args.to_version, {
|
|
7468
|
+
includePrivate: args.include_private,
|
|
7469
|
+
kind: toSymbolKind(args.kind),
|
|
7470
|
+
limit: args.limit,
|
|
7471
|
+
waitTimeoutMs: args.wait_timeout_ms
|
|
7472
|
+
});
|
|
7473
|
+
const graphqlError = handleGraphQLErrors(result.errors);
|
|
7474
|
+
if (graphqlError)
|
|
7475
|
+
return graphqlError;
|
|
7476
|
+
if (!result.data.versionDiff) {
|
|
7477
|
+
return notFoundError(args.package_name, args.registry);
|
|
7478
|
+
}
|
|
7479
|
+
return textResult(JSON.stringify(result.data.versionDiff, null, 2));
|
|
7480
|
+
});
|
|
7481
|
+
}
|
|
7482
|
+
};
|
|
7483
|
+
}
|
|
6960
7484
|
// src/commands/mcp.ts
|
|
6961
7485
|
var TOOL_FACTORIES = {
|
|
6962
7486
|
package_summary: ({ pkgseerService }) => createPackageSummaryTool(pkgseerService),
|
|
@@ -6981,7 +7505,10 @@ var TOOL_FACTORIES = {
|
|
|
6981
7505
|
symbol_callees: ({ pkgseerService }) => createSymbolCalleesTool(pkgseerService),
|
|
6982
7506
|
package_imports: ({ pkgseerService }) => createPackageImportsTool(pkgseerService),
|
|
6983
7507
|
call_path: ({ pkgseerService }) => createCallPathTool(pkgseerService),
|
|
6984
|
-
trigger_indexing: ({ pkgseerService }) => createTriggerIndexingTool(pkgseerService)
|
|
7508
|
+
trigger_indexing: ({ pkgseerService }) => createTriggerIndexingTool(pkgseerService),
|
|
7509
|
+
list_repo_files: ({ pkgseerService }) => createListRepoFilesTool(pkgseerService),
|
|
7510
|
+
grep_repo_file: ({ pkgseerService }) => createGrepRepoFileTool(pkgseerService),
|
|
7511
|
+
version_diff: ({ pkgseerService }) => createVersionDiffTool(pkgseerService)
|
|
6985
7512
|
};
|
|
6986
7513
|
var PUBLIC_READ_TOOLS = [
|
|
6987
7514
|
"package_summary",
|
|
@@ -7001,7 +7528,10 @@ var PUBLIC_READ_TOOLS = [
|
|
|
7001
7528
|
"symbol_callees",
|
|
7002
7529
|
"package_imports",
|
|
7003
7530
|
"call_path",
|
|
7004
|
-
"trigger_indexing"
|
|
7531
|
+
"trigger_indexing",
|
|
7532
|
+
"list_repo_files",
|
|
7533
|
+
"grep_repo_file",
|
|
7534
|
+
"version_diff"
|
|
7005
7535
|
];
|
|
7006
7536
|
var PROJECT_READ_TOOLS = ["search_project_docs"];
|
|
7007
7537
|
var ALL_TOOLS = [...PUBLIC_READ_TOOLS, ...PROJECT_READ_TOOLS];
|
|
@@ -8003,8 +8533,11 @@ Documentation commands:
|
|
|
8003
8533
|
|
|
8004
8534
|
Code navigation commands:
|
|
8005
8535
|
pkgseer code find <pkg> [name] Find symbols by name
|
|
8006
|
-
pkgseer code search <pkg>
|
|
8536
|
+
pkgseer code search <pkg> [q] Search in package code
|
|
8007
8537
|
pkgseer code list <package> Browse package symbols
|
|
8538
|
+
pkgseer code files <package> List repository files
|
|
8539
|
+
pkgseer code grep <pkg> <f> <p> Search pattern in a file
|
|
8540
|
+
pkgseer code diff <pkg> <v> <v> Compare versions
|
|
8008
8541
|
pkgseer code callers <symbol> Find what calls a symbol
|
|
8009
8542
|
pkgseer code callees <symbol> Find what a symbol calls
|
|
8010
8543
|
pkgseer code imports <package> List package imports
|
|
@@ -8038,6 +8571,9 @@ var code = program.command("code").description("Code navigation commands");
|
|
|
8038
8571
|
registerCodeFindCommand(code);
|
|
8039
8572
|
registerCodeSearchCommand(code);
|
|
8040
8573
|
registerCodeListCommand(code);
|
|
8574
|
+
registerCodeFilesCommand(code);
|
|
8575
|
+
registerCodeGrepCommand(code);
|
|
8576
|
+
registerCodeDiffCommand(code);
|
|
8041
8577
|
registerCodeCallersCommand(code);
|
|
8042
8578
|
registerCodeCalleesCommand(code);
|
|
8043
8579
|
registerCodeImportsCommand(code);
|
package/dist/index.js
CHANGED