@pkgseer/cli 0.4.10 → 0.4.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  version
4
- } from "./shared/chunk-5nhq42tx.js";
4
+ } from "./shared/chunk-r3pnzy5b.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
@@ -1643,6 +1643,8 @@ var TOOL_NAMES = [
1643
1643
  "search_status",
1644
1644
  "fetch_code_context",
1645
1645
  "search_project_docs",
1646
+ "list_package_files",
1647
+ "grep_package_file",
1646
1648
  "find_symbol",
1647
1649
  "search_symbols",
1648
1650
  "list_symbols",
@@ -1651,8 +1653,6 @@ var TOOL_NAMES = [
1651
1653
  "package_imports",
1652
1654
  "call_path",
1653
1655
  "trigger_indexing",
1654
- "list_repo_files",
1655
- "grep_repo_file",
1656
1656
  "version_diff"
1657
1657
  ];
1658
1658
  var ToolNameSchema = z.enum(TOOL_NAMES);
@@ -2749,8 +2749,8 @@ function outputError(message, json) {
2749
2749
  }
2750
2750
  var CLI_HINTS = {
2751
2751
  being_indexed: " Hint: package is being indexed. Try again with a longer --wait value (e.g., --wait 30000).",
2752
- timeout: " Hint: lower the limit or narrow the scope, then retry.",
2753
- not_found: " Hint: verify the name/registry and that the resource exists.",
2752
+ timeout: " Hint: this may be transient — retry the same command. If the issue persists, try simplifying the query.",
2753
+ not_found: " Hint: verify the package name and registry are correct.",
2754
2754
  auth: " Hint: check login or token validity (pkgseer auth-status).",
2755
2755
  rate_limit: " Hint: wait and retry, or reduce request frequency.",
2756
2756
  unknown: ""
@@ -3007,14 +3007,10 @@ async function codeCalleesAction(symbolArg, options, deps) {
3007
3007
  waitTimeoutMs: parseWaitTimeout(options.wait)
3008
3008
  });
3009
3009
  handleErrors(result.errors, options.json ?? false);
3010
- if (!result.data?.symbolDependencies) {
3011
- outputError("Symbol not found. Verify the symbol reference or use --ref.", options.json ?? false);
3012
- return;
3013
- }
3014
3010
  if (options.json) {
3015
- output(result.data?.symbolDependencies, true);
3011
+ output(result.data.symbolDependencies, true);
3016
3012
  } else {
3017
- console.log(formatCalleesResult(result.data?.symbolDependencies));
3013
+ console.log(formatCalleesResult(result.data.symbolDependencies));
3018
3014
  }
3019
3015
  }
3020
3016
  var CALLEES_DESCRIPTION = `Find what a symbol calls.
@@ -3058,14 +3054,10 @@ async function codeCallersAction(symbolArg, options, deps) {
3058
3054
  waitTimeoutMs: parseWaitTimeout(options.wait)
3059
3055
  });
3060
3056
  handleErrors(result.errors, options.json ?? false);
3061
- if (!result.data?.symbolDependents) {
3062
- outputError("Symbol not found. Verify the symbol reference or use --ref.", options.json ?? false);
3063
- return;
3064
- }
3065
3057
  if (options.json) {
3066
- output(result.data?.symbolDependents, true);
3058
+ output(result.data.symbolDependents, true);
3067
3059
  } else {
3068
- console.log(formatCallersResult(result.data?.symbolDependents));
3060
+ console.log(formatCallersResult(result.data.symbolDependents));
3069
3061
  }
3070
3062
  }
3071
3063
  var CALLERS_DESCRIPTION = `Find what calls a symbol.
@@ -3130,14 +3122,10 @@ async function codeDiffAction(packageArg, fromVersion, toVersion, options, deps)
3130
3122
  waitTimeoutMs: parseWaitTimeout(options.wait)
3131
3123
  });
3132
3124
  handleErrors(result.errors, options.json ?? false);
3133
- if (!result.data?.versionDiff) {
3134
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3135
- return;
3136
- }
3137
3125
  if (options.json) {
3138
- output(result.data?.versionDiff, true);
3126
+ output(result.data.versionDiff, true);
3139
3127
  } else {
3140
- console.log(formatDiffResult(result.data?.versionDiff));
3128
+ console.log(formatDiffResult(result.data.versionDiff));
3141
3129
  }
3142
3130
  }
3143
3131
  var DIFF_DESCRIPTION = `Compare symbols between two package versions.
@@ -3190,11 +3178,7 @@ async function codeFilesAction(packageArg, options, deps) {
3190
3178
  waitTimeoutMs: parseWaitTimeout(options.wait)
3191
3179
  });
3192
3180
  handleErrors(result.errors, options.json ?? false);
3193
- if (!result.data?.listRepoFiles) {
3194
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3195
- return;
3196
- }
3197
- const data = result.data?.listRepoFiles;
3181
+ const data = result.data.listRepoFiles;
3198
3182
  if (options.json) {
3199
3183
  output(data, true);
3200
3184
  } else {
@@ -3255,11 +3239,7 @@ async function codeFindAction(packageArg, nameArg, options, deps) {
3255
3239
  waitTimeoutMs: parseWaitTimeout(options.wait)
3256
3240
  });
3257
3241
  handleErrors(result.errors, options.json ?? false);
3258
- if (!result.data?.findSymbol) {
3259
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3260
- return;
3261
- }
3262
- const data = result.data?.findSymbol;
3242
+ const data = result.data.findSymbol;
3263
3243
  if (options.json) {
3264
3244
  output(data, true);
3265
3245
  } else {
@@ -3329,11 +3309,7 @@ async function codeGrepAction(packageArg, filePath, pattern, options, deps) {
3329
3309
  waitTimeoutMs: parseWaitTimeout(options.wait)
3330
3310
  });
3331
3311
  handleErrors(result.errors, options.json ?? false);
3332
- if (!result.data?.grepRepoFile) {
3333
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3334
- return;
3335
- }
3336
- const data = result.data?.grepRepoFile;
3312
+ const data = result.data.grepRepoFile;
3337
3313
  if (options.json) {
3338
3314
  output(data, true);
3339
3315
  } else {
@@ -3416,14 +3392,10 @@ async function codeImportsAction(packageArg, options, deps) {
3416
3392
  waitTimeoutMs: parseWaitTimeout(options.wait)
3417
3393
  });
3418
3394
  handleErrors(result.errors, options.json ?? false);
3419
- if (!result.data?.packageImports) {
3420
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3421
- return;
3422
- }
3423
3395
  if (options.json) {
3424
- output(result.data?.packageImports, true);
3396
+ output(result.data.packageImports, true);
3425
3397
  } else {
3426
- console.log(formatImportsResult(result.data?.packageImports));
3398
+ console.log(formatImportsResult(result.data.packageImports));
3427
3399
  }
3428
3400
  }
3429
3401
  var IMPORTS_DESCRIPTION = `List import statements in a package.
@@ -3485,14 +3457,10 @@ async function codeListAction(packageArg, options, deps) {
3485
3457
  waitTimeoutMs: parseWaitTimeout(options.wait)
3486
3458
  });
3487
3459
  handleErrors(result.errors, options.json ?? false);
3488
- if (!result.data?.listSymbols) {
3489
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3490
- return;
3491
- }
3492
3460
  if (options.json) {
3493
- output(result.data?.listSymbols, true);
3461
+ output(result.data.listSymbols, true);
3494
3462
  } else {
3495
- console.log(formatListResult(result.data?.listSymbols));
3463
+ console.log(formatListResult(result.data.listSymbols));
3496
3464
  }
3497
3465
  }
3498
3466
  var LIST_DESCRIPTION = `Browse symbols in a package.
@@ -3550,14 +3518,10 @@ async function codePathAction(fromArg, toArg, options, deps) {
3550
3518
  waitTimeoutMs: parseWaitTimeout(options.wait)
3551
3519
  });
3552
3520
  handleErrors(result.errors, options.json ?? false);
3553
- if (!result.data?.callPath) {
3554
- outputError("Could not find call path. Verify the symbol references.", options.json ?? false);
3555
- return;
3556
- }
3557
3521
  if (options.json) {
3558
- output(result.data?.callPath, true);
3522
+ output(result.data.callPath, true);
3559
3523
  } else {
3560
- console.log(formatPathResult(result.data?.callPath));
3524
+ console.log(formatPathResult(result.data.callPath));
3561
3525
  }
3562
3526
  }
3563
3527
  var PATH_DESCRIPTION = `Find call path between two symbols.
@@ -3630,11 +3594,7 @@ async function codeSearchAction(packageArg, query, options, deps) {
3630
3594
  waitTimeoutMs: parseWaitTimeout(options.wait)
3631
3595
  });
3632
3596
  handleErrors(result.errors, options.json ?? false);
3633
- if (!result.data?.searchSymbols) {
3634
- outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3635
- return;
3636
- }
3637
- const data = result.data?.searchSymbols;
3597
+ const data = result.data.searchSymbols;
3638
3598
  if (options.json) {
3639
3599
  output(data, true);
3640
3600
  } else {
@@ -5118,7 +5078,7 @@ async function setupCodexViaCli(shellService) {
5118
5078
  }
5119
5079
  function showAvailableTools(hasProject, useColors) {
5120
5080
  console.log(`
5121
- Available MCP tools (21):`);
5081
+ Available MCP tools (22):`);
5122
5082
  console.log("");
5123
5083
  console.log(" Navigate source:");
5124
5084
  console.log(" • find_symbol - Read source code of functions/classes");
@@ -5129,8 +5089,8 @@ Available MCP tools (21):`);
5129
5089
  console.log(" • call_path - Find call path between two functions");
5130
5090
  console.log("");
5131
5091
  console.log(" Browse files:");
5132
- console.log(" • list_repo_files - Explore package file structure");
5133
- console.log(" • grep_repo_file - Search for patterns in source files");
5092
+ console.log(" • list_package_files - Explore package file structure");
5093
+ console.log(" • grep_package_file - Search for patterns in source files");
5134
5094
  console.log(" • fetch_code_context - Read source by file path and line range");
5135
5095
  console.log("");
5136
5096
  console.log(" Search & docs:");
@@ -6782,9 +6742,9 @@ function toListScope(scope) {
6782
6742
  var schemas = {
6783
6743
  registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).describe("Package registry (npm, pypi, hex, crates, nuget, maven, zig, or vcpkg)"),
6784
6744
  packageName: z2.string().max(255).describe("Name of the package"),
6785
- version: z2.string().max(100).optional().describe("Specific version (defaults to latest)"),
6745
+ version: z2.string().max(100).optional().describe("Specific version, e.g. '4.18.2' (defaults to latest)"),
6786
6746
  navigationMode: z2.enum(["summary", "detailed"]).optional().describe("Response detail level. summary (default) returns core fields; detailed adds all optional fields."),
6787
- waitTimeoutMs: z2.number().int().min(0).max(30000).optional().describe("Max milliseconds to wait for package indexing (0-30000). 0 = error immediately if not indexed."),
6747
+ waitTimeoutMs: z2.coerce.number().int().min(0).max(30000).optional().describe("Max milliseconds to wait for package indexing (0-30000, default 10000). Set 0 to error immediately if not indexed."),
6788
6748
  symbolReference: z2.object({
6789
6749
  symbol_ref: z2.string().optional().describe("Compound symbol reference (registry:package:version:id) from find_symbol or list_symbols results. Self-contained — no additional fields needed."),
6790
6750
  registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry (required for name-based lookup)"),
@@ -6800,9 +6760,10 @@ function toSymbolReferenceInput(ref) {
6800
6760
  symbolName: ref.symbol_name
6801
6761
  };
6802
6762
  }
6763
+ var DEFAULT_WAIT_TIMEOUT_MS2 = 1e4;
6803
6764
  var MCP_HINTS = {
6804
6765
  being_indexed: "Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).",
6805
- timeout: "Hint: try lowering the limit or narrowing the scope, then retry."
6766
+ timeout: "Hint: this may be transient — retry the same query. If the issue persists, try simplifying the query."
6806
6767
  };
6807
6768
  function buildHintedMessage(operation, message) {
6808
6769
  const kind = classifyError(message);
@@ -6830,9 +6791,9 @@ function buildHintedMessage(operation, message) {
6830
6791
  return `Failed to ${operation}: ${message}`;
6831
6792
  }
6832
6793
  var MCP_GRAPHQL_HINTS = {
6833
- not_found: "Hint: verify the name/registry and that the resource exists.",
6794
+ not_found: "Hint: verify the package name and registry are correct.",
6834
6795
  being_indexed: "Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).",
6835
- timeout: "Hint: try lowering the limit or narrowing the scope, then retry."
6796
+ timeout: "Hint: this may be transient — retry the same query. If the issue persists, try simplifying the query."
6836
6797
  };
6837
6798
  function handleGraphQLErrors(errors) {
6838
6799
  if (errors && errors.length > 0) {
@@ -6852,14 +6813,14 @@ async function withErrorHandling(operation, fn) {
6852
6813
  }
6853
6814
  }
6854
6815
  function notFoundError(packageName, registry) {
6855
- return errorResult(`Package not found: ${packageName} in ${registry}`);
6816
+ return errorResult(`Package not found: ${packageName} in ${registry}. Verify the package name and registry are correct.`);
6856
6817
  }
6857
6818
 
6858
6819
  // src/tools/call-path.ts
6859
6820
  var argsSchema = {
6860
6821
  from: schemas.symbolReference.describe("Source symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6861
6822
  to: schemas.symbolReference.describe("Destination symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6862
- max_depth: z3.number().int().min(1).max(10).optional().describe("Maximum path length to search (max hops between from and to)"),
6823
+ max_depth: z3.coerce.number().int().min(1).max(10).optional().describe("Maximum path length to search (max hops between from and to)"),
6863
6824
  mode: schemas.navigationMode,
6864
6825
  wait_timeout_ms: schemas.waitTimeoutMs
6865
6826
  };
@@ -6882,15 +6843,12 @@ function createCallPathTool(pkgseerService) {
6882
6843
  const result = await pkgseerService.callPath(fromInput, toInput, {
6883
6844
  maxDepth: args.max_depth,
6884
6845
  mode: toNavigationMode(args.mode),
6885
- waitTimeoutMs: args.wait_timeout_ms
6846
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
6886
6847
  });
6887
6848
  const graphqlError = handleGraphQLErrors(result.errors);
6888
6849
  if (graphqlError)
6889
6850
  return graphqlError;
6890
- if (!result.data?.callPath) {
6891
- return errorResult("Could not find call path. Verify the symbols exist and the package is indexed.");
6892
- }
6893
- return textResult(JSON.stringify(result.data?.callPath, null, 2));
6851
+ return textResult(JSON.stringify(result.data.callPath, null, 2));
6894
6852
  });
6895
6853
  }
6896
6854
  };
@@ -6908,7 +6866,7 @@ var argsSchema2 = {
6908
6866
  function createComparePackagesTool(pkgseerService) {
6909
6867
  return {
6910
6868
  name: "compare_packages",
6911
- 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"}]',
6869
+ description: "Compare 2-10 packages side-by-side (available immediately — no indexing required). " + "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"}]',
6912
6870
  schema: argsSchema2,
6913
6871
  annotations: { readOnlyHint: true },
6914
6872
  handler: async ({ packages }, _extra) => {
@@ -6933,16 +6891,22 @@ function createComparePackagesTool(pkgseerService) {
6933
6891
  // src/tools/fetch-code-context.ts
6934
6892
  import { z as z5 } from "zod";
6935
6893
  var argsSchema3 = {
6936
- repo_url: z5.string().min(1).describe("Repository URL (GitHub). Example: https://github.com/expressjs/express"),
6937
- git_ref: z5.string().min(1).describe("Git reference (tag, commit, or branch). Example: v4.18.2"),
6938
- file_path: z5.string().min(1).describe("Path to file in repository. Example: src/router/index.js"),
6939
- start_line: z5.number().int().positive().optional().describe("Starting line (1-indexed). If omitted, starts from line 1."),
6940
- end_line: z5.number().int().positive().optional().describe("Ending line. If omitted, returns to end of file.")
6894
+ repo_url: z5.string({
6895
+ error: "repo_url is required. Get it from package_summary (returns repository URL). " + "Or use find_symbol(include_code=true) to read source without needing repo_url."
6896
+ }).min(1).describe("Repository URL (GitHub). Example: https://github.com/expressjs/express"),
6897
+ git_ref: z5.string({
6898
+ error: "git_ref is required. Use the package version as a tag (e.g., 'v4.18.2'). " + "Get the latest version from package_summary."
6899
+ }).min(1).describe("Git reference (tag, commit, or branch). Example: v4.18.2"),
6900
+ file_path: z5.string({
6901
+ error: "file_path is required. Get file paths from find_symbol (returns file locations) " + "or list_package_files (browse package file structure)."
6902
+ }).min(1).describe("Path to file in repository. Example: src/router/index.js"),
6903
+ start_line: z5.coerce.number().int().positive().optional().describe("Starting line (1-indexed). If omitted, starts from line 1."),
6904
+ end_line: z5.coerce.number().int().positive().optional().describe("Ending line. If omitted, returns to end of file.")
6941
6905
  };
6942
6906
  function createFetchCodeContextTool(pkgseerService) {
6943
6907
  return {
6944
6908
  name: "fetch_code_context",
6945
- 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.",
6909
+ 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 (from package_summary), git_ref (version tag, e.g. 'v4.18.2'), " + "and file_path (from find_symbol or list_package_files). " + "Operates on the full repository — not filtered to package subdirectory in monorepos.",
6946
6910
  schema: argsSchema3,
6947
6911
  annotations: { readOnlyHint: true },
6948
6912
  handler: async ({ repo_url, git_ref, file_path, start_line, end_line }, _extra) => {
@@ -6970,7 +6934,7 @@ var argsSchema4 = {
6970
6934
  function createFetchPackageDocTool(pkgseerService) {
6971
6935
  return {
6972
6936
  name: "fetch_package_doc",
6973
- 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.",
6937
+ 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. " + "Requires documentation to have been crawled — if page_id is from a stale listing, re-check with list_package_docs.",
6974
6938
  schema: argsSchema4,
6975
6939
  annotations: { readOnlyHint: true },
6976
6940
  handler: async ({ page_id }, _extra) => {
@@ -7006,14 +6970,14 @@ var argsSchema5 = {
7006
6970
  public_only: z7.boolean().optional().describe("Only return public/exported symbols"),
7007
6971
  version: schemas.version,
7008
6972
  include_code: z7.boolean().optional().describe("Include source code in results"),
7009
- context_lines: z7.number().int().min(0).max(30).optional().describe("Lines of surrounding context when include_code=true (max 30)"),
6973
+ context_lines: z7.coerce.number().int().min(0).max(30).optional().describe("Lines of surrounding context when include_code=true (max 30)"),
7010
6974
  mode: schemas.navigationMode,
7011
6975
  wait_timeout_ms: schemas.waitTimeoutMs
7012
6976
  };
7013
6977
  function createFindSymbolTool(pkgseerService) {
7014
6978
  return {
7015
6979
  name: "find_symbol",
7016
- 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.",
6980
+ 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: symbolRef, name, qualified path, kind, file location, and optionally source code. " + "Omit name to get all public exports. Use namespace to filter by module path. " + "Pass symbolRef from results to symbol_callers, symbol_callees, or call_path.",
7017
6981
  schema: argsSchema5,
7018
6982
  annotations: { readOnlyHint: true },
7019
6983
  handler: async (args, _extra) => {
@@ -7027,15 +6991,12 @@ function createFindSymbolTool(pkgseerService) {
7027
6991
  includeCode: args.include_code,
7028
6992
  contextLines: args.context_lines,
7029
6993
  mode: toNavigationMode(args.mode),
7030
- waitTimeoutMs: args.wait_timeout_ms
6994
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7031
6995
  });
7032
6996
  const graphqlError = handleGraphQLErrors(result.errors);
7033
6997
  if (graphqlError)
7034
6998
  return graphqlError;
7035
- if (!result.data?.findSymbol) {
7036
- return notFoundError(args.package_name, args.registry);
7037
- }
7038
- const data = result.data?.findSymbol;
6999
+ const data = result.data.findSymbol;
7039
7000
  if (data.symbols.length === 0 && data.diagnostics?.hint) {
7040
7001
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7041
7002
  }
@@ -7044,39 +7005,36 @@ function createFindSymbolTool(pkgseerService) {
7044
7005
  }
7045
7006
  };
7046
7007
  }
7047
- // src/tools/grep-repo-file.ts
7008
+ // src/tools/grep-package-file.ts
7048
7009
  import { z as z8 } from "zod";
7049
7010
  var argsSchema6 = {
7050
7011
  registry: schemas.registry,
7051
7012
  package_name: schemas.packageName.describe("Name of the package to search within"),
7052
7013
  file_path: z8.string().describe("Path to the file (relative to package root)"),
7053
7014
  pattern: z8.string().max(200).describe("Case-insensitive substring to search for (max 200 chars)"),
7054
- context_lines: z8.number().int().min(0).max(10).optional().describe("Lines of context around each match (max 10)"),
7055
- max_matches: z8.number().int().min(1).max(200).optional().describe("Maximum matches to return (max 200)"),
7015
+ context_lines: z8.coerce.number().int().min(0).max(10).optional().describe("Lines of context around each match (max 10)"),
7016
+ max_matches: z8.coerce.number().int().min(1).max(200).optional().describe("Maximum matches to return (max 200)"),
7056
7017
  version: schemas.version,
7057
7018
  wait_timeout_ms: schemas.waitTimeoutMs
7058
7019
  };
7059
- function createGrepRepoFileTool(pkgseerService) {
7020
+ function createGrepPackageFileTool(pkgseerService) {
7060
7021
  return {
7061
- name: "grep_repo_file",
7062
- 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.",
7022
+ name: "grep_package_file",
7023
+ 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. " + "Use when you know the file path and are looking for specific text. " + "Use list_package_files to discover file paths. " + "In monorepos, operates only within this package's subdirectory. " + "Requires code indexing.",
7063
7024
  schema: argsSchema6,
7064
7025
  annotations: { readOnlyHint: true },
7065
7026
  handler: async (args, _extra) => {
7066
- return withErrorHandling("grep repo file", async () => {
7027
+ return withErrorHandling("grep package file", async () => {
7067
7028
  const result = await pkgseerService.grepRepoFile(toGraphQLRegistry(args.registry), args.package_name, args.file_path, args.pattern, {
7068
7029
  contextLines: args.context_lines,
7069
7030
  maxMatches: args.max_matches,
7070
7031
  version: args.version,
7071
- waitTimeoutMs: args.wait_timeout_ms
7032
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7072
7033
  });
7073
7034
  const graphqlError = handleGraphQLErrors(result.errors);
7074
7035
  if (graphqlError)
7075
7036
  return graphqlError;
7076
- if (!result.data?.grepRepoFile) {
7077
- return notFoundError(args.package_name, args.registry);
7078
- }
7079
- const data = result.data?.grepRepoFile;
7037
+ const data = result.data.grepRepoFile;
7080
7038
  if (data.matches.length === 0 && data.diagnostics?.hint) {
7081
7039
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7082
7040
  }
@@ -7094,7 +7052,7 @@ var argsSchema7 = {
7094
7052
  function createListPackageDocsTool(pkgseerService) {
7095
7053
  return {
7096
7054
  name: "list_package_docs",
7097
- 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.",
7055
+ description: "Discover available documentation pages for a package. Start here before fetching or searching docs. " + "Returns: page titles, unique IDs (needed for fetch_package_doc), word counts, and update timestamps. " + "Workflow: list_package_docs → fetch_package_doc for full content, or search(mode='docs') to find specific topics. " + "Requires documentation to have been crawled — if results are empty, use trigger_indexing first, then retry.",
7098
7056
  schema: argsSchema7,
7099
7057
  annotations: { readOnlyHint: true },
7100
7058
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
@@ -7111,37 +7069,34 @@ function createListPackageDocsTool(pkgseerService) {
7111
7069
  }
7112
7070
  };
7113
7071
  }
7114
- // src/tools/list-repo-files.ts
7072
+ // src/tools/list-package-files.ts
7115
7073
  import { z as z9 } from "zod";
7116
7074
  var argsSchema8 = {
7117
7075
  registry: schemas.registry,
7118
7076
  package_name: schemas.packageName.describe("Name of the package to list files for"),
7119
7077
  version: schemas.version,
7120
7078
  path_prefix: z9.string().optional().describe("Filter to files under this path (e.g., 'src/')"),
7121
- limit: z9.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
7079
+ limit: z9.coerce.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
7122
7080
  wait_timeout_ms: schemas.waitTimeoutMs
7123
7081
  };
7124
- function createListRepoFilesTool(pkgseerService) {
7082
+ function createListPackageFilesTool(pkgseerService) {
7125
7083
  return {
7126
- name: "list_repo_files",
7127
- 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.",
7084
+ name: "list_package_files",
7085
+ 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. " + "In monorepos, returns only files within this package's subdirectory. " + "Requires code indexing.",
7128
7086
  schema: argsSchema8,
7129
7087
  annotations: { readOnlyHint: true },
7130
7088
  handler: async (args, _extra) => {
7131
- return withErrorHandling("list repo files", async () => {
7089
+ return withErrorHandling("list package files", async () => {
7132
7090
  const result = await pkgseerService.listRepoFiles(toGraphQLRegistry(args.registry), args.package_name, {
7133
7091
  version: args.version,
7134
7092
  pathPrefix: args.path_prefix,
7135
7093
  limit: args.limit,
7136
- waitTimeoutMs: args.wait_timeout_ms
7094
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7137
7095
  });
7138
7096
  const graphqlError = handleGraphQLErrors(result.errors);
7139
7097
  if (graphqlError)
7140
7098
  return graphqlError;
7141
- if (!result.data?.listRepoFiles) {
7142
- return notFoundError(args.package_name, args.registry);
7143
- }
7144
- const data = result.data?.listRepoFiles;
7099
+ const data = result.data.listRepoFiles;
7145
7100
  if (data.files.length === 0 && data.diagnostics?.hint) {
7146
7101
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7147
7102
  }
@@ -7160,7 +7115,7 @@ var argsSchema9 = {
7160
7115
  namespace: z10.string().max(500).optional().describe("Filter by namespace prefix (e.g., 'React' to see React.*)"),
7161
7116
  public_only: z10.boolean().optional().describe("Only return public symbols"),
7162
7117
  include_popularity: z10.boolean().optional().describe("Include callerCount for each symbol (slightly slower)"),
7163
- limit: z10.number().int().min(1).max(100).optional().describe("Max symbols to return (max 100)"),
7118
+ limit: z10.coerce.number().int().min(1).max(100).optional().describe("Max symbols to return (max 100)"),
7164
7119
  version: schemas.version,
7165
7120
  mode: schemas.navigationMode,
7166
7121
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7193,15 +7148,12 @@ function createListSymbolsTool(pkgseerService) {
7193
7148
  limit: args.limit,
7194
7149
  version: args.version,
7195
7150
  mode: toNavigationMode(args.mode),
7196
- waitTimeoutMs: args.wait_timeout_ms
7151
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7197
7152
  });
7198
7153
  const graphqlError = handleGraphQLErrors(result.errors);
7199
7154
  if (graphqlError)
7200
7155
  return graphqlError;
7201
- if (!result.data?.listSymbols) {
7202
- return notFoundError(args.package_name, args.registry);
7203
- }
7204
- return textResult(JSON.stringify(result.data?.listSymbols, null, 2));
7156
+ return textResult(JSON.stringify(result.data.listSymbols, null, 2));
7205
7157
  });
7206
7158
  }
7207
7159
  };
@@ -7213,7 +7165,7 @@ var argsSchema10 = {
7213
7165
  package_name: schemas.packageName.describe("Name of the package to retrieve dependencies for"),
7214
7166
  version: schemas.version,
7215
7167
  include_transitive: z11.boolean().optional().describe("Whether to include transitive dependency DAG"),
7216
- max_depth: z11.number().int().min(1).max(10).optional().describe("Maximum depth for transitive traversal (1-10)")
7168
+ max_depth: z11.coerce.number().int().min(1).max(10).optional().describe("Maximum depth for transitive traversal (1-10)")
7217
7169
  };
7218
7170
  function decodeDag(rawDag) {
7219
7171
  if (!rawDag || typeof rawDag !== "object")
@@ -7336,7 +7288,7 @@ var argsSchema11 = {
7336
7288
  package_name: schemas.packageName.describe("Name of the package to get imports for"),
7337
7289
  file_path: z12.string().max(1000).optional().describe("Filter to a specific file path"),
7338
7290
  resolved_only: z12.boolean().optional().describe("Only return imports resolved to a known package"),
7339
- limit: z12.number().int().min(1).max(500).optional().describe("Max imports to return"),
7291
+ limit: z12.coerce.number().int().min(1).max(500).optional().describe("Max imports to return"),
7340
7292
  version: schemas.version,
7341
7293
  mode: schemas.navigationMode,
7342
7294
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7355,15 +7307,12 @@ function createPackageImportsTool(pkgseerService) {
7355
7307
  limit: args.limit,
7356
7308
  version: args.version,
7357
7309
  mode: toNavigationMode(args.mode),
7358
- waitTimeoutMs: args.wait_timeout_ms
7310
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7359
7311
  });
7360
7312
  const graphqlError = handleGraphQLErrors(result.errors);
7361
7313
  if (graphqlError)
7362
7314
  return graphqlError;
7363
- if (!result.data?.packageImports) {
7364
- return notFoundError(args.package_name, args.registry);
7365
- }
7366
- return textResult(JSON.stringify(result.data?.packageImports, null, 2));
7315
+ return textResult(JSON.stringify(result.data.packageImports, null, 2));
7367
7316
  });
7368
7317
  }
7369
7318
  };
@@ -7377,7 +7326,7 @@ var argsSchema12 = {
7377
7326
  function createPackageQualityTool(pkgseerService) {
7378
7327
  return {
7379
7328
  name: "package_quality",
7380
- 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.",
7329
+ description: "Evaluate package maintenance health and code quality (available immediately — no indexing required). " + "Use this to assess if a package is well-maintained " + "before adding it as a dependency. Returns: overall score (0-100), category scores (documentation, " + "testing, community, maintenance), and individual rule results with pass/fail status. " + "Useful for comparing quality between alternative packages.",
7381
7330
  schema: argsSchema12,
7382
7331
  annotations: { readOnlyHint: true },
7383
7332
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
@@ -7402,7 +7351,7 @@ var argsSchema13 = {
7402
7351
  function createPackageSummaryTool(pkgseerService) {
7403
7352
  return {
7404
7353
  name: "package_summary",
7405
- 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).",
7354
+ description: "Get a comprehensive overview of a package (available immediately — no indexing required). " + "Use this as your first tool when researching a package. " + "Returns: description, latest version, license, repository URL, download stats, " + "active security advisories count, and quickstart/installation instructions. " + "For deeper analysis, follow up with package_quality (maintenance health) or " + "package_vulnerabilities (security details). " + "Use package.repositoryUrl + package.latestVersion as git_ref with fetch_code_context to read source files.",
7406
7355
  schema: argsSchema13,
7407
7356
  annotations: { readOnlyHint: true },
7408
7357
  handler: async ({ registry, package_name }, _extra) => {
@@ -7428,7 +7377,7 @@ var argsSchema14 = {
7428
7377
  function createPackageVulnerabilitiesTool(pkgseerService) {
7429
7378
  return {
7430
7379
  name: "package_vulnerabilities",
7431
- 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.",
7380
+ description: "Check security vulnerabilities for a package (available immediately — no indexing required). " + "Use this before adding dependencies or when auditing existing ones. " + "Returns: list of CVEs/advisories with severity levels, affected version ranges, fixed versions, " + "and upgrade recommendations. If version is specified, shows only vulnerabilities affecting that version.",
7432
7381
  schema: argsSchema14,
7433
7382
  annotations: { readOnlyHint: true },
7434
7383
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
@@ -7452,13 +7401,16 @@ var packageInputSchema2 = z13.object({
7452
7401
  name: z13.string().min(1).describe("Package name"),
7453
7402
  version: z13.string().optional().describe("Specific version (defaults to latest)")
7454
7403
  });
7455
- var DEFAULT_AGENT_WAIT_TIMEOUT_MS = 1e4;
7456
7404
  var argsSchema15 = {
7457
- packages: z13.array(packageInputSchema2).min(1).max(20).describe("Packages to search (1-20). Each package needs registry and name."),
7458
- query: z13.string().min(1).describe("Search query - natural language or keywords"),
7405
+ packages: z13.array(packageInputSchema2, {
7406
+ error: 'packages is required. Provide 1-20 packages as [{registry: "npm", name: "express"}]. ' + "Use package_summary to verify a package exists. " + "For project-wide doc search without specifying packages, use search_project_docs instead."
7407
+ }).min(1).max(20).describe('Packages to search (1-20). Format: [{"registry":"npm","name":"express"}]'),
7408
+ query: z13.string({
7409
+ error: "query is required. Provide search terms as natural language or keywords, " + "e.g., 'error handling middleware'."
7410
+ }).min(1).describe("Search query - natural language or keywords"),
7459
7411
  mode: z13.enum(["all", "code", "docs"]).optional().describe('Search mode: "all" (default), "code" only, or "docs" only'),
7460
- limit: z13.number().int().min(1).max(100).optional().describe("Maximum results (default: 20)"),
7461
- waitTimeoutMs: z13.number().int().min(0).max(60000).optional().describe("Max milliseconds to wait for indexing (default: 10000, 0=immediate)")
7412
+ limit: z13.coerce.number().int().min(1).max(100).optional().describe("Maximum results (default: 20)"),
7413
+ waitTimeoutMs: z13.coerce.number().int().min(0).max(60000).optional().describe("Max milliseconds to wait for indexing (default: 10000, 0=immediate)")
7462
7414
  };
7463
7415
  function toSearchMode2(mode) {
7464
7416
  if (!mode)
@@ -7496,7 +7448,7 @@ Results may be incomplete. Retry later for more complete results.`;
7496
7448
  function createSearchTool(pkgseerService) {
7497
7449
  return {
7498
7450
  name: "search",
7499
- 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.",
7451
+ description: "Search code and documentation across packages using full-text search. " + "Returns code chunks and doc pages matching your query with relevance scores and snippets. " + "Use mode='code' for code only, mode='docs' for docs only, or mode='all' (default). " + "Provide 1-20 packages. For symbol-level results that feed into symbol_callers/symbol_callees, " + "use search_symbols instead. " + "For full source of code results, use find_symbol(name=<title>, include_code=true). " + "Code results include repoUrl and filePath for use with fetch_code_context. " + "If packages need indexing, waits up to waitTimeoutMs (default 10s) or returns searchRef — use search_status to poll.",
7500
7452
  schema: argsSchema15,
7501
7453
  annotations: { readOnlyHint: true },
7502
7454
  handler: async ({ packages, query, mode, limit, waitTimeoutMs }, _extra) => {
@@ -7513,7 +7465,7 @@ function createSearchTool(pkgseerService) {
7513
7465
  const result = await pkgseerService.combinedSearch(graphqlPackages, normalizedQuery, {
7514
7466
  mode: toSearchMode2(mode),
7515
7467
  limit,
7516
- waitTimeoutMs: waitTimeoutMs ?? DEFAULT_AGENT_WAIT_TIMEOUT_MS
7468
+ waitTimeoutMs: waitTimeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS2
7517
7469
  });
7518
7470
  const graphqlError = handleGraphQLErrors(result.errors);
7519
7471
  if (graphqlError)
@@ -7557,7 +7509,7 @@ var argsSchema16 = {
7557
7509
  terms: z14.array(z14.string()).optional().describe("Search terms to match. Provide a few key words or phrases that should appear in results."),
7558
7510
  match_mode: z14.enum(["any", "or", "all", "and"]).optional().describe('How to combine terms: "any" (OR) or "all" (AND).'),
7559
7511
  include_snippets: z14.boolean().optional().describe("Include content excerpts around matches"),
7560
- limit: z14.number().int().min(1).max(100).optional().describe("Maximum number of results to return")
7512
+ limit: z14.coerce.number().int().min(1).max(100).optional().describe("Maximum number of results to return")
7561
7513
  };
7562
7514
  function createSearchProjectDocsTool(deps) {
7563
7515
  const { pkgseerService, configService, defaultProjectDir } = deps;
@@ -7582,7 +7534,9 @@ function createSearchProjectDocsTool(deps) {
7582
7534
  return errorResult(`No project specified and no pkgseer.yml found. To fix:
7583
7535
  ` + ` 1. Pass project_directory: '/path/to/project' (folder containing pkgseer.yml)
7584
7536
  ` + ` 2. Pass project: 'project-name' directly if you know the project name
7585
- ` + " 3. Run 'pkgseer project init' to create pkgseer.yml in your project");
7537
+ ` + ` 3. Run 'pkgseer project init' to create pkgseer.yml in your project
7538
+
7539
+ ` + "Or use search(mode='docs', packages=[{registry: 'npm', name: '...'}]) to search " + "specific packages without a project.");
7586
7540
  }
7587
7541
  const normalizedTerms = terms?.map((term) => term.trim()).filter((term) => term.length > 0) ?? [];
7588
7542
  if (normalizedTerms.length === 0) {
@@ -7679,14 +7633,14 @@ var argsSchema18 = {
7679
7633
  ]).optional().describe("Filter results by code chunk type"),
7680
7634
  file_path: z16.string().optional().describe("Filter results to files whose path starts with this value (e.g., 'src/' for a directory)"),
7681
7635
  version: schemas.version,
7682
- limit: z16.number().int().min(1).max(50).optional().describe("Max results to return (max 50)"),
7636
+ limit: z16.coerce.number().int().min(1).max(50).optional().describe("Max results to return (max 50)"),
7683
7637
  mode: schemas.navigationMode,
7684
7638
  wait_timeout_ms: schemas.waitTimeoutMs
7685
7639
  };
7686
7640
  function createSearchSymbolsTool(pkgseerService) {
7687
7641
  return {
7688
7642
  name: "search_symbols",
7689
- 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.",
7643
+ description: "Search a dependency's source code by text using the code navigation index — " + "find where error messages, exceptions, or patterns appear across functions, classes, and modules. " + "Supports query string or keyword list with match_mode. " + "Use file_path to filter by directory (e.g., 'src/'). " + "Returns symbol-level results that can feed directly into symbol_callers, symbol_callees, or call_path. " + "Follow up with find_symbol(name=<result.name>, include_code=true) for full source. " + "For free-form text search across multiple packages, use search(mode='code') instead.",
7690
7644
  schema: argsSchema18,
7691
7645
  annotations: { readOnlyHint: true },
7692
7646
  handler: async (args, _extra) => {
@@ -7700,15 +7654,12 @@ function createSearchSymbolsTool(pkgseerService) {
7700
7654
  version: args.version,
7701
7655
  limit: args.limit,
7702
7656
  mode: toNavigationMode(args.mode),
7703
- waitTimeoutMs: args.wait_timeout_ms
7657
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7704
7658
  });
7705
7659
  const graphqlError = handleGraphQLErrors(result.errors);
7706
7660
  if (graphqlError)
7707
7661
  return graphqlError;
7708
- if (!result.data?.searchSymbols) {
7709
- return notFoundError(args.package_name, args.registry);
7710
- }
7711
- const data = result.data?.searchSymbols;
7662
+ const data = result.data.searchSymbols;
7712
7663
  const extra = {};
7713
7664
  if (data.results.length === 0 && data.diagnostics?.hint) {
7714
7665
  extra._hint = data.diagnostics.hint;
@@ -7728,9 +7679,9 @@ function createSearchSymbolsTool(pkgseerService) {
7728
7679
  import { z as z17 } from "zod";
7729
7680
  var argsSchema19 = {
7730
7681
  symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide either symbol_ref or registry + package_name + symbol_name."),
7731
- max_depth: z17.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
7732
- limit: z17.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
7733
- include_external: z17.boolean().optional().describe("Include calls to symbols in other packages"),
7682
+ max_depth: z17.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
7683
+ limit: z17.coerce.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
7684
+ include_external: z17.boolean().optional().describe("Include calls to symbols in other indexed packages. " + "Default (false) shows only calls within the same package."),
7734
7685
  include_builtins: z17.boolean().optional().describe("Include calls to built-in/standard library functions (console, Math, etc.)"),
7735
7686
  mode: schemas.navigationMode,
7736
7687
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7753,15 +7704,12 @@ function createSymbolCalleesTool(pkgseerService) {
7753
7704
  includeExternal: args.include_external,
7754
7705
  includeBuiltins: args.include_builtins,
7755
7706
  mode: toNavigationMode(args.mode),
7756
- waitTimeoutMs: args.wait_timeout_ms
7707
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7757
7708
  });
7758
7709
  const graphqlError = handleGraphQLErrors(result.errors);
7759
7710
  if (graphqlError)
7760
7711
  return graphqlError;
7761
- if (!result.data?.symbolDependencies) {
7762
- return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7763
- }
7764
- return textResult(JSON.stringify(result.data?.symbolDependencies, null, 2));
7712
+ return textResult(JSON.stringify(result.data.symbolDependencies, null, 2));
7765
7713
  });
7766
7714
  }
7767
7715
  };
@@ -7770,16 +7718,16 @@ function createSymbolCalleesTool(pkgseerService) {
7770
7718
  import { z as z18 } from "zod";
7771
7719
  var argsSchema20 = {
7772
7720
  symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide either symbol_ref or registry + package_name + symbol_name."),
7773
- same_package_only: z18.boolean().optional().describe("Only return callers from the same package"),
7774
- max_depth: z18.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callers only, 2+ = transitive, max 5)"),
7775
- limit: z18.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
7721
+ same_package_only: z18.boolean().optional().describe("Only return callers from the same package. " + "Default (false) includes callers from other indexed packages."),
7722
+ max_depth: z18.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callers only, 2+ = transitive, max 5)"),
7723
+ limit: z18.coerce.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
7776
7724
  mode: schemas.navigationMode,
7777
7725
  wait_timeout_ms: schemas.waitTimeoutMs
7778
7726
  };
7779
7727
  function createSymbolCallersTool(pkgseerService) {
7780
7728
  return {
7781
7729
  name: "symbol_callers",
7782
- 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.",
7730
+ 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. " + "Use find_symbol(include_code=true) on any caller to read its source.",
7783
7731
  schema: argsSchema20,
7784
7732
  annotations: { readOnlyHint: true },
7785
7733
  handler: async (args, _extra) => {
@@ -7793,15 +7741,12 @@ function createSymbolCallersTool(pkgseerService) {
7793
7741
  maxDepth: args.max_depth,
7794
7742
  maxResults: args.limit,
7795
7743
  mode: toNavigationMode(args.mode),
7796
- waitTimeoutMs: args.wait_timeout_ms
7744
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7797
7745
  });
7798
7746
  const graphqlError = handleGraphQLErrors(result.errors);
7799
7747
  if (graphqlError)
7800
7748
  return graphqlError;
7801
- if (!result.data?.symbolDependents) {
7802
- return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7803
- }
7804
- return textResult(JSON.stringify(result.data?.symbolDependents, null, 2));
7749
+ return textResult(JSON.stringify(result.data.symbolDependents, null, 2));
7805
7750
  });
7806
7751
  }
7807
7752
  };
@@ -7825,7 +7770,7 @@ var argsSchema21 = {
7825
7770
  function createTriggerIndexingTool(pkgseerService) {
7826
7771
  return {
7827
7772
  name: "trigger_indexing",
7828
- 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.",
7773
+ description: "Pre-warm PkgSeer indexes by triggering indexing for packages and/or repositories. " + "Fire-and-forget: triggers jobs and returns immediately with accepted/skipped counts. " + "Use before search or doc requests to ensure packages are indexed. " + "Code tools auto-wait via wait_timeout_ms on subsequent calls. Most packages index within 10-30s. " + "Rate limited to 10 requests per minute.",
7829
7774
  schema: argsSchema21,
7830
7775
  annotations: { readOnlyHint: false, idempotentHint: true },
7831
7776
  handler: async (args, _extra) => {
@@ -7880,7 +7825,7 @@ var argsSchema22 = {
7880
7825
  "type",
7881
7826
  "doc_section"
7882
7827
  ]).optional().describe("Filter by symbol kind"),
7883
- limit: z20.number().int().min(1).max(500).optional().describe("Max changes to return (max 500). Summary always reflects full counts."),
7828
+ limit: z20.coerce.number().int().min(1).max(500).optional().describe("Max changes to return (max 500). Summary always reflects full counts."),
7884
7829
  wait_timeout_ms: schemas.waitTimeoutMs
7885
7830
  };
7886
7831
  function createVersionDiffTool(pkgseerService) {
@@ -7895,15 +7840,12 @@ function createVersionDiffTool(pkgseerService) {
7895
7840
  includePrivate: args.include_private,
7896
7841
  kind: toSymbolKind(args.kind),
7897
7842
  limit: args.limit,
7898
- waitTimeoutMs: args.wait_timeout_ms
7843
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7899
7844
  });
7900
7845
  const graphqlError = handleGraphQLErrors(result.errors);
7901
7846
  if (graphqlError)
7902
7847
  return graphqlError;
7903
- if (!result.data?.versionDiff) {
7904
- return notFoundError(args.package_name, args.registry);
7905
- }
7906
- return textResult(JSON.stringify(result.data?.versionDiff, null, 2));
7848
+ return textResult(JSON.stringify(result.data.versionDiff, null, 2));
7907
7849
  });
7908
7850
  }
7909
7851
  };
@@ -7919,18 +7861,47 @@ Use PkgSeer when:
7919
7861
  - You need to understand what changed between package versions
7920
7862
 
7921
7863
  Instead of guessing library behavior from training data, use find_symbol(include_code=true) to read actual source.
7922
- Instead of cloning repos to search code, use search_symbols or grep_repo_file.
7864
+ Instead of cloning repos to search code, use search_symbols or grep_package_file.
7923
7865
  Instead of manually tracing call chains on GitHub, use symbol_callers and symbol_callees.
7924
7866
 
7925
- Tool groups:
7926
- - Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
7927
- - Browse files: list_repo_files, grep_repo_file, fetch_code_context
7928
- - Search across packages: search, search_project_docs
7929
- - Browse docs: list_package_docs, fetch_package_doc
7930
- - Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
7931
- - Utility: trigger_indexing, search_status, package_imports
7867
+ Data availability — tools are grouped by what backend data they need:
7868
+
7869
+ 1. Registry metadata (available immediately, no indexing):
7870
+ package_summary, package_quality, package_vulnerabilities, package_dependencies, compare_packages
7871
+ Start here when researching a package — these always work instantly.
7872
+
7873
+ 2. Documentation (requires doc site crawling):
7874
+ list_package_docs, fetch_package_doc, search(mode='docs'), search_project_docs
7875
+ If results are empty, docs may not be crawled yet — use trigger_indexing first, then retry.
7876
+
7877
+ 3. Package code (requires code repo indexing):
7878
+ find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path,
7879
+ package_imports, version_diff, list_package_files, grep_package_file, search(mode='code')
7880
+ These wait up to wait_timeout_ms (default 10s) for indexing. If indexing takes longer, you'll get a "being indexed" response — retry the same call. Most packages index within 10-30 seconds.
7881
+
7882
+ 4. Repository (full repo scope, not package-filtered):
7883
+ fetch_code_context
7884
+ Uses repo_url (get from package_summary) + git_ref (version tag) + file_path. Operates on the full repository, not filtered to a package subdirectory.
7885
+
7886
+ Scope — package vs repository:
7887
+ Package code tools (group 3) are scoped to a single package. In monorepos, they return only data from that package's subdirectory. fetch_code_context (group 4) operates on the full repository. symbol_callers/symbol_callees can show cross-package results from other indexed packages.
7888
+
7889
+ Choosing a code search tool:
7890
+ - search_symbols: single package, symbol-level → results feed symbol_callers/callees/call_path
7891
+ - search(mode='code'): multi-package, full-text → code chunks with snippets
7892
+ - grep_package_file: single file, pattern match → when you know the file path
7893
+
7894
+ Utility: trigger_indexing (pre-warm indexes), search_status (poll async search).
7895
+
7896
+ Quick start: find_symbol(registry="npm", name="<function>", package_name="<pkg>", include_code=true) often answers the question in one call.
7932
7897
 
7933
- Quick start: find_symbol(registry="npm", name="<function>", package_name="<pkg>", include_code=true) often answers the question in one call.`;
7898
+ Common workflows (pass symbolRef between tools for chaining):
7899
+ - Read source: find_symbol(name=<fn>, include_code=true)
7900
+ - Trace calls: find_symbol → symbol_callees(symbol={symbol_ref: <symbolRef>})
7901
+ - Find callers: find_symbol → symbol_callers(symbol={symbol_ref: <symbolRef>})
7902
+ - Read file: package_summary → fetch_code_context(repo_url, git_ref, file_path)
7903
+ - Search code: search_symbols (single pkg, feeds callers/callees) or search(mode='code', packages=[...]) (multi-pkg)
7904
+ - Browse docs: list_package_docs → fetch_package_doc(page_id)`;
7934
7905
  var TOOL_FACTORIES = {
7935
7906
  package_summary: ({ pkgseerService }) => createPackageSummaryTool(pkgseerService),
7936
7907
  package_vulnerabilities: ({ pkgseerService }) => createPackageVulnerabilitiesTool(pkgseerService),
@@ -7955,8 +7926,8 @@ var TOOL_FACTORIES = {
7955
7926
  package_imports: ({ pkgseerService }) => createPackageImportsTool(pkgseerService),
7956
7927
  call_path: ({ pkgseerService }) => createCallPathTool(pkgseerService),
7957
7928
  trigger_indexing: ({ pkgseerService }) => createTriggerIndexingTool(pkgseerService),
7958
- list_repo_files: ({ pkgseerService }) => createListRepoFilesTool(pkgseerService),
7959
- grep_repo_file: ({ pkgseerService }) => createGrepRepoFileTool(pkgseerService),
7929
+ list_package_files: ({ pkgseerService }) => createListPackageFilesTool(pkgseerService),
7930
+ grep_package_file: ({ pkgseerService }) => createGrepPackageFileTool(pkgseerService),
7960
7931
  version_diff: ({ pkgseerService }) => createVersionDiffTool(pkgseerService)
7961
7932
  };
7962
7933
  var PUBLIC_READ_TOOLS = [
@@ -7978,8 +7949,8 @@ var PUBLIC_READ_TOOLS = [
7978
7949
  "package_imports",
7979
7950
  "call_path",
7980
7951
  "trigger_indexing",
7981
- "list_repo_files",
7982
- "grep_repo_file",
7952
+ "list_package_files",
7953
+ "grep_package_file",
7983
7954
  "version_diff"
7984
7955
  ];
7985
7956
  var PROJECT_READ_TOOLS = ["search_project_docs"];
@@ -8052,9 +8023,9 @@ function registerMcpCommand(program) {
8052
8023
  When run interactively (TTY), shows setup instructions.
8053
8024
  When run via stdio (non-TTY), starts the MCP server.
8054
8025
 
8055
- Available tools (21):
8026
+ Available tools (22):
8056
8027
  Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
8057
- Browse files: list_repo_files, grep_repo_file, fetch_code_context
8028
+ Browse files: list_package_files, grep_package_file, fetch_code_context
8058
8029
  Search: search, search_project_docs
8059
8030
  Docs: list_package_docs, fetch_package_doc
8060
8031
  Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./shared/chunk-5nhq42tx.js";
3
+ } from "./shared/chunk-r3pnzy5b.js";
4
4
  export {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
1
  // package.json
2
- var version = "0.4.10";
2
+ var version = "0.4.11";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pkgseer/cli",
3
3
  "description": "CLI companion for PkgSeer - package intelligence for developers and AI assistants",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",