@pkgseer/cli 0.4.2 → 0.4.7

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-w4ht5me5.js";
4
+ } from "./shared/chunk-z0xepgqq.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
@@ -670,7 +670,7 @@ var FindSymbolDocument = gql`
670
670
  waitTimeoutMs: $waitTimeoutMs
671
671
  ) {
672
672
  symbols {
673
- symbolId
673
+ symbolRef
674
674
  name
675
675
  qualifiedPath
676
676
  kind
@@ -685,6 +685,13 @@ var FindSymbolDocument = gql`
685
685
  totalMatches
686
686
  hasMore
687
687
  indexedVersion
688
+ diagnostics {
689
+ indexed
690
+ chunkCount
691
+ fileCount
692
+ indexedAt
693
+ hint
694
+ }
688
695
  }
689
696
  }
690
697
  `;
@@ -713,7 +720,7 @@ var SearchSymbolsDocument = gql`
713
720
  contentPreview
714
721
  code
715
722
  language
716
- symbolId
723
+ symbolRef
717
724
  qualifiedPath
718
725
  kind
719
726
  arity
@@ -730,6 +737,7 @@ var SearchSymbolsDocument = gql`
730
737
  indexedAt
731
738
  hint
732
739
  }
740
+ warning
733
741
  }
734
742
  }
735
743
  `;
@@ -749,7 +757,7 @@ var ListSymbolsDocument = gql`
749
757
  waitTimeoutMs: $waitTimeoutMs
750
758
  ) {
751
759
  symbols {
752
- symbolId
760
+ symbolRef
753
761
  name
754
762
  qualifiedPath
755
763
  kind
@@ -767,12 +775,11 @@ var ListSymbolsDocument = gql`
767
775
  path
768
776
  language
769
777
  }
770
- error
771
778
  }
772
779
  }
773
780
  `;
774
781
  var SymbolDependenciesDocument = gql`
775
- query SymbolDependencies($symbol: SymbolReferenceInput!, $maxDepth: Int, $maxResults: Int, $includeExternal: Boolean, $includeBuiltins: Boolean, $mode: NavigationMode, $waitTimeoutMs: Int) {
782
+ query SymbolDependencies($symbol: SymbolReferenceInput!, $maxDepth: Int, $maxResults: Int, $includeExternal: Boolean, $includeBuiltins: Boolean, $mode: NavigationMode, $waitTimeoutMs: Int, $version: String) {
776
783
  symbolDependencies(
777
784
  symbol: $symbol
778
785
  maxDepth: $maxDepth
@@ -781,14 +788,15 @@ var SymbolDependenciesDocument = gql`
781
788
  includeBuiltins: $includeBuiltins
782
789
  mode: $mode
783
790
  waitTimeoutMs: $waitTimeoutMs
791
+ version: $version
784
792
  ) {
785
793
  root {
786
- symbolId
794
+ symbolRef
787
795
  name
788
796
  qualifiedPath
789
797
  }
790
798
  dependencies {
791
- symbolId
799
+ symbolRef
792
800
  name
793
801
  qualifiedPath
794
802
  kind
@@ -810,21 +818,22 @@ var SymbolDependenciesDocument = gql`
810
818
  }
811
819
  `;
812
820
  var SymbolDependentsDocument = gql`
813
- query SymbolDependents($symbol: SymbolReferenceInput!, $samePackageOnly: Boolean, $maxResults: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
821
+ query SymbolDependents($symbol: SymbolReferenceInput!, $samePackageOnly: Boolean, $maxResults: Int, $maxDepth: Int, $mode: NavigationMode, $waitTimeoutMs: Int) {
814
822
  symbolDependents(
815
823
  symbol: $symbol
816
824
  samePackageOnly: $samePackageOnly
817
825
  maxResults: $maxResults
826
+ maxDepth: $maxDepth
818
827
  mode: $mode
819
828
  waitTimeoutMs: $waitTimeoutMs
820
829
  ) {
821
830
  target {
822
- symbolId
831
+ symbolRef
823
832
  name
824
833
  qualifiedPath
825
834
  }
826
835
  dependents {
827
- symbolId
836
+ symbolRef
828
837
  name
829
838
  qualifiedPath
830
839
  kind
@@ -880,19 +889,19 @@ var CallPathDocument = gql`
880
889
  ) {
881
890
  pathFound
882
891
  fromSymbol {
883
- symbolId
892
+ symbolRef
884
893
  name
885
894
  qualifiedPath
886
895
  }
887
896
  toSymbol {
888
- symbolId
897
+ symbolRef
889
898
  name
890
899
  qualifiedPath
891
900
  }
892
901
  paths {
893
902
  length
894
903
  hops {
895
- symbolId
904
+ symbolRef
896
905
  name
897
906
  qualifiedPath
898
907
  filePath
@@ -950,6 +959,13 @@ var ListRepoFilesDocument = gql`
950
959
  total
951
960
  hasMore
952
961
  indexedVersion
962
+ diagnostics {
963
+ indexed
964
+ chunkCount
965
+ fileCount
966
+ indexedAt
967
+ hint
968
+ }
953
969
  }
954
970
  }
955
971
  `;
@@ -977,6 +993,13 @@ var GrepRepoFileDocument = gql`
977
993
  language
978
994
  totalLines
979
995
  indexedVersion
996
+ diagnostics {
997
+ indexed
998
+ chunkCount
999
+ fileCount
1000
+ indexedAt
1001
+ hint
1002
+ }
980
1003
  }
981
1004
  }
982
1005
  `;
@@ -1019,7 +1042,7 @@ var VersionDiffDocument = gql`
1019
1042
  endLine
1020
1043
  isPublic
1021
1044
  minArity
1022
- symbolId
1045
+ symbolRef
1023
1046
  }
1024
1047
  to {
1025
1048
  contentHash
@@ -1029,7 +1052,7 @@ var VersionDiffDocument = gql`
1029
1052
  endLine
1030
1053
  isPublic
1031
1054
  minArity
1032
- symbolId
1055
+ symbolRef
1033
1056
  }
1034
1057
  }
1035
1058
  hasMore
@@ -1198,7 +1221,7 @@ function createClient(apiToken) {
1198
1221
  if (apiToken) {
1199
1222
  headers.Authorization = `Bearer ${apiToken}`;
1200
1223
  }
1201
- const client = new GraphQLClient(apiUrl, { headers });
1224
+ const client = new GraphQLClient(apiUrl, { headers, errorPolicy: "all" });
1202
1225
  return getSdk(client);
1203
1226
  }
1204
1227
 
@@ -1371,7 +1394,7 @@ class AuthStorageImpl {
1371
1394
  this.configDir = configDir ?? fs.joinPath(fs.getHomeDir(), CONFIG_DIR);
1372
1395
  this.authPath = fs.joinPath(this.configDir, AUTH_FILE);
1373
1396
  }
1374
- getPath() {
1397
+ getStorageLocation() {
1375
1398
  return this.authPath;
1376
1399
  }
1377
1400
  async load(baseUrl) {
@@ -1491,6 +1514,117 @@ class BrowserServiceImpl {
1491
1514
  await open(url);
1492
1515
  }
1493
1516
  }
1517
+ // src/services/chunking-keyring-service.ts
1518
+ var WINDOWS_MAX_ENTRY_SIZE = 1200;
1519
+ var CHUNKED_PREFIX = "CHUNKED:";
1520
+ var MAX_CHUNK_COUNT = 100;
1521
+ function chunkKey(account, writeId, index) {
1522
+ return `${account}:chunk:${writeId}:${index}`;
1523
+ }
1524
+ function parseChunkedSentinel(value) {
1525
+ if (!value.startsWith(CHUNKED_PREFIX))
1526
+ return null;
1527
+ const rest = value.slice(CHUNKED_PREFIX.length);
1528
+ const colonIndex = rest.indexOf(":");
1529
+ if (colonIndex === -1)
1530
+ return null;
1531
+ const writeId = rest.slice(0, colonIndex);
1532
+ if (writeId.length === 0)
1533
+ return null;
1534
+ const countStr = rest.slice(colonIndex + 1);
1535
+ const count = Number(countStr);
1536
+ if (!Number.isInteger(count) || count <= 0)
1537
+ return null;
1538
+ return { writeId, count };
1539
+ }
1540
+ function splitIntoChunks(value, maxSize) {
1541
+ if (value.length === 0)
1542
+ return [""];
1543
+ const chunks = [];
1544
+ for (let offset = 0;offset < value.length; offset += maxSize) {
1545
+ chunks.push(value.slice(offset, offset + maxSize));
1546
+ }
1547
+ return chunks;
1548
+ }
1549
+ function generateWriteId() {
1550
+ let id;
1551
+ do {
1552
+ id = Math.random().toString(36).slice(2, 8);
1553
+ } while (id.length < 6);
1554
+ return id;
1555
+ }
1556
+
1557
+ class ChunkingKeyringService {
1558
+ inner;
1559
+ maxEntrySize;
1560
+ constructor(inner, maxEntrySize = WINDOWS_MAX_ENTRY_SIZE) {
1561
+ this.inner = inner;
1562
+ this.maxEntrySize = maxEntrySize;
1563
+ }
1564
+ getPassword(service, account) {
1565
+ const value = this.inner.getPassword(service, account);
1566
+ if (value === null)
1567
+ return null;
1568
+ if (!value.startsWith(CHUNKED_PREFIX))
1569
+ return value;
1570
+ const sentinel = parseChunkedSentinel(value);
1571
+ if (sentinel === null)
1572
+ return null;
1573
+ const chunks = [];
1574
+ for (let i = 0;i < sentinel.count; i++) {
1575
+ const chunk = this.inner.getPassword(service, chunkKey(account, sentinel.writeId, i));
1576
+ if (chunk === null) {
1577
+ console.error(`Warning: Incomplete chunked keychain entry for "${account}" (missing chunk ${i} of ${sentinel.count}). Treating as missing.`);
1578
+ return null;
1579
+ }
1580
+ chunks.push(chunk);
1581
+ }
1582
+ return chunks.join("");
1583
+ }
1584
+ setPassword(service, account, password) {
1585
+ const oldValue = this.readOldSentinel(service, account);
1586
+ if (password.length <= this.maxEntrySize) {
1587
+ this.inner.setPassword(service, account, password);
1588
+ } else {
1589
+ const chunks = splitIntoChunks(password, this.maxEntrySize);
1590
+ if (chunks.length > MAX_CHUNK_COUNT) {
1591
+ throw new Error(`Value requires ${chunks.length} chunks, exceeding maximum of ${MAX_CHUNK_COUNT}. ` + `This likely indicates a bug — credential data should not be this large.`);
1592
+ }
1593
+ const writeId = generateWriteId();
1594
+ for (const [i, chunk] of chunks.entries()) {
1595
+ this.inner.setPassword(service, chunkKey(account, writeId, i), chunk);
1596
+ }
1597
+ this.inner.setPassword(service, account, `${CHUNKED_PREFIX}${writeId}:${chunks.length}`);
1598
+ }
1599
+ if (oldValue !== null) {
1600
+ this.deleteChunkEntries(service, account, oldValue);
1601
+ }
1602
+ }
1603
+ deletePassword(service, account) {
1604
+ const oldValue = this.readOldSentinel(service, account);
1605
+ if (oldValue !== null) {
1606
+ this.deleteChunkEntries(service, account, oldValue);
1607
+ }
1608
+ return this.inner.deletePassword(service, account);
1609
+ }
1610
+ readOldSentinel(service, account) {
1611
+ try {
1612
+ const value = this.inner.getPassword(service, account);
1613
+ if (value === null)
1614
+ return null;
1615
+ return parseChunkedSentinel(value);
1616
+ } catch {
1617
+ return null;
1618
+ }
1619
+ }
1620
+ deleteChunkEntries(service, account, sentinel) {
1621
+ for (let i = 0;i < sentinel.count; i++) {
1622
+ try {
1623
+ this.inner.deletePassword(service, chunkKey(account, sentinel.writeId, i));
1624
+ } catch {}
1625
+ }
1626
+ }
1627
+ }
1494
1628
  // src/services/config-service.ts
1495
1629
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
1496
1630
  import { z } from "zod";
@@ -1749,6 +1883,143 @@ class GitServiceImpl {
1749
1883
  return existsSync(gitPath);
1750
1884
  }
1751
1885
  }
1886
+ // src/services/keychain-auth-storage.ts
1887
+ var SERVICE_NAME = "pkgseer";
1888
+ var TOKEN_PREFIX = "v1:tokens:";
1889
+ function normalizeBaseUrl2(url) {
1890
+ return url.replace(/\/+$/, "");
1891
+ }
1892
+ function parseJsonOrNull(json) {
1893
+ if (json === null)
1894
+ return null;
1895
+ try {
1896
+ const parsed = JSON.parse(json);
1897
+ if (typeof parsed !== "object" || parsed === null)
1898
+ return null;
1899
+ return parsed;
1900
+ } catch {
1901
+ return null;
1902
+ }
1903
+ }
1904
+ function isValidTokenData(data) {
1905
+ if (typeof data !== "object" || data === null)
1906
+ return false;
1907
+ const d = data;
1908
+ return typeof d.token === "string" && d.token.length > 0 && typeof d.tokenName === "string" && d.tokenName.length > 0 && Array.isArray(d.scopes) && typeof d.createdAt === "string" && d.createdAt.length > 0 && (d.expiresAt === null || typeof d.expiresAt === "string" && d.expiresAt.length > 0) && typeof d.apiKeyId === "number";
1909
+ }
1910
+
1911
+ class KeychainAuthStorage {
1912
+ keyring;
1913
+ constructor(keyring) {
1914
+ this.keyring = keyring;
1915
+ }
1916
+ async load(baseUrl) {
1917
+ const key = `${TOKEN_PREFIX}${normalizeBaseUrl2(baseUrl)}`;
1918
+ const json = this.keyring.getPassword(SERVICE_NAME, key);
1919
+ const data = parseJsonOrNull(json);
1920
+ if (data !== null && !isValidTokenData(data))
1921
+ return null;
1922
+ return data;
1923
+ }
1924
+ async save(baseUrl, data) {
1925
+ const key = `${TOKEN_PREFIX}${normalizeBaseUrl2(baseUrl)}`;
1926
+ this.keyring.setPassword(SERVICE_NAME, key, JSON.stringify(data));
1927
+ }
1928
+ async clear(baseUrl) {
1929
+ const key = `${TOKEN_PREFIX}${normalizeBaseUrl2(baseUrl)}`;
1930
+ this.keyring.deletePassword(SERVICE_NAME, key);
1931
+ }
1932
+ getStorageLocation() {
1933
+ switch (process.platform) {
1934
+ case "darwin":
1935
+ return "macOS Keychain (pkgseer)";
1936
+ case "win32":
1937
+ return "Windows Credential Manager (pkgseer)";
1938
+ default:
1939
+ return "System keychain (pkgseer)";
1940
+ }
1941
+ }
1942
+ }
1943
+ // src/services/keyring-service.ts
1944
+ import { Entry } from "@napi-rs/keyring";
1945
+
1946
+ class KeychainUnavailableError extends Error {
1947
+ constructor(message, cause) {
1948
+ super(message);
1949
+ this.name = "KeychainUnavailableError";
1950
+ this.cause = cause;
1951
+ }
1952
+ }
1953
+ function wrapKeyringError(error) {
1954
+ const message = error instanceof Error ? error.message : String(error);
1955
+ throw new KeychainUnavailableError(`System keychain unavailable: ${message}`, error);
1956
+ }
1957
+
1958
+ class KeyringServiceImpl {
1959
+ getPassword(service, account) {
1960
+ try {
1961
+ return new Entry(service, account).getPassword();
1962
+ } catch (error) {
1963
+ wrapKeyringError(error);
1964
+ }
1965
+ }
1966
+ setPassword(service, account, password) {
1967
+ try {
1968
+ new Entry(service, account).setPassword(password);
1969
+ } catch (error) {
1970
+ wrapKeyringError(error);
1971
+ }
1972
+ }
1973
+ deletePassword(service, account) {
1974
+ try {
1975
+ return new Entry(service, account).deleteCredential();
1976
+ } catch (error) {
1977
+ wrapKeyringError(error);
1978
+ }
1979
+ }
1980
+ }
1981
+ // src/services/migrating-auth-storage.ts
1982
+ class MigratingAuthStorage {
1983
+ primary;
1984
+ legacy;
1985
+ constructor(primary, legacy) {
1986
+ this.primary = primary;
1987
+ this.legacy = legacy;
1988
+ }
1989
+ async load(baseUrl) {
1990
+ const tokens = await this.primary.load(baseUrl);
1991
+ if (tokens)
1992
+ return tokens;
1993
+ const legacyTokens = await this.legacy.load(baseUrl);
1994
+ if (legacyTokens) {
1995
+ await this.primary.save(baseUrl, legacyTokens);
1996
+ try {
1997
+ await this.legacy.clear(baseUrl);
1998
+ } catch {}
1999
+ return legacyTokens;
2000
+ }
2001
+ return null;
2002
+ }
2003
+ async save(baseUrl, data) {
2004
+ await this.primary.save(baseUrl, data);
2005
+ }
2006
+ async clear(baseUrl) {
2007
+ let primaryError;
2008
+ try {
2009
+ await this.primary.clear(baseUrl);
2010
+ } catch (error) {
2011
+ primaryError = error;
2012
+ }
2013
+ try {
2014
+ await this.legacy.clear(baseUrl);
2015
+ } catch {}
2016
+ if (primaryError)
2017
+ throw primaryError;
2018
+ }
2019
+ getStorageLocation() {
2020
+ return this.primary.getStorageLocation();
2021
+ }
2022
+ }
1752
2023
  // src/services/pkgseer-service.ts
1753
2024
  class PkgseerServiceImpl {
1754
2025
  client;
@@ -1998,7 +2269,8 @@ class PkgseerServiceImpl {
1998
2269
  includeExternal: options?.includeExternal,
1999
2270
  includeBuiltins: options?.includeBuiltins,
2000
2271
  mode: options?.mode,
2001
- waitTimeoutMs: options?.waitTimeoutMs
2272
+ waitTimeoutMs: options?.waitTimeoutMs,
2273
+ version: options?.version
2002
2274
  });
2003
2275
  return { data: result.data, errors: result.errors };
2004
2276
  }
@@ -2006,6 +2278,7 @@ class PkgseerServiceImpl {
2006
2278
  const result = await this.client.SymbolDependents({
2007
2279
  symbol,
2008
2280
  samePackageOnly: options?.samePackageOnly,
2281
+ maxDepth: options?.maxDepth,
2009
2282
  maxResults: options?.maxResults,
2010
2283
  mode: options?.mode,
2011
2284
  waitTimeoutMs: options?.waitTimeoutMs
@@ -2296,10 +2569,29 @@ async function resolveApiToken(configService, baseUrl) {
2296
2569
  const tokenData = await configService.getApiToken(baseUrl);
2297
2570
  return tokenData?.token;
2298
2571
  }
2572
+ function createAuthStorage(fileSystemService) {
2573
+ const fileStorage = new AuthStorageImpl(fileSystemService);
2574
+ try {
2575
+ const rawKeyring = new KeyringServiceImpl;
2576
+ const keyring = process.platform === "win32" ? new ChunkingKeyringService(rawKeyring, WINDOWS_MAX_ENTRY_SIZE) : rawKeyring;
2577
+ const probeKey = `__probe_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
2578
+ keyring.setPassword("pkgseer", probeKey, "probe");
2579
+ try {
2580
+ keyring.deletePassword("pkgseer", probeKey);
2581
+ } catch {}
2582
+ const keychainStorage = new KeychainAuthStorage(keyring);
2583
+ return new MigratingAuthStorage(keychainStorage, fileStorage);
2584
+ } catch (error) {
2585
+ if (!(error instanceof KeychainUnavailableError))
2586
+ throw error;
2587
+ console.error("Warning: System keychain unavailable. Falling back to file-based credential storage.");
2588
+ return fileStorage;
2589
+ }
2590
+ }
2299
2591
  async function createContainer() {
2300
2592
  const baseUrl = getBaseUrl();
2301
2593
  const fileSystemService = new FileSystemServiceImpl;
2302
- const authStorage = new AuthStorageImpl(fileSystemService);
2594
+ const authStorage = createAuthStorage(fileSystemService);
2303
2595
  const configService = new ConfigServiceImpl(fileSystemService, authStorage);
2304
2596
  const [apiToken, configResult] = await Promise.all([
2305
2597
  resolveApiToken(configService, baseUrl),
@@ -2360,7 +2652,7 @@ async function authStatusAction(deps) {
2360
2652
  console.log(" Expires: never");
2361
2653
  }
2362
2654
  console.log(`
2363
- Stored at: ${authStorage.getPath()}`);
2655
+ Storage: ${authStorage.getStorageLocation()}`);
2364
2656
  }
2365
2657
  var STATUS_DESCRIPTION = `Show current authentication status.
2366
2658
 
@@ -2373,6 +2665,42 @@ function registerAuthStatusCommand(program) {
2373
2665
  });
2374
2666
  }
2375
2667
 
2668
+ // src/lib/error-classification.ts
2669
+ function classifyError(message) {
2670
+ const lower = message.toLowerCase();
2671
+ if (lower.includes("being indexed") || lower.includes("retry with waittimeoutms")) {
2672
+ return "being_indexed";
2673
+ }
2674
+ if (lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out")) {
2675
+ return "timeout";
2676
+ }
2677
+ if (lower.includes("not found") || lower.includes("does not exist")) {
2678
+ return "not_found";
2679
+ }
2680
+ if (lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("token") || lower.includes("authentication") || lower.includes("permission")) {
2681
+ return "auth";
2682
+ }
2683
+ if (lower.includes("rate limit") || lower.includes("too many requests")) {
2684
+ return "rate_limit";
2685
+ }
2686
+ return "unknown";
2687
+ }
2688
+
2689
+ // src/lib/registry.ts
2690
+ var REGISTRY_MAP = {
2691
+ npm: "NPM",
2692
+ pypi: "PYPI",
2693
+ hex: "HEX",
2694
+ crates: "CRATES",
2695
+ nuget: "NUGET",
2696
+ maven: "MAVEN",
2697
+ zig: "ZIG",
2698
+ vcpkg: "VCPKG"
2699
+ };
2700
+ function toGraphQLRegistry(registry) {
2701
+ return REGISTRY_MAP[registry.toLowerCase()] || "NPM";
2702
+ }
2703
+
2376
2704
  // src/commands/shared.ts
2377
2705
  function parsePackageSpec(spec) {
2378
2706
  let registry = "npm";
@@ -2404,19 +2732,6 @@ function parsePackageSpec(spec) {
2404
2732
  }
2405
2733
  return { registry, name: rest };
2406
2734
  }
2407
- function toGraphQLRegistry(registry) {
2408
- const map = {
2409
- npm: "NPM",
2410
- pypi: "PYPI",
2411
- hex: "HEX",
2412
- crates: "CRATES",
2413
- nuget: "NUGET",
2414
- maven: "MAVEN",
2415
- zig: "ZIG",
2416
- vcpkg: "VCPKG"
2417
- };
2418
- return map[registry.toLowerCase()] || "NPM";
2419
- }
2420
2735
  function output(data, json) {
2421
2736
  if (json) {
2422
2737
  console.log(JSON.stringify(data));
@@ -2432,27 +2747,20 @@ function outputError(message, json) {
2432
2747
  }
2433
2748
  process.exit(1);
2434
2749
  }
2750
+ var CLI_HINTS = {
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.",
2754
+ auth: " Hint: check login or token validity (pkgseer auth-status).",
2755
+ rate_limit: " Hint: wait and retry, or reduce request frequency.",
2756
+ unknown: ""
2757
+ };
2435
2758
  function handleErrors(errors, json) {
2436
2759
  if (!errors || errors.length === 0)
2437
2760
  return;
2438
2761
  const combined = errors.map((e) => e.message).filter(Boolean).join(", ");
2439
- const lower = combined.toLowerCase();
2440
- const isTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
2441
- const isNotFound = lower.includes("not found") || lower.includes("does not exist") || lower.includes("unknown");
2442
- const isAuth = lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("token") || lower.includes("authentication") || lower.includes("permission");
2443
- const isRateLimit = lower.includes("rate limit") || lower.includes("too many requests");
2444
- let hint = "";
2445
- if (isTimeout) {
2446
- hint = " Hint: lower the limit or narrow the scope, then retry.";
2447
- } else if (isNotFound) {
2448
- hint = " Hint: verify the name/registry and that the resource exists.";
2449
- } else if (isAuth) {
2450
- hint = " Hint: check login or token validity (pkgseer auth-status).";
2451
- } else if (isRateLimit) {
2452
- hint = " Hint: wait and retry, or reduce request frequency.";
2453
- }
2454
- const message = `${combined}${hint}`;
2455
- outputError(message, json);
2762
+ const hint = CLI_HINTS[classifyError(combined)];
2763
+ outputError(`${combined}${hint}`, json);
2456
2764
  }
2457
2765
  function formatNumber(num) {
2458
2766
  if (num == null)
@@ -2480,14 +2788,20 @@ function formatSeverity(severity) {
2480
2788
  return indicators[severity] || severity;
2481
2789
  }
2482
2790
  function extractGraphQLError(error) {
2483
- if (error && typeof error === "object" && "response" in error && error.response && typeof error.response === "object" && "errors" in error.response && Array.isArray(error.response.errors)) {
2484
- const errors = error.response.errors;
2485
- if (errors.length > 0) {
2486
- const messages = errors.map((e) => e.message).filter((m) => typeof m === "string");
2791
+ if (error && typeof error === "object" && "response" in error && error.response && typeof error.response === "object" && "errors" in error.response) {
2792
+ const respErrors = error.response.errors;
2793
+ if (Array.isArray(respErrors)) {
2794
+ const messages = respErrors.map((e) => e.message).filter((m) => typeof m === "string");
2487
2795
  if (messages.length > 0) {
2488
2796
  return messages.join("; ");
2489
2797
  }
2490
2798
  }
2799
+ if (respErrors && typeof respErrors === "object" && !Array.isArray(respErrors) && "detail" in respErrors) {
2800
+ const detail = respErrors.detail;
2801
+ if (typeof detail === "string") {
2802
+ return detail;
2803
+ }
2804
+ }
2491
2805
  }
2492
2806
  if (error && typeof error === "object" && "errors" in error && Array.isArray(error.errors)) {
2493
2807
  const errors = error.errors;
@@ -2535,17 +2849,10 @@ async function withCliErrorHandling(json, fn) {
2535
2849
  return;
2536
2850
  }
2537
2851
  const message = error instanceof Error ? error.message : "Unknown error";
2538
- const lower = message.toLowerCase();
2539
- if (lower.includes("-32001") || lower.includes("timeout")) {
2540
- outputError(`${message}. Hint: lower the limit or narrow the scope, then retry.`, json);
2541
- return;
2542
- }
2543
- if (lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("token") || lower.includes("authentication") || lower.includes("permission")) {
2544
- outputError(`${message}. Hint: check login or token validity.`, json);
2545
- return;
2546
- }
2547
- if (lower.includes("rate limit") || lower.includes("too many requests")) {
2548
- outputError(`${message}. Hint: wait and retry.`, json);
2852
+ const kind = classifyError(message);
2853
+ const hint = CLI_HINTS[kind];
2854
+ if (hint) {
2855
+ outputError(`${message}.${hint}`, json);
2549
2856
  return;
2550
2857
  }
2551
2858
  const colonMatch = message.match(/^([^:]+):/);
@@ -2581,12 +2888,12 @@ function parseSymbolRef(spec) {
2581
2888
  packageName: parsed.name
2582
2889
  };
2583
2890
  }
2584
- function buildSymbolReference(spec, id) {
2585
- if (id) {
2586
- return { symbolId: Number.parseInt(id, 10) };
2891
+ function buildSymbolReference(spec, ref) {
2892
+ if (ref) {
2893
+ return { symbolRef: ref };
2587
2894
  }
2588
2895
  if (!spec) {
2589
- throw new Error("Symbol reference required. Use registry:package#symbolName or --id <number>");
2896
+ throw new Error("Symbol reference required. Use registry:package#symbolName or --ref <string>");
2590
2897
  }
2591
2898
  return parseSymbolRef(spec);
2592
2899
  }
@@ -2629,7 +2936,7 @@ function formatSymbol(symbol) {
2629
2936
  const loc = symbol.startLine ? `${symbol.filePath}:${symbol.startLine}` : symbol.filePath;
2630
2937
  parts.push(` File: ${loc}`);
2631
2938
  }
2632
- const meta = [`id:${symbol.symbolId}`];
2939
+ const meta = [`ref:${symbol.symbolRef}`];
2633
2940
  if (symbol.callerCount != null) {
2634
2941
  meta.push(`callers:${symbol.callerCount}`);
2635
2942
  }
@@ -2659,8 +2966,8 @@ function formatDependencyEntry(entry) {
2659
2966
  if (entry.package) {
2660
2967
  parts.push(` Package: ${entry.package.registry}:${entry.package.name}`);
2661
2968
  }
2662
- if (entry.symbolId) {
2663
- parts.push(` id:${entry.symbolId}`);
2969
+ if (entry.symbolRef) {
2970
+ parts.push(` ref:${entry.symbolRef}`);
2664
2971
  }
2665
2972
  return parts.join(`
2666
2973
  `);
@@ -2669,7 +2976,7 @@ function formatDependencyEntry(entry) {
2669
2976
  // src/commands/code/callees.ts
2670
2977
  function formatCalleesResult(data) {
2671
2978
  const lines = [];
2672
- lines.push(`Callees of ${data.root.qualifiedPath ?? data.root.name} (id:${data.root.symbolId})`);
2979
+ lines.push(`Callees of ${data.root.qualifiedPath ?? data.root.name} (ref:${data.root.symbolRef})`);
2673
2980
  lines.push(`${data.total} callee(s)${data.hasMore ? " (more available)" : ""}`);
2674
2981
  if (data.externalPackages && data.externalPackages.length > 0) {
2675
2982
  lines.push(`External packages: ${data.externalPackages.join(", ")}`);
@@ -2690,7 +2997,7 @@ function formatCalleesResult(data) {
2690
2997
  }
2691
2998
  async function codeCalleesAction(symbolArg, options, deps) {
2692
2999
  const { pkgseerService } = deps;
2693
- const symbolRef = buildSymbolReference(symbolArg, options.id);
3000
+ const symbolRef = buildSymbolReference(symbolArg, options.ref);
2694
3001
  const result = await pkgseerService.symbolDependencies(symbolRef, {
2695
3002
  maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
2696
3003
  maxResults: parseIntOption(options.limit, "--limit"),
@@ -2700,27 +3007,27 @@ async function codeCalleesAction(symbolArg, options, deps) {
2700
3007
  waitTimeoutMs: parseWaitTimeout(options.wait)
2701
3008
  });
2702
3009
  handleErrors(result.errors, options.json ?? false);
2703
- if (!result.data.symbolDependencies) {
2704
- outputError("Symbol not found. Verify the symbol reference or use --id.", options.json ?? false);
3010
+ if (!result.data?.symbolDependencies) {
3011
+ outputError("Symbol not found. Verify the symbol reference or use --ref.", options.json ?? false);
2705
3012
  return;
2706
3013
  }
2707
3014
  if (options.json) {
2708
- output(result.data.symbolDependencies, true);
3015
+ output(result.data?.symbolDependencies, true);
2709
3016
  } else {
2710
- console.log(formatCalleesResult(result.data.symbolDependencies));
3017
+ console.log(formatCalleesResult(result.data?.symbolDependencies));
2711
3018
  }
2712
3019
  }
2713
3020
  var CALLEES_DESCRIPTION = `Find what a symbol calls.
2714
3021
 
2715
3022
  Shows functions and methods that the specified symbol depends on.
2716
- Use registry:package#symbolName format or --id for direct lookup.
3023
+ Use registry:package#symbolName format or --ref for direct lookup.
2717
3024
 
2718
3025
  Examples:
2719
3026
  pkgseer code callees npm:express#Router
2720
- pkgseer code callees --id 12345
3027
+ pkgseer code callees --ref npm:express:4.18.2:42
2721
3028
  pkgseer code callees npm:lodash#merge --max-depth 2 --include-external`;
2722
3029
  function registerCodeCalleesCommand(program) {
2723
- program.command("callees [symbol]").summary("Find what a symbol calls").description(CALLEES_DESCRIPTION).option("--id <id>", "Direct symbol ID").option("--max-depth <n>", "Max traversal depth").option("--limit <n>", "Max results").option("--include-external", "Include external package calls").option("--include-builtins", "Include builtin function calls").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (symbolArg, options) => {
3030
+ program.command("callees [symbol]").summary("Find what a symbol calls").description(CALLEES_DESCRIPTION).option("--ref <ref>", "Direct symbol reference (registry:package:version:id)").option("--max-depth <n>", "Max traversal depth").option("--limit <n>", "Max results").option("--include-external", "Include external package calls").option("--include-builtins", "Include builtin function calls").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (symbolArg, options) => {
2724
3031
  await withCliErrorHandling(options.json ?? false, async () => {
2725
3032
  const deps = await createContainer();
2726
3033
  await codeCalleesAction(symbolArg, options, deps);
@@ -2730,7 +3037,7 @@ function registerCodeCalleesCommand(program) {
2730
3037
  // src/commands/code/callers.ts
2731
3038
  function formatCallersResult(data) {
2732
3039
  const lines = [];
2733
- lines.push(`Callers of ${data.target.qualifiedPath ?? data.target.name} (id:${data.target.symbolId})`);
3040
+ lines.push(`Callers of ${data.target.qualifiedPath ?? data.target.name} (ref:${data.target.symbolRef})`);
2734
3041
  lines.push(`${data.total} caller(s)${data.hasMore ? " (more available)" : ""}`);
2735
3042
  lines.push("");
2736
3043
  for (const dep of data.dependents) {
@@ -2742,35 +3049,36 @@ function formatCallersResult(data) {
2742
3049
  }
2743
3050
  async function codeCallersAction(symbolArg, options, deps) {
2744
3051
  const { pkgseerService } = deps;
2745
- const symbolRef = buildSymbolReference(symbolArg, options.id);
3052
+ const symbolRef = buildSymbolReference(symbolArg, options.ref);
2746
3053
  const result = await pkgseerService.symbolDependents(symbolRef, {
2747
3054
  samePackageOnly: options.samePackageOnly,
3055
+ maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
2748
3056
  maxResults: parseIntOption(options.limit, "--limit"),
2749
3057
  mode: parseNavigationMode(options.mode),
2750
3058
  waitTimeoutMs: parseWaitTimeout(options.wait)
2751
3059
  });
2752
3060
  handleErrors(result.errors, options.json ?? false);
2753
- if (!result.data.symbolDependents) {
2754
- outputError("Symbol not found. Verify the symbol reference or use --id.", options.json ?? false);
3061
+ if (!result.data?.symbolDependents) {
3062
+ outputError("Symbol not found. Verify the symbol reference or use --ref.", options.json ?? false);
2755
3063
  return;
2756
3064
  }
2757
3065
  if (options.json) {
2758
- output(result.data.symbolDependents, true);
3066
+ output(result.data?.symbolDependents, true);
2759
3067
  } else {
2760
- console.log(formatCallersResult(result.data.symbolDependents));
3068
+ console.log(formatCallersResult(result.data?.symbolDependents));
2761
3069
  }
2762
3070
  }
2763
3071
  var CALLERS_DESCRIPTION = `Find what calls a symbol.
2764
3072
 
2765
3073
  Shows functions and methods that call the specified symbol.
2766
- Use registry:package#symbolName format or --id for direct lookup.
3074
+ Use registry:package#symbolName format or --ref for direct lookup.
2767
3075
 
2768
3076
  Examples:
2769
3077
  pkgseer code callers npm:express#Router
2770
- pkgseer code callers --id 12345
3078
+ pkgseer code callers --ref npm:express:4.18.2:42
2771
3079
  pkgseer code callers npm:lodash#debounce --same-package-only`;
2772
3080
  function registerCodeCallersCommand(program) {
2773
- program.command("callers [symbol]").summary("Find what calls a symbol").description(CALLERS_DESCRIPTION).option("--id <id>", "Direct symbol ID").option("--same-package-only", "Only show callers from the same package").option("--limit <n>", "Max results").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (symbolArg, options) => {
3081
+ program.command("callers [symbol]").summary("Find what calls a symbol").description(CALLERS_DESCRIPTION).option("--ref <ref>", "Direct symbol reference (registry:package:version:id)").option("--same-package-only", "Only show callers from the same package").option("--max-depth <n>", "Max traversal depth").option("--limit <n>", "Max results").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (symbolArg, options) => {
2774
3082
  await withCliErrorHandling(options.json ?? false, async () => {
2775
3083
  const deps = await createContainer();
2776
3084
  await codeCallersAction(symbolArg, options, deps);
@@ -2822,14 +3130,14 @@ async function codeDiffAction(packageArg, fromVersion, toVersion, options, deps)
2822
3130
  waitTimeoutMs: parseWaitTimeout(options.wait)
2823
3131
  });
2824
3132
  handleErrors(result.errors, options.json ?? false);
2825
- if (!result.data.versionDiff) {
3133
+ if (!result.data?.versionDiff) {
2826
3134
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2827
3135
  return;
2828
3136
  }
2829
3137
  if (options.json) {
2830
- output(result.data.versionDiff, true);
3138
+ output(result.data?.versionDiff, true);
2831
3139
  } else {
2832
- console.log(formatDiffResult(result.data.versionDiff));
3140
+ console.log(formatDiffResult(result.data?.versionDiff));
2833
3141
  }
2834
3142
  }
2835
3143
  var DIFF_DESCRIPTION = `Compare symbols between two package versions.
@@ -2882,14 +3190,21 @@ async function codeFilesAction(packageArg, options, deps) {
2882
3190
  waitTimeoutMs: parseWaitTimeout(options.wait)
2883
3191
  });
2884
3192
  handleErrors(result.errors, options.json ?? false);
2885
- if (!result.data.listRepoFiles) {
3193
+ if (!result.data?.listRepoFiles) {
2886
3194
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2887
3195
  return;
2888
3196
  }
3197
+ const data = result.data?.listRepoFiles;
2889
3198
  if (options.json) {
2890
- output(result.data.listRepoFiles, true);
3199
+ output(data, true);
2891
3200
  } else {
2892
- console.log(formatFilesResult(result.data.listRepoFiles));
3201
+ const formatted = formatFilesResult(data);
3202
+ if (data.files.length === 0 && data.diagnostics?.hint) {
3203
+ console.log(`${formatted}
3204
+ Note: ${data.diagnostics.hint}`);
3205
+ } else {
3206
+ console.log(formatted);
3207
+ }
2893
3208
  }
2894
3209
  }
2895
3210
  var FILES_DESCRIPTION = `List files in a package's indexed repository.
@@ -2940,14 +3255,21 @@ async function codeFindAction(packageArg, nameArg, options, deps) {
2940
3255
  waitTimeoutMs: parseWaitTimeout(options.wait)
2941
3256
  });
2942
3257
  handleErrors(result.errors, options.json ?? false);
2943
- if (!result.data.findSymbol) {
3258
+ if (!result.data?.findSymbol) {
2944
3259
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2945
3260
  return;
2946
3261
  }
3262
+ const data = result.data?.findSymbol;
2947
3263
  if (options.json) {
2948
- output(result.data.findSymbol, true);
3264
+ output(data, true);
2949
3265
  } else {
2950
- console.log(formatFindResult(result.data.findSymbol));
3266
+ const formatted = formatFindResult(data);
3267
+ if (data.symbols.length === 0 && data.diagnostics?.hint) {
3268
+ console.log(`${formatted}
3269
+ Note: ${data.diagnostics.hint}`);
3270
+ } else {
3271
+ console.log(formatted);
3272
+ }
2951
3273
  }
2952
3274
  }
2953
3275
  var FIND_DESCRIPTION = `Find symbols (functions, classes, modules) by name.
@@ -3007,14 +3329,21 @@ async function codeGrepAction(packageArg, filePath, pattern, options, deps) {
3007
3329
  waitTimeoutMs: parseWaitTimeout(options.wait)
3008
3330
  });
3009
3331
  handleErrors(result.errors, options.json ?? false);
3010
- if (!result.data.grepRepoFile) {
3332
+ if (!result.data?.grepRepoFile) {
3011
3333
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3012
3334
  return;
3013
3335
  }
3336
+ const data = result.data?.grepRepoFile;
3014
3337
  if (options.json) {
3015
- output(result.data.grepRepoFile, true);
3338
+ output(data, true);
3016
3339
  } else {
3017
- console.log(formatGrepResult(result.data.grepRepoFile));
3340
+ const formatted = formatGrepResult(data);
3341
+ if (data.matches.length === 0 && data.diagnostics?.hint) {
3342
+ console.log(`${formatted}
3343
+ Note: ${data.diagnostics.hint}`);
3344
+ } else {
3345
+ console.log(formatted);
3346
+ }
3018
3347
  }
3019
3348
  }
3020
3349
  var GREP_DESCRIPTION = `Search for a pattern within a file in a package's repository.
@@ -3087,14 +3416,14 @@ async function codeImportsAction(packageArg, options, deps) {
3087
3416
  waitTimeoutMs: parseWaitTimeout(options.wait)
3088
3417
  });
3089
3418
  handleErrors(result.errors, options.json ?? false);
3090
- if (!result.data.packageImports) {
3419
+ if (!result.data?.packageImports) {
3091
3420
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3092
3421
  return;
3093
3422
  }
3094
3423
  if (options.json) {
3095
- output(result.data.packageImports, true);
3424
+ output(result.data?.packageImports, true);
3096
3425
  } else {
3097
- console.log(formatImportsResult(result.data.packageImports));
3426
+ console.log(formatImportsResult(result.data?.packageImports));
3098
3427
  }
3099
3428
  }
3100
3429
  var IMPORTS_DESCRIPTION = `List import statements in a package.
@@ -3124,9 +3453,6 @@ function formatListResult(data) {
3124
3453
  if (data.file) {
3125
3454
  lines.push(`File: ${data.file.path}${data.file.language ? ` (${data.file.language})` : ""}`);
3126
3455
  }
3127
- if (data.error) {
3128
- lines.push(`Warning: ${data.error}`);
3129
- }
3130
3456
  lines.push("");
3131
3457
  for (const symbol of data.symbols) {
3132
3458
  lines.push(formatSymbol(symbol));
@@ -3159,14 +3485,14 @@ async function codeListAction(packageArg, options, deps) {
3159
3485
  waitTimeoutMs: parseWaitTimeout(options.wait)
3160
3486
  });
3161
3487
  handleErrors(result.errors, options.json ?? false);
3162
- if (!result.data.listSymbols) {
3488
+ if (!result.data?.listSymbols) {
3163
3489
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3164
3490
  return;
3165
3491
  }
3166
3492
  if (options.json) {
3167
- output(result.data.listSymbols, true);
3493
+ output(result.data?.listSymbols, true);
3168
3494
  } else {
3169
- console.log(formatListResult(result.data.listSymbols));
3495
+ console.log(formatListResult(result.data?.listSymbols));
3170
3496
  }
3171
3497
  }
3172
3498
  var LIST_DESCRIPTION = `Browse symbols in a package.
@@ -3205,9 +3531,9 @@ function formatPathResult(data) {
3205
3531
  for (const [j, hop] of callPath.hops.entries()) {
3206
3532
  const name = hop.qualifiedPath ?? hop.name ?? "unknown";
3207
3533
  const loc = hop.filePath ? hop.callLine ? ` ${hop.filePath}:${hop.callLine}` : ` ${hop.filePath}` : "";
3208
- const idPart = hop.symbolId ? ` (id:${hop.symbolId})` : "";
3534
+ const refPart = hop.symbolRef ? ` (ref:${hop.symbolRef})` : "";
3209
3535
  const arrow = j < callPath.hops.length - 1 ? " ->" : "";
3210
- lines.push(` ${j + 1}. ${name}${idPart}${loc}${arrow}`);
3536
+ lines.push(` ${j + 1}. ${name}${refPart}${loc}${arrow}`);
3211
3537
  }
3212
3538
  lines.push("");
3213
3539
  }
@@ -3216,35 +3542,35 @@ function formatPathResult(data) {
3216
3542
  }
3217
3543
  async function codePathAction(fromArg, toArg, options, deps) {
3218
3544
  const { pkgseerService } = deps;
3219
- const fromRef = buildSymbolReference(fromArg, options.fromId);
3220
- const toRef = buildSymbolReference(toArg, options.toId);
3545
+ const fromRef = buildSymbolReference(fromArg, options.fromRef);
3546
+ const toRef = buildSymbolReference(toArg, options.toRef);
3221
3547
  const result = await pkgseerService.callPath(fromRef, toRef, {
3222
3548
  maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
3223
3549
  mode: parseNavigationMode(options.mode),
3224
3550
  waitTimeoutMs: parseWaitTimeout(options.wait)
3225
3551
  });
3226
3552
  handleErrors(result.errors, options.json ?? false);
3227
- if (!result.data.callPath) {
3553
+ if (!result.data?.callPath) {
3228
3554
  outputError("Could not find call path. Verify the symbol references.", options.json ?? false);
3229
3555
  return;
3230
3556
  }
3231
3557
  if (options.json) {
3232
- output(result.data.callPath, true);
3558
+ output(result.data?.callPath, true);
3233
3559
  } else {
3234
- console.log(formatPathResult(result.data.callPath));
3560
+ console.log(formatPathResult(result.data?.callPath));
3235
3561
  }
3236
3562
  }
3237
3563
  var PATH_DESCRIPTION = `Find call path between two symbols.
3238
3564
 
3239
3565
  Discovers the shortest call path from one symbol to another.
3240
- Use registry:package#symbolName format or --from-id/--to-id for direct lookup.
3566
+ Use registry:package#symbolName format or --from-ref/--to-ref for direct lookup.
3241
3567
 
3242
3568
  Examples:
3243
3569
  pkgseer code path npm:express#app npm:express#Router
3244
- pkgseer code path --from-id 123 --to-id 456
3570
+ pkgseer code path --from-ref npm:express:4.18.2:123 --to-ref npm:express:4.18.2:456
3245
3571
  pkgseer code path npm:lodash#merge npm:lodash#cloneDeep --max-depth 5`;
3246
3572
  function registerCodePathCommand(program) {
3247
- program.command("path [from] [to]").summary("Find call path between symbols").description(PATH_DESCRIPTION).option("--from-id <id>", "Source symbol ID").option("--to-id <id>", "Target symbol ID").option("--max-depth <n>", "Max path depth").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (fromArg, toArg, options) => {
3573
+ program.command("path [from] [to]").summary("Find call path between symbols").description(PATH_DESCRIPTION).option("--from-ref <ref>", "Source symbol reference (registry:package:version:id)").option("--to-ref <ref>", "Target symbol reference (registry:package:version:id)").option("--max-depth <n>", "Max path depth").option("--mode <mode>", "Response detail: summary or detailed").option("--wait <ms>", "Max ms to wait for indexing (0-30000)").option("--json", "Output as JSON").action(async (fromArg, toArg, options) => {
3248
3574
  await withCliErrorHandling(options.json ?? false, async () => {
3249
3575
  const deps = await createContainer();
3250
3576
  await codePathAction(fromArg, toArg, options, deps);
@@ -3304,14 +3630,25 @@ async function codeSearchAction(packageArg, query, options, deps) {
3304
3630
  waitTimeoutMs: parseWaitTimeout(options.wait)
3305
3631
  });
3306
3632
  handleErrors(result.errors, options.json ?? false);
3307
- if (!result.data.searchSymbols) {
3633
+ if (!result.data?.searchSymbols) {
3308
3634
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3309
3635
  return;
3310
3636
  }
3637
+ const data = result.data?.searchSymbols;
3311
3638
  if (options.json) {
3312
- output(result.data.searchSymbols, true);
3639
+ output(data, true);
3313
3640
  } else {
3314
- console.log(formatSearchResult(result.data.searchSymbols));
3641
+ let formatted = formatSearchResult(data);
3642
+ if (data.warning) {
3643
+ formatted = `Warning: ${data.warning}
3644
+
3645
+ ${formatted}`;
3646
+ }
3647
+ if (data.results.length === 0 && data.diagnostics?.hint) {
3648
+ formatted = `${formatted}
3649
+ Note: ${data.diagnostics.hint}`;
3650
+ }
3651
+ console.log(formatted);
3315
3652
  }
3316
3653
  }
3317
3654
  var SEARCH_DESCRIPTION = `Full-text search within package code.
@@ -3535,7 +3872,7 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3535
3872
  }).join("; ");
3536
3873
  return { ref: ref.originalRef, result: null, error: errorMsg };
3537
3874
  }
3538
- if (!result2.data.getDocPage) {
3875
+ if (!result2.data?.getDocPage) {
3539
3876
  return {
3540
3877
  ref: ref.originalRef,
3541
3878
  result: null,
@@ -3545,8 +3882,8 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3545
3882
  return {
3546
3883
  ref: ref.originalRef,
3547
3884
  result: {
3548
- schemaVersion: result2.data.getDocPage?.schemaVersion ?? null,
3549
- page: result2.data.getDocPage?.page ?? null
3885
+ schemaVersion: result2.data?.getDocPage?.schemaVersion ?? null,
3886
+ page: result2.data?.getDocPage?.page ?? null
3550
3887
  }
3551
3888
  };
3552
3889
  }
@@ -3579,7 +3916,7 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3579
3916
  }).join("; ");
3580
3917
  return { ref: ref.originalRef, result: null, error: errorMsg };
3581
3918
  }
3582
- if (!result.data.fetchPackageDoc) {
3919
+ if (!result.data?.fetchPackageDoc) {
3583
3920
  return {
3584
3921
  ref: ref.originalRef,
3585
3922
  result: null,
@@ -3588,8 +3925,8 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3588
3925
  }
3589
3926
  return {
3590
3927
  ref: ref.originalRef,
3591
- result: result.data.fetchPackageDoc ? {
3592
- page: result.data.fetchPackageDoc.page ?? null
3928
+ result: result.data?.fetchPackageDoc ? {
3929
+ page: result.data?.fetchPackageDoc.page ?? null
3593
3930
  } : null
3594
3931
  };
3595
3932
  } catch (error) {
@@ -3734,12 +4071,12 @@ async function docsListAction(packageArg, options, deps) {
3734
4071
  const version2 = parsed.version ?? options.pkgVersion;
3735
4072
  const result = await pkgseerService.cliDocsList(registry, parsed.name, version2);
3736
4073
  handleErrors(result.errors, options.json ?? false);
3737
- if (!result.data.listPackageDocs) {
4074
+ if (!result.data?.listPackageDocs) {
3738
4075
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3739
4076
  return;
3740
4077
  }
3741
4078
  if (options.json) {
3742
- const pages = result.data.listPackageDocs.pages?.filter((p) => p) ?? [];
4079
+ const pages = result.data?.listPackageDocs.pages?.filter((p) => p) ?? [];
3743
4080
  const slim = pages.map((p) => {
3744
4081
  if (!p || !p.id)
3745
4082
  return null;
@@ -3750,7 +4087,7 @@ async function docsListAction(packageArg, options, deps) {
3750
4087
  }).filter((p) => p !== null);
3751
4088
  output(slim, true);
3752
4089
  } else {
3753
- console.log(formatDocsList(result.data.listPackageDocs));
4090
+ console.log(formatDocsList(result.data?.listPackageDocs));
3754
4091
  }
3755
4092
  }
3756
4093
  var LIST_DESCRIPTION2 = `List available documentation pages for a package.
@@ -4229,7 +4566,7 @@ async function pollSearchProgress(searchRef, pkgseerService, useColors) {
4229
4566
  const result = await pollUntilDone({
4230
4567
  fetch: async () => {
4231
4568
  const res = await pkgseerService.getSearchProgress(searchRef);
4232
- return res.data.searchProgress ?? null;
4569
+ return res.data?.searchProgress ?? null;
4233
4570
  },
4234
4571
  isDone: (progress) => {
4235
4572
  if (!progress)
@@ -4262,7 +4599,7 @@ async function handleResume(searchRef, pkgseerService, options, useColors) {
4262
4599
  handleErrors(progressResult.errors, options.json ?? false);
4263
4600
  return true;
4264
4601
  }
4265
- const progress = progressResult.data.searchProgress;
4602
+ const progress = progressResult.data?.searchProgress;
4266
4603
  if (!progress) {
4267
4604
  outputError("Search session not found. It may have expired (sessions last 1 hour).", options.json ?? false);
4268
4605
  return true;
@@ -4273,7 +4610,7 @@ async function handleResume(searchRef, pkgseerService, options, useColors) {
4273
4610
  handleErrors(resultsResponse.errors, options.json ?? false);
4274
4611
  return true;
4275
4612
  }
4276
- const searchResults = resultsResponse.data.searchResults;
4613
+ const searchResults = resultsResponse.data?.searchResults;
4277
4614
  if (!searchResults) {
4278
4615
  outputError("Search completed but no results returned.", options.json ?? false);
4279
4616
  return true;
@@ -4316,8 +4653,8 @@ Ref: ${searchRef}`, options.json ?? false);
4316
4653
  }
4317
4654
  if (pollResult.status === "COMPLETED") {
4318
4655
  const resultsResponse = await pkgseerService.getSearchResults(searchRef);
4319
- if (resultsResponse.data.searchResults) {
4320
- outputResults(resultsResponse.data.searchResults, options, useColors);
4656
+ if (resultsResponse.data?.searchResults) {
4657
+ outputResults(resultsResponse.data?.searchResults, options, useColors);
4321
4658
  }
4322
4659
  } else {
4323
4660
  console.log(`Search ended with status: ${pollResult.status.toLowerCase()}`);
@@ -4358,7 +4695,7 @@ async function searchAction(queryArg, options, deps, defaultMode = "ALL") {
4358
4695
  waitTimeoutMs
4359
4696
  });
4360
4697
  handleErrors(result.errors, options.json ?? false);
4361
- const asyncResult = result.data.combinedSearch;
4698
+ const asyncResult = result.data?.combinedSearch;
4362
4699
  if (!asyncResult) {
4363
4700
  outputError("No results returned. Check package names and registries.", options.json ?? false);
4364
4701
  return;
@@ -4379,9 +4716,9 @@ async function searchAction(queryArg, options, deps, defaultMode = "ALL") {
4379
4716
  const pollResult = await pollSearchProgress(searchRef, pkgseerService, useColors);
4380
4717
  if (pollResult.success && pollResult.status === "COMPLETED") {
4381
4718
  const resultsResponse = await pkgseerService.getSearchResults(searchRef);
4382
- if (resultsResponse.data.searchResults) {
4719
+ if (resultsResponse.data?.searchResults) {
4383
4720
  console.log("");
4384
- outputResults(resultsResponse.data.searchResults, options, useColors);
4721
+ outputResults(resultsResponse.data?.searchResults, options, useColors);
4385
4722
  return;
4386
4723
  }
4387
4724
  }
@@ -4535,7 +4872,7 @@ async function indexAction(packages, options, deps) {
4535
4872
  }
4536
4873
  const result = await pkgseerService.triggerIndexing(input2);
4537
4874
  handleErrors(result.errors, options.json ?? false);
4538
- const data = result.data.triggerIndexing;
4875
+ const data = result.data?.triggerIndexing;
4539
4876
  if (options.json) {
4540
4877
  output(data, true);
4541
4878
  } else {
@@ -6363,19 +6700,6 @@ function errorResult(message) {
6363
6700
  }
6364
6701
 
6365
6702
  // src/tools/shared.ts
6366
- function toGraphQLRegistry2(registry) {
6367
- const map = {
6368
- npm: "NPM",
6369
- pypi: "PYPI",
6370
- hex: "HEX",
6371
- crates: "CRATES",
6372
- nuget: "NUGET",
6373
- maven: "MAVEN",
6374
- zig: "ZIG",
6375
- vcpkg: "VCPKG"
6376
- };
6377
- return map[registry.toLowerCase()] || "NPM";
6378
- }
6379
6703
  function toNavigationMode(mode) {
6380
6704
  if (!mode)
6381
6705
  return;
@@ -6424,7 +6748,7 @@ var schemas = {
6424
6748
  navigationMode: z2.enum(["summary", "detailed"]).optional().describe("Response detail level. summary (default) returns core fields; detailed adds all optional fields."),
6425
6749
  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."),
6426
6750
  symbolReference: z2.object({
6427
- symbol_id: z2.number().int().optional().describe("Direct symbol ID from find_symbol or list_symbols results (preferred, avoids ambiguity)"),
6751
+ 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."),
6428
6752
  registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry (required for name-based lookup)"),
6429
6753
  package_name: z2.string().max(255).optional().describe("Package name (required for name-based lookup)"),
6430
6754
  symbol_name: z2.string().max(500).optional().describe("Symbol name or qualified path (required for name-based lookup). Matches both short name and qualifiedPath.")
@@ -6432,34 +6756,52 @@ var schemas = {
6432
6756
  };
6433
6757
  function toSymbolReferenceInput(ref) {
6434
6758
  return {
6435
- symbolId: ref.symbol_id,
6436
- registry: ref.registry ? toGraphQLRegistry2(ref.registry) : undefined,
6759
+ symbolRef: ref.symbol_ref,
6760
+ registry: ref.registry ? toGraphQLRegistry(ref.registry) : undefined,
6437
6761
  packageName: ref.package_name,
6438
6762
  symbolName: ref.symbol_name
6439
6763
  };
6440
6764
  }
6765
+ var MCP_HINTS = {
6766
+ being_indexed: "Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).",
6767
+ timeout: "Hint: try lowering the limit or narrowing the scope, then retry."
6768
+ };
6441
6769
  function buildHintedMessage(operation, message) {
6770
+ const kind = classifyError(message);
6771
+ const hint = MCP_HINTS[kind];
6772
+ if (hint) {
6773
+ return `Failed to ${operation}: ${message}. ${hint}`;
6774
+ }
6442
6775
  const lower = message.toLowerCase();
6443
- const isTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
6444
- if (isTimeout) {
6445
- return `Failed to ${operation}: ${message}. ` + "Hint: try lowering the limit or narrowing the scope, then retry.";
6776
+ if (lower.includes("graphql error (code: 500)")) {
6777
+ try {
6778
+ const jsonMatch = message.match(/\{.*\}/s);
6779
+ if (jsonMatch) {
6780
+ const parsed = JSON.parse(jsonMatch[0]);
6781
+ const detail = parsed.errors?.detail ?? parsed.detail;
6782
+ if (typeof detail === "string") {
6783
+ return `Failed to ${operation}: ${detail}`;
6784
+ }
6785
+ }
6786
+ } catch {}
6787
+ const detailMatch = message.match(/"detail"\s*:\s*"([^"]+)"/);
6788
+ if (detailMatch?.[1]) {
6789
+ return `Failed to ${operation}: ${detailMatch[1]}`;
6790
+ }
6446
6791
  }
6447
6792
  return `Failed to ${operation}: ${message}`;
6448
6793
  }
6794
+ var MCP_GRAPHQL_HINTS = {
6795
+ not_found: "Hint: verify the name/registry and that the resource exists.",
6796
+ being_indexed: "Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).",
6797
+ timeout: "Hint: try lowering the limit or narrowing the scope, then retry."
6798
+ };
6449
6799
  function handleGraphQLErrors(errors) {
6450
6800
  if (errors && errors.length > 0) {
6451
- const messages = errors.map((e) => e.message).filter(Boolean);
6452
- const combined = messages.join(", ");
6453
- const lower = combined.toLowerCase();
6454
- const hasNotFound = lower.includes("not found") || lower.includes("does not exist");
6455
- const hasTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
6456
- if (hasNotFound) {
6457
- return errorResult(`Error: ${combined}. Hint: verify the name/registry and that the resource exists.`);
6458
- }
6459
- if (hasTimeout) {
6460
- return errorResult(`Error: ${combined}. Hint: try lowering the limit or narrowing the scope, then retry.`);
6461
- }
6462
- return errorResult(`Error: ${combined}`);
6801
+ const combined = errors.map((e) => e.message).filter(Boolean).join(", ");
6802
+ const hint = MCP_GRAPHQL_HINTS[classifyError(combined)];
6803
+ const suffix = hint ? `. ${hint}` : "";
6804
+ return errorResult(`Error: ${combined}${suffix}`);
6463
6805
  }
6464
6806
  return null;
6465
6807
  }
@@ -6477,8 +6819,8 @@ function notFoundError(packageName, registry) {
6477
6819
 
6478
6820
  // src/tools/call-path.ts
6479
6821
  var argsSchema = {
6480
- from: schemas.symbolReference.describe("Source symbol. Provide either symbol_id or registry + package_name + symbol_name."),
6481
- to: schemas.symbolReference.describe("Destination symbol. Provide either symbol_id or registry + package_name + symbol_name."),
6822
+ from: schemas.symbolReference.describe("Source symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6823
+ to: schemas.symbolReference.describe("Destination symbol. Provide either symbol_ref or registry + package_name + symbol_name."),
6482
6824
  max_depth: z3.number().int().min(1).max(10).optional().describe("Maximum path length to search (max hops between from and to)"),
6483
6825
  mode: schemas.navigationMode,
6484
6826
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -6492,11 +6834,11 @@ function createCallPathTool(pkgseerService) {
6492
6834
  return withErrorHandling("find call path", async () => {
6493
6835
  const fromInput = toSymbolReferenceInput(args.from);
6494
6836
  const toInput = toSymbolReferenceInput(args.to);
6495
- if (!fromInput.symbolId && (!fromInput.symbolName || !fromInput.registry || !fromInput.packageName)) {
6496
- return errorResult("Invalid 'from' symbol: provide either symbol_id or symbol_name with registry and package_name.");
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.");
6497
6839
  }
6498
- if (!toInput.symbolId && (!toInput.symbolName || !toInput.registry || !toInput.packageName)) {
6499
- return errorResult("Invalid 'to' symbol: provide either symbol_id or symbol_name with registry and package_name.");
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.");
6500
6842
  }
6501
6843
  const result = await pkgseerService.callPath(fromInput, toInput, {
6502
6844
  maxDepth: args.max_depth,
@@ -6506,10 +6848,10 @@ function createCallPathTool(pkgseerService) {
6506
6848
  const graphqlError = handleGraphQLErrors(result.errors);
6507
6849
  if (graphqlError)
6508
6850
  return graphqlError;
6509
- if (!result.data.callPath) {
6851
+ if (!result.data?.callPath) {
6510
6852
  return errorResult("Could not find call path. Verify the symbols exist and the package is indexed.");
6511
6853
  }
6512
- return textResult(JSON.stringify(result.data.callPath, null, 2));
6854
+ return textResult(JSON.stringify(result.data?.callPath, null, 2));
6513
6855
  });
6514
6856
  }
6515
6857
  };
@@ -6532,7 +6874,7 @@ function createComparePackagesTool(pkgseerService) {
6532
6874
  handler: async ({ packages }, _extra) => {
6533
6875
  return withErrorHandling("compare packages", async () => {
6534
6876
  const input2 = packages.map((pkg) => ({
6535
- registry: toGraphQLRegistry2(pkg.registry),
6877
+ registry: toGraphQLRegistry(pkg.registry),
6536
6878
  name: pkg.name,
6537
6879
  version: pkg.version
6538
6880
  }));
@@ -6540,10 +6882,10 @@ function createComparePackagesTool(pkgseerService) {
6540
6882
  const graphqlError = handleGraphQLErrors(result.errors);
6541
6883
  if (graphqlError)
6542
6884
  return graphqlError;
6543
- if (!result.data.comparePackages) {
6885
+ if (!result.data?.comparePackages) {
6544
6886
  return errorResult("Comparison failed: no results returned");
6545
6887
  }
6546
- return textResult(JSON.stringify(result.data.comparePackages, null, 2));
6888
+ return textResult(JSON.stringify(result.data?.comparePackages, null, 2));
6547
6889
  });
6548
6890
  }
6549
6891
  };
@@ -6571,10 +6913,10 @@ function createFetchCodeContextTool(pkgseerService) {
6571
6913
  const graphqlError = handleGraphQLErrors(result.errors);
6572
6914
  if (graphqlError)
6573
6915
  return graphqlError;
6574
- if (!result.data.fetchCodeContext) {
6916
+ if (!result.data?.fetchCodeContext) {
6575
6917
  return errorResult(`Code not found: ${file_path} at ${git_ref} in ${repo_url}. ` + "Check that the repository, file path, and git ref are correct.");
6576
6918
  }
6577
- return textResult(JSON.stringify(result.data.fetchCodeContext, null, 2));
6919
+ return textResult(JSON.stringify(result.data?.fetchCodeContext, null, 2));
6578
6920
  });
6579
6921
  }
6580
6922
  };
@@ -6595,10 +6937,10 @@ function createFetchPackageDocTool(pkgseerService) {
6595
6937
  const graphqlError = handleGraphQLErrors(result.errors);
6596
6938
  if (graphqlError)
6597
6939
  return graphqlError;
6598
- if (!result.data.getDocPage) {
6940
+ if (!result.data?.getDocPage) {
6599
6941
  return errorResult(`Documentation page not found: ${page_id}`);
6600
6942
  }
6601
- return textResult(JSON.stringify(result.data.getDocPage, null, 2));
6943
+ return textResult(JSON.stringify(result.data?.getDocPage, null, 2));
6602
6944
  });
6603
6945
  }
6604
6946
  };
@@ -6629,11 +6971,11 @@ var argsSchema5 = {
6629
6971
  function createFindSymbolTool(pkgseerService) {
6630
6972
  return {
6631
6973
  name: "find_symbol",
6632
- description: "Find functions, methods, or classes by name in a package. " + "Set include_code=true to get full source code inline, avoiding separate fetch_code_context calls. " + "Returns: symbol ID, name, qualified path, kind, file location, and optionally source code. " + "Omit name to get all public exports. Use namespace to filter by module path.",
6974
+ description: "Find functions, methods, or classes by name in a package. " + "Set include_code=true to get full source code inline, avoiding separate fetch_code_context calls. " + "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.",
6633
6975
  schema: argsSchema5,
6634
6976
  handler: async (args, _extra) => {
6635
6977
  return withErrorHandling("find symbol", async () => {
6636
- const result = await pkgseerService.findSymbol(toGraphQLRegistry2(args.registry), args.package_name, {
6978
+ const result = await pkgseerService.findSymbol(toGraphQLRegistry(args.registry), args.package_name, {
6637
6979
  name: args.name,
6638
6980
  namespace: args.namespace,
6639
6981
  kind: toSymbolKind(args.kind),
@@ -6647,10 +6989,14 @@ function createFindSymbolTool(pkgseerService) {
6647
6989
  const graphqlError = handleGraphQLErrors(result.errors);
6648
6990
  if (graphqlError)
6649
6991
  return graphqlError;
6650
- if (!result.data.findSymbol) {
6992
+ if (!result.data?.findSymbol) {
6651
6993
  return notFoundError(args.package_name, args.registry);
6652
6994
  }
6653
- return textResult(JSON.stringify(result.data.findSymbol, null, 2));
6995
+ const data = result.data?.findSymbol;
6996
+ if (data.symbols.length === 0 && data.diagnostics?.hint) {
6997
+ return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
6998
+ }
6999
+ return textResult(JSON.stringify(data, null, 2));
6654
7000
  });
6655
7001
  }
6656
7002
  };
@@ -6674,7 +7020,7 @@ function createGrepRepoFileTool(pkgseerService) {
6674
7020
  schema: argsSchema6,
6675
7021
  handler: async (args, _extra) => {
6676
7022
  return withErrorHandling("grep repo file", async () => {
6677
- const result = await pkgseerService.grepRepoFile(toGraphQLRegistry2(args.registry), args.package_name, args.file_path, args.pattern, {
7023
+ const result = await pkgseerService.grepRepoFile(toGraphQLRegistry(args.registry), args.package_name, args.file_path, args.pattern, {
6678
7024
  contextLines: args.context_lines,
6679
7025
  maxMatches: args.max_matches,
6680
7026
  version: args.version,
@@ -6683,10 +7029,14 @@ function createGrepRepoFileTool(pkgseerService) {
6683
7029
  const graphqlError = handleGraphQLErrors(result.errors);
6684
7030
  if (graphqlError)
6685
7031
  return graphqlError;
6686
- if (!result.data.grepRepoFile) {
7032
+ if (!result.data?.grepRepoFile) {
6687
7033
  return notFoundError(args.package_name, args.registry);
6688
7034
  }
6689
- return textResult(JSON.stringify(result.data.grepRepoFile, null, 2));
7035
+ const data = result.data?.grepRepoFile;
7036
+ if (data.matches.length === 0 && data.diagnostics?.hint) {
7037
+ return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7038
+ }
7039
+ return textResult(JSON.stringify(data, null, 2));
6690
7040
  });
6691
7041
  }
6692
7042
  };
@@ -6704,14 +7054,14 @@ function createListPackageDocsTool(pkgseerService) {
6704
7054
  schema: argsSchema7,
6705
7055
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
6706
7056
  return withErrorHandling("list package documentation", async () => {
6707
- const result = await pkgseerService.listPackageDocs(toGraphQLRegistry2(registry), package_name, version2);
7057
+ const result = await pkgseerService.listPackageDocs(toGraphQLRegistry(registry), package_name, version2);
6708
7058
  const graphqlError = handleGraphQLErrors(result.errors);
6709
7059
  if (graphqlError)
6710
7060
  return graphqlError;
6711
- if (!result.data.listPackageDocs) {
7061
+ if (!result.data?.listPackageDocs) {
6712
7062
  return notFoundError(package_name, registry);
6713
7063
  }
6714
- return textResult(JSON.stringify(result.data.listPackageDocs, null, 2));
7064
+ return textResult(JSON.stringify(result.data?.listPackageDocs, null, 2));
6715
7065
  });
6716
7066
  }
6717
7067
  };
@@ -6733,7 +7083,7 @@ function createListRepoFilesTool(pkgseerService) {
6733
7083
  schema: argsSchema8,
6734
7084
  handler: async (args, _extra) => {
6735
7085
  return withErrorHandling("list repo files", async () => {
6736
- const result = await pkgseerService.listRepoFiles(toGraphQLRegistry2(args.registry), args.package_name, {
7086
+ const result = await pkgseerService.listRepoFiles(toGraphQLRegistry(args.registry), args.package_name, {
6737
7087
  version: args.version,
6738
7088
  pathPrefix: args.path_prefix,
6739
7089
  limit: args.limit,
@@ -6742,10 +7092,14 @@ function createListRepoFilesTool(pkgseerService) {
6742
7092
  const graphqlError = handleGraphQLErrors(result.errors);
6743
7093
  if (graphqlError)
6744
7094
  return graphqlError;
6745
- if (!result.data.listRepoFiles) {
7095
+ if (!result.data?.listRepoFiles) {
6746
7096
  return notFoundError(args.package_name, args.registry);
6747
7097
  }
6748
- return textResult(JSON.stringify(result.data.listRepoFiles, null, 2));
7098
+ const data = result.data?.listRepoFiles;
7099
+ if (data.files.length === 0 && data.diagnostics?.hint) {
7100
+ return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
7101
+ }
7102
+ return textResult(JSON.stringify(data, null, 2));
6749
7103
  });
6750
7104
  }
6751
7105
  };
@@ -6768,7 +7122,7 @@ var argsSchema9 = {
6768
7122
  function createListSymbolsTool(pkgseerService) {
6769
7123
  return {
6770
7124
  name: "list_symbols",
6771
- description: "Browse symbols in a package by scope. " + "Use scope='exports' for public API with namespace grouping and optional popularity. " + "Use scope='file' with file_path for all symbols in a specific file. " + "Returns symbols with IDs, names, qualified paths, kinds, and file locations. " + "Use find_symbol(name=<symbol>, include_code=true) to get source for any listed symbol.",
7125
+ description: "Browse symbols in a package by scope. " + "Use scope='exports' for public API with namespace grouping and optional popularity. " + "Use scope='file' with file_path for all symbols in a specific file. " + "Returns symbols with refs, names, qualified paths, kinds, and file locations. " + "Use find_symbol(name=<symbol>, include_code=true) to get source for any listed symbol.",
6772
7126
  schema: argsSchema9,
6773
7127
  handler: async (args, _extra) => {
6774
7128
  return withErrorHandling("list symbols", async () => {
@@ -6784,7 +7138,7 @@ function createListSymbolsTool(pkgseerService) {
6784
7138
  isError: true
6785
7139
  };
6786
7140
  }
6787
- const result = await pkgseerService.listSymbols(toGraphQLRegistry2(args.registry), args.package_name, scope, {
7141
+ const result = await pkgseerService.listSymbols(toGraphQLRegistry(args.registry), args.package_name, scope, {
6788
7142
  filePath: args.file_path,
6789
7143
  namespace: args.namespace,
6790
7144
  publicOnly: args.public_only,
@@ -6797,10 +7151,10 @@ function createListSymbolsTool(pkgseerService) {
6797
7151
  const graphqlError = handleGraphQLErrors(result.errors);
6798
7152
  if (graphqlError)
6799
7153
  return graphqlError;
6800
- if (!result.data.listSymbols) {
7154
+ if (!result.data?.listSymbols) {
6801
7155
  return notFoundError(args.package_name, args.registry);
6802
7156
  }
6803
- return textResult(JSON.stringify(result.data.listSymbols, null, 2));
7157
+ return textResult(JSON.stringify(result.data?.listSymbols, null, 2));
6804
7158
  });
6805
7159
  }
6806
7160
  };
@@ -6893,20 +7247,20 @@ function createPackageDependenciesTool(pkgseerService) {
6893
7247
  schema: argsSchema10,
6894
7248
  handler: async ({ registry, package_name, version: version2, include_transitive, max_depth }, _extra) => {
6895
7249
  return withErrorHandling("fetch package dependencies", async () => {
6896
- const result = await pkgseerService.getPackageDependencies(toGraphQLRegistry2(registry), package_name, version2, include_transitive, max_depth);
7250
+ const result = await pkgseerService.getPackageDependencies(toGraphQLRegistry(registry), package_name, version2, include_transitive, max_depth);
6897
7251
  const graphqlError = handleGraphQLErrors(result.errors);
6898
7252
  if (graphqlError)
6899
7253
  return graphqlError;
6900
- if (!result.data.packageDependencies) {
7254
+ if (!result.data?.packageDependencies) {
6901
7255
  return notFoundError(package_name, registry);
6902
7256
  }
6903
- const deps = result.data.packageDependencies.dependencies;
7257
+ const deps = result.data?.packageDependencies.dependencies;
6904
7258
  const decodedDag = decodeDag(deps?.transitive?.dag);
6905
7259
  const transitiveDag = deps?.transitive?.dag;
6906
7260
  const edgesWithDepth = buildEdgeDepths(decodedDag, typeof transitiveDag?.root === "string" ? transitiveDag.root : undefined);
6907
7261
  const output2 = {
6908
7262
  summary: deps?.summary,
6909
- package: result.data.packageDependencies.package,
7263
+ package: result.data?.packageDependencies.package,
6910
7264
  direct: deps?.direct,
6911
7265
  transitive: deps?.transitive ? {
6912
7266
  totalEdges: deps.transitive.totalEdges,
@@ -6920,7 +7274,7 @@ function createPackageDependenciesTool(pkgseerService) {
6920
7274
  raw: deps.transitive.dag
6921
7275
  }
6922
7276
  } : undefined,
6923
- raw: result.data.packageDependencies
7277
+ raw: result.data?.packageDependencies
6924
7278
  };
6925
7279
  return textResult(JSON.stringify(output2, null, 2));
6926
7280
  });
@@ -6946,7 +7300,7 @@ function createPackageImportsTool(pkgseerService) {
6946
7300
  schema: argsSchema11,
6947
7301
  handler: async (args, _extra) => {
6948
7302
  return withErrorHandling("fetch package imports", async () => {
6949
- const result = await pkgseerService.packageImports(toGraphQLRegistry2(args.registry), args.package_name, {
7303
+ const result = await pkgseerService.packageImports(toGraphQLRegistry(args.registry), args.package_name, {
6950
7304
  filePath: args.file_path,
6951
7305
  resolvedOnly: args.resolved_only,
6952
7306
  limit: args.limit,
@@ -6957,10 +7311,10 @@ function createPackageImportsTool(pkgseerService) {
6957
7311
  const graphqlError = handleGraphQLErrors(result.errors);
6958
7312
  if (graphqlError)
6959
7313
  return graphqlError;
6960
- if (!result.data.packageImports) {
7314
+ if (!result.data?.packageImports) {
6961
7315
  return notFoundError(args.package_name, args.registry);
6962
7316
  }
6963
- return textResult(JSON.stringify(result.data.packageImports, null, 2));
7317
+ return textResult(JSON.stringify(result.data?.packageImports, null, 2));
6964
7318
  });
6965
7319
  }
6966
7320
  };
@@ -6978,14 +7332,14 @@ function createPackageQualityTool(pkgseerService) {
6978
7332
  schema: argsSchema12,
6979
7333
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
6980
7334
  return withErrorHandling("fetch package quality", async () => {
6981
- const result = await pkgseerService.getPackageQuality(toGraphQLRegistry2(registry), package_name, version2);
7335
+ const result = await pkgseerService.getPackageQuality(toGraphQLRegistry(registry), package_name, version2);
6982
7336
  const graphqlError = handleGraphQLErrors(result.errors);
6983
7337
  if (graphqlError)
6984
7338
  return graphqlError;
6985
- if (!result.data.packageQuality) {
7339
+ if (!result.data?.packageQuality) {
6986
7340
  return notFoundError(package_name, registry);
6987
7341
  }
6988
- return textResult(JSON.stringify(result.data.packageQuality, null, 2));
7342
+ return textResult(JSON.stringify(result.data?.packageQuality, null, 2));
6989
7343
  });
6990
7344
  }
6991
7345
  };
@@ -7002,14 +7356,14 @@ function createPackageSummaryTool(pkgseerService) {
7002
7356
  schema: argsSchema13,
7003
7357
  handler: async ({ registry, package_name }, _extra) => {
7004
7358
  return withErrorHandling("fetch package summary", async () => {
7005
- const result = await pkgseerService.getPackageSummary(toGraphQLRegistry2(registry), package_name);
7359
+ const result = await pkgseerService.getPackageSummary(toGraphQLRegistry(registry), package_name);
7006
7360
  const graphqlError = handleGraphQLErrors(result.errors);
7007
7361
  if (graphqlError)
7008
7362
  return graphqlError;
7009
- if (!result.data.packageSummary) {
7363
+ if (!result.data?.packageSummary) {
7010
7364
  return notFoundError(package_name, registry);
7011
7365
  }
7012
- return textResult(JSON.stringify(result.data.packageSummary, null, 2));
7366
+ return textResult(JSON.stringify(result.data?.packageSummary, null, 2));
7013
7367
  });
7014
7368
  }
7015
7369
  };
@@ -7027,14 +7381,14 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
7027
7381
  schema: argsSchema14,
7028
7382
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
7029
7383
  return withErrorHandling("fetch package vulnerabilities", async () => {
7030
- const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry2(registry), package_name, version2);
7384
+ const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry(registry), package_name, version2);
7031
7385
  const graphqlError = handleGraphQLErrors(result.errors);
7032
7386
  if (graphqlError)
7033
7387
  return graphqlError;
7034
- if (!result.data.packageVulnerabilities) {
7388
+ if (!result.data?.packageVulnerabilities) {
7035
7389
  return notFoundError(package_name, registry);
7036
7390
  }
7037
- return textResult(JSON.stringify(result.data.packageVulnerabilities, null, 2));
7391
+ return textResult(JSON.stringify(result.data?.packageVulnerabilities, null, 2));
7038
7392
  });
7039
7393
  }
7040
7394
  };
@@ -7099,7 +7453,7 @@ function createSearchTool(pkgseerService) {
7099
7453
  return errorResult("Search query is required.");
7100
7454
  }
7101
7455
  const graphqlPackages = packages.map((pkg) => ({
7102
- registry: toGraphQLRegistry2(pkg.registry),
7456
+ registry: toGraphQLRegistry(pkg.registry),
7103
7457
  name: pkg.name,
7104
7458
  version: pkg.version
7105
7459
  }));
@@ -7111,7 +7465,7 @@ function createSearchTool(pkgseerService) {
7111
7465
  const graphqlError = handleGraphQLErrors(result.errors);
7112
7466
  if (graphqlError)
7113
7467
  return graphqlError;
7114
- const asyncResult = result.data.combinedSearch;
7468
+ const asyncResult = result.data?.combinedSearch;
7115
7469
  if (!asyncResult) {
7116
7470
  return errorResult("No search results returned. Check package names and registries.");
7117
7471
  }
@@ -7191,13 +7545,13 @@ function createSearchProjectDocsTool(deps) {
7191
7545
  const graphqlError = handleGraphQLErrors(result.errors);
7192
7546
  if (graphqlError)
7193
7547
  return graphqlError;
7194
- if (!result.data.searchProjectDocs) {
7548
+ if (!result.data?.searchProjectDocs) {
7195
7549
  return errorResult(`Project not found: ${resolvedProject}`);
7196
7550
  }
7197
- if ((result.data.searchProjectDocs.entries ?? []).length === 0 && normalizedTerms.length > 0) {
7551
+ if ((result.data?.searchProjectDocs.entries ?? []).length === 0 && normalizedTerms.length > 0) {
7198
7552
  return errorResult(`No documentation matched: ${normalizedTerms.join(", ")}. ` + "Try fewer or broader terms, or reduce match constraints.");
7199
7553
  }
7200
- return textResult(JSON.stringify(result.data.searchProjectDocs, null, 2));
7554
+ return textResult(JSON.stringify(result.data?.searchProjectDocs, null, 2));
7201
7555
  });
7202
7556
  }
7203
7557
  };
@@ -7218,7 +7572,7 @@ function createSearchStatusTool(pkgseerService) {
7218
7572
  const graphqlError = handleGraphQLErrors(progressResult.errors);
7219
7573
  if (graphqlError)
7220
7574
  return graphqlError;
7221
- const progress = progressResult.data.searchProgress;
7575
+ const progress = progressResult.data?.searchProgress;
7222
7576
  if (!progress) {
7223
7577
  return errorResult("Search session not found. It may have expired (sessions last 1 hour).");
7224
7578
  }
@@ -7227,7 +7581,7 @@ function createSearchStatusTool(pkgseerService) {
7227
7581
  const resultsError = handleGraphQLErrors(resultsResponse.errors);
7228
7582
  if (resultsError)
7229
7583
  return resultsError;
7230
- const searchResults = resultsResponse.data.searchResults;
7584
+ const searchResults = resultsResponse.data?.searchResults;
7231
7585
  if (!searchResults) {
7232
7586
  return errorResult("Search completed but results are no longer available. " + "The session may have expired (sessions last 1 hour).");
7233
7587
  }
@@ -7281,7 +7635,7 @@ function createSearchSymbolsTool(pkgseerService) {
7281
7635
  schema: argsSchema18,
7282
7636
  handler: async (args, _extra) => {
7283
7637
  return withErrorHandling("search symbols", async () => {
7284
- const result = await pkgseerService.searchSymbols(toGraphQLRegistry2(args.registry), args.package_name, {
7638
+ const result = await pkgseerService.searchSymbols(toGraphQLRegistry(args.registry), args.package_name, {
7285
7639
  query: args.query,
7286
7640
  keywords: args.keywords,
7287
7641
  matchMode: toMatchMode(args.match_mode),
@@ -7295,10 +7649,21 @@ function createSearchSymbolsTool(pkgseerService) {
7295
7649
  const graphqlError = handleGraphQLErrors(result.errors);
7296
7650
  if (graphqlError)
7297
7651
  return graphqlError;
7298
- if (!result.data.searchSymbols) {
7652
+ if (!result.data?.searchSymbols) {
7299
7653
  return notFoundError(args.package_name, args.registry);
7300
7654
  }
7301
- return textResult(JSON.stringify(result.data.searchSymbols, null, 2));
7655
+ const data = result.data?.searchSymbols;
7656
+ const extra = {};
7657
+ if (data.results.length === 0 && data.diagnostics?.hint) {
7658
+ extra._hint = data.diagnostics.hint;
7659
+ }
7660
+ if (data.warning) {
7661
+ extra._warning = data.warning;
7662
+ }
7663
+ if (Object.keys(extra).length > 0) {
7664
+ return textResult(JSON.stringify({ ...data, ...extra }, null, 2));
7665
+ }
7666
+ return textResult(JSON.stringify(data, null, 2));
7302
7667
  });
7303
7668
  }
7304
7669
  };
@@ -7306,7 +7671,7 @@ function createSearchSymbolsTool(pkgseerService) {
7306
7671
  // src/tools/symbol-callees.ts
7307
7672
  import { z as z17 } from "zod";
7308
7673
  var argsSchema19 = {
7309
- symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide either symbol_id or registry + package_name + symbol_name."),
7674
+ symbol: schemas.symbolReference.describe("Symbol to find callees for. Provide either symbol_ref or registry + package_name + symbol_name."),
7310
7675
  max_depth: z17.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
7311
7676
  limit: z17.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
7312
7677
  include_external: z17.boolean().optional().describe("Include calls to symbols in other packages"),
@@ -7317,13 +7682,13 @@ var argsSchema19 = {
7317
7682
  function createSymbolCalleesTool(pkgseerService) {
7318
7683
  return {
7319
7684
  name: "symbol_callees",
7320
- description: "Find what a symbol calls (its dependencies). " + "Returns direct callees at max_depth=1, or transitive call chains at higher depths. " + "Includes callee names, qualified paths, file locations, call lines, and external package references. " + "Get symbol_id from find_symbol or list_symbols results. See symbol_callers for the reverse.",
7685
+ description: "Find what a symbol calls (its dependencies). " + "Returns direct callees at max_depth=1, or transitive call chains at higher depths. " + "Includes callee names, qualified paths, file locations, call lines, and external package references. " + "Get symbol_ref from find_symbol or list_symbols results. See symbol_callers for the reverse.",
7321
7686
  schema: argsSchema19,
7322
7687
  handler: async (args, _extra) => {
7323
7688
  return withErrorHandling("find symbol callees", async () => {
7324
7689
  const symbolInput = toSymbolReferenceInput(args.symbol);
7325
- if (!symbolInput.symbolId && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7326
- return errorResult("Provide either symbol_id or symbol_name with registry and package_name to identify the symbol.");
7690
+ if (!symbolInput.symbolRef && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7691
+ return errorResult("Provide either symbol_ref or symbol_name with registry and package_name to identify the symbol.");
7327
7692
  }
7328
7693
  const result = await pkgseerService.symbolDependencies(symbolInput, {
7329
7694
  maxDepth: args.max_depth,
@@ -7336,10 +7701,10 @@ function createSymbolCalleesTool(pkgseerService) {
7336
7701
  const graphqlError = handleGraphQLErrors(result.errors);
7337
7702
  if (graphqlError)
7338
7703
  return graphqlError;
7339
- if (!result.data.symbolDependencies) {
7704
+ if (!result.data?.symbolDependencies) {
7340
7705
  return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7341
7706
  }
7342
- return textResult(JSON.stringify(result.data.symbolDependencies, null, 2));
7707
+ return textResult(JSON.stringify(result.data?.symbolDependencies, null, 2));
7343
7708
  });
7344
7709
  }
7345
7710
  };
@@ -7347,8 +7712,9 @@ function createSymbolCalleesTool(pkgseerService) {
7347
7712
  // src/tools/symbol-callers.ts
7348
7713
  import { z as z18 } from "zod";
7349
7714
  var argsSchema20 = {
7350
- symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide either symbol_id or registry + package_name + symbol_name."),
7715
+ symbol: schemas.symbolReference.describe("Symbol to find callers for. Provide either symbol_ref or registry + package_name + symbol_name."),
7351
7716
  same_package_only: z18.boolean().optional().describe("Only return callers from the same package"),
7717
+ max_depth: z18.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callers only, 2+ = transitive, max 5)"),
7352
7718
  limit: z18.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
7353
7719
  mode: schemas.navigationMode,
7354
7720
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7356,16 +7722,17 @@ var argsSchema20 = {
7356
7722
  function createSymbolCallersTool(pkgseerService) {
7357
7723
  return {
7358
7724
  name: "symbol_callers",
7359
- description: "Find what calls a symbol (its dependents/callers). " + "Returns the target symbol and a list of callers with file locations and call line numbers. " + "Use same_package_only to limit to callers within the same package. " + "Get symbol_id from find_symbol or list_symbols results. See symbol_callees for the reverse.",
7725
+ description: "Find what calls a symbol (its dependents/callers). " + "Returns the target symbol and a list of callers with file locations and call line numbers. " + "Use same_package_only to limit to callers within the same package. " + "Get symbol_ref from find_symbol or list_symbols results. See symbol_callees for the reverse.",
7360
7726
  schema: argsSchema20,
7361
7727
  handler: async (args, _extra) => {
7362
7728
  return withErrorHandling("find symbol callers", async () => {
7363
7729
  const symbolInput = toSymbolReferenceInput(args.symbol);
7364
- if (!symbolInput.symbolId && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7365
- return errorResult("Provide either symbol_id or symbol_name with registry and package_name to identify the symbol.");
7730
+ if (!symbolInput.symbolRef && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7731
+ return errorResult("Provide either symbol_ref or symbol_name with registry and package_name to identify the symbol.");
7366
7732
  }
7367
7733
  const result = await pkgseerService.symbolDependents(symbolInput, {
7368
7734
  samePackageOnly: args.same_package_only,
7735
+ maxDepth: args.max_depth,
7369
7736
  maxResults: args.limit,
7370
7737
  mode: toNavigationMode(args.mode),
7371
7738
  waitTimeoutMs: args.wait_timeout_ms
@@ -7373,10 +7740,10 @@ function createSymbolCallersTool(pkgseerService) {
7373
7740
  const graphqlError = handleGraphQLErrors(result.errors);
7374
7741
  if (graphqlError)
7375
7742
  return graphqlError;
7376
- if (!result.data.symbolDependents) {
7743
+ if (!result.data?.symbolDependents) {
7377
7744
  return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7378
7745
  }
7379
- return textResult(JSON.stringify(result.data.symbolDependents, null, 2));
7746
+ return textResult(JSON.stringify(result.data?.symbolDependents, null, 2));
7380
7747
  });
7381
7748
  }
7382
7749
  };
@@ -7405,7 +7772,7 @@ function createTriggerIndexingTool(pkgseerService) {
7405
7772
  handler: async (args, _extra) => {
7406
7773
  return withErrorHandling("trigger indexing", async () => {
7407
7774
  const packages = args.packages?.map((p) => ({
7408
- registry: toGraphQLRegistry2(p.registry),
7775
+ registry: toGraphQLRegistry(p.registry),
7409
7776
  name: p.name,
7410
7777
  version: p.version
7411
7778
  }));
@@ -7421,7 +7788,7 @@ function createTriggerIndexingTool(pkgseerService) {
7421
7788
  const graphqlError = handleGraphQLErrors(result.errors);
7422
7789
  if (graphqlError)
7423
7790
  return graphqlError;
7424
- if (!result.data.triggerIndexing) {
7791
+ if (!result.data?.triggerIndexing) {
7425
7792
  return {
7426
7793
  content: [
7427
7794
  {
@@ -7432,7 +7799,7 @@ function createTriggerIndexingTool(pkgseerService) {
7432
7799
  isError: true
7433
7800
  };
7434
7801
  }
7435
- return textResult(JSON.stringify(result.data.triggerIndexing, null, 2));
7802
+ return textResult(JSON.stringify(result.data?.triggerIndexing, null, 2));
7436
7803
  });
7437
7804
  }
7438
7805
  };
@@ -7464,7 +7831,7 @@ function createVersionDiffTool(pkgseerService) {
7464
7831
  schema: argsSchema22,
7465
7832
  handler: async (args, _extra) => {
7466
7833
  return withErrorHandling("version diff", async () => {
7467
- const result = await pkgseerService.versionDiff(toGraphQLRegistry2(args.registry), args.package_name, args.from_version, args.to_version, {
7834
+ const result = await pkgseerService.versionDiff(toGraphQLRegistry(args.registry), args.package_name, args.from_version, args.to_version, {
7468
7835
  includePrivate: args.include_private,
7469
7836
  kind: toSymbolKind(args.kind),
7470
7837
  limit: args.limit,
@@ -7473,10 +7840,10 @@ function createVersionDiffTool(pkgseerService) {
7473
7840
  const graphqlError = handleGraphQLErrors(result.errors);
7474
7841
  if (graphqlError)
7475
7842
  return graphqlError;
7476
- if (!result.data.versionDiff) {
7843
+ if (!result.data?.versionDiff) {
7477
7844
  return notFoundError(args.package_name, args.registry);
7478
7845
  }
7479
- return textResult(JSON.stringify(result.data.versionDiff, null, 2));
7846
+ return textResult(JSON.stringify(result.data?.versionDiff, null, 2));
7480
7847
  });
7481
7848
  }
7482
7849
  };
@@ -7669,12 +8036,12 @@ async function pkgCompareAction(packages, options, deps) {
7669
8036
  });
7670
8037
  const result = await pkgseerService.cliComparePackages(input2);
7671
8038
  handleErrors(result.errors, options.json ?? false);
7672
- if (!result.data.comparePackages) {
8039
+ if (!result.data?.comparePackages) {
7673
8040
  outputError("Comparison failed", options.json ?? false);
7674
8041
  return;
7675
8042
  }
7676
8043
  if (options.json) {
7677
- const pkgs = result.data.comparePackages.packages?.filter((p) => p) ?? [];
8044
+ const pkgs = result.data?.comparePackages.packages?.filter((p) => p) ?? [];
7678
8045
  const slim = pkgs.map((p) => ({
7679
8046
  package: `${p?.packageName}@${p?.version}`,
7680
8047
  quality: p?.quality?.score,
@@ -7683,7 +8050,7 @@ async function pkgCompareAction(packages, options, deps) {
7683
8050
  }));
7684
8051
  output(slim, true);
7685
8052
  } else {
7686
- console.log(formatPackageComparison(result.data.comparePackages));
8053
+ console.log(formatPackageComparison(result.data?.comparePackages));
7687
8054
  }
7688
8055
  }
7689
8056
  var COMPARE_DESCRIPTION = `Compare multiple packages.
@@ -7752,13 +8119,13 @@ async function pkgDepsAction(packageArg, options, deps) {
7752
8119
  const transitiveRequested = options.transitive ?? false;
7753
8120
  const result = await pkgseerService.cliPackageDeps(registry, parsed.name, version2, options.transitive, options.maxDepth ? Number.parseInt(options.maxDepth, 10) : undefined);
7754
8121
  handleErrors(result.errors, options.json ?? false);
7755
- if (!result.data.packageDependencies) {
8122
+ if (!result.data?.packageDependencies) {
7756
8123
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
7757
8124
  return;
7758
8125
  }
7759
8126
  const format = options.json ? "json" : options.format ?? "human";
7760
8127
  if (format === "json") {
7761
- const data = result.data.packageDependencies;
8128
+ const data = result.data?.packageDependencies;
7762
8129
  output({
7763
8130
  package: `${data.package?.name}@${data.package?.version}`,
7764
8131
  directCount: data.dependencies?.summary?.directCount ?? 0,
@@ -7771,7 +8138,7 @@ async function pkgDepsAction(packageArg, options, deps) {
7771
8138
  }))
7772
8139
  }, true);
7773
8140
  } else if (format === "summary") {
7774
- const data = result.data.packageDependencies;
8141
+ const data = result.data?.packageDependencies;
7775
8142
  const deps2 = data.dependencies;
7776
8143
  const directCount = deps2?.summary?.directCount ?? 0;
7777
8144
  const uniquePackagesCount = deps2?.summary?.uniquePackagesCount ?? 0;
@@ -7784,7 +8151,7 @@ async function pkgDepsAction(packageArg, options, deps) {
7784
8151
  console.log(lines.join(`
7785
8152
  `));
7786
8153
  } else {
7787
- console.log(formatPackageDependencies(result.data.packageDependencies, transitiveRequested));
8154
+ console.log(formatPackageDependencies(result.data?.packageDependencies, transitiveRequested));
7788
8155
  }
7789
8156
  }
7790
8157
  var DEPS_DESCRIPTION = `Get package dependencies.
@@ -7868,12 +8235,12 @@ async function pkgInfoAction(packageArg, options, deps) {
7868
8235
  const registry = toGraphQLRegistry(parsed.registry !== "npm" ? parsed.registry : options.registry);
7869
8236
  const result = await pkgseerService.cliPackageInfo(registry, parsed.name);
7870
8237
  handleErrors(result.errors, options.json ?? false);
7871
- if (!result.data.packageSummary) {
8238
+ if (!result.data?.packageSummary) {
7872
8239
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
7873
8240
  return;
7874
8241
  }
7875
8242
  if (options.json) {
7876
- const data = result.data.packageSummary;
8243
+ const data = result.data?.packageSummary;
7877
8244
  const pkg = data.package;
7878
8245
  const slim = {
7879
8246
  name: pkg?.name,
@@ -7885,7 +8252,7 @@ async function pkgInfoAction(packageArg, options, deps) {
7885
8252
  };
7886
8253
  output(slim, true);
7887
8254
  } else {
7888
- console.log(formatPackageSummary(result.data.packageSummary));
8255
+ console.log(formatPackageSummary(result.data?.packageSummary));
7889
8256
  }
7890
8257
  }
7891
8258
  var INFO_DESCRIPTION = `Get package summary and metadata.
@@ -7936,15 +8303,15 @@ async function pkgQualityAction(packageArg, options, deps) {
7936
8303
  const version2 = parsed.version ?? options.pkgVersion;
7937
8304
  const result = await pkgseerService.cliPackageQuality(registry, parsed.name, version2);
7938
8305
  handleErrors(result.errors, options.json ?? false);
7939
- if (!result.data.packageQuality) {
8306
+ if (!result.data?.packageQuality) {
7940
8307
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
7941
8308
  return;
7942
8309
  }
7943
8310
  const format = options.json ? "json" : options.format ?? "human";
7944
8311
  if (format === "json") {
7945
- const quality = result.data.packageQuality.quality;
8312
+ const quality = result.data?.packageQuality.quality;
7946
8313
  const slim = {
7947
- package: `${result.data.packageQuality.package?.name}@${result.data.packageQuality.package?.version}`,
8314
+ package: `${result.data?.packageQuality.package?.name}@${result.data?.packageQuality.package?.version}`,
7948
8315
  score: quality?.overallScore,
7949
8316
  grade: quality?.grade,
7950
8317
  categories: quality?.categories?.filter((c) => c).map((c) => ({
@@ -7954,7 +8321,7 @@ async function pkgQualityAction(packageArg, options, deps) {
7954
8321
  };
7955
8322
  output(slim, true);
7956
8323
  } else {
7957
- console.log(formatPackageQuality(result.data.packageQuality));
8324
+ console.log(formatPackageQuality(result.data?.packageQuality));
7958
8325
  }
7959
8326
  }
7960
8327
  var QUALITY_DESCRIPTION = `Get package quality score and breakdown.
@@ -8039,12 +8406,12 @@ async function pkgVulnsAction(packageArg, options, deps) {
8039
8406
  const version2 = parsed.version ?? options.pkgVersion;
8040
8407
  const result = await pkgseerService.cliPackageVulns(registry, parsed.name, version2);
8041
8408
  handleErrors(result.errors, options.json ?? false);
8042
- if (!result.data.packageVulnerabilities) {
8409
+ if (!result.data?.packageVulnerabilities) {
8043
8410
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
8044
8411
  return;
8045
8412
  }
8046
8413
  if (options.json) {
8047
- const data = result.data.packageVulnerabilities;
8414
+ const data = result.data?.packageVulnerabilities;
8048
8415
  const vulns = data.security?.vulnerabilities ?? [];
8049
8416
  const slim = {
8050
8417
  package: `${data.package?.name}@${data.package?.version}`,
@@ -8058,7 +8425,7 @@ async function pkgVulnsAction(packageArg, options, deps) {
8058
8425
  };
8059
8426
  output(slim, true);
8060
8427
  } else {
8061
- console.log(formatPackageVulnerabilities(result.data.packageVulnerabilities));
8428
+ console.log(formatPackageVulnerabilities(result.data?.packageVulnerabilities));
8062
8429
  }
8063
8430
  }
8064
8431
  var VULNS_DESCRIPTION = `Check package for security vulnerabilities.