@pkgseer/cli 0.4.11 → 0.5.0

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-r3pnzy5b.js";
4
+ } from "./shared/chunk-kh5enjt9.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
@@ -315,13 +315,17 @@ var SearchResultsDocument = gql`
315
315
  }
316
316
  `;
317
317
  var FetchCodeContextDocument = gql`
318
- query FetchCodeContext($repoUrl: String!, $gitRef: String!, $filePath: String!, $startLine: Int, $endLine: Int) {
318
+ query FetchCodeContext($repoUrl: String, $gitRef: String, $registry: Registry, $packageName: String, $version: String, $filePath: String!, $startLine: Int, $endLine: Int, $waitTimeoutMs: Int) {
319
319
  fetchCodeContext(
320
320
  repoUrl: $repoUrl
321
321
  gitRef: $gitRef
322
+ registry: $registry
323
+ packageName: $packageName
324
+ version: $version
322
325
  filePath: $filePath
323
326
  startLine: $startLine
324
327
  endLine: $endLine
328
+ waitTimeoutMs: $waitTimeoutMs
325
329
  ) {
326
330
  content
327
331
  filePath
@@ -656,10 +660,12 @@ var SearchPackageDocsDocument = gql`
656
660
  }
657
661
  `;
658
662
  var FindSymbolDocument = gql`
659
- query FindSymbol($registry: Registry!, $packageName: String!, $name: String, $namespace: String, $kind: SymbolKind, $publicOnly: Boolean, $version: String, $includeCode: Boolean, $contextLines: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
663
+ query FindSymbol($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $name: String, $namespace: String, $kind: SymbolKind, $publicOnly: Boolean, $version: String, $includeCode: Boolean, $contextLines: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
660
664
  findSymbol(
661
665
  registry: $registry
662
666
  packageName: $packageName
667
+ repoUrl: $repoUrl
668
+ gitRef: $gitRef
663
669
  name: $name
664
670
  namespace: $namespace
665
671
  kind: $kind
@@ -697,10 +703,12 @@ var FindSymbolDocument = gql`
697
703
  }
698
704
  `;
699
705
  var SearchSymbolsDocument = gql`
700
- query SearchSymbols($registry: Registry!, $packageName: String!, $query: String, $keywords: [String!], $matchMode: MatchMode, $kind: SymbolKind, $filePath: String, $version: String, $limit: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
706
+ query SearchSymbols($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $query: String, $keywords: [String!], $matchMode: MatchMode, $kind: SymbolKind, $filePath: String, $version: String, $limit: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
701
707
  searchSymbols(
702
708
  registry: $registry
703
709
  packageName: $packageName
710
+ repoUrl: $repoUrl
711
+ gitRef: $gitRef
704
712
  query: $query
705
713
  keywords: $keywords
706
714
  matchMode: $matchMode
@@ -743,10 +751,12 @@ var SearchSymbolsDocument = gql`
743
751
  }
744
752
  `;
745
753
  var ListSymbolsDocument = gql`
746
- query ListSymbols($registry: Registry!, $packageName: String!, $scope: ListScope!, $filePath: String, $namespace: String, $publicOnly: Boolean, $includePopularity: Boolean, $limit: Int, $version: String, $mode: NavigationMode, $waitTimeoutMs: Int) {
754
+ query ListSymbols($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $scope: ListScope!, $filePath: String, $namespace: String, $publicOnly: Boolean, $includePopularity: Boolean, $limit: Int, $version: String, $mode: NavigationMode, $waitTimeoutMs: Int) {
747
755
  listSymbols(
748
756
  registry: $registry
749
757
  packageName: $packageName
758
+ repoUrl: $repoUrl
759
+ gitRef: $gitRef
750
760
  scope: $scope
751
761
  filePath: $filePath
752
762
  namespace: $namespace
@@ -848,10 +858,12 @@ var SymbolDependentsDocument = gql`
848
858
  }
849
859
  `;
850
860
  var PackageImportsDocument = gql`
851
- query PackageImports($registry: Registry!, $packageName: String!, $filePath: String, $resolvedOnly: Boolean, $limit: Int, $version: String, $mode: NavigationMode, $waitTimeoutMs: Int) {
861
+ query PackageImports($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $filePath: String, $resolvedOnly: Boolean, $limit: Int, $version: String, $mode: NavigationMode, $waitTimeoutMs: Int) {
852
862
  packageImports(
853
863
  registry: $registry
854
864
  packageName: $packageName
865
+ repoUrl: $repoUrl
866
+ gitRef: $gitRef
855
867
  filePath: $filePath
856
868
  resolvedOnly: $resolvedOnly
857
869
  limit: $limit
@@ -941,10 +953,12 @@ var SearchProjectDocsDocument = gql`
941
953
  }
942
954
  `;
943
955
  var ListRepoFilesDocument = gql`
944
- query ListRepoFiles($registry: Registry!, $packageName: String!, $version: String, $pathPrefix: String, $limit: Int, $waitTimeoutMs: Int) {
956
+ query ListRepoFiles($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $version: String, $pathPrefix: String, $limit: Int, $waitTimeoutMs: Int) {
945
957
  listRepoFiles(
946
958
  registry: $registry
947
959
  packageName: $packageName
960
+ repoUrl: $repoUrl
961
+ gitRef: $gitRef
948
962
  version: $version
949
963
  pathPrefix: $pathPrefix
950
964
  limit: $limit
@@ -971,10 +985,12 @@ var ListRepoFilesDocument = gql`
971
985
  }
972
986
  `;
973
987
  var GrepRepoFileDocument = gql`
974
- query GrepRepoFile($registry: Registry!, $packageName: String!, $filePath: String!, $pattern: String!, $contextLines: Int, $maxMatches: Int, $version: String, $waitTimeoutMs: Int) {
988
+ query GrepRepoFile($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $filePath: String!, $pattern: String!, $contextLines: Int, $maxMatches: Int, $version: String, $waitTimeoutMs: Int) {
975
989
  grepRepoFile(
976
990
  registry: $registry
977
991
  packageName: $packageName
992
+ repoUrl: $repoUrl
993
+ gitRef: $gitRef
978
994
  filePath: $filePath
979
995
  pattern: $pattern
980
996
  contextLines: $contextLines
@@ -1005,10 +1021,12 @@ var GrepRepoFileDocument = gql`
1005
1021
  }
1006
1022
  `;
1007
1023
  var VersionDiffDocument = gql`
1008
- query VersionDiff($registry: Registry!, $packageName: String!, $fromVersion: String!, $toVersion: String!, $includePrivate: Boolean, $kind: SymbolKind, $limit: Int, $waitTimeoutMs: Int) {
1024
+ query VersionDiff($registry: Registry, $packageName: String, $repoUrl: String, $gitRef: String, $fromVersion: String!, $toVersion: String!, $includePrivate: Boolean, $kind: SymbolKind, $limit: Int, $waitTimeoutMs: Int) {
1009
1025
  versionDiff(
1010
1026
  registry: $registry
1011
1027
  packageName: $packageName
1028
+ repoUrl: $repoUrl
1029
+ gitRef: $gitRef
1012
1030
  fromVersion: $fromVersion
1013
1031
  toVersion: $toVersion
1014
1032
  includePrivate: $includePrivate
@@ -1641,20 +1659,26 @@ var TOOL_NAMES = [
1641
1659
  "fetch_package_doc",
1642
1660
  "search",
1643
1661
  "search_status",
1644
- "fetch_code_context",
1662
+ "read_file",
1645
1663
  "search_project_docs",
1646
- "list_package_files",
1647
- "grep_package_file",
1664
+ "list_files",
1665
+ "grep_file",
1648
1666
  "find_symbol",
1649
1667
  "search_symbols",
1650
1668
  "list_symbols",
1651
1669
  "symbol_callers",
1652
1670
  "symbol_callees",
1653
- "package_imports",
1671
+ "list_imports",
1654
1672
  "call_path",
1655
1673
  "trigger_indexing",
1656
1674
  "version_diff"
1657
1675
  ];
1676
+ var TOOL_NAME_MIGRATION = {
1677
+ fetch_code_context: "read_file",
1678
+ list_package_files: "list_files",
1679
+ grep_package_file: "grep_file",
1680
+ package_imports: "list_imports"
1681
+ };
1658
1682
  var ToolNameSchema = z.enum(TOOL_NAMES);
1659
1683
  var SharedConfigFields = {
1660
1684
  enabled_tools: z.array(ToolNameSchema).optional()
@@ -1762,6 +1786,24 @@ class ConfigServiceImpl {
1762
1786
  if (parsed === null || parsed === undefined) {
1763
1787
  return schema.parse({});
1764
1788
  }
1789
+ if (parsed && typeof parsed === "object" && Array.isArray(parsed.enabled_tools)) {
1790
+ const migrated = [];
1791
+ let hasMigrations = false;
1792
+ for (const name of parsed.enabled_tools) {
1793
+ const replacement = TOOL_NAME_MIGRATION[name];
1794
+ if (replacement) {
1795
+ migrated.push(replacement);
1796
+ hasMigrations = true;
1797
+ } else {
1798
+ migrated.push(name);
1799
+ }
1800
+ }
1801
+ if (hasMigrations) {
1802
+ const oldNames = parsed.enabled_tools.filter((n) => TOOL_NAME_MIGRATION[n]);
1803
+ console.warn(`[pkgseer] Config at ${path}: migrating deprecated tool names: ${oldNames.join(", ")}. Update your config to use the new names.`);
1804
+ parsed.enabled_tools = migrated;
1805
+ }
1806
+ }
1765
1807
  const result = schema.safeParse(parsed);
1766
1808
  if (result.success) {
1767
1809
  return result.data;
@@ -2207,9 +2249,13 @@ class PkgseerServiceImpl {
2207
2249
  const result = await this.client.FetchCodeContext({
2208
2250
  repoUrl,
2209
2251
  gitRef,
2252
+ registry: options?.registry,
2253
+ packageName: options?.packageName,
2254
+ version: options?.version,
2210
2255
  filePath,
2211
2256
  startLine: options?.startLine,
2212
- endLine: options?.endLine
2257
+ endLine: options?.endLine,
2258
+ waitTimeoutMs: options?.waitTimeoutMs
2213
2259
  });
2214
2260
  return { data: result.data, errors: result.errors };
2215
2261
  }
@@ -2217,6 +2263,8 @@ class PkgseerServiceImpl {
2217
2263
  const result = await this.client.FindSymbol({
2218
2264
  registry,
2219
2265
  packageName,
2266
+ repoUrl: options?.repoUrl,
2267
+ gitRef: options?.gitRef,
2220
2268
  name: options?.name,
2221
2269
  namespace: options?.namespace,
2222
2270
  kind: options?.kind,
@@ -2233,6 +2281,8 @@ class PkgseerServiceImpl {
2233
2281
  const result = await this.client.SearchSymbols({
2234
2282
  registry,
2235
2283
  packageName,
2284
+ repoUrl: options?.repoUrl,
2285
+ gitRef: options?.gitRef,
2236
2286
  query: options?.query,
2237
2287
  keywords: options?.keywords,
2238
2288
  matchMode: options?.matchMode,
@@ -2249,6 +2299,8 @@ class PkgseerServiceImpl {
2249
2299
  const result = await this.client.ListSymbols({
2250
2300
  registry,
2251
2301
  packageName,
2302
+ repoUrl: options?.repoUrl,
2303
+ gitRef: options?.gitRef,
2252
2304
  scope,
2253
2305
  filePath: options?.filePath,
2254
2306
  namespace: options?.namespace,
@@ -2289,6 +2341,8 @@ class PkgseerServiceImpl {
2289
2341
  const result = await this.client.PackageImports({
2290
2342
  registry,
2291
2343
  packageName,
2344
+ repoUrl: options?.repoUrl,
2345
+ gitRef: options?.gitRef,
2292
2346
  filePath: options?.filePath,
2293
2347
  resolvedOnly: options?.resolvedOnly,
2294
2348
  limit: options?.limit,
@@ -2312,6 +2366,8 @@ class PkgseerServiceImpl {
2312
2366
  const result = await this.client.ListRepoFiles({
2313
2367
  registry,
2314
2368
  packageName,
2369
+ repoUrl: options?.repoUrl,
2370
+ gitRef: options?.gitRef,
2315
2371
  version: options?.version,
2316
2372
  pathPrefix: options?.pathPrefix,
2317
2373
  limit: options?.limit,
@@ -2323,6 +2379,8 @@ class PkgseerServiceImpl {
2323
2379
  const result = await this.client.GrepRepoFile({
2324
2380
  registry,
2325
2381
  packageName,
2382
+ repoUrl: options?.repoUrl,
2383
+ gitRef: options?.gitRef,
2326
2384
  filePath,
2327
2385
  pattern,
2328
2386
  contextLines: options?.contextLines,
@@ -2336,6 +2394,8 @@ class PkgseerServiceImpl {
2336
2394
  const result = await this.client.VersionDiff({
2337
2395
  registry,
2338
2396
  packageName,
2397
+ repoUrl: options?.repoUrl,
2398
+ gitRef: options?.gitRef,
2339
2399
  fromVersion,
2340
2400
  toVersion,
2341
2401
  includePrivate: options?.includePrivate,
@@ -6747,17 +6807,88 @@ var schemas = {
6747
6807
  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."),
6748
6808
  symbolReference: z2.object({
6749
6809
  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."),
6750
- registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry (required for name-based lookup)"),
6751
- package_name: z2.string().max(255).optional().describe("Package name (required for name-based lookup)"),
6752
- symbol_name: z2.string().max(500).optional().describe("Symbol name or qualified path (required for name-based lookup). Matches both short name and qualifiedPath.")
6753
- })
6810
+ registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry. For package-scoped lookup (with package_name + symbol_name)."),
6811
+ package_name: z2.string().max(255).optional().describe("Package name. For package-scoped lookup (with registry + symbol_name)."),
6812
+ symbol_name: z2.string().max(500).optional().describe("Symbol name or qualified path (required for name-based lookup). Matches both short name and qualifiedPath."),
6813
+ version: z2.string().max(100).optional().describe("Package version. For package-scoped lookup."),
6814
+ repo_url: z2.string().optional().describe("Repository URL (GitHub). For repo-scoped lookup (with git_ref + symbol_name)."),
6815
+ git_ref: z2.string().optional().describe("Git ref (tag, branch, commit, or HEAD). Required with repo_url.")
6816
+ }),
6817
+ codeTarget: z2.object({
6818
+ registry: z2.enum([
6819
+ "npm",
6820
+ "pypi",
6821
+ "hex",
6822
+ "crates",
6823
+ "nuget",
6824
+ "maven",
6825
+ "zig",
6826
+ "vcpkg"
6827
+ ]).optional().describe("Package registry (npm, pypi, hex, etc.). Required for package scope."),
6828
+ package_name: z2.string().max(255).optional().describe("Package name. Required for package scope."),
6829
+ version: z2.string().max(100).optional().describe("Package version, e.g. '4.18.2' (defaults to latest). For package scope only."),
6830
+ repo_url: z2.string().optional().describe("Repository URL (GitHub). Required for repo scope. Example: https://github.com/expressjs/express"),
6831
+ git_ref: z2.string().optional().describe("Git ref — tag, branch, or commit. Required for repo scope. Use HEAD for latest.")
6832
+ }).describe("Target: provide registry + package_name (package scope) OR repo_url + git_ref (repo scope).")
6754
6833
  };
6755
6834
  function toSymbolReferenceInput(ref) {
6756
6835
  return {
6757
6836
  symbolRef: ref.symbol_ref,
6758
6837
  registry: ref.registry ? toGraphQLRegistry(ref.registry) : undefined,
6759
6838
  packageName: ref.package_name,
6760
- symbolName: ref.symbol_name
6839
+ symbolName: ref.symbol_name,
6840
+ version: ref.version,
6841
+ repoUrl: ref.repo_url,
6842
+ gitRef: ref.git_ref
6843
+ };
6844
+ }
6845
+ function isToolError(value) {
6846
+ return "content" in value;
6847
+ }
6848
+ function resolveCodeTarget(target) {
6849
+ const hasPackage = target.registry || target.package_name;
6850
+ const hasRepo = target.repo_url || target.git_ref;
6851
+ if (hasPackage && hasRepo) {
6852
+ return errorResult("Invalid target: provide either registry + package_name (package scope) or repo_url + git_ref (repo scope), not both.");
6853
+ }
6854
+ if (!hasPackage && !hasRepo) {
6855
+ return errorResult("Missing target: provide registry + package_name (package scope) or repo_url + git_ref (repo scope).");
6856
+ }
6857
+ if (hasPackage) {
6858
+ if (!target.registry || !target.package_name) {
6859
+ return errorResult("Incomplete package target: both registry and package_name are required for package scope.");
6860
+ }
6861
+ return {
6862
+ mode: "package",
6863
+ registry: target.registry,
6864
+ packageName: target.package_name,
6865
+ version: target.version
6866
+ };
6867
+ }
6868
+ if (!target.repo_url) {
6869
+ return errorResult("Incomplete repo target: repo_url is required with git_ref.");
6870
+ }
6871
+ if (!target.git_ref) {
6872
+ return errorResult("Incomplete repo target: git_ref is required with repo_url (use HEAD for latest).");
6873
+ }
6874
+ return { mode: "repo", repoUrl: target.repo_url, gitRef: target.git_ref };
6875
+ }
6876
+ function buildCodeTargetVars(resolved) {
6877
+ if (resolved.mode === "package") {
6878
+ return {
6879
+ registry: toGraphQLRegistry(resolved.registry),
6880
+ packageName: resolved.packageName,
6881
+ version: resolved.version,
6882
+ repoUrl: undefined,
6883
+ gitRef: undefined
6884
+ };
6885
+ }
6886
+ return {
6887
+ registry: undefined,
6888
+ packageName: undefined,
6889
+ version: undefined,
6890
+ repoUrl: resolved.repoUrl,
6891
+ gitRef: resolved.gitRef
6761
6892
  };
6762
6893
  }
6763
6894
  var DEFAULT_WAIT_TIMEOUT_MS2 = 1e4;
@@ -6818,8 +6949,8 @@ function notFoundError(packageName, registry) {
6818
6949
 
6819
6950
  // src/tools/call-path.ts
6820
6951
  var argsSchema = {
6821
- from: schemas.symbolReference.describe("Source symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6822
- to: schemas.symbolReference.describe("Destination symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6952
+ from: schemas.symbolReference.describe("Source symbol. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
6953
+ to: schemas.symbolReference.describe("Destination symbol. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
6823
6954
  max_depth: z3.coerce.number().int().min(1).max(10).optional().describe("Maximum path length to search (max hops between from and to)"),
6824
6955
  mode: schemas.navigationMode,
6825
6956
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -6827,18 +6958,18 @@ var argsSchema = {
6827
6958
  function createCallPathTool(pkgseerService) {
6828
6959
  return {
6829
6960
  name: "call_path",
6830
- 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.",
6961
+ 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. " + "Supports package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "For direct callers/callees only, use symbol_callers or symbol_callees instead.",
6831
6962
  schema: argsSchema,
6832
6963
  annotations: { readOnlyHint: true },
6833
6964
  handler: async (args, _extra) => {
6834
6965
  return withErrorHandling("find call path", async () => {
6835
6966
  const fromInput = toSymbolReferenceInput(args.from);
6836
6967
  const toInput = toSymbolReferenceInput(args.to);
6837
- if (!fromInput.symbolRef && (!fromInput.symbolName || !fromInput.registry || !fromInput.packageName)) {
6838
- return errorResult("Invalid 'from' symbol: provide either symbol_ref or symbol_name with registry and package_name.");
6968
+ if (!fromInput.symbolRef && !(fromInput.symbolName && fromInput.registry && fromInput.packageName) && !(fromInput.symbolName && fromInput.repoUrl && fromInput.gitRef)) {
6969
+ return errorResult("Invalid 'from' symbol: provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name.");
6839
6970
  }
6840
- if (!toInput.symbolRef && (!toInput.symbolName || !toInput.registry || !toInput.packageName)) {
6841
- return errorResult("Invalid 'to' symbol: provide either symbol_ref or symbol_name with registry and package_name.");
6971
+ if (!toInput.symbolRef && !(toInput.symbolName && toInput.registry && toInput.packageName) && !(toInput.symbolName && toInput.repoUrl && toInput.gitRef)) {
6972
+ return errorResult("Invalid 'to' symbol: provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name.");
6842
6973
  }
6843
6974
  const result = await pkgseerService.callPath(fromInput, toInput, {
6844
6975
  maxDepth: args.max_depth,
@@ -6888,54 +7019,16 @@ function createComparePackagesTool(pkgseerService) {
6888
7019
  }
6889
7020
  };
6890
7021
  }
6891
- // src/tools/fetch-code-context.ts
7022
+ // src/tools/fetch-package-doc.ts
6892
7023
  import { z as z5 } from "zod";
6893
7024
  var argsSchema3 = {
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.")
6905
- };
6906
- function createFetchCodeContextTool(pkgseerService) {
6907
- return {
6908
- name: "fetch_code_context",
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.",
6910
- schema: argsSchema3,
6911
- annotations: { readOnlyHint: true },
6912
- handler: async ({ repo_url, git_ref, file_path, start_line, end_line }, _extra) => {
6913
- return withErrorHandling("fetch code context", async () => {
6914
- const result = await pkgseerService.fetchCodeContext(repo_url, git_ref, file_path, {
6915
- startLine: start_line,
6916
- endLine: end_line
6917
- });
6918
- const graphqlError = handleGraphQLErrors(result.errors);
6919
- if (graphqlError)
6920
- return graphqlError;
6921
- if (!result.data?.fetchCodeContext) {
6922
- return errorResult(`Code not found: ${file_path} at ${git_ref} in ${repo_url}. ` + "Check that the repository, file path, and git ref are correct.");
6923
- }
6924
- return textResult(JSON.stringify(result.data?.fetchCodeContext, null, 2));
6925
- });
6926
- }
6927
- };
6928
- }
6929
- // src/tools/fetch-package-doc.ts
6930
- import { z as z6 } from "zod";
6931
- var argsSchema4 = {
6932
- page_id: z6.string().max(500).describe("Globally unique documentation page identifier (from list_package_docs)")
7025
+ page_id: z5.string().max(500).describe("Globally unique documentation page identifier (from list_package_docs)")
6933
7026
  };
6934
7027
  function createFetchPackageDocTool(pkgseerService) {
6935
7028
  return {
6936
7029
  name: "fetch_package_doc",
6937
7030
  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.",
6938
- schema: argsSchema4,
7031
+ schema: argsSchema3,
6939
7032
  annotations: { readOnlyHint: true },
6940
7033
  handler: async ({ page_id }, _extra) => {
6941
7034
  return withErrorHandling("fetch documentation page", async () => {
@@ -6952,13 +7045,12 @@ function createFetchPackageDocTool(pkgseerService) {
6952
7045
  };
6953
7046
  }
6954
7047
  // src/tools/find-symbol.ts
6955
- import { z as z7 } from "zod";
6956
- var argsSchema5 = {
6957
- registry: schemas.registry,
6958
- package_name: schemas.packageName.describe("Name of the package to search for symbols"),
6959
- name: z7.string().max(500).optional().describe("Symbol name to search for (exact match or prefix). Omit to return all public exports."),
6960
- namespace: z7.string().max(500).optional().describe("Filter by namespace/module path prefix"),
6961
- kind: z7.enum([
7048
+ import { z as z6 } from "zod";
7049
+ var argsSchema4 = {
7050
+ target: schemas.codeTarget,
7051
+ name: z6.string().max(500).optional().describe("Symbol name to search for (exact match or prefix). Omit to return all public exports."),
7052
+ namespace: z6.string().max(500).optional().describe("Filter by namespace/module path prefix"),
7053
+ kind: z6.enum([
6962
7054
  "function",
6963
7055
  "method",
6964
7056
  "class",
@@ -6967,31 +7059,36 @@ var argsSchema5 = {
6967
7059
  "type",
6968
7060
  "doc_section"
6969
7061
  ]).optional().describe("Filter by symbol kind"),
6970
- public_only: z7.boolean().optional().describe("Only return public/exported symbols"),
6971
- version: schemas.version,
6972
- include_code: z7.boolean().optional().describe("Include source code in results"),
6973
- context_lines: z7.coerce.number().int().min(0).max(30).optional().describe("Lines of surrounding context when include_code=true (max 30)"),
7062
+ public_only: z6.boolean().optional().describe("Only return public/exported symbols"),
7063
+ include_code: z6.boolean().optional().describe("Include source code in results"),
7064
+ context_lines: z6.coerce.number().int().min(0).max(30).optional().describe("Lines of surrounding context when include_code=true (max 30)"),
6974
7065
  mode: schemas.navigationMode,
6975
7066
  wait_timeout_ms: schemas.waitTimeoutMs
6976
7067
  };
6977
7068
  function createFindSymbolTool(pkgseerService) {
6978
7069
  return {
6979
7070
  name: "find_symbol",
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.",
6981
- schema: argsSchema5,
7071
+ description: "Read source code of any function, class, or method use instead of guessing " + "implementations from training data. Accepts package scope (registry + package_name) " + "or repo scope (repo_url + git_ref) via the target parameter. " + "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.",
7072
+ schema: argsSchema4,
6982
7073
  annotations: { readOnlyHint: true },
6983
7074
  handler: async (args, _extra) => {
6984
7075
  return withErrorHandling("find symbol", async () => {
6985
- const result = await pkgseerService.findSymbol(toGraphQLRegistry(args.registry), args.package_name, {
7076
+ const resolved = resolveCodeTarget(args.target);
7077
+ if (isToolError(resolved))
7078
+ return resolved;
7079
+ const tv = buildCodeTargetVars(resolved);
7080
+ const result = await pkgseerService.findSymbol(tv.registry, tv.packageName, {
6986
7081
  name: args.name,
6987
7082
  namespace: args.namespace,
6988
7083
  kind: toSymbolKind(args.kind),
6989
7084
  publicOnly: args.public_only,
6990
- version: args.version,
7085
+ version: tv.version,
6991
7086
  includeCode: args.include_code,
6992
7087
  contextLines: args.context_lines,
6993
7088
  mode: toNavigationMode(args.mode),
6994
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7089
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7090
+ repoUrl: tv.repoUrl,
7091
+ gitRef: tv.gitRef
6995
7092
  });
6996
7093
  const graphqlError = handleGraphQLErrors(result.errors);
6997
7094
  if (graphqlError)
@@ -7005,31 +7102,35 @@ function createFindSymbolTool(pkgseerService) {
7005
7102
  }
7006
7103
  };
7007
7104
  }
7008
- // src/tools/grep-package-file.ts
7009
- import { z as z8 } from "zod";
7010
- var argsSchema6 = {
7011
- registry: schemas.registry,
7012
- package_name: schemas.packageName.describe("Name of the package to search within"),
7013
- file_path: z8.string().describe("Path to the file (relative to package root)"),
7014
- pattern: z8.string().max(200).describe("Case-insensitive substring to search for (max 200 chars)"),
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)"),
7017
- version: schemas.version,
7105
+ // src/tools/grep-file.ts
7106
+ import { z as z7 } from "zod";
7107
+ var argsSchema5 = {
7108
+ target: schemas.codeTarget,
7109
+ file_path: z7.string().describe("Path to the file (relative to package root)"),
7110
+ pattern: z7.string().max(200).describe("Case-insensitive substring to search for (max 200 chars)"),
7111
+ context_lines: z7.coerce.number().int().min(0).max(10).optional().describe("Lines of context around each match (max 10)"),
7112
+ max_matches: z7.coerce.number().int().min(1).max(200).optional().describe("Maximum matches to return (max 200)"),
7018
7113
  wait_timeout_ms: schemas.waitTimeoutMs
7019
7114
  };
7020
- function createGrepPackageFileTool(pkgseerService) {
7115
+ function createGrepFileTool(pkgseerService) {
7021
7116
  return {
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.",
7024
- schema: argsSchema6,
7117
+ name: "grep_file",
7118
+ description: "Search for a pattern within a dependency's source file — " + "find error messages, config keys, or specific patterns without cloning the repo. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Case-insensitive substring matching with context lines. " + "Use when you know the file path and are looking for specific text. " + "Use list_files to discover file paths. " + "In monorepos with package scope, operates only within this package's subdirectory. " + "Requires code indexing.",
7119
+ schema: argsSchema5,
7025
7120
  annotations: { readOnlyHint: true },
7026
7121
  handler: async (args, _extra) => {
7027
- return withErrorHandling("grep package file", async () => {
7028
- const result = await pkgseerService.grepRepoFile(toGraphQLRegistry(args.registry), args.package_name, args.file_path, args.pattern, {
7122
+ return withErrorHandling("grep file", async () => {
7123
+ const resolved = resolveCodeTarget(args.target);
7124
+ if (isToolError(resolved))
7125
+ return resolved;
7126
+ const tv = buildCodeTargetVars(resolved);
7127
+ const result = await pkgseerService.grepRepoFile(tv.registry, tv.packageName, args.file_path, args.pattern, {
7029
7128
  contextLines: args.context_lines,
7030
7129
  maxMatches: args.max_matches,
7031
- version: args.version,
7032
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7130
+ version: tv.version,
7131
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7132
+ repoUrl: tv.repoUrl,
7133
+ gitRef: tv.gitRef
7033
7134
  });
7034
7135
  const graphqlError = handleGraphQLErrors(result.errors);
7035
7136
  if (graphqlError)
@@ -7043,64 +7144,108 @@ function createGrepPackageFileTool(pkgseerService) {
7043
7144
  }
7044
7145
  };
7045
7146
  }
7046
- // src/tools/list-package-docs.ts
7047
- var argsSchema7 = {
7048
- registry: schemas.registry,
7049
- package_name: schemas.packageName.describe("Name of the package to list documentation for"),
7050
- version: schemas.version
7147
+ // src/tools/list-files.ts
7148
+ import { z as z8 } from "zod";
7149
+ var argsSchema6 = {
7150
+ target: schemas.codeTarget,
7151
+ path_prefix: z8.string().optional().describe("Filter to files under this path (e.g., 'src/')"),
7152
+ limit: z8.coerce.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
7153
+ wait_timeout_ms: schemas.waitTimeoutMs
7051
7154
  };
7052
- function createListPackageDocsTool(pkgseerService) {
7155
+ function createListFilesTool(pkgseerService) {
7053
7156
  return {
7054
- name: "list_package_docs",
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.",
7056
- schema: argsSchema7,
7157
+ name: "list_files",
7158
+ description: "Explore a dependency's file structure " + "see what source files, configs, and docs exist. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns file paths, names, languages, types (source/doc/config), and sizes. " + "Use path_prefix to filter by directory (e.g., 'src/'). " + "Good first step when investigating unfamiliar package internals. " + "In monorepos with package scope, returns only files within this package's subdirectory. " + "Requires code indexing.",
7159
+ schema: argsSchema6,
7057
7160
  annotations: { readOnlyHint: true },
7058
- handler: async ({ registry, package_name, version: version2 }, _extra) => {
7059
- return withErrorHandling("list package documentation", async () => {
7060
- const result = await pkgseerService.listPackageDocs(toGraphQLRegistry(registry), package_name, version2);
7161
+ handler: async (args, _extra) => {
7162
+ return withErrorHandling("list files", async () => {
7163
+ const resolved = resolveCodeTarget(args.target);
7164
+ if (isToolError(resolved))
7165
+ return resolved;
7166
+ const tv = buildCodeTargetVars(resolved);
7167
+ const result = await pkgseerService.listRepoFiles(tv.registry, tv.packageName, {
7168
+ version: tv.version,
7169
+ pathPrefix: args.path_prefix,
7170
+ limit: args.limit,
7171
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7172
+ repoUrl: tv.repoUrl,
7173
+ gitRef: tv.gitRef
7174
+ });
7061
7175
  const graphqlError = handleGraphQLErrors(result.errors);
7062
7176
  if (graphqlError)
7063
7177
  return graphqlError;
7064
- if (!result.data?.listPackageDocs) {
7065
- return notFoundError(package_name, registry);
7178
+ const data = result.data.listRepoFiles;
7179
+ if (data.files.length === 0 && data.diagnostics?.hint) {
7180
+ return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7066
7181
  }
7067
- return textResult(JSON.stringify(result.data?.listPackageDocs, null, 2));
7182
+ return textResult(JSON.stringify(data, null, 2));
7068
7183
  });
7069
7184
  }
7070
7185
  };
7071
7186
  }
7072
- // src/tools/list-package-files.ts
7187
+ // src/tools/list-imports.ts
7073
7188
  import { z as z9 } from "zod";
7074
- var argsSchema8 = {
7075
- registry: schemas.registry,
7076
- package_name: schemas.packageName.describe("Name of the package to list files for"),
7077
- version: schemas.version,
7078
- path_prefix: z9.string().optional().describe("Filter to files under this path (e.g., 'src/')"),
7079
- limit: z9.coerce.number().int().min(1).max(1000).optional().describe("Max files to return (max 1000)"),
7189
+ var argsSchema7 = {
7190
+ target: schemas.codeTarget,
7191
+ file_path: z9.string().max(1000).optional().describe("Filter to a specific file path"),
7192
+ resolved_only: z9.boolean().optional().describe("Only return imports resolved to a known package"),
7193
+ limit: z9.coerce.number().int().min(1).max(500).optional().describe("Max imports to return"),
7194
+ mode: schemas.navigationMode,
7080
7195
  wait_timeout_ms: schemas.waitTimeoutMs
7081
7196
  };
7082
- function createListPackageFilesTool(pkgseerService) {
7197
+ function createListImportsTool(pkgseerService) {
7083
7198
  return {
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.",
7086
- schema: argsSchema8,
7199
+ name: "list_imports",
7200
+ description: "See what a dependency importsunderstand its internal dependencies and external package usage. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns parsed import/require/use statements with optional resolution to known packages. " + "Use resolved_only=true to see only imports that map to packages in the PkgSeer registry. " + "Includes: source path, imported names, and de-duplicated dependency list.",
7201
+ schema: argsSchema7,
7087
7202
  annotations: { readOnlyHint: true },
7088
7203
  handler: async (args, _extra) => {
7089
- return withErrorHandling("list package files", async () => {
7090
- const result = await pkgseerService.listRepoFiles(toGraphQLRegistry(args.registry), args.package_name, {
7091
- version: args.version,
7092
- pathPrefix: args.path_prefix,
7204
+ return withErrorHandling("list imports", async () => {
7205
+ const resolved = resolveCodeTarget(args.target);
7206
+ if (isToolError(resolved))
7207
+ return resolved;
7208
+ const tv = buildCodeTargetVars(resolved);
7209
+ const result = await pkgseerService.packageImports(tv.registry, tv.packageName, {
7210
+ filePath: args.file_path,
7211
+ resolvedOnly: args.resolved_only,
7093
7212
  limit: args.limit,
7094
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7213
+ version: tv.version,
7214
+ mode: toNavigationMode(args.mode),
7215
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7216
+ repoUrl: tv.repoUrl,
7217
+ gitRef: tv.gitRef
7095
7218
  });
7096
7219
  const graphqlError = handleGraphQLErrors(result.errors);
7097
7220
  if (graphqlError)
7098
7221
  return graphqlError;
7099
- const data = result.data.listRepoFiles;
7100
- if (data.files.length === 0 && data.diagnostics?.hint) {
7101
- return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7222
+ return textResult(JSON.stringify(result.data.packageImports, null, 2));
7223
+ });
7224
+ }
7225
+ };
7226
+ }
7227
+ // src/tools/list-package-docs.ts
7228
+ var argsSchema8 = {
7229
+ registry: schemas.registry,
7230
+ package_name: schemas.packageName.describe("Name of the package to list documentation for"),
7231
+ version: schemas.version
7232
+ };
7233
+ function createListPackageDocsTool(pkgseerService) {
7234
+ return {
7235
+ name: "list_package_docs",
7236
+ description: "Discover available documentation pages for a package. Start here before fetching or searching docs. " + "Returns: page titles, unique IDs (needed for fetch_package_doc), word counts, and update timestamps. " + "Workflow: list_package_docs → fetch_package_doc for full content, or search(mode='docs') to find specific topics. " + "Requires documentation to have been crawled — if results are empty, use trigger_indexing first, then retry.",
7237
+ schema: argsSchema8,
7238
+ annotations: { readOnlyHint: true },
7239
+ handler: async ({ registry, package_name, version: version2 }, _extra) => {
7240
+ return withErrorHandling("list package documentation", async () => {
7241
+ const result = await pkgseerService.listPackageDocs(toGraphQLRegistry(registry), package_name, version2);
7242
+ const graphqlError = handleGraphQLErrors(result.errors);
7243
+ if (graphqlError)
7244
+ return graphqlError;
7245
+ if (!result.data?.listPackageDocs) {
7246
+ return notFoundError(package_name, registry);
7102
7247
  }
7103
- return textResult(JSON.stringify(data, null, 2));
7248
+ return textResult(JSON.stringify(result.data?.listPackageDocs, null, 2));
7104
7249
  });
7105
7250
  }
7106
7251
  };
@@ -7108,22 +7253,20 @@ function createListPackageFilesTool(pkgseerService) {
7108
7253
  // src/tools/list-symbols.ts
7109
7254
  import { z as z10 } from "zod";
7110
7255
  var argsSchema9 = {
7111
- registry: schemas.registry,
7112
- package_name: schemas.packageName.describe("Name of the package to browse symbols for"),
7256
+ target: schemas.codeTarget,
7113
7257
  scope: z10.enum(["exports", "file"]).describe("Browsing scope: 'exports' for public API, 'file' for all symbols in a specific file"),
7114
7258
  file_path: z10.string().max(1000).optional().describe("File path within the repo (required when scope=file)"),
7115
7259
  namespace: z10.string().max(500).optional().describe("Filter by namespace prefix (e.g., 'React' to see React.*)"),
7116
7260
  public_only: z10.boolean().optional().describe("Only return public symbols"),
7117
7261
  include_popularity: z10.boolean().optional().describe("Include callerCount for each symbol (slightly slower)"),
7118
7262
  limit: z10.coerce.number().int().min(1).max(100).optional().describe("Max symbols to return (max 100)"),
7119
- version: schemas.version,
7120
7263
  mode: schemas.navigationMode,
7121
7264
  wait_timeout_ms: schemas.waitTimeoutMs
7122
7265
  };
7123
7266
  function createListSymbolsTool(pkgseerService) {
7124
7267
  return {
7125
7268
  name: "list_symbols",
7126
- 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.",
7269
+ description: "Browse a dependency's public API or file-level symbols. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Use scope='exports' for the public API with optional popularity ranking. " + "Use scope='file' with file_path for all symbols in a specific file. " + "Returns symbol refs, names, qualified paths, kinds, and file locations. " + "Use find_symbol(name=<symbol>, include_code=true) to read source for any result.",
7127
7270
  schema: argsSchema9,
7128
7271
  annotations: { readOnlyHint: true },
7129
7272
  handler: async (args, _extra) => {
@@ -7140,15 +7283,21 @@ function createListSymbolsTool(pkgseerService) {
7140
7283
  isError: true
7141
7284
  };
7142
7285
  }
7143
- const result = await pkgseerService.listSymbols(toGraphQLRegistry(args.registry), args.package_name, scope, {
7286
+ const resolved = resolveCodeTarget(args.target);
7287
+ if (isToolError(resolved))
7288
+ return resolved;
7289
+ const tv = buildCodeTargetVars(resolved);
7290
+ const result = await pkgseerService.listSymbols(tv.registry, tv.packageName, scope, {
7144
7291
  filePath: args.file_path,
7145
7292
  namespace: args.namespace,
7146
7293
  publicOnly: args.public_only,
7147
7294
  includePopularity: args.include_popularity,
7148
7295
  limit: args.limit,
7149
- version: args.version,
7296
+ version: tv.version,
7150
7297
  mode: toNavigationMode(args.mode),
7151
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7298
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7299
+ repoUrl: tv.repoUrl,
7300
+ gitRef: tv.gitRef
7152
7301
  });
7153
7302
  const graphqlError = handleGraphQLErrors(result.errors);
7154
7303
  if (graphqlError)
@@ -7281,44 +7430,8 @@ function createPackageDependenciesTool(pkgseerService) {
7281
7430
  }
7282
7431
  };
7283
7432
  }
7284
- // src/tools/package-imports.ts
7285
- import { z as z12 } from "zod";
7286
- var argsSchema11 = {
7287
- registry: schemas.registry,
7288
- package_name: schemas.packageName.describe("Name of the package to get imports for"),
7289
- file_path: z12.string().max(1000).optional().describe("Filter to a specific file path"),
7290
- resolved_only: z12.boolean().optional().describe("Only return imports resolved to a known package"),
7291
- limit: z12.coerce.number().int().min(1).max(500).optional().describe("Max imports to return"),
7292
- version: schemas.version,
7293
- mode: schemas.navigationMode,
7294
- wait_timeout_ms: schemas.waitTimeoutMs
7295
- };
7296
- function createPackageImportsTool(pkgseerService) {
7297
- return {
7298
- name: "package_imports",
7299
- 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
- schema: argsSchema11,
7301
- annotations: { readOnlyHint: true },
7302
- handler: async (args, _extra) => {
7303
- return withErrorHandling("fetch package imports", async () => {
7304
- const result = await pkgseerService.packageImports(toGraphQLRegistry(args.registry), args.package_name, {
7305
- filePath: args.file_path,
7306
- resolvedOnly: args.resolved_only,
7307
- limit: args.limit,
7308
- version: args.version,
7309
- mode: toNavigationMode(args.mode),
7310
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7311
- });
7312
- const graphqlError = handleGraphQLErrors(result.errors);
7313
- if (graphqlError)
7314
- return graphqlError;
7315
- return textResult(JSON.stringify(result.data.packageImports, null, 2));
7316
- });
7317
- }
7318
- };
7319
- }
7320
7433
  // src/tools/package-quality.ts
7321
- var argsSchema12 = {
7434
+ var argsSchema11 = {
7322
7435
  registry: schemas.registry,
7323
7436
  package_name: schemas.packageName.describe("Name of the package to analyze"),
7324
7437
  version: schemas.version
@@ -7327,7 +7440,7 @@ function createPackageQualityTool(pkgseerService) {
7327
7440
  return {
7328
7441
  name: "package_quality",
7329
7442
  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.",
7330
- schema: argsSchema12,
7443
+ schema: argsSchema11,
7331
7444
  annotations: { readOnlyHint: true },
7332
7445
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
7333
7446
  return withErrorHandling("fetch package quality", async () => {
@@ -7344,7 +7457,7 @@ function createPackageQualityTool(pkgseerService) {
7344
7457
  };
7345
7458
  }
7346
7459
  // src/tools/package-summary.ts
7347
- var argsSchema13 = {
7460
+ var argsSchema12 = {
7348
7461
  registry: schemas.registry,
7349
7462
  package_name: schemas.packageName.describe("Name of the package to retrieve summary for")
7350
7463
  };
@@ -7352,7 +7465,7 @@ function createPackageSummaryTool(pkgseerService) {
7352
7465
  return {
7353
7466
  name: "package_summary",
7354
7467
  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.",
7355
- schema: argsSchema13,
7468
+ schema: argsSchema12,
7356
7469
  annotations: { readOnlyHint: true },
7357
7470
  handler: async ({ registry, package_name }, _extra) => {
7358
7471
  return withErrorHandling("fetch package summary", async () => {
@@ -7369,7 +7482,7 @@ function createPackageSummaryTool(pkgseerService) {
7369
7482
  };
7370
7483
  }
7371
7484
  // src/tools/package-vulnerabilities.ts
7372
- var argsSchema14 = {
7485
+ var argsSchema13 = {
7373
7486
  registry: schemas.registry,
7374
7487
  package_name: schemas.packageName.describe("Name of the package to inspect for vulnerabilities"),
7375
7488
  version: schemas.version
@@ -7378,7 +7491,7 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
7378
7491
  return {
7379
7492
  name: "package_vulnerabilities",
7380
7493
  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.",
7381
- schema: argsSchema14,
7494
+ schema: argsSchema13,
7382
7495
  annotations: { readOnlyHint: true },
7383
7496
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
7384
7497
  return withErrorHandling("fetch package vulnerabilities", async () => {
@@ -7394,6 +7507,48 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
7394
7507
  }
7395
7508
  };
7396
7509
  }
7510
+ // src/tools/read-file.ts
7511
+ import { z as z12 } from "zod";
7512
+ var argsSchema14 = {
7513
+ target: schemas.codeTarget,
7514
+ file_path: z12.string({
7515
+ error: "file_path is required. Get file paths from find_symbol (returns file locations) " + "or list_files (browse file structure)."
7516
+ }).min(1).describe("Path to file in repository. Example: src/router/index.js"),
7517
+ start_line: z12.coerce.number().int().positive().optional().describe("Starting line (1-indexed). If omitted, starts from line 1."),
7518
+ end_line: z12.coerce.number().int().positive().optional().describe("Ending line. If omitted, returns to end of file."),
7519
+ wait_timeout_ms: schemas.waitTimeoutMs
7520
+ };
7521
+ function createReadFileTool(pkgseerService) {
7522
+ return {
7523
+ name: "read_file",
7524
+ description: "Read source code from a dependency's repository by file path and line range — " + "use when you have a file path from a stack trace or symbol lookup. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Returns full file or a specific line range. " + "Prefer find_symbol(include_code=true) for function/class lookup. " + "Use list_files to discover file paths. " + "With repo scope, operates on the full repository. " + "With package scope, scoped to the package subdirectory in monorepos.",
7525
+ schema: argsSchema14,
7526
+ annotations: { readOnlyHint: true },
7527
+ handler: async (args, _extra) => {
7528
+ return withErrorHandling("read file", async () => {
7529
+ const resolved = resolveCodeTarget(args.target);
7530
+ if (isToolError(resolved))
7531
+ return resolved;
7532
+ const tv = buildCodeTargetVars(resolved);
7533
+ const result = await pkgseerService.fetchCodeContext(tv.repoUrl, tv.gitRef, args.file_path, {
7534
+ startLine: args.start_line,
7535
+ endLine: args.end_line,
7536
+ registry: tv.registry,
7537
+ packageName: tv.packageName,
7538
+ version: tv.version,
7539
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7540
+ });
7541
+ const graphqlError = handleGraphQLErrors(result.errors);
7542
+ if (graphqlError)
7543
+ return graphqlError;
7544
+ if (!result.data?.fetchCodeContext) {
7545
+ return errorResult(`File not found: ${args.file_path}. ` + "Check that the file path and target are correct. " + "Use list_files to discover available files.");
7546
+ }
7547
+ return textResult(JSON.stringify(result.data.fetchCodeContext, null, 2));
7548
+ });
7549
+ }
7550
+ };
7551
+ }
7397
7552
  // src/tools/search.ts
7398
7553
  import { z as z13 } from "zod";
7399
7554
  var packageInputSchema2 = z13.object({
@@ -7617,8 +7772,7 @@ function createSearchStatusTool(pkgseerService) {
7617
7772
  // src/tools/search-symbols.ts
7618
7773
  import { z as z16 } from "zod";
7619
7774
  var argsSchema18 = {
7620
- registry: schemas.registry,
7621
- package_name: schemas.packageName.describe("Name of the package to search within"),
7775
+ target: schemas.codeTarget,
7622
7776
  query: z16.string().max(500).optional().describe("Search query for full-text code search (max 500 chars). Required if keywords not provided."),
7623
7777
  keywords: z16.array(z16.string()).max(20).optional().describe("Search keywords (max 20). Combined using match_mode. Alternative to query."),
7624
7778
  match_mode: z16.enum(["or", "and"]).optional().describe("How to combine keywords: or (any match) or and (all must match)"),
@@ -7632,7 +7786,6 @@ var argsSchema18 = {
7632
7786
  "doc_section"
7633
7787
  ]).optional().describe("Filter results by code chunk type"),
7634
7788
  file_path: z16.string().optional().describe("Filter results to files whose path starts with this value (e.g., 'src/' for a directory)"),
7635
- version: schemas.version,
7636
7789
  limit: z16.coerce.number().int().min(1).max(50).optional().describe("Max results to return (max 50)"),
7637
7790
  mode: schemas.navigationMode,
7638
7791
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7640,21 +7793,27 @@ var argsSchema18 = {
7640
7793
  function createSearchSymbolsTool(pkgseerService) {
7641
7794
  return {
7642
7795
  name: "search_symbols",
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.",
7796
+ description: "Search a dependency's source code by text using the code navigation index — " + "find where error messages, exceptions, or patterns appear across functions, classes, and modules. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "Supports query string or keyword list with match_mode. " + "Use file_path to filter by directory (e.g., 'src/'). " + "Returns symbol-level results that can feed directly into symbol_callers, symbol_callees, or call_path. " + "Follow up with find_symbol(name=<result.name>, include_code=true) for full source. " + "For free-form text search across multiple packages, use search(mode='code') instead.",
7644
7797
  schema: argsSchema18,
7645
7798
  annotations: { readOnlyHint: true },
7646
7799
  handler: async (args, _extra) => {
7647
7800
  return withErrorHandling("search symbols", async () => {
7648
- const result = await pkgseerService.searchSymbols(toGraphQLRegistry(args.registry), args.package_name, {
7801
+ const resolved = resolveCodeTarget(args.target);
7802
+ if (isToolError(resolved))
7803
+ return resolved;
7804
+ const tv = buildCodeTargetVars(resolved);
7805
+ const result = await pkgseerService.searchSymbols(tv.registry, tv.packageName, {
7649
7806
  query: args.query,
7650
7807
  keywords: args.keywords,
7651
7808
  matchMode: toMatchMode(args.match_mode),
7652
7809
  kind: toSymbolKind(args.kind),
7653
7810
  filePath: args.file_path,
7654
- version: args.version,
7811
+ version: tv.version,
7655
7812
  limit: args.limit,
7656
7813
  mode: toNavigationMode(args.mode),
7657
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
7814
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
7815
+ repoUrl: tv.repoUrl,
7816
+ gitRef: tv.gitRef
7658
7817
  });
7659
7818
  const graphqlError = handleGraphQLErrors(result.errors);
7660
7819
  if (graphqlError)
@@ -7678,7 +7837,7 @@ function createSearchSymbolsTool(pkgseerService) {
7678
7837
  // src/tools/symbol-callees.ts
7679
7838
  import { z as z17 } from "zod";
7680
7839
  var argsSchema19 = {
7681
- symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide either symbol_ref or registry + package_name + symbol_name."),
7840
+ symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
7682
7841
  max_depth: z17.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
7683
7842
  limit: z17.coerce.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
7684
7843
  include_external: z17.boolean().optional().describe("Include calls to symbols in other indexed packages. " + "Default (false) shows only calls within the same package."),
@@ -7689,14 +7848,14 @@ var argsSchema19 = {
7689
7848
  function createSymbolCalleesTool(pkgseerService) {
7690
7849
  return {
7691
7850
  name: "symbol_callees",
7692
- 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.",
7851
+ description: "Trace what a function calls internally — " + "understand dependency behavior by following its execution path. " + "Returns direct callees at max_depth=1, or transitive call chains at higher depths. " + "Includes callee names, qualified paths, file locations, call lines, and external package references. " + "Supports package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callers for the reverse.",
7693
7852
  schema: argsSchema19,
7694
7853
  annotations: { readOnlyHint: true },
7695
7854
  handler: async (args, _extra) => {
7696
7855
  return withErrorHandling("find symbol callees", async () => {
7697
7856
  const symbolInput = toSymbolReferenceInput(args.symbol);
7698
- if (!symbolInput.symbolRef && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7699
- return errorResult("Provide either symbol_ref or symbol_name with registry and package_name to identify the symbol.");
7857
+ if (!symbolInput.symbolRef && !(symbolInput.symbolName && symbolInput.registry && symbolInput.packageName) && !(symbolInput.symbolName && symbolInput.repoUrl && symbolInput.gitRef)) {
7858
+ return errorResult("Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name.");
7700
7859
  }
7701
7860
  const result = await pkgseerService.symbolDependencies(symbolInput, {
7702
7861
  maxDepth: args.max_depth,
@@ -7717,7 +7876,7 @@ function createSymbolCalleesTool(pkgseerService) {
7717
7876
  // src/tools/symbol-callers.ts
7718
7877
  import { z as z18 } from "zod";
7719
7878
  var argsSchema20 = {
7720
- symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide either symbol_ref or registry + package_name + symbol_name."),
7879
+ symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name."),
7721
7880
  same_package_only: z18.boolean().optional().describe("Only return callers from the same package. " + "Default (false) includes callers from other indexed packages."),
7722
7881
  max_depth: z18.coerce.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callers only, 2+ = transitive, max 5)"),
7723
7882
  limit: z18.coerce.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
@@ -7727,14 +7886,14 @@ var argsSchema20 = {
7727
7886
  function createSymbolCallersTool(pkgseerService) {
7728
7887
  return {
7729
7888
  name: "symbol_callers",
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.",
7889
+ description: "Trace what calls a function in a dependency's source code — " + "find entry points or debug why behavior triggers. " + "Returns callers with file locations and call line numbers. " + "Supports package scope (registry + package_name) or repo scope (repo_url + git_ref). " + "Use same_package_only for within-package callers only. " + "Get symbol_ref from find_symbol or list_symbols. See symbol_callees for the reverse. " + "Use find_symbol(include_code=true) on any caller to read its source.",
7731
7890
  schema: argsSchema20,
7732
7891
  annotations: { readOnlyHint: true },
7733
7892
  handler: async (args, _extra) => {
7734
7893
  return withErrorHandling("find symbol callers", async () => {
7735
7894
  const symbolInput = toSymbolReferenceInput(args.symbol);
7736
- if (!symbolInput.symbolRef && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7737
- return errorResult("Provide either symbol_ref or symbol_name with registry and package_name to identify the symbol.");
7895
+ if (!symbolInput.symbolRef && !(symbolInput.symbolName && symbolInput.registry && symbolInput.packageName) && !(symbolInput.symbolName && symbolInput.repoUrl && symbolInput.gitRef)) {
7896
+ return errorResult("Provide symbol_ref, or registry + package_name + symbol_name, or repo_url + git_ref + symbol_name.");
7738
7897
  }
7739
7898
  const result = await pkgseerService.symbolDependents(symbolInput, {
7740
7899
  samePackageOnly: args.same_package_only,
@@ -7811,8 +7970,7 @@ function createTriggerIndexingTool(pkgseerService) {
7811
7970
  // src/tools/version-diff.ts
7812
7971
  import { z as z20 } from "zod";
7813
7972
  var argsSchema22 = {
7814
- registry: schemas.registry,
7815
- package_name: schemas.packageName.describe("Name of the package to compare versions for"),
7973
+ target: schemas.codeTarget,
7816
7974
  from_version: z20.string().max(100).describe("Source version (git ref, e.g., 'v4.18.2')"),
7817
7975
  to_version: z20.string().max(100).describe("Target version (git ref, e.g., 'v5.0.0')"),
7818
7976
  include_private: z20.boolean().optional().describe("Include private/non-exported symbols in the diff"),
@@ -7831,16 +7989,22 @@ var argsSchema22 = {
7831
7989
  function createVersionDiffTool(pkgseerService) {
7832
7990
  return {
7833
7991
  name: "version_diff",
7834
- 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.",
7992
+ description: "Compare two versions of a dependency to understand what changed — " + "use when debugging issues after upgrades or planning migrations. " + "Accepts package scope (registry + package_name) or repo scope (repo_url + git_ref) via the target parameter. " + "With repo scope, from_version and to_version are literal git refs (tags, branches, commits) — " + "the backend does not normalize them. Use target.git_ref=HEAD to identify the repository. " + "Detects added, removed, moved, and modified symbols with severity " + "(breaking, behavior_change, non_breaking, internal). " + "Returns summary counts and per-symbol changes with file locations.",
7835
7993
  schema: argsSchema22,
7836
7994
  annotations: { readOnlyHint: true },
7837
7995
  handler: async (args, _extra) => {
7838
7996
  return withErrorHandling("version diff", async () => {
7839
- const result = await pkgseerService.versionDiff(toGraphQLRegistry(args.registry), args.package_name, args.from_version, args.to_version, {
7997
+ const resolved = resolveCodeTarget(args.target);
7998
+ if (isToolError(resolved))
7999
+ return resolved;
8000
+ const tv = buildCodeTargetVars(resolved);
8001
+ const result = await pkgseerService.versionDiff(tv.registry, tv.packageName, args.from_version, args.to_version, {
7840
8002
  includePrivate: args.include_private,
7841
8003
  kind: toSymbolKind(args.kind),
7842
8004
  limit: args.limit,
7843
- waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2
8005
+ waitTimeoutMs: args.wait_timeout_ms ?? DEFAULT_WAIT_TIMEOUT_MS2,
8006
+ repoUrl: tv.repoUrl,
8007
+ gitRef: tv.gitRef
7844
8008
  });
7845
8009
  const graphqlError = handleGraphQLErrors(result.errors);
7846
8010
  if (graphqlError)
@@ -7861,9 +8025,17 @@ Use PkgSeer when:
7861
8025
  - You need to understand what changed between package versions
7862
8026
 
7863
8027
  Instead of guessing library behavior from training data, use find_symbol(include_code=true) to read actual source.
7864
- Instead of cloning repos to search code, use search_symbols or grep_package_file.
8028
+ Instead of cloning repos to search code, use search_symbols or grep_file.
7865
8029
  Instead of manually tracing call chains on GitHub, use symbol_callers and symbol_callees.
7866
8030
 
8031
+ Dual addressing — code tools accept a target object with two modes:
8032
+ - Package scope: target: { registry: "npm", package_name: "express" } (optional version)
8033
+ In monorepos, results are scoped to the package's subdirectory.
8034
+ - Repo scope: target: { repo_url: "https://github.com/expressjs/express", git_ref: "v4.18.2" }
8035
+ Operates on the full repository, not filtered to a package subdirectory.
8036
+
8037
+ Use package scope when you know the package name. Use repo scope when you have a repo URL (e.g., from package_summary) and need full-repo access or the repo isn't published as a package.
8038
+
7867
8039
  Data availability — tools are grouped by what backend data they need:
7868
8040
 
7869
8041
  1. Registry metadata (available immediately, no indexing):
@@ -7874,32 +8046,31 @@ Data availability — tools are grouped by what backend data they need:
7874
8046
  list_package_docs, fetch_package_doc, search(mode='docs'), search_project_docs
7875
8047
  If results are empty, docs may not be crawled yet — use trigger_indexing first, then retry.
7876
8048
 
7877
- 3. Package code (requires code repo indexing):
8049
+ 3. Code navigation (requires code repo indexing, dual addressing via target):
7878
8050
  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')
8051
+ list_imports, version_diff, list_files, grep_file, read_file, search(mode='code')
7880
8052
  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
8053
 
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.
8054
+ Symbol reference tools (symbol_callers, symbol_callees, call_path) accept a symbol object with either:
8055
+ - symbol_ref from a previous find_symbol/search_symbols result (preferred, fastest)
8056
+ - Package lookup: registry + package_name + symbol_name
8057
+ - Repo lookup: repo_url + git_ref + symbol_name
8058
+ symbol_callers/symbol_callees can show cross-package results from other indexed packages.
7888
8059
 
7889
8060
  Choosing a code search tool:
7890
8061
  - search_symbols: single package, symbol-level → results feed symbol_callers/callees/call_path
7891
8062
  - 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
8063
+ - grep_file: single file, pattern match → when you know the file path
7893
8064
 
7894
8065
  Utility: trigger_indexing (pre-warm indexes), search_status (poll async search).
7895
8066
 
7896
- Quick start: find_symbol(registry="npm", name="<function>", package_name="<pkg>", include_code=true) often answers the question in one call.
8067
+ Quick start: find_symbol(target={registry:"npm", package_name:"<pkg>"}, name="<function>", include_code=true) often answers the question in one call.
7897
8068
 
7898
8069
  Common workflows (pass symbolRef between tools for chaining):
7899
- - Read source: find_symbol(name=<fn>, include_code=true)
8070
+ - Read source: find_symbol(target={registry, package_name}, name=<fn>, include_code=true)
7900
8071
  - Trace calls: find_symbol → symbol_callees(symbol={symbol_ref: <symbolRef>})
7901
8072
  - Find callers: find_symbol → symbol_callers(symbol={symbol_ref: <symbolRef>})
7902
- - Read file: package_summary fetch_code_context(repo_url, git_ref, file_path)
8073
+ - Read file: read_file(target={registry, package_name}, file_path=<path>) or read_file(target={repo_url, git_ref}, file_path=<path>)
7903
8074
  - Search code: search_symbols (single pkg, feeds callers/callees) or search(mode='code', packages=[...]) (multi-pkg)
7904
8075
  - Browse docs: list_package_docs → fetch_package_doc(page_id)`;
7905
8076
  var TOOL_FACTORIES = {
@@ -7912,7 +8083,7 @@ var TOOL_FACTORIES = {
7912
8083
  fetch_package_doc: ({ pkgseerService }) => createFetchPackageDocTool(pkgseerService),
7913
8084
  search: ({ pkgseerService }) => createSearchTool(pkgseerService),
7914
8085
  search_status: ({ pkgseerService }) => createSearchStatusTool(pkgseerService),
7915
- fetch_code_context: ({ pkgseerService }) => createFetchCodeContextTool(pkgseerService),
8086
+ read_file: ({ pkgseerService }) => createReadFileTool(pkgseerService),
7916
8087
  search_project_docs: ({ pkgseerService, configService, defaultProjectDir }) => createSearchProjectDocsTool({
7917
8088
  pkgseerService,
7918
8089
  configService,
@@ -7923,11 +8094,11 @@ var TOOL_FACTORIES = {
7923
8094
  list_symbols: ({ pkgseerService }) => createListSymbolsTool(pkgseerService),
7924
8095
  symbol_callers: ({ pkgseerService }) => createSymbolCallersTool(pkgseerService),
7925
8096
  symbol_callees: ({ pkgseerService }) => createSymbolCalleesTool(pkgseerService),
7926
- package_imports: ({ pkgseerService }) => createPackageImportsTool(pkgseerService),
8097
+ list_imports: ({ pkgseerService }) => createListImportsTool(pkgseerService),
7927
8098
  call_path: ({ pkgseerService }) => createCallPathTool(pkgseerService),
7928
8099
  trigger_indexing: ({ pkgseerService }) => createTriggerIndexingTool(pkgseerService),
7929
- list_package_files: ({ pkgseerService }) => createListPackageFilesTool(pkgseerService),
7930
- grep_package_file: ({ pkgseerService }) => createGrepPackageFileTool(pkgseerService),
8100
+ list_files: ({ pkgseerService }) => createListFilesTool(pkgseerService),
8101
+ grep_file: ({ pkgseerService }) => createGrepFileTool(pkgseerService),
7931
8102
  version_diff: ({ pkgseerService }) => createVersionDiffTool(pkgseerService)
7932
8103
  };
7933
8104
  var PUBLIC_READ_TOOLS = [
@@ -7940,24 +8111,24 @@ var PUBLIC_READ_TOOLS = [
7940
8111
  "fetch_package_doc",
7941
8112
  "search",
7942
8113
  "search_status",
7943
- "fetch_code_context",
8114
+ "read_file",
7944
8115
  "find_symbol",
7945
8116
  "search_symbols",
7946
8117
  "list_symbols",
7947
8118
  "symbol_callers",
7948
8119
  "symbol_callees",
7949
- "package_imports",
8120
+ "list_imports",
7950
8121
  "call_path",
7951
8122
  "trigger_indexing",
7952
- "list_package_files",
7953
- "grep_package_file",
8123
+ "list_files",
8124
+ "grep_file",
7954
8125
  "version_diff"
7955
8126
  ];
7956
8127
  var PROJECT_READ_TOOLS = ["search_project_docs"];
7957
8128
  var ALL_TOOLS = [...PUBLIC_READ_TOOLS, ...PROJECT_READ_TOOLS];
7958
8129
  function createMcpServer(deps) {
7959
8130
  const { pkgseerService, configService, config, fileSystemService } = deps;
7960
- const server = new McpServer({ name: "pkgseer", version: "0.1.0" }, { instructions: PKGSEER_INSTRUCTIONS });
8131
+ const server = new McpServer({ name: "pkgseer", version: "0.5.0" }, { instructions: PKGSEER_INSTRUCTIONS });
7961
8132
  const defaultProjectDir = fileSystemService.getCwd();
7962
8133
  const enabledToolNames = config.enabled_tools ?? ALL_TOOLS;
7963
8134
  const toolsToRegister = enabledToolNames.filter((name) => ALL_TOOLS.includes(name));
@@ -8025,11 +8196,11 @@ When run via stdio (non-TTY), starts the MCP server.
8025
8196
 
8026
8197
  Available tools (22):
8027
8198
  Navigate source: find_symbol, list_symbols, search_symbols, symbol_callers, symbol_callees, call_path
8028
- Browse files: list_package_files, grep_package_file, fetch_code_context
8199
+ Browse files: list_files, grep_file, read_file
8029
8200
  Search: search, search_project_docs
8030
8201
  Docs: list_package_docs, fetch_package_doc
8031
8202
  Evaluate: package_summary, package_quality, package_vulnerabilities, compare_packages, package_dependencies, version_diff
8032
- Utility: trigger_indexing, search_status, package_imports`).action(async () => {
8203
+ Utility: trigger_indexing, search_status, list_imports`).action(async () => {
8033
8204
  const deps = await createContainer();
8034
8205
  if (process.stdout.isTTY && process.stdin.isTTY) {
8035
8206
  showMcpSetupInstructions(deps);
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./shared/chunk-r3pnzy5b.js";
3
+ } from "./shared/chunk-kh5enjt9.js";
4
4
  export {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
1
  // package.json
2
- var version = "0.4.11";
2
+ var version = "0.5.0";
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.11",
4
+ "version": "0.5.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",