@pkgseer/cli 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +149 -62
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-z0xepgqq.js → chunk-bahf01jh.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-bahf01jh.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -355,6 +355,7 @@ var TriggerIndexingDocument = gql`
|
|
|
355
355
|
triggerIndexing(input: $input) {
|
|
356
356
|
accepted
|
|
357
357
|
skipped
|
|
358
|
+
alreadyIndexed
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
361
|
`;
|
|
@@ -4879,6 +4880,7 @@ async function indexAction(packages, options, deps) {
|
|
|
4879
4880
|
if (data) {
|
|
4880
4881
|
console.log(`Accepted: ${data.accepted}`);
|
|
4881
4882
|
console.log(`Skipped: ${data.skipped}`);
|
|
4883
|
+
console.log(`Already indexed: ${data.alreadyIndexed}`);
|
|
4882
4884
|
} else {
|
|
4883
4885
|
console.log("Indexing request submitted.");
|
|
4884
4886
|
}
|
|
@@ -5117,16 +5119,39 @@ async function setupCodexViaCli(shellService) {
|
|
|
5117
5119
|
}
|
|
5118
5120
|
function showAvailableTools(hasProject, useColors) {
|
|
5119
5121
|
console.log(`
|
|
5120
|
-
Available MCP tools:`);
|
|
5121
|
-
console.log("
|
|
5122
|
-
console.log("
|
|
5123
|
-
console.log("
|
|
5124
|
-
console.log("
|
|
5125
|
-
console.log("
|
|
5126
|
-
console.log("
|
|
5127
|
-
console.log("
|
|
5128
|
-
console.log("
|
|
5129
|
-
console.log("
|
|
5122
|
+
Available MCP tools (21):`);
|
|
5123
|
+
console.log("");
|
|
5124
|
+
console.log(" Navigate source:");
|
|
5125
|
+
console.log(" • find_symbol - Read source code of functions/classes");
|
|
5126
|
+
console.log(" • list_symbols - Browse public API or file symbols");
|
|
5127
|
+
console.log(" • search_symbols - Full-text search within package code");
|
|
5128
|
+
console.log(" • symbol_callers - Trace what calls a function");
|
|
5129
|
+
console.log(" • symbol_callees - Trace what a function calls");
|
|
5130
|
+
console.log(" • call_path - Find call path between two functions");
|
|
5131
|
+
console.log("");
|
|
5132
|
+
console.log(" Browse files:");
|
|
5133
|
+
console.log(" • list_repo_files - Explore package file structure");
|
|
5134
|
+
console.log(" • grep_repo_file - Search for patterns in source files");
|
|
5135
|
+
console.log(" • fetch_code_context - Read source by file path and line range");
|
|
5136
|
+
console.log("");
|
|
5137
|
+
console.log(" Search & docs:");
|
|
5138
|
+
console.log(" • search - Search code and docs across packages");
|
|
5139
|
+
console.log(" • search_project_docs - Search docs across project dependencies");
|
|
5140
|
+
console.log(" • list_package_docs - List documentation pages");
|
|
5141
|
+
console.log(" • fetch_package_doc - Fetch documentation content");
|
|
5142
|
+
console.log("");
|
|
5143
|
+
console.log(" Evaluate:");
|
|
5144
|
+
console.log(" • package_summary - Get package overview");
|
|
5145
|
+
console.log(" • package_quality - Get quality score");
|
|
5146
|
+
console.log(" • package_vulnerabilities - Check for security issues");
|
|
5147
|
+
console.log(" • compare_packages - Compare multiple packages");
|
|
5148
|
+
console.log(" • package_dependencies - List dependencies");
|
|
5149
|
+
console.log(" • version_diff - Compare changes between versions");
|
|
5150
|
+
console.log("");
|
|
5151
|
+
console.log(" Utility:");
|
|
5152
|
+
console.log(" • trigger_indexing - Pre-warm package indexes");
|
|
5153
|
+
console.log(" • search_status - Check async search progress");
|
|
5154
|
+
console.log(" • package_imports - See what a package imports");
|
|
5130
5155
|
if (!hasProject) {
|
|
5131
5156
|
console.log(dim(`
|
|
5132
5157
|
Tip: Create pkgseer.yml to enable automatic project detection for search_project_docs.`, useColors));
|
|
@@ -6022,27 +6047,51 @@ function generateSkillContent(invocation = "pkgseer") {
|
|
|
6022
6047
|
return `---
|
|
6023
6048
|
name: pkgseer
|
|
6024
6049
|
version: ${version}
|
|
6025
|
-
description:
|
|
6050
|
+
description: Navigate source code, trace call graphs, and search docs across npm/PyPI/Hex packages. Quality scores, vulnerability checks, dependency analysis, and cross-package comparison. Use when debugging third-party dependencies, understanding how a library works internally, tracing a stack trace into dependency code, evaluating or comparing packages, checking security vulnerabilities, or understanding what changed between versions.
|
|
6026
6051
|
---
|
|
6027
6052
|
|
|
6028
|
-
# PkgSeer - Package Intelligence
|
|
6053
|
+
# PkgSeer - Package Source Code & Intelligence
|
|
6029
6054
|
|
|
6030
|
-
|
|
6055
|
+
Navigate dependency source code and analyze packages across npm, PyPI, and Hex. All commands support \`--json\`.
|
|
6031
6056
|
|
|
6032
|
-
|
|
6057
|
+
Use PkgSeer instead of guessing library behavior, cloning repos, or browsing GitHub.
|
|
6058
|
+
|
|
6059
|
+
## Code Navigation (Debug & Understand Dependencies)
|
|
6060
|
+
|
|
6061
|
+
\`\`\`bash
|
|
6062
|
+
# Read source code of a function/class — use instead of guessing from training data
|
|
6063
|
+
${invocation} code find express Router --include-code
|
|
6064
|
+
${invocation} code find pypi:requests Session --include-code
|
|
6065
|
+
|
|
6066
|
+
# Trace what calls a function (find entry points, debug triggers)
|
|
6067
|
+
${invocation} code callers -r npm -p express -n Router
|
|
6068
|
+
|
|
6069
|
+
# Trace what a function calls (follow execution path)
|
|
6070
|
+
${invocation} code callees -r npm -p express -n Router
|
|
6071
|
+
|
|
6072
|
+
# Find how function A reaches function B
|
|
6073
|
+
${invocation} code path -r npm -p express --from-name listen --to-name createServer
|
|
6074
|
+
|
|
6075
|
+
# Search for error messages or patterns in dependency source
|
|
6076
|
+
${invocation} code search express "ERR_HTTP_HEADERS_SENT"
|
|
6077
|
+
${invocation} code grep express src/router/index.js "handle"
|
|
6078
|
+
|
|
6079
|
+
# Browse package structure, API, and imports
|
|
6080
|
+
${invocation} code files express --path-prefix src/
|
|
6081
|
+
${invocation} code list express --scope exports
|
|
6082
|
+
${invocation} code imports express --resolved-only
|
|
6083
|
+
|
|
6084
|
+
# Compare versions (detect breaking changes after upgrades)
|
|
6085
|
+
${invocation} code diff express v4.18.2 v5.0.0
|
|
6086
|
+
\`\`\`
|
|
6087
|
+
|
|
6088
|
+
## Search Across Packages
|
|
6033
6089
|
|
|
6034
6090
|
\`\`\`bash
|
|
6035
|
-
# Search code and docs across packages
|
|
6036
6091
|
${invocation} search "<query>" -P lodash,express # npm packages
|
|
6037
6092
|
${invocation} search "<query>" -P pypi:requests # PyPI packages
|
|
6038
|
-
${invocation} search "authentication" -P hex:phoenix,hex:plug
|
|
6039
|
-
|
|
6040
|
-
# Search modes
|
|
6041
6093
|
${invocation} search "<query>" -P <packages> --mode code # Code only
|
|
6042
6094
|
${invocation} search "<query>" -P <packages> --mode docs # Docs only
|
|
6043
|
-
|
|
6044
|
-
# Docs-only search (shorthand)
|
|
6045
|
-
${invocation} docs search "<query>" -P <packages>
|
|
6046
6095
|
\`\`\`
|
|
6047
6096
|
|
|
6048
6097
|
## Package Analysis
|
|
@@ -6050,23 +6099,11 @@ ${invocation} docs search "<query>" -P <packages>
|
|
|
6050
6099
|
Package format: \`[registry:]name[@version]\`
|
|
6051
6100
|
|
|
6052
6101
|
\`\`\`bash
|
|
6053
|
-
# Overview
|
|
6054
|
-
${invocation} pkg
|
|
6055
|
-
${invocation} pkg
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
${invocation} pkg quality express@4.18.0
|
|
6059
|
-
${invocation} pkg quality pypi:django@4.2
|
|
6060
|
-
|
|
6061
|
-
# Security: CVEs, severity, upgrade paths
|
|
6062
|
-
${invocation} pkg vulns lodash@4.17.21
|
|
6063
|
-
|
|
6064
|
-
# Dependencies: direct, transitive, tree view
|
|
6065
|
-
${invocation} pkg deps express --transitive
|
|
6066
|
-
|
|
6067
|
-
# Compare up to 10 packages
|
|
6068
|
-
${invocation} pkg compare lodash underscore ramda
|
|
6069
|
-
${invocation} pkg compare axios pypi:httpx # cross-registry
|
|
6102
|
+
${invocation} pkg info lodash # Overview, versions, quickstart
|
|
6103
|
+
${invocation} pkg quality express@4.18.0 # Quality score (0-100)
|
|
6104
|
+
${invocation} pkg vulns lodash@4.17.21 # CVEs, severity, upgrade paths
|
|
6105
|
+
${invocation} pkg deps express --transitive # Dependency tree
|
|
6106
|
+
${invocation} pkg compare lodash underscore ramda # Side-by-side comparison
|
|
6070
6107
|
\`\`\`
|
|
6071
6108
|
|
|
6072
6109
|
## Documentation
|
|
@@ -6082,6 +6119,7 @@ ${invocation} docs search "<query>" -P <packages> # Search docs only
|
|
|
6082
6119
|
- Package format: \`[registry:]name[@version]\` (e.g., \`pypi:django@4.2\`)
|
|
6083
6120
|
- Default registry: npm
|
|
6084
6121
|
- Use \`--json\` for structured output when parsing
|
|
6122
|
+
- Quick start: \`${invocation} code find <package> <function> --include-code\`
|
|
6085
6123
|
`;
|
|
6086
6124
|
}
|
|
6087
6125
|
function extractSkillVersion(content) {
|
|
@@ -6214,7 +6252,8 @@ PkgSeer skill ${action} for ${toolName}!`, useColors));
|
|
|
6214
6252
|
console.log(`Location: ${highlight(paths.skillPath, useColors)}`);
|
|
6215
6253
|
console.log(dim(`
|
|
6216
6254
|
The skill is now available. Try asking:
|
|
6217
|
-
` + ` "
|
|
6255
|
+
` + ` "How does express Router work internally?"
|
|
6256
|
+
` + ` "What changed between express v4 and v5?"
|
|
6218
6257
|
` + ` "Is lodash secure? Check for vulnerabilities"
|
|
6219
6258
|
` + ' "Compare axios vs fetch vs got"', useColors));
|
|
6220
6259
|
}
|
|
@@ -6828,8 +6867,9 @@ var argsSchema = {
|
|
|
6828
6867
|
function createCallPathTool(pkgseerService) {
|
|
6829
6868
|
return {
|
|
6830
6869
|
name: "call_path",
|
|
6831
|
-
description: "
|
|
6870
|
+
description: "Trace how execution flows from one function to another in a dependency — " + "debug how a public API reaches an internal function or error handler. " + "Uses BFS through intermediate calls. " + "Returns ordered call paths (shortest first) with hop details. " + "For direct callers/callees only, use symbol_callers or symbol_callees instead.",
|
|
6832
6871
|
schema: argsSchema,
|
|
6872
|
+
annotations: { readOnlyHint: true },
|
|
6833
6873
|
handler: async (args, _extra) => {
|
|
6834
6874
|
return withErrorHandling("find call path", async () => {
|
|
6835
6875
|
const fromInput = toSymbolReferenceInput(args.from);
|
|
@@ -6871,6 +6911,7 @@ function createComparePackagesTool(pkgseerService) {
|
|
|
6871
6911
|
name: "compare_packages",
|
|
6872
6912
|
description: "Compare 2-10 packages side-by-side. Use this when evaluating alternatives (e.g., react vs preact vs solid-js). " + "Returns for each package: quality score, download counts, vulnerability count, license, and latest version. " + "Supports cross-registry comparison (npm, pypi, hex, crates). " + 'Format: [{"registry":"npm","name":"lodash"},{"registry":"npm","name":"underscore"}]',
|
|
6873
6913
|
schema: argsSchema2,
|
|
6914
|
+
annotations: { readOnlyHint: true },
|
|
6874
6915
|
handler: async ({ packages }, _extra) => {
|
|
6875
6916
|
return withErrorHandling("compare packages", async () => {
|
|
6876
6917
|
const input2 = packages.map((pkg) => ({
|
|
@@ -6902,8 +6943,9 @@ var argsSchema3 = {
|
|
|
6902
6943
|
function createFetchCodeContextTool(pkgseerService) {
|
|
6903
6944
|
return {
|
|
6904
6945
|
name: "fetch_code_context",
|
|
6905
|
-
description: "
|
|
6946
|
+
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. " + "Returns full file or a specific line range. " + "Prefer find_symbol(include_code=true) for function/class lookup. " + "Requires repo_url, git_ref, and file_path.",
|
|
6906
6947
|
schema: argsSchema3,
|
|
6948
|
+
annotations: { readOnlyHint: true },
|
|
6907
6949
|
handler: async ({ repo_url, git_ref, file_path, start_line, end_line }, _extra) => {
|
|
6908
6950
|
return withErrorHandling("fetch code context", async () => {
|
|
6909
6951
|
const result = await pkgseerService.fetchCodeContext(repo_url, git_ref, file_path, {
|
|
@@ -6931,6 +6973,7 @@ function createFetchPackageDocTool(pkgseerService) {
|
|
|
6931
6973
|
name: "fetch_package_doc",
|
|
6932
6974
|
description: "Get full content of a documentation page. Requires page_id from list_package_docs. " + "Returns: title, full content (markdown/HTML), format type, navigation breadcrumbs, " + "source URL, and last updated timestamp. Use this when you need complete documentation, " + "not just search snippets.",
|
|
6933
6975
|
schema: argsSchema4,
|
|
6976
|
+
annotations: { readOnlyHint: true },
|
|
6934
6977
|
handler: async ({ page_id }, _extra) => {
|
|
6935
6978
|
return withErrorHandling("fetch documentation page", async () => {
|
|
6936
6979
|
const result = await pkgseerService.getDocPage(page_id);
|
|
@@ -6971,8 +7014,9 @@ var argsSchema5 = {
|
|
|
6971
7014
|
function createFindSymbolTool(pkgseerService) {
|
|
6972
7015
|
return {
|
|
6973
7016
|
name: "find_symbol",
|
|
6974
|
-
description: "
|
|
7017
|
+
description: "Read source code of any function, class, or method in a third-party package — " + "use instead of guessing implementations from training data. " + "Set include_code=true for full source inline. " + "Returns: symbol ref, name, qualified path, kind, file location, and optionally source code. " + "Omit name to get all public exports. Use namespace to filter by module path.",
|
|
6975
7018
|
schema: argsSchema5,
|
|
7019
|
+
annotations: { readOnlyHint: true },
|
|
6976
7020
|
handler: async (args, _extra) => {
|
|
6977
7021
|
return withErrorHandling("find symbol", async () => {
|
|
6978
7022
|
const result = await pkgseerService.findSymbol(toGraphQLRegistry(args.registry), args.package_name, {
|
|
@@ -7016,8 +7060,9 @@ var argsSchema6 = {
|
|
|
7016
7060
|
function createGrepRepoFileTool(pkgseerService) {
|
|
7017
7061
|
return {
|
|
7018
7062
|
name: "grep_repo_file",
|
|
7019
|
-
description: "Search for a pattern within a file
|
|
7063
|
+
description: "Search for a pattern within a dependency's source file — " + "find error messages, config keys, or specific patterns without cloning the repo. " + "Case-insensitive substring matching with context lines. " + "Faster than fetch_code_context for large files. " + "Use list_repo_files to discover file paths.",
|
|
7020
7064
|
schema: argsSchema6,
|
|
7065
|
+
annotations: { readOnlyHint: true },
|
|
7021
7066
|
handler: async (args, _extra) => {
|
|
7022
7067
|
return withErrorHandling("grep repo file", async () => {
|
|
7023
7068
|
const result = await pkgseerService.grepRepoFile(toGraphQLRegistry(args.registry), args.package_name, args.file_path, args.pattern, {
|
|
@@ -7050,8 +7095,9 @@ var argsSchema7 = {
|
|
|
7050
7095
|
function createListPackageDocsTool(pkgseerService) {
|
|
7051
7096
|
return {
|
|
7052
7097
|
name: "list_package_docs",
|
|
7053
|
-
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
|
|
7098
|
+
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.",
|
|
7054
7099
|
schema: argsSchema7,
|
|
7100
|
+
annotations: { readOnlyHint: true },
|
|
7055
7101
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7056
7102
|
return withErrorHandling("list package documentation", async () => {
|
|
7057
7103
|
const result = await pkgseerService.listPackageDocs(toGraphQLRegistry(registry), package_name, version2);
|
|
@@ -7079,8 +7125,9 @@ var argsSchema8 = {
|
|
|
7079
7125
|
function createListRepoFilesTool(pkgseerService) {
|
|
7080
7126
|
return {
|
|
7081
7127
|
name: "list_repo_files",
|
|
7082
|
-
description: "
|
|
7128
|
+
description: "Explore a dependency's file structure — " + "see what source files, configs, and docs exist. " + "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.",
|
|
7083
7129
|
schema: argsSchema8,
|
|
7130
|
+
annotations: { readOnlyHint: true },
|
|
7084
7131
|
handler: async (args, _extra) => {
|
|
7085
7132
|
return withErrorHandling("list repo files", async () => {
|
|
7086
7133
|
const result = await pkgseerService.listRepoFiles(toGraphQLRegistry(args.registry), args.package_name, {
|
|
@@ -7122,8 +7169,9 @@ var argsSchema9 = {
|
|
|
7122
7169
|
function createListSymbolsTool(pkgseerService) {
|
|
7123
7170
|
return {
|
|
7124
7171
|
name: "list_symbols",
|
|
7125
|
-
description: "Browse
|
|
7172
|
+
description: "Browse a dependency's public API or file-level symbols. " + "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.",
|
|
7126
7173
|
schema: argsSchema9,
|
|
7174
|
+
annotations: { readOnlyHint: true },
|
|
7127
7175
|
handler: async (args, _extra) => {
|
|
7128
7176
|
return withErrorHandling("list symbols", async () => {
|
|
7129
7177
|
const scope = toListScope(args.scope);
|
|
@@ -7245,6 +7293,7 @@ function createPackageDependenciesTool(pkgseerService) {
|
|
|
7245
7293
|
name: "package_dependencies",
|
|
7246
7294
|
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.",
|
|
7247
7295
|
schema: argsSchema10,
|
|
7296
|
+
annotations: { readOnlyHint: true },
|
|
7248
7297
|
handler: async ({ registry, package_name, version: version2, include_transitive, max_depth }, _extra) => {
|
|
7249
7298
|
return withErrorHandling("fetch package dependencies", async () => {
|
|
7250
7299
|
const result = await pkgseerService.getPackageDependencies(toGraphQLRegistry(registry), package_name, version2, include_transitive, max_depth);
|
|
@@ -7296,8 +7345,9 @@ var argsSchema11 = {
|
|
|
7296
7345
|
function createPackageImportsTool(pkgseerService) {
|
|
7297
7346
|
return {
|
|
7298
7347
|
name: "package_imports",
|
|
7299
|
-
description: "
|
|
7348
|
+
description: "See what a dependency imports — understand its internal dependencies and external package usage. " + "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.",
|
|
7300
7349
|
schema: argsSchema11,
|
|
7350
|
+
annotations: { readOnlyHint: true },
|
|
7301
7351
|
handler: async (args, _extra) => {
|
|
7302
7352
|
return withErrorHandling("fetch package imports", async () => {
|
|
7303
7353
|
const result = await pkgseerService.packageImports(toGraphQLRegistry(args.registry), args.package_name, {
|
|
@@ -7330,6 +7380,7 @@ function createPackageQualityTool(pkgseerService) {
|
|
|
7330
7380
|
name: "package_quality",
|
|
7331
7381
|
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.",
|
|
7332
7382
|
schema: argsSchema12,
|
|
7383
|
+
annotations: { readOnlyHint: true },
|
|
7333
7384
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7334
7385
|
return withErrorHandling("fetch package quality", async () => {
|
|
7335
7386
|
const result = await pkgseerService.getPackageQuality(toGraphQLRegistry(registry), package_name, version2);
|
|
@@ -7354,6 +7405,7 @@ function createPackageSummaryTool(pkgseerService) {
|
|
|
7354
7405
|
name: "package_summary",
|
|
7355
7406
|
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).",
|
|
7356
7407
|
schema: argsSchema13,
|
|
7408
|
+
annotations: { readOnlyHint: true },
|
|
7357
7409
|
handler: async ({ registry, package_name }, _extra) => {
|
|
7358
7410
|
return withErrorHandling("fetch package summary", async () => {
|
|
7359
7411
|
const result = await pkgseerService.getPackageSummary(toGraphQLRegistry(registry), package_name);
|
|
@@ -7379,6 +7431,7 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
|
|
|
7379
7431
|
name: "package_vulnerabilities",
|
|
7380
7432
|
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.",
|
|
7381
7433
|
schema: argsSchema14,
|
|
7434
|
+
annotations: { readOnlyHint: true },
|
|
7382
7435
|
handler: async ({ registry, package_name, version: version2 }, _extra) => {
|
|
7383
7436
|
return withErrorHandling("fetch package vulnerabilities", async () => {
|
|
7384
7437
|
const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry(registry), package_name, version2);
|
|
@@ -7446,6 +7499,7 @@ function createSearchTool(pkgseerService) {
|
|
|
7446
7499
|
name: "search",
|
|
7447
7500
|
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.",
|
|
7448
7501
|
schema: argsSchema15,
|
|
7502
|
+
annotations: { readOnlyHint: true },
|
|
7449
7503
|
handler: async ({ packages, query, mode, limit, waitTimeoutMs }, _extra) => {
|
|
7450
7504
|
return withErrorHandling("search packages", async () => {
|
|
7451
7505
|
const normalizedQuery = query.trim();
|
|
@@ -7510,8 +7564,9 @@ function createSearchProjectDocsTool(deps) {
|
|
|
7510
7564
|
const { pkgseerService, configService, defaultProjectDir } = deps;
|
|
7511
7565
|
return {
|
|
7512
7566
|
name: "search_project_docs",
|
|
7513
|
-
description: "
|
|
7567
|
+
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.",
|
|
7514
7568
|
schema: argsSchema16,
|
|
7569
|
+
annotations: { readOnlyHint: true },
|
|
7515
7570
|
handler: async ({
|
|
7516
7571
|
project_directory,
|
|
7517
7572
|
project,
|
|
@@ -7566,6 +7621,7 @@ function createSearchStatusTool(pkgseerService) {
|
|
|
7566
7621
|
name: "search_status",
|
|
7567
7622
|
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.",
|
|
7568
7623
|
schema: argsSchema17,
|
|
7624
|
+
annotations: { readOnlyHint: true },
|
|
7569
7625
|
handler: async ({ searchRef }, _extra) => {
|
|
7570
7626
|
return withErrorHandling("check search status", async () => {
|
|
7571
7627
|
const progressResult = await pkgseerService.getSearchProgress(searchRef);
|
|
@@ -7631,8 +7687,9 @@ var argsSchema18 = {
|
|
|
7631
7687
|
function createSearchSymbolsTool(pkgseerService) {
|
|
7632
7688
|
return {
|
|
7633
7689
|
name: "search_symbols",
|
|
7634
|
-
description: "
|
|
7690
|
+
description: "Search a dependency's source code by text — " + "find where error messages, exceptions, or patterns appear across functions, classes, and modules. " + "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 with find_symbol(name=<result.name>, include_code=true) for full source.",
|
|
7635
7691
|
schema: argsSchema18,
|
|
7692
|
+
annotations: { readOnlyHint: true },
|
|
7636
7693
|
handler: async (args, _extra) => {
|
|
7637
7694
|
return withErrorHandling("search symbols", async () => {
|
|
7638
7695
|
const result = await pkgseerService.searchSymbols(toGraphQLRegistry(args.registry), args.package_name, {
|
|
@@ -7682,8 +7739,9 @@ var argsSchema19 = {
|
|
|
7682
7739
|
function createSymbolCalleesTool(pkgseerService) {
|
|
7683
7740
|
return {
|
|
7684
7741
|
name: "symbol_callees",
|
|
7685
|
-
description: "
|
|
7742
|
+
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. " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callers for the reverse.",
|
|
7686
7743
|
schema: argsSchema19,
|
|
7744
|
+
annotations: { readOnlyHint: true },
|
|
7687
7745
|
handler: async (args, _extra) => {
|
|
7688
7746
|
return withErrorHandling("find symbol callees", async () => {
|
|
7689
7747
|
const symbolInput = toSymbolReferenceInput(args.symbol);
|
|
@@ -7722,8 +7780,9 @@ var argsSchema20 = {
|
|
|
7722
7780
|
function createSymbolCallersTool(pkgseerService) {
|
|
7723
7781
|
return {
|
|
7724
7782
|
name: "symbol_callers",
|
|
7725
|
-
description: "
|
|
7783
|
+
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. " + "Use same_package_only for within-package callers only. " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callees for the reverse.",
|
|
7726
7784
|
schema: argsSchema20,
|
|
7785
|
+
annotations: { readOnlyHint: true },
|
|
7727
7786
|
handler: async (args, _extra) => {
|
|
7728
7787
|
return withErrorHandling("find symbol callers", async () => {
|
|
7729
7788
|
const symbolInput = toSymbolReferenceInput(args.symbol);
|
|
@@ -7769,6 +7828,7 @@ function createTriggerIndexingTool(pkgseerService) {
|
|
|
7769
7828
|
name: "trigger_indexing",
|
|
7770
7829
|
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.",
|
|
7771
7830
|
schema: argsSchema21,
|
|
7831
|
+
annotations: { readOnlyHint: false, idempotentHint: true },
|
|
7772
7832
|
handler: async (args, _extra) => {
|
|
7773
7833
|
return withErrorHandling("trigger indexing", async () => {
|
|
7774
7834
|
const packages = args.packages?.map((p) => ({
|
|
@@ -7827,8 +7887,9 @@ var argsSchema22 = {
|
|
|
7827
7887
|
function createVersionDiffTool(pkgseerService) {
|
|
7828
7888
|
return {
|
|
7829
7889
|
name: "version_diff",
|
|
7830
|
-
description: "Compare
|
|
7890
|
+
description: "Compare two versions of a dependency to understand what changed — " + "use when debugging issues after upgrades or planning migrations. " + "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.",
|
|
7831
7891
|
schema: argsSchema22,
|
|
7892
|
+
annotations: { readOnlyHint: true },
|
|
7832
7893
|
handler: async (args, _extra) => {
|
|
7833
7894
|
return withErrorHandling("version diff", async () => {
|
|
7834
7895
|
const result = await pkgseerService.versionDiff(toGraphQLRegistry(args.registry), args.package_name, args.from_version, args.to_version, {
|
|
@@ -7849,6 +7910,28 @@ function createVersionDiffTool(pkgseerService) {
|
|
|
7849
7910
|
};
|
|
7850
7911
|
}
|
|
7851
7912
|
// src/commands/mcp.ts
|
|
7913
|
+
var PKGSEER_INSTRUCTIONS = `PkgSeer provides source code intelligence for third-party packages across npm, PyPI, Hex, and other registries. All tools are read-only except trigger_indexing (which only queues background work).
|
|
7914
|
+
|
|
7915
|
+
Use PkgSeer when:
|
|
7916
|
+
- A stack trace or error originates in a third-party dependency
|
|
7917
|
+
- You need to understand how a library function works internally
|
|
7918
|
+
- You want to trace call chains through dependency source code
|
|
7919
|
+
- You're evaluating, comparing, or auditing packages
|
|
7920
|
+
- You need to understand what changed between package versions
|
|
7921
|
+
|
|
7922
|
+
Instead of guessing library behavior from training data, use find_symbol(include_code=true) to read actual source.
|
|
7923
|
+
Instead of cloning repos to search code, use search_symbols or grep_repo_file.
|
|
7924
|
+
Instead of manually tracing call chains on GitHub, use symbol_callers and symbol_callees.
|
|
7925
|
+
|
|
7926
|
+
Tool groups:
|
|
7927
|
+
- Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
|
|
7928
|
+
- Browse files: list_repo_files, grep_repo_file, fetch_code_context
|
|
7929
|
+
- Search across packages: search, search_project_docs
|
|
7930
|
+
- Browse docs: list_package_docs, fetch_package_doc
|
|
7931
|
+
- Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
|
|
7932
|
+
- Utility: trigger_indexing, search_status, package_imports
|
|
7933
|
+
|
|
7934
|
+
Quick start: find_symbol(registry="npm", name="<function>", package_name="<pkg>", include_code=true) often answers the question in one call.`;
|
|
7852
7935
|
var TOOL_FACTORIES = {
|
|
7853
7936
|
package_summary: ({ pkgseerService }) => createPackageSummaryTool(pkgseerService),
|
|
7854
7937
|
package_vulnerabilities: ({ pkgseerService }) => createPackageVulnerabilitiesTool(pkgseerService),
|
|
@@ -7904,10 +7987,7 @@ var PROJECT_READ_TOOLS = ["search_project_docs"];
|
|
|
7904
7987
|
var ALL_TOOLS = [...PUBLIC_READ_TOOLS, ...PROJECT_READ_TOOLS];
|
|
7905
7988
|
function createMcpServer(deps) {
|
|
7906
7989
|
const { pkgseerService, configService, config, fileSystemService } = deps;
|
|
7907
|
-
const server = new McpServer({
|
|
7908
|
-
name: "pkgseer",
|
|
7909
|
-
version: "0.1.0"
|
|
7910
|
-
});
|
|
7990
|
+
const server = new McpServer({ name: "pkgseer", version: "0.1.0" }, { instructions: PKGSEER_INSTRUCTIONS });
|
|
7911
7991
|
const defaultProjectDir = fileSystemService.getCwd();
|
|
7912
7992
|
const enabledToolNames = config.enabled_tools ?? ALL_TOOLS;
|
|
7913
7993
|
const toolsToRegister = enabledToolNames.filter((name) => ALL_TOOLS.includes(name));
|
|
@@ -7920,7 +8000,11 @@ function createMcpServer(deps) {
|
|
|
7920
8000
|
for (const toolName of toolsToRegister) {
|
|
7921
8001
|
const factory = TOOL_FACTORIES[toolName];
|
|
7922
8002
|
const tool = factory(factoryDeps);
|
|
7923
|
-
server.registerTool(tool.name, {
|
|
8003
|
+
server.registerTool(tool.name, {
|
|
8004
|
+
description: tool.description,
|
|
8005
|
+
inputSchema: tool.schema,
|
|
8006
|
+
annotations: tool.annotations
|
|
8007
|
+
}, tool.handler);
|
|
7924
8008
|
}
|
|
7925
8009
|
return server;
|
|
7926
8010
|
}
|
|
@@ -7969,10 +8053,13 @@ function registerMcpCommand(program) {
|
|
|
7969
8053
|
When run interactively (TTY), shows setup instructions.
|
|
7970
8054
|
When run via stdio (non-TTY), starts the MCP server.
|
|
7971
8055
|
|
|
7972
|
-
Available tools:
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
8056
|
+
Available tools (21):
|
|
8057
|
+
Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
|
|
8058
|
+
Browse files: list_repo_files, grep_repo_file, fetch_code_context
|
|
8059
|
+
Search: search, search_project_docs
|
|
8060
|
+
Docs: list_package_docs, fetch_package_doc
|
|
8061
|
+
Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
|
|
8062
|
+
Utility: trigger_indexing, search_status, package_imports`).action(async () => {
|
|
7976
8063
|
const deps = await createContainer();
|
|
7977
8064
|
if (process.stdout.isTTY && process.stdin.isTTY) {
|
|
7978
8065
|
showMcpSetupInstructions(deps);
|
package/dist/index.js
CHANGED