@pkgseer/cli 0.4.3 → 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-d3mfgdr9.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
@@ -720,7 +720,7 @@ var SearchSymbolsDocument = gql`
720
720
  contentPreview
721
721
  code
722
722
  language
723
- symbolId
723
+ symbolRef
724
724
  qualifiedPath
725
725
  kind
726
726
  arity
@@ -757,7 +757,7 @@ var ListSymbolsDocument = gql`
757
757
  waitTimeoutMs: $waitTimeoutMs
758
758
  ) {
759
759
  symbols {
760
- symbolId
760
+ symbolRef
761
761
  name
762
762
  qualifiedPath
763
763
  kind
@@ -779,7 +779,7 @@ var ListSymbolsDocument = gql`
779
779
  }
780
780
  `;
781
781
  var SymbolDependenciesDocument = gql`
782
- 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) {
783
783
  symbolDependencies(
784
784
  symbol: $symbol
785
785
  maxDepth: $maxDepth
@@ -788,14 +788,15 @@ var SymbolDependenciesDocument = gql`
788
788
  includeBuiltins: $includeBuiltins
789
789
  mode: $mode
790
790
  waitTimeoutMs: $waitTimeoutMs
791
+ version: $version
791
792
  ) {
792
793
  root {
793
- symbolId
794
+ symbolRef
794
795
  name
795
796
  qualifiedPath
796
797
  }
797
798
  dependencies {
798
- symbolId
799
+ symbolRef
799
800
  name
800
801
  qualifiedPath
801
802
  kind
@@ -817,21 +818,22 @@ var SymbolDependenciesDocument = gql`
817
818
  }
818
819
  `;
819
820
  var SymbolDependentsDocument = gql`
820
- 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) {
821
822
  symbolDependents(
822
823
  symbol: $symbol
823
824
  samePackageOnly: $samePackageOnly
824
825
  maxResults: $maxResults
826
+ maxDepth: $maxDepth
825
827
  mode: $mode
826
828
  waitTimeoutMs: $waitTimeoutMs
827
829
  ) {
828
830
  target {
829
- symbolId
831
+ symbolRef
830
832
  name
831
833
  qualifiedPath
832
834
  }
833
835
  dependents {
834
- symbolId
836
+ symbolRef
835
837
  name
836
838
  qualifiedPath
837
839
  kind
@@ -887,19 +889,19 @@ var CallPathDocument = gql`
887
889
  ) {
888
890
  pathFound
889
891
  fromSymbol {
890
- symbolId
892
+ symbolRef
891
893
  name
892
894
  qualifiedPath
893
895
  }
894
896
  toSymbol {
895
- symbolId
897
+ symbolRef
896
898
  name
897
899
  qualifiedPath
898
900
  }
899
901
  paths {
900
902
  length
901
903
  hops {
902
- symbolId
904
+ symbolRef
903
905
  name
904
906
  qualifiedPath
905
907
  filePath
@@ -1040,7 +1042,7 @@ var VersionDiffDocument = gql`
1040
1042
  endLine
1041
1043
  isPublic
1042
1044
  minArity
1043
- symbolId
1045
+ symbolRef
1044
1046
  }
1045
1047
  to {
1046
1048
  contentHash
@@ -1050,7 +1052,7 @@ var VersionDiffDocument = gql`
1050
1052
  endLine
1051
1053
  isPublic
1052
1054
  minArity
1053
- symbolId
1055
+ symbolRef
1054
1056
  }
1055
1057
  }
1056
1058
  hasMore
@@ -1219,7 +1221,7 @@ function createClient(apiToken) {
1219
1221
  if (apiToken) {
1220
1222
  headers.Authorization = `Bearer ${apiToken}`;
1221
1223
  }
1222
- const client = new GraphQLClient(apiUrl, { headers });
1224
+ const client = new GraphQLClient(apiUrl, { headers, errorPolicy: "all" });
1223
1225
  return getSdk(client);
1224
1226
  }
1225
1227
 
@@ -1392,7 +1394,7 @@ class AuthStorageImpl {
1392
1394
  this.configDir = configDir ?? fs.joinPath(fs.getHomeDir(), CONFIG_DIR);
1393
1395
  this.authPath = fs.joinPath(this.configDir, AUTH_FILE);
1394
1396
  }
1395
- getPath() {
1397
+ getStorageLocation() {
1396
1398
  return this.authPath;
1397
1399
  }
1398
1400
  async load(baseUrl) {
@@ -1512,6 +1514,117 @@ class BrowserServiceImpl {
1512
1514
  await open(url);
1513
1515
  }
1514
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
+ }
1515
1628
  // src/services/config-service.ts
1516
1629
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
1517
1630
  import { z } from "zod";
@@ -1770,6 +1883,143 @@ class GitServiceImpl {
1770
1883
  return existsSync(gitPath);
1771
1884
  }
1772
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
+ }
1773
2023
  // src/services/pkgseer-service.ts
1774
2024
  class PkgseerServiceImpl {
1775
2025
  client;
@@ -2019,7 +2269,8 @@ class PkgseerServiceImpl {
2019
2269
  includeExternal: options?.includeExternal,
2020
2270
  includeBuiltins: options?.includeBuiltins,
2021
2271
  mode: options?.mode,
2022
- waitTimeoutMs: options?.waitTimeoutMs
2272
+ waitTimeoutMs: options?.waitTimeoutMs,
2273
+ version: options?.version
2023
2274
  });
2024
2275
  return { data: result.data, errors: result.errors };
2025
2276
  }
@@ -2027,6 +2278,7 @@ class PkgseerServiceImpl {
2027
2278
  const result = await this.client.SymbolDependents({
2028
2279
  symbol,
2029
2280
  samePackageOnly: options?.samePackageOnly,
2281
+ maxDepth: options?.maxDepth,
2030
2282
  maxResults: options?.maxResults,
2031
2283
  mode: options?.mode,
2032
2284
  waitTimeoutMs: options?.waitTimeoutMs
@@ -2317,10 +2569,29 @@ async function resolveApiToken(configService, baseUrl) {
2317
2569
  const tokenData = await configService.getApiToken(baseUrl);
2318
2570
  return tokenData?.token;
2319
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
+ }
2320
2591
  async function createContainer() {
2321
2592
  const baseUrl = getBaseUrl();
2322
2593
  const fileSystemService = new FileSystemServiceImpl;
2323
- const authStorage = new AuthStorageImpl(fileSystemService);
2594
+ const authStorage = createAuthStorage(fileSystemService);
2324
2595
  const configService = new ConfigServiceImpl(fileSystemService, authStorage);
2325
2596
  const [apiToken, configResult] = await Promise.all([
2326
2597
  resolveApiToken(configService, baseUrl),
@@ -2381,7 +2652,7 @@ async function authStatusAction(deps) {
2381
2652
  console.log(" Expires: never");
2382
2653
  }
2383
2654
  console.log(`
2384
- Stored at: ${authStorage.getPath()}`);
2655
+ Storage: ${authStorage.getStorageLocation()}`);
2385
2656
  }
2386
2657
  var STATUS_DESCRIPTION = `Show current authentication status.
2387
2658
 
@@ -2394,6 +2665,42 @@ function registerAuthStatusCommand(program) {
2394
2665
  });
2395
2666
  }
2396
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
+
2397
2704
  // src/commands/shared.ts
2398
2705
  function parsePackageSpec(spec) {
2399
2706
  let registry = "npm";
@@ -2425,19 +2732,6 @@ function parsePackageSpec(spec) {
2425
2732
  }
2426
2733
  return { registry, name: rest };
2427
2734
  }
2428
- function toGraphQLRegistry(registry) {
2429
- const map = {
2430
- npm: "NPM",
2431
- pypi: "PYPI",
2432
- hex: "HEX",
2433
- crates: "CRATES",
2434
- nuget: "NUGET",
2435
- maven: "MAVEN",
2436
- zig: "ZIG",
2437
- vcpkg: "VCPKG"
2438
- };
2439
- return map[registry.toLowerCase()] || "NPM";
2440
- }
2441
2735
  function output(data, json) {
2442
2736
  if (json) {
2443
2737
  console.log(JSON.stringify(data));
@@ -2453,30 +2747,20 @@ function outputError(message, json) {
2453
2747
  }
2454
2748
  process.exit(1);
2455
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
+ };
2456
2758
  function handleErrors(errors, json) {
2457
2759
  if (!errors || errors.length === 0)
2458
2760
  return;
2459
2761
  const combined = errors.map((e) => e.message).filter(Boolean).join(", ");
2460
- const lower = combined.toLowerCase();
2461
- const isTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
2462
- const isNotFound = lower.includes("not found") || lower.includes("does not exist") || lower.includes("unknown");
2463
- const isAuth = lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("token") || lower.includes("authentication") || lower.includes("permission");
2464
- const isRateLimit = lower.includes("rate limit") || lower.includes("too many requests");
2465
- const isBeingIndexed = lower.includes("being indexed") || lower.includes("retry with waittimeoutms");
2466
- let hint = "";
2467
- if (isBeingIndexed) {
2468
- hint = " Hint: package is being indexed. Try again with a longer --wait value (e.g., --wait 30000).";
2469
- } else if (isTimeout) {
2470
- hint = " Hint: lower the limit or narrow the scope, then retry.";
2471
- } else if (isNotFound) {
2472
- hint = " Hint: verify the name/registry and that the resource exists.";
2473
- } else if (isAuth) {
2474
- hint = " Hint: check login or token validity (pkgseer auth-status).";
2475
- } else if (isRateLimit) {
2476
- hint = " Hint: wait and retry, or reduce request frequency.";
2477
- }
2478
- const message = `${combined}${hint}`;
2479
- outputError(message, json);
2762
+ const hint = CLI_HINTS[classifyError(combined)];
2763
+ outputError(`${combined}${hint}`, json);
2480
2764
  }
2481
2765
  function formatNumber(num) {
2482
2766
  if (num == null)
@@ -2565,21 +2849,10 @@ async function withCliErrorHandling(json, fn) {
2565
2849
  return;
2566
2850
  }
2567
2851
  const message = error instanceof Error ? error.message : "Unknown error";
2568
- const lower = message.toLowerCase();
2569
- if (lower.includes("being indexed") || lower.includes("retry with waittimeoutms")) {
2570
- outputError(`${message}. Hint: package is being indexed. Try again with a longer --wait value (e.g., --wait 30000).`, json);
2571
- return;
2572
- }
2573
- if (lower.includes("-32001") || lower.includes("timeout")) {
2574
- outputError(`${message}. Hint: lower the limit or narrow the scope, then retry.`, json);
2575
- return;
2576
- }
2577
- if (lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("token") || lower.includes("authentication") || lower.includes("permission")) {
2578
- outputError(`${message}. Hint: check login or token validity.`, json);
2579
- return;
2580
- }
2581
- if (lower.includes("rate limit") || lower.includes("too many requests")) {
2582
- 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);
2583
2856
  return;
2584
2857
  }
2585
2858
  const colonMatch = message.match(/^([^:]+):/);
@@ -2615,12 +2888,12 @@ function parseSymbolRef(spec) {
2615
2888
  packageName: parsed.name
2616
2889
  };
2617
2890
  }
2618
- function buildSymbolReference(spec, id) {
2619
- if (id) {
2620
- return { symbolId: Number.parseInt(id, 10) };
2891
+ function buildSymbolReference(spec, ref) {
2892
+ if (ref) {
2893
+ return { symbolRef: ref };
2621
2894
  }
2622
2895
  if (!spec) {
2623
- 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>");
2624
2897
  }
2625
2898
  return parseSymbolRef(spec);
2626
2899
  }
@@ -2663,7 +2936,7 @@ function formatSymbol(symbol) {
2663
2936
  const loc = symbol.startLine ? `${symbol.filePath}:${symbol.startLine}` : symbol.filePath;
2664
2937
  parts.push(` File: ${loc}`);
2665
2938
  }
2666
- const meta = [`id:${symbol.symbolId}`];
2939
+ const meta = [`ref:${symbol.symbolRef}`];
2667
2940
  if (symbol.callerCount != null) {
2668
2941
  meta.push(`callers:${symbol.callerCount}`);
2669
2942
  }
@@ -2693,8 +2966,8 @@ function formatDependencyEntry(entry) {
2693
2966
  if (entry.package) {
2694
2967
  parts.push(` Package: ${entry.package.registry}:${entry.package.name}`);
2695
2968
  }
2696
- if (entry.symbolId) {
2697
- parts.push(` id:${entry.symbolId}`);
2969
+ if (entry.symbolRef) {
2970
+ parts.push(` ref:${entry.symbolRef}`);
2698
2971
  }
2699
2972
  return parts.join(`
2700
2973
  `);
@@ -2703,7 +2976,7 @@ function formatDependencyEntry(entry) {
2703
2976
  // src/commands/code/callees.ts
2704
2977
  function formatCalleesResult(data) {
2705
2978
  const lines = [];
2706
- 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})`);
2707
2980
  lines.push(`${data.total} callee(s)${data.hasMore ? " (more available)" : ""}`);
2708
2981
  if (data.externalPackages && data.externalPackages.length > 0) {
2709
2982
  lines.push(`External packages: ${data.externalPackages.join(", ")}`);
@@ -2724,7 +2997,7 @@ function formatCalleesResult(data) {
2724
2997
  }
2725
2998
  async function codeCalleesAction(symbolArg, options, deps) {
2726
2999
  const { pkgseerService } = deps;
2727
- const symbolRef = buildSymbolReference(symbolArg, options.id);
3000
+ const symbolRef = buildSymbolReference(symbolArg, options.ref);
2728
3001
  const result = await pkgseerService.symbolDependencies(symbolRef, {
2729
3002
  maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
2730
3003
  maxResults: parseIntOption(options.limit, "--limit"),
@@ -2734,27 +3007,27 @@ async function codeCalleesAction(symbolArg, options, deps) {
2734
3007
  waitTimeoutMs: parseWaitTimeout(options.wait)
2735
3008
  });
2736
3009
  handleErrors(result.errors, options.json ?? false);
2737
- if (!result.data.symbolDependencies) {
2738
- 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);
2739
3012
  return;
2740
3013
  }
2741
3014
  if (options.json) {
2742
- output(result.data.symbolDependencies, true);
3015
+ output(result.data?.symbolDependencies, true);
2743
3016
  } else {
2744
- console.log(formatCalleesResult(result.data.symbolDependencies));
3017
+ console.log(formatCalleesResult(result.data?.symbolDependencies));
2745
3018
  }
2746
3019
  }
2747
3020
  var CALLEES_DESCRIPTION = `Find what a symbol calls.
2748
3021
 
2749
3022
  Shows functions and methods that the specified symbol depends on.
2750
- Use registry:package#symbolName format or --id for direct lookup.
3023
+ Use registry:package#symbolName format or --ref for direct lookup.
2751
3024
 
2752
3025
  Examples:
2753
3026
  pkgseer code callees npm:express#Router
2754
- pkgseer code callees --id 12345
3027
+ pkgseer code callees --ref npm:express:4.18.2:42
2755
3028
  pkgseer code callees npm:lodash#merge --max-depth 2 --include-external`;
2756
3029
  function registerCodeCalleesCommand(program) {
2757
- 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) => {
2758
3031
  await withCliErrorHandling(options.json ?? false, async () => {
2759
3032
  const deps = await createContainer();
2760
3033
  await codeCalleesAction(symbolArg, options, deps);
@@ -2764,7 +3037,7 @@ function registerCodeCalleesCommand(program) {
2764
3037
  // src/commands/code/callers.ts
2765
3038
  function formatCallersResult(data) {
2766
3039
  const lines = [];
2767
- 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})`);
2768
3041
  lines.push(`${data.total} caller(s)${data.hasMore ? " (more available)" : ""}`);
2769
3042
  lines.push("");
2770
3043
  for (const dep of data.dependents) {
@@ -2776,35 +3049,36 @@ function formatCallersResult(data) {
2776
3049
  }
2777
3050
  async function codeCallersAction(symbolArg, options, deps) {
2778
3051
  const { pkgseerService } = deps;
2779
- const symbolRef = buildSymbolReference(symbolArg, options.id);
3052
+ const symbolRef = buildSymbolReference(symbolArg, options.ref);
2780
3053
  const result = await pkgseerService.symbolDependents(symbolRef, {
2781
3054
  samePackageOnly: options.samePackageOnly,
3055
+ maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
2782
3056
  maxResults: parseIntOption(options.limit, "--limit"),
2783
3057
  mode: parseNavigationMode(options.mode),
2784
3058
  waitTimeoutMs: parseWaitTimeout(options.wait)
2785
3059
  });
2786
3060
  handleErrors(result.errors, options.json ?? false);
2787
- if (!result.data.symbolDependents) {
2788
- 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);
2789
3063
  return;
2790
3064
  }
2791
3065
  if (options.json) {
2792
- output(result.data.symbolDependents, true);
3066
+ output(result.data?.symbolDependents, true);
2793
3067
  } else {
2794
- console.log(formatCallersResult(result.data.symbolDependents));
3068
+ console.log(formatCallersResult(result.data?.symbolDependents));
2795
3069
  }
2796
3070
  }
2797
3071
  var CALLERS_DESCRIPTION = `Find what calls a symbol.
2798
3072
 
2799
3073
  Shows functions and methods that call the specified symbol.
2800
- Use registry:package#symbolName format or --id for direct lookup.
3074
+ Use registry:package#symbolName format or --ref for direct lookup.
2801
3075
 
2802
3076
  Examples:
2803
3077
  pkgseer code callers npm:express#Router
2804
- pkgseer code callers --id 12345
3078
+ pkgseer code callers --ref npm:express:4.18.2:42
2805
3079
  pkgseer code callers npm:lodash#debounce --same-package-only`;
2806
3080
  function registerCodeCallersCommand(program) {
2807
- 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) => {
2808
3082
  await withCliErrorHandling(options.json ?? false, async () => {
2809
3083
  const deps = await createContainer();
2810
3084
  await codeCallersAction(symbolArg, options, deps);
@@ -2856,14 +3130,14 @@ async function codeDiffAction(packageArg, fromVersion, toVersion, options, deps)
2856
3130
  waitTimeoutMs: parseWaitTimeout(options.wait)
2857
3131
  });
2858
3132
  handleErrors(result.errors, options.json ?? false);
2859
- if (!result.data.versionDiff) {
3133
+ if (!result.data?.versionDiff) {
2860
3134
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2861
3135
  return;
2862
3136
  }
2863
3137
  if (options.json) {
2864
- output(result.data.versionDiff, true);
3138
+ output(result.data?.versionDiff, true);
2865
3139
  } else {
2866
- console.log(formatDiffResult(result.data.versionDiff));
3140
+ console.log(formatDiffResult(result.data?.versionDiff));
2867
3141
  }
2868
3142
  }
2869
3143
  var DIFF_DESCRIPTION = `Compare symbols between two package versions.
@@ -2916,11 +3190,11 @@ async function codeFilesAction(packageArg, options, deps) {
2916
3190
  waitTimeoutMs: parseWaitTimeout(options.wait)
2917
3191
  });
2918
3192
  handleErrors(result.errors, options.json ?? false);
2919
- if (!result.data.listRepoFiles) {
3193
+ if (!result.data?.listRepoFiles) {
2920
3194
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2921
3195
  return;
2922
3196
  }
2923
- const data = result.data.listRepoFiles;
3197
+ const data = result.data?.listRepoFiles;
2924
3198
  if (options.json) {
2925
3199
  output(data, true);
2926
3200
  } else {
@@ -2981,11 +3255,11 @@ async function codeFindAction(packageArg, nameArg, options, deps) {
2981
3255
  waitTimeoutMs: parseWaitTimeout(options.wait)
2982
3256
  });
2983
3257
  handleErrors(result.errors, options.json ?? false);
2984
- if (!result.data.findSymbol) {
3258
+ if (!result.data?.findSymbol) {
2985
3259
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
2986
3260
  return;
2987
3261
  }
2988
- const data = result.data.findSymbol;
3262
+ const data = result.data?.findSymbol;
2989
3263
  if (options.json) {
2990
3264
  output(data, true);
2991
3265
  } else {
@@ -3055,11 +3329,11 @@ async function codeGrepAction(packageArg, filePath, pattern, options, deps) {
3055
3329
  waitTimeoutMs: parseWaitTimeout(options.wait)
3056
3330
  });
3057
3331
  handleErrors(result.errors, options.json ?? false);
3058
- if (!result.data.grepRepoFile) {
3332
+ if (!result.data?.grepRepoFile) {
3059
3333
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3060
3334
  return;
3061
3335
  }
3062
- const data = result.data.grepRepoFile;
3336
+ const data = result.data?.grepRepoFile;
3063
3337
  if (options.json) {
3064
3338
  output(data, true);
3065
3339
  } else {
@@ -3142,14 +3416,14 @@ async function codeImportsAction(packageArg, options, deps) {
3142
3416
  waitTimeoutMs: parseWaitTimeout(options.wait)
3143
3417
  });
3144
3418
  handleErrors(result.errors, options.json ?? false);
3145
- if (!result.data.packageImports) {
3419
+ if (!result.data?.packageImports) {
3146
3420
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3147
3421
  return;
3148
3422
  }
3149
3423
  if (options.json) {
3150
- output(result.data.packageImports, true);
3424
+ output(result.data?.packageImports, true);
3151
3425
  } else {
3152
- console.log(formatImportsResult(result.data.packageImports));
3426
+ console.log(formatImportsResult(result.data?.packageImports));
3153
3427
  }
3154
3428
  }
3155
3429
  var IMPORTS_DESCRIPTION = `List import statements in a package.
@@ -3211,14 +3485,14 @@ async function codeListAction(packageArg, options, deps) {
3211
3485
  waitTimeoutMs: parseWaitTimeout(options.wait)
3212
3486
  });
3213
3487
  handleErrors(result.errors, options.json ?? false);
3214
- if (!result.data.listSymbols) {
3488
+ if (!result.data?.listSymbols) {
3215
3489
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3216
3490
  return;
3217
3491
  }
3218
3492
  if (options.json) {
3219
- output(result.data.listSymbols, true);
3493
+ output(result.data?.listSymbols, true);
3220
3494
  } else {
3221
- console.log(formatListResult(result.data.listSymbols));
3495
+ console.log(formatListResult(result.data?.listSymbols));
3222
3496
  }
3223
3497
  }
3224
3498
  var LIST_DESCRIPTION = `Browse symbols in a package.
@@ -3257,9 +3531,9 @@ function formatPathResult(data) {
3257
3531
  for (const [j, hop] of callPath.hops.entries()) {
3258
3532
  const name = hop.qualifiedPath ?? hop.name ?? "unknown";
3259
3533
  const loc = hop.filePath ? hop.callLine ? ` ${hop.filePath}:${hop.callLine}` : ` ${hop.filePath}` : "";
3260
- const idPart = hop.symbolId ? ` (id:${hop.symbolId})` : "";
3534
+ const refPart = hop.symbolRef ? ` (ref:${hop.symbolRef})` : "";
3261
3535
  const arrow = j < callPath.hops.length - 1 ? " ->" : "";
3262
- lines.push(` ${j + 1}. ${name}${idPart}${loc}${arrow}`);
3536
+ lines.push(` ${j + 1}. ${name}${refPart}${loc}${arrow}`);
3263
3537
  }
3264
3538
  lines.push("");
3265
3539
  }
@@ -3268,35 +3542,35 @@ function formatPathResult(data) {
3268
3542
  }
3269
3543
  async function codePathAction(fromArg, toArg, options, deps) {
3270
3544
  const { pkgseerService } = deps;
3271
- const fromRef = buildSymbolReference(fromArg, options.fromId);
3272
- const toRef = buildSymbolReference(toArg, options.toId);
3545
+ const fromRef = buildSymbolReference(fromArg, options.fromRef);
3546
+ const toRef = buildSymbolReference(toArg, options.toRef);
3273
3547
  const result = await pkgseerService.callPath(fromRef, toRef, {
3274
3548
  maxDepth: parseIntOption(options.maxDepth, "--max-depth"),
3275
3549
  mode: parseNavigationMode(options.mode),
3276
3550
  waitTimeoutMs: parseWaitTimeout(options.wait)
3277
3551
  });
3278
3552
  handleErrors(result.errors, options.json ?? false);
3279
- if (!result.data.callPath) {
3553
+ if (!result.data?.callPath) {
3280
3554
  outputError("Could not find call path. Verify the symbol references.", options.json ?? false);
3281
3555
  return;
3282
3556
  }
3283
3557
  if (options.json) {
3284
- output(result.data.callPath, true);
3558
+ output(result.data?.callPath, true);
3285
3559
  } else {
3286
- console.log(formatPathResult(result.data.callPath));
3560
+ console.log(formatPathResult(result.data?.callPath));
3287
3561
  }
3288
3562
  }
3289
3563
  var PATH_DESCRIPTION = `Find call path between two symbols.
3290
3564
 
3291
3565
  Discovers the shortest call path from one symbol to another.
3292
- 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.
3293
3567
 
3294
3568
  Examples:
3295
3569
  pkgseer code path npm:express#app npm:express#Router
3296
- 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
3297
3571
  pkgseer code path npm:lodash#merge npm:lodash#cloneDeep --max-depth 5`;
3298
3572
  function registerCodePathCommand(program) {
3299
- 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) => {
3300
3574
  await withCliErrorHandling(options.json ?? false, async () => {
3301
3575
  const deps = await createContainer();
3302
3576
  await codePathAction(fromArg, toArg, options, deps);
@@ -3356,11 +3630,11 @@ async function codeSearchAction(packageArg, query, options, deps) {
3356
3630
  waitTimeoutMs: parseWaitTimeout(options.wait)
3357
3631
  });
3358
3632
  handleErrors(result.errors, options.json ?? false);
3359
- if (!result.data.searchSymbols) {
3633
+ if (!result.data?.searchSymbols) {
3360
3634
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3361
3635
  return;
3362
3636
  }
3363
- const data = result.data.searchSymbols;
3637
+ const data = result.data?.searchSymbols;
3364
3638
  if (options.json) {
3365
3639
  output(data, true);
3366
3640
  } else {
@@ -3598,7 +3872,7 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3598
3872
  }).join("; ");
3599
3873
  return { ref: ref.originalRef, result: null, error: errorMsg };
3600
3874
  }
3601
- if (!result2.data.getDocPage) {
3875
+ if (!result2.data?.getDocPage) {
3602
3876
  return {
3603
3877
  ref: ref.originalRef,
3604
3878
  result: null,
@@ -3608,8 +3882,8 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3608
3882
  return {
3609
3883
  ref: ref.originalRef,
3610
3884
  result: {
3611
- schemaVersion: result2.data.getDocPage?.schemaVersion ?? null,
3612
- page: result2.data.getDocPage?.page ?? null
3885
+ schemaVersion: result2.data?.getDocPage?.schemaVersion ?? null,
3886
+ page: result2.data?.getDocPage?.page ?? null
3613
3887
  }
3614
3888
  };
3615
3889
  }
@@ -3642,7 +3916,7 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3642
3916
  }).join("; ");
3643
3917
  return { ref: ref.originalRef, result: null, error: errorMsg };
3644
3918
  }
3645
- if (!result.data.fetchPackageDoc) {
3919
+ if (!result.data?.fetchPackageDoc) {
3646
3920
  return {
3647
3921
  ref: ref.originalRef,
3648
3922
  result: null,
@@ -3651,8 +3925,8 @@ async function fetchPage(ref, defaultRegistry, defaultVersion, pkgseerService) {
3651
3925
  }
3652
3926
  return {
3653
3927
  ref: ref.originalRef,
3654
- result: result.data.fetchPackageDoc ? {
3655
- page: result.data.fetchPackageDoc.page ?? null
3928
+ result: result.data?.fetchPackageDoc ? {
3929
+ page: result.data?.fetchPackageDoc.page ?? null
3656
3930
  } : null
3657
3931
  };
3658
3932
  } catch (error) {
@@ -3797,12 +4071,12 @@ async function docsListAction(packageArg, options, deps) {
3797
4071
  const version2 = parsed.version ?? options.pkgVersion;
3798
4072
  const result = await pkgseerService.cliDocsList(registry, parsed.name, version2);
3799
4073
  handleErrors(result.errors, options.json ?? false);
3800
- if (!result.data.listPackageDocs) {
4074
+ if (!result.data?.listPackageDocs) {
3801
4075
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
3802
4076
  return;
3803
4077
  }
3804
4078
  if (options.json) {
3805
- const pages = result.data.listPackageDocs.pages?.filter((p) => p) ?? [];
4079
+ const pages = result.data?.listPackageDocs.pages?.filter((p) => p) ?? [];
3806
4080
  const slim = pages.map((p) => {
3807
4081
  if (!p || !p.id)
3808
4082
  return null;
@@ -3813,7 +4087,7 @@ async function docsListAction(packageArg, options, deps) {
3813
4087
  }).filter((p) => p !== null);
3814
4088
  output(slim, true);
3815
4089
  } else {
3816
- console.log(formatDocsList(result.data.listPackageDocs));
4090
+ console.log(formatDocsList(result.data?.listPackageDocs));
3817
4091
  }
3818
4092
  }
3819
4093
  var LIST_DESCRIPTION2 = `List available documentation pages for a package.
@@ -4292,7 +4566,7 @@ async function pollSearchProgress(searchRef, pkgseerService, useColors) {
4292
4566
  const result = await pollUntilDone({
4293
4567
  fetch: async () => {
4294
4568
  const res = await pkgseerService.getSearchProgress(searchRef);
4295
- return res.data.searchProgress ?? null;
4569
+ return res.data?.searchProgress ?? null;
4296
4570
  },
4297
4571
  isDone: (progress) => {
4298
4572
  if (!progress)
@@ -4325,7 +4599,7 @@ async function handleResume(searchRef, pkgseerService, options, useColors) {
4325
4599
  handleErrors(progressResult.errors, options.json ?? false);
4326
4600
  return true;
4327
4601
  }
4328
- const progress = progressResult.data.searchProgress;
4602
+ const progress = progressResult.data?.searchProgress;
4329
4603
  if (!progress) {
4330
4604
  outputError("Search session not found. It may have expired (sessions last 1 hour).", options.json ?? false);
4331
4605
  return true;
@@ -4336,7 +4610,7 @@ async function handleResume(searchRef, pkgseerService, options, useColors) {
4336
4610
  handleErrors(resultsResponse.errors, options.json ?? false);
4337
4611
  return true;
4338
4612
  }
4339
- const searchResults = resultsResponse.data.searchResults;
4613
+ const searchResults = resultsResponse.data?.searchResults;
4340
4614
  if (!searchResults) {
4341
4615
  outputError("Search completed but no results returned.", options.json ?? false);
4342
4616
  return true;
@@ -4379,8 +4653,8 @@ Ref: ${searchRef}`, options.json ?? false);
4379
4653
  }
4380
4654
  if (pollResult.status === "COMPLETED") {
4381
4655
  const resultsResponse = await pkgseerService.getSearchResults(searchRef);
4382
- if (resultsResponse.data.searchResults) {
4383
- outputResults(resultsResponse.data.searchResults, options, useColors);
4656
+ if (resultsResponse.data?.searchResults) {
4657
+ outputResults(resultsResponse.data?.searchResults, options, useColors);
4384
4658
  }
4385
4659
  } else {
4386
4660
  console.log(`Search ended with status: ${pollResult.status.toLowerCase()}`);
@@ -4421,7 +4695,7 @@ async function searchAction(queryArg, options, deps, defaultMode = "ALL") {
4421
4695
  waitTimeoutMs
4422
4696
  });
4423
4697
  handleErrors(result.errors, options.json ?? false);
4424
- const asyncResult = result.data.combinedSearch;
4698
+ const asyncResult = result.data?.combinedSearch;
4425
4699
  if (!asyncResult) {
4426
4700
  outputError("No results returned. Check package names and registries.", options.json ?? false);
4427
4701
  return;
@@ -4442,9 +4716,9 @@ async function searchAction(queryArg, options, deps, defaultMode = "ALL") {
4442
4716
  const pollResult = await pollSearchProgress(searchRef, pkgseerService, useColors);
4443
4717
  if (pollResult.success && pollResult.status === "COMPLETED") {
4444
4718
  const resultsResponse = await pkgseerService.getSearchResults(searchRef);
4445
- if (resultsResponse.data.searchResults) {
4719
+ if (resultsResponse.data?.searchResults) {
4446
4720
  console.log("");
4447
- outputResults(resultsResponse.data.searchResults, options, useColors);
4721
+ outputResults(resultsResponse.data?.searchResults, options, useColors);
4448
4722
  return;
4449
4723
  }
4450
4724
  }
@@ -4598,7 +4872,7 @@ async function indexAction(packages, options, deps) {
4598
4872
  }
4599
4873
  const result = await pkgseerService.triggerIndexing(input2);
4600
4874
  handleErrors(result.errors, options.json ?? false);
4601
- const data = result.data.triggerIndexing;
4875
+ const data = result.data?.triggerIndexing;
4602
4876
  if (options.json) {
4603
4877
  output(data, true);
4604
4878
  } else {
@@ -6426,19 +6700,6 @@ function errorResult(message) {
6426
6700
  }
6427
6701
 
6428
6702
  // src/tools/shared.ts
6429
- function toGraphQLRegistry2(registry) {
6430
- const map = {
6431
- npm: "NPM",
6432
- pypi: "PYPI",
6433
- hex: "HEX",
6434
- crates: "CRATES",
6435
- nuget: "NUGET",
6436
- maven: "MAVEN",
6437
- zig: "ZIG",
6438
- vcpkg: "VCPKG"
6439
- };
6440
- return map[registry.toLowerCase()] || "NPM";
6441
- }
6442
6703
  function toNavigationMode(mode) {
6443
6704
  if (!mode)
6444
6705
  return;
@@ -6487,7 +6748,7 @@ var schemas = {
6487
6748
  navigationMode: z2.enum(["summary", "detailed"]).optional().describe("Response detail level. summary (default) returns core fields; detailed adds all optional fields."),
6488
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."),
6489
6750
  symbolReference: z2.object({
6490
- 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."),
6491
6752
  registry: z2.enum(["npm", "pypi", "hex", "crates", "nuget", "maven", "zig", "vcpkg"]).optional().describe("Package registry (required for name-based lookup)"),
6492
6753
  package_name: z2.string().max(255).optional().describe("Package name (required for name-based lookup)"),
6493
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.")
@@ -6495,22 +6756,23 @@ var schemas = {
6495
6756
  };
6496
6757
  function toSymbolReferenceInput(ref) {
6497
6758
  return {
6498
- symbolId: ref.symbol_id,
6499
- registry: ref.registry ? toGraphQLRegistry2(ref.registry) : undefined,
6759
+ symbolRef: ref.symbol_ref,
6760
+ registry: ref.registry ? toGraphQLRegistry(ref.registry) : undefined,
6500
6761
  packageName: ref.package_name,
6501
6762
  symbolName: ref.symbol_name
6502
6763
  };
6503
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
+ };
6504
6769
  function buildHintedMessage(operation, message) {
6505
- const lower = message.toLowerCase();
6506
- const isBeingIndexed = lower.includes("being indexed") || lower.includes("retry with waittimeoutms");
6507
- if (isBeingIndexed) {
6508
- return `Failed to ${operation}: ${message}. ` + "Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).";
6509
- }
6510
- const isTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
6511
- if (isTimeout) {
6512
- return `Failed to ${operation}: ${message}. ` + "Hint: try lowering the limit or narrowing the scope, then retry.";
6770
+ const kind = classifyError(message);
6771
+ const hint = MCP_HINTS[kind];
6772
+ if (hint) {
6773
+ return `Failed to ${operation}: ${message}. ${hint}`;
6513
6774
  }
6775
+ const lower = message.toLowerCase();
6514
6776
  if (lower.includes("graphql error (code: 500)")) {
6515
6777
  try {
6516
6778
  const jsonMatch = message.match(/\{.*\}/s);
@@ -6529,24 +6791,17 @@ function buildHintedMessage(operation, message) {
6529
6791
  }
6530
6792
  return `Failed to ${operation}: ${message}`;
6531
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
+ };
6532
6799
  function handleGraphQLErrors(errors) {
6533
6800
  if (errors && errors.length > 0) {
6534
- const messages = errors.map((e) => e.message).filter(Boolean);
6535
- const combined = messages.join(", ");
6536
- const lower = combined.toLowerCase();
6537
- const hasNotFound = lower.includes("not found") || lower.includes("does not exist");
6538
- const hasBeingIndexed = lower.includes("being indexed") || lower.includes("retry with waittimeoutms");
6539
- const hasTimeout = lower.includes("-32001") || lower.includes("timeout") || lower.includes("timed out");
6540
- if (hasNotFound) {
6541
- return errorResult(`Error: ${combined}. Hint: verify the name/registry and that the resource exists.`);
6542
- }
6543
- if (hasBeingIndexed) {
6544
- return errorResult(`Error: ${combined}. Hint: package is being indexed. Try again with a longer wait_timeout_ms (e.g., 30000).`);
6545
- }
6546
- if (hasTimeout) {
6547
- return errorResult(`Error: ${combined}. Hint: try lowering the limit or narrowing the scope, then retry.`);
6548
- }
6549
- 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}`);
6550
6805
  }
6551
6806
  return null;
6552
6807
  }
@@ -6564,8 +6819,8 @@ function notFoundError(packageName, registry) {
6564
6819
 
6565
6820
  // src/tools/call-path.ts
6566
6821
  var argsSchema = {
6567
- from: schemas.symbolReference.describe("Source symbol. Provide either symbol_id or registry + package_name + symbol_name."),
6568
- 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."),
6569
6824
  max_depth: z3.number().int().min(1).max(10).optional().describe("Maximum path length to search (max hops between from and to)"),
6570
6825
  mode: schemas.navigationMode,
6571
6826
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -6579,11 +6834,11 @@ function createCallPathTool(pkgseerService) {
6579
6834
  return withErrorHandling("find call path", async () => {
6580
6835
  const fromInput = toSymbolReferenceInput(args.from);
6581
6836
  const toInput = toSymbolReferenceInput(args.to);
6582
- if (!fromInput.symbolId && (!fromInput.symbolName || !fromInput.registry || !fromInput.packageName)) {
6583
- 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.");
6584
6839
  }
6585
- if (!toInput.symbolId && (!toInput.symbolName || !toInput.registry || !toInput.packageName)) {
6586
- 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.");
6587
6842
  }
6588
6843
  const result = await pkgseerService.callPath(fromInput, toInput, {
6589
6844
  maxDepth: args.max_depth,
@@ -6593,10 +6848,10 @@ function createCallPathTool(pkgseerService) {
6593
6848
  const graphqlError = handleGraphQLErrors(result.errors);
6594
6849
  if (graphqlError)
6595
6850
  return graphqlError;
6596
- if (!result.data.callPath) {
6851
+ if (!result.data?.callPath) {
6597
6852
  return errorResult("Could not find call path. Verify the symbols exist and the package is indexed.");
6598
6853
  }
6599
- return textResult(JSON.stringify(result.data.callPath, null, 2));
6854
+ return textResult(JSON.stringify(result.data?.callPath, null, 2));
6600
6855
  });
6601
6856
  }
6602
6857
  };
@@ -6619,7 +6874,7 @@ function createComparePackagesTool(pkgseerService) {
6619
6874
  handler: async ({ packages }, _extra) => {
6620
6875
  return withErrorHandling("compare packages", async () => {
6621
6876
  const input2 = packages.map((pkg) => ({
6622
- registry: toGraphQLRegistry2(pkg.registry),
6877
+ registry: toGraphQLRegistry(pkg.registry),
6623
6878
  name: pkg.name,
6624
6879
  version: pkg.version
6625
6880
  }));
@@ -6627,10 +6882,10 @@ function createComparePackagesTool(pkgseerService) {
6627
6882
  const graphqlError = handleGraphQLErrors(result.errors);
6628
6883
  if (graphqlError)
6629
6884
  return graphqlError;
6630
- if (!result.data.comparePackages) {
6885
+ if (!result.data?.comparePackages) {
6631
6886
  return errorResult("Comparison failed: no results returned");
6632
6887
  }
6633
- return textResult(JSON.stringify(result.data.comparePackages, null, 2));
6888
+ return textResult(JSON.stringify(result.data?.comparePackages, null, 2));
6634
6889
  });
6635
6890
  }
6636
6891
  };
@@ -6658,10 +6913,10 @@ function createFetchCodeContextTool(pkgseerService) {
6658
6913
  const graphqlError = handleGraphQLErrors(result.errors);
6659
6914
  if (graphqlError)
6660
6915
  return graphqlError;
6661
- if (!result.data.fetchCodeContext) {
6916
+ if (!result.data?.fetchCodeContext) {
6662
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.");
6663
6918
  }
6664
- return textResult(JSON.stringify(result.data.fetchCodeContext, null, 2));
6919
+ return textResult(JSON.stringify(result.data?.fetchCodeContext, null, 2));
6665
6920
  });
6666
6921
  }
6667
6922
  };
@@ -6682,10 +6937,10 @@ function createFetchPackageDocTool(pkgseerService) {
6682
6937
  const graphqlError = handleGraphQLErrors(result.errors);
6683
6938
  if (graphqlError)
6684
6939
  return graphqlError;
6685
- if (!result.data.getDocPage) {
6940
+ if (!result.data?.getDocPage) {
6686
6941
  return errorResult(`Documentation page not found: ${page_id}`);
6687
6942
  }
6688
- return textResult(JSON.stringify(result.data.getDocPage, null, 2));
6943
+ return textResult(JSON.stringify(result.data?.getDocPage, null, 2));
6689
6944
  });
6690
6945
  }
6691
6946
  };
@@ -6716,11 +6971,11 @@ var argsSchema5 = {
6716
6971
  function createFindSymbolTool(pkgseerService) {
6717
6972
  return {
6718
6973
  name: "find_symbol",
6719
- 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.",
6720
6975
  schema: argsSchema5,
6721
6976
  handler: async (args, _extra) => {
6722
6977
  return withErrorHandling("find symbol", async () => {
6723
- const result = await pkgseerService.findSymbol(toGraphQLRegistry2(args.registry), args.package_name, {
6978
+ const result = await pkgseerService.findSymbol(toGraphQLRegistry(args.registry), args.package_name, {
6724
6979
  name: args.name,
6725
6980
  namespace: args.namespace,
6726
6981
  kind: toSymbolKind(args.kind),
@@ -6734,10 +6989,10 @@ function createFindSymbolTool(pkgseerService) {
6734
6989
  const graphqlError = handleGraphQLErrors(result.errors);
6735
6990
  if (graphqlError)
6736
6991
  return graphqlError;
6737
- if (!result.data.findSymbol) {
6992
+ if (!result.data?.findSymbol) {
6738
6993
  return notFoundError(args.package_name, args.registry);
6739
6994
  }
6740
- const data = result.data.findSymbol;
6995
+ const data = result.data?.findSymbol;
6741
6996
  if (data.symbols.length === 0 && data.diagnostics?.hint) {
6742
6997
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
6743
6998
  }
@@ -6765,7 +7020,7 @@ function createGrepRepoFileTool(pkgseerService) {
6765
7020
  schema: argsSchema6,
6766
7021
  handler: async (args, _extra) => {
6767
7022
  return withErrorHandling("grep repo file", async () => {
6768
- 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, {
6769
7024
  contextLines: args.context_lines,
6770
7025
  maxMatches: args.max_matches,
6771
7026
  version: args.version,
@@ -6774,10 +7029,10 @@ function createGrepRepoFileTool(pkgseerService) {
6774
7029
  const graphqlError = handleGraphQLErrors(result.errors);
6775
7030
  if (graphqlError)
6776
7031
  return graphqlError;
6777
- if (!result.data.grepRepoFile) {
7032
+ if (!result.data?.grepRepoFile) {
6778
7033
  return notFoundError(args.package_name, args.registry);
6779
7034
  }
6780
- const data = result.data.grepRepoFile;
7035
+ const data = result.data?.grepRepoFile;
6781
7036
  if (data.matches.length === 0 && data.diagnostics?.hint) {
6782
7037
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
6783
7038
  }
@@ -6799,14 +7054,14 @@ function createListPackageDocsTool(pkgseerService) {
6799
7054
  schema: argsSchema7,
6800
7055
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
6801
7056
  return withErrorHandling("list package documentation", async () => {
6802
- const result = await pkgseerService.listPackageDocs(toGraphQLRegistry2(registry), package_name, version2);
7057
+ const result = await pkgseerService.listPackageDocs(toGraphQLRegistry(registry), package_name, version2);
6803
7058
  const graphqlError = handleGraphQLErrors(result.errors);
6804
7059
  if (graphqlError)
6805
7060
  return graphqlError;
6806
- if (!result.data.listPackageDocs) {
7061
+ if (!result.data?.listPackageDocs) {
6807
7062
  return notFoundError(package_name, registry);
6808
7063
  }
6809
- return textResult(JSON.stringify(result.data.listPackageDocs, null, 2));
7064
+ return textResult(JSON.stringify(result.data?.listPackageDocs, null, 2));
6810
7065
  });
6811
7066
  }
6812
7067
  };
@@ -6828,7 +7083,7 @@ function createListRepoFilesTool(pkgseerService) {
6828
7083
  schema: argsSchema8,
6829
7084
  handler: async (args, _extra) => {
6830
7085
  return withErrorHandling("list repo files", async () => {
6831
- const result = await pkgseerService.listRepoFiles(toGraphQLRegistry2(args.registry), args.package_name, {
7086
+ const result = await pkgseerService.listRepoFiles(toGraphQLRegistry(args.registry), args.package_name, {
6832
7087
  version: args.version,
6833
7088
  pathPrefix: args.path_prefix,
6834
7089
  limit: args.limit,
@@ -6837,10 +7092,10 @@ function createListRepoFilesTool(pkgseerService) {
6837
7092
  const graphqlError = handleGraphQLErrors(result.errors);
6838
7093
  if (graphqlError)
6839
7094
  return graphqlError;
6840
- if (!result.data.listRepoFiles) {
7095
+ if (!result.data?.listRepoFiles) {
6841
7096
  return notFoundError(args.package_name, args.registry);
6842
7097
  }
6843
- const data = result.data.listRepoFiles;
7098
+ const data = result.data?.listRepoFiles;
6844
7099
  if (data.files.length === 0 && data.diagnostics?.hint) {
6845
7100
  return textResult(JSON.stringify({ ...data, _hint: data.diagnostics.hint }, null, 2));
6846
7101
  }
@@ -6867,7 +7122,7 @@ var argsSchema9 = {
6867
7122
  function createListSymbolsTool(pkgseerService) {
6868
7123
  return {
6869
7124
  name: "list_symbols",
6870
- 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.",
6871
7126
  schema: argsSchema9,
6872
7127
  handler: async (args, _extra) => {
6873
7128
  return withErrorHandling("list symbols", async () => {
@@ -6883,7 +7138,7 @@ function createListSymbolsTool(pkgseerService) {
6883
7138
  isError: true
6884
7139
  };
6885
7140
  }
6886
- 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, {
6887
7142
  filePath: args.file_path,
6888
7143
  namespace: args.namespace,
6889
7144
  publicOnly: args.public_only,
@@ -6896,10 +7151,10 @@ function createListSymbolsTool(pkgseerService) {
6896
7151
  const graphqlError = handleGraphQLErrors(result.errors);
6897
7152
  if (graphqlError)
6898
7153
  return graphqlError;
6899
- if (!result.data.listSymbols) {
7154
+ if (!result.data?.listSymbols) {
6900
7155
  return notFoundError(args.package_name, args.registry);
6901
7156
  }
6902
- return textResult(JSON.stringify(result.data.listSymbols, null, 2));
7157
+ return textResult(JSON.stringify(result.data?.listSymbols, null, 2));
6903
7158
  });
6904
7159
  }
6905
7160
  };
@@ -6992,20 +7247,20 @@ function createPackageDependenciesTool(pkgseerService) {
6992
7247
  schema: argsSchema10,
6993
7248
  handler: async ({ registry, package_name, version: version2, include_transitive, max_depth }, _extra) => {
6994
7249
  return withErrorHandling("fetch package dependencies", async () => {
6995
- 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);
6996
7251
  const graphqlError = handleGraphQLErrors(result.errors);
6997
7252
  if (graphqlError)
6998
7253
  return graphqlError;
6999
- if (!result.data.packageDependencies) {
7254
+ if (!result.data?.packageDependencies) {
7000
7255
  return notFoundError(package_name, registry);
7001
7256
  }
7002
- const deps = result.data.packageDependencies.dependencies;
7257
+ const deps = result.data?.packageDependencies.dependencies;
7003
7258
  const decodedDag = decodeDag(deps?.transitive?.dag);
7004
7259
  const transitiveDag = deps?.transitive?.dag;
7005
7260
  const edgesWithDepth = buildEdgeDepths(decodedDag, typeof transitiveDag?.root === "string" ? transitiveDag.root : undefined);
7006
7261
  const output2 = {
7007
7262
  summary: deps?.summary,
7008
- package: result.data.packageDependencies.package,
7263
+ package: result.data?.packageDependencies.package,
7009
7264
  direct: deps?.direct,
7010
7265
  transitive: deps?.transitive ? {
7011
7266
  totalEdges: deps.transitive.totalEdges,
@@ -7019,7 +7274,7 @@ function createPackageDependenciesTool(pkgseerService) {
7019
7274
  raw: deps.transitive.dag
7020
7275
  }
7021
7276
  } : undefined,
7022
- raw: result.data.packageDependencies
7277
+ raw: result.data?.packageDependencies
7023
7278
  };
7024
7279
  return textResult(JSON.stringify(output2, null, 2));
7025
7280
  });
@@ -7045,7 +7300,7 @@ function createPackageImportsTool(pkgseerService) {
7045
7300
  schema: argsSchema11,
7046
7301
  handler: async (args, _extra) => {
7047
7302
  return withErrorHandling("fetch package imports", async () => {
7048
- const result = await pkgseerService.packageImports(toGraphQLRegistry2(args.registry), args.package_name, {
7303
+ const result = await pkgseerService.packageImports(toGraphQLRegistry(args.registry), args.package_name, {
7049
7304
  filePath: args.file_path,
7050
7305
  resolvedOnly: args.resolved_only,
7051
7306
  limit: args.limit,
@@ -7056,10 +7311,10 @@ function createPackageImportsTool(pkgseerService) {
7056
7311
  const graphqlError = handleGraphQLErrors(result.errors);
7057
7312
  if (graphqlError)
7058
7313
  return graphqlError;
7059
- if (!result.data.packageImports) {
7314
+ if (!result.data?.packageImports) {
7060
7315
  return notFoundError(args.package_name, args.registry);
7061
7316
  }
7062
- return textResult(JSON.stringify(result.data.packageImports, null, 2));
7317
+ return textResult(JSON.stringify(result.data?.packageImports, null, 2));
7063
7318
  });
7064
7319
  }
7065
7320
  };
@@ -7077,14 +7332,14 @@ function createPackageQualityTool(pkgseerService) {
7077
7332
  schema: argsSchema12,
7078
7333
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
7079
7334
  return withErrorHandling("fetch package quality", async () => {
7080
- const result = await pkgseerService.getPackageQuality(toGraphQLRegistry2(registry), package_name, version2);
7335
+ const result = await pkgseerService.getPackageQuality(toGraphQLRegistry(registry), package_name, version2);
7081
7336
  const graphqlError = handleGraphQLErrors(result.errors);
7082
7337
  if (graphqlError)
7083
7338
  return graphqlError;
7084
- if (!result.data.packageQuality) {
7339
+ if (!result.data?.packageQuality) {
7085
7340
  return notFoundError(package_name, registry);
7086
7341
  }
7087
- return textResult(JSON.stringify(result.data.packageQuality, null, 2));
7342
+ return textResult(JSON.stringify(result.data?.packageQuality, null, 2));
7088
7343
  });
7089
7344
  }
7090
7345
  };
@@ -7101,14 +7356,14 @@ function createPackageSummaryTool(pkgseerService) {
7101
7356
  schema: argsSchema13,
7102
7357
  handler: async ({ registry, package_name }, _extra) => {
7103
7358
  return withErrorHandling("fetch package summary", async () => {
7104
- const result = await pkgseerService.getPackageSummary(toGraphQLRegistry2(registry), package_name);
7359
+ const result = await pkgseerService.getPackageSummary(toGraphQLRegistry(registry), package_name);
7105
7360
  const graphqlError = handleGraphQLErrors(result.errors);
7106
7361
  if (graphqlError)
7107
7362
  return graphqlError;
7108
- if (!result.data.packageSummary) {
7363
+ if (!result.data?.packageSummary) {
7109
7364
  return notFoundError(package_name, registry);
7110
7365
  }
7111
- return textResult(JSON.stringify(result.data.packageSummary, null, 2));
7366
+ return textResult(JSON.stringify(result.data?.packageSummary, null, 2));
7112
7367
  });
7113
7368
  }
7114
7369
  };
@@ -7126,14 +7381,14 @@ function createPackageVulnerabilitiesTool(pkgseerService) {
7126
7381
  schema: argsSchema14,
7127
7382
  handler: async ({ registry, package_name, version: version2 }, _extra) => {
7128
7383
  return withErrorHandling("fetch package vulnerabilities", async () => {
7129
- const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry2(registry), package_name, version2);
7384
+ const result = await pkgseerService.getPackageVulnerabilities(toGraphQLRegistry(registry), package_name, version2);
7130
7385
  const graphqlError = handleGraphQLErrors(result.errors);
7131
7386
  if (graphqlError)
7132
7387
  return graphqlError;
7133
- if (!result.data.packageVulnerabilities) {
7388
+ if (!result.data?.packageVulnerabilities) {
7134
7389
  return notFoundError(package_name, registry);
7135
7390
  }
7136
- return textResult(JSON.stringify(result.data.packageVulnerabilities, null, 2));
7391
+ return textResult(JSON.stringify(result.data?.packageVulnerabilities, null, 2));
7137
7392
  });
7138
7393
  }
7139
7394
  };
@@ -7198,7 +7453,7 @@ function createSearchTool(pkgseerService) {
7198
7453
  return errorResult("Search query is required.");
7199
7454
  }
7200
7455
  const graphqlPackages = packages.map((pkg) => ({
7201
- registry: toGraphQLRegistry2(pkg.registry),
7456
+ registry: toGraphQLRegistry(pkg.registry),
7202
7457
  name: pkg.name,
7203
7458
  version: pkg.version
7204
7459
  }));
@@ -7210,7 +7465,7 @@ function createSearchTool(pkgseerService) {
7210
7465
  const graphqlError = handleGraphQLErrors(result.errors);
7211
7466
  if (graphqlError)
7212
7467
  return graphqlError;
7213
- const asyncResult = result.data.combinedSearch;
7468
+ const asyncResult = result.data?.combinedSearch;
7214
7469
  if (!asyncResult) {
7215
7470
  return errorResult("No search results returned. Check package names and registries.");
7216
7471
  }
@@ -7290,13 +7545,13 @@ function createSearchProjectDocsTool(deps) {
7290
7545
  const graphqlError = handleGraphQLErrors(result.errors);
7291
7546
  if (graphqlError)
7292
7547
  return graphqlError;
7293
- if (!result.data.searchProjectDocs) {
7548
+ if (!result.data?.searchProjectDocs) {
7294
7549
  return errorResult(`Project not found: ${resolvedProject}`);
7295
7550
  }
7296
- if ((result.data.searchProjectDocs.entries ?? []).length === 0 && normalizedTerms.length > 0) {
7551
+ if ((result.data?.searchProjectDocs.entries ?? []).length === 0 && normalizedTerms.length > 0) {
7297
7552
  return errorResult(`No documentation matched: ${normalizedTerms.join(", ")}. ` + "Try fewer or broader terms, or reduce match constraints.");
7298
7553
  }
7299
- return textResult(JSON.stringify(result.data.searchProjectDocs, null, 2));
7554
+ return textResult(JSON.stringify(result.data?.searchProjectDocs, null, 2));
7300
7555
  });
7301
7556
  }
7302
7557
  };
@@ -7317,7 +7572,7 @@ function createSearchStatusTool(pkgseerService) {
7317
7572
  const graphqlError = handleGraphQLErrors(progressResult.errors);
7318
7573
  if (graphqlError)
7319
7574
  return graphqlError;
7320
- const progress = progressResult.data.searchProgress;
7575
+ const progress = progressResult.data?.searchProgress;
7321
7576
  if (!progress) {
7322
7577
  return errorResult("Search session not found. It may have expired (sessions last 1 hour).");
7323
7578
  }
@@ -7326,7 +7581,7 @@ function createSearchStatusTool(pkgseerService) {
7326
7581
  const resultsError = handleGraphQLErrors(resultsResponse.errors);
7327
7582
  if (resultsError)
7328
7583
  return resultsError;
7329
- const searchResults = resultsResponse.data.searchResults;
7584
+ const searchResults = resultsResponse.data?.searchResults;
7330
7585
  if (!searchResults) {
7331
7586
  return errorResult("Search completed but results are no longer available. " + "The session may have expired (sessions last 1 hour).");
7332
7587
  }
@@ -7380,7 +7635,7 @@ function createSearchSymbolsTool(pkgseerService) {
7380
7635
  schema: argsSchema18,
7381
7636
  handler: async (args, _extra) => {
7382
7637
  return withErrorHandling("search symbols", async () => {
7383
- const result = await pkgseerService.searchSymbols(toGraphQLRegistry2(args.registry), args.package_name, {
7638
+ const result = await pkgseerService.searchSymbols(toGraphQLRegistry(args.registry), args.package_name, {
7384
7639
  query: args.query,
7385
7640
  keywords: args.keywords,
7386
7641
  matchMode: toMatchMode(args.match_mode),
@@ -7394,10 +7649,10 @@ function createSearchSymbolsTool(pkgseerService) {
7394
7649
  const graphqlError = handleGraphQLErrors(result.errors);
7395
7650
  if (graphqlError)
7396
7651
  return graphqlError;
7397
- if (!result.data.searchSymbols) {
7652
+ if (!result.data?.searchSymbols) {
7398
7653
  return notFoundError(args.package_name, args.registry);
7399
7654
  }
7400
- const data = result.data.searchSymbols;
7655
+ const data = result.data?.searchSymbols;
7401
7656
  const extra = {};
7402
7657
  if (data.results.length === 0 && data.diagnostics?.hint) {
7403
7658
  extra._hint = data.diagnostics.hint;
@@ -7416,7 +7671,7 @@ function createSearchSymbolsTool(pkgseerService) {
7416
7671
  // src/tools/symbol-callees.ts
7417
7672
  import { z as z17 } from "zod";
7418
7673
  var argsSchema19 = {
7419
- 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."),
7420
7675
  max_depth: z17.number().int().min(1).max(5).optional().describe("BFS traversal depth (1 = direct callees only, 2+ = transitive, max 5)"),
7421
7676
  limit: z17.number().int().min(1).max(100).optional().describe("Maximum dependency entries to return"),
7422
7677
  include_external: z17.boolean().optional().describe("Include calls to symbols in other packages"),
@@ -7427,13 +7682,13 @@ var argsSchema19 = {
7427
7682
  function createSymbolCalleesTool(pkgseerService) {
7428
7683
  return {
7429
7684
  name: "symbol_callees",
7430
- 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.",
7431
7686
  schema: argsSchema19,
7432
7687
  handler: async (args, _extra) => {
7433
7688
  return withErrorHandling("find symbol callees", async () => {
7434
7689
  const symbolInput = toSymbolReferenceInput(args.symbol);
7435
- if (!symbolInput.symbolId && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7436
- 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.");
7437
7692
  }
7438
7693
  const result = await pkgseerService.symbolDependencies(symbolInput, {
7439
7694
  maxDepth: args.max_depth,
@@ -7446,10 +7701,10 @@ function createSymbolCalleesTool(pkgseerService) {
7446
7701
  const graphqlError = handleGraphQLErrors(result.errors);
7447
7702
  if (graphqlError)
7448
7703
  return graphqlError;
7449
- if (!result.data.symbolDependencies) {
7704
+ if (!result.data?.symbolDependencies) {
7450
7705
  return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7451
7706
  }
7452
- return textResult(JSON.stringify(result.data.symbolDependencies, null, 2));
7707
+ return textResult(JSON.stringify(result.data?.symbolDependencies, null, 2));
7453
7708
  });
7454
7709
  }
7455
7710
  };
@@ -7457,8 +7712,9 @@ function createSymbolCalleesTool(pkgseerService) {
7457
7712
  // src/tools/symbol-callers.ts
7458
7713
  import { z as z18 } from "zod";
7459
7714
  var argsSchema20 = {
7460
- 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."),
7461
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)"),
7462
7718
  limit: z18.number().int().min(1).max(100).optional().describe("Maximum entries to return"),
7463
7719
  mode: schemas.navigationMode,
7464
7720
  wait_timeout_ms: schemas.waitTimeoutMs
@@ -7466,16 +7722,17 @@ var argsSchema20 = {
7466
7722
  function createSymbolCallersTool(pkgseerService) {
7467
7723
  return {
7468
7724
  name: "symbol_callers",
7469
- 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.",
7470
7726
  schema: argsSchema20,
7471
7727
  handler: async (args, _extra) => {
7472
7728
  return withErrorHandling("find symbol callers", async () => {
7473
7729
  const symbolInput = toSymbolReferenceInput(args.symbol);
7474
- if (!symbolInput.symbolId && (!symbolInput.symbolName || !symbolInput.registry || !symbolInput.packageName)) {
7475
- 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.");
7476
7732
  }
7477
7733
  const result = await pkgseerService.symbolDependents(symbolInput, {
7478
7734
  samePackageOnly: args.same_package_only,
7735
+ maxDepth: args.max_depth,
7479
7736
  maxResults: args.limit,
7480
7737
  mode: toNavigationMode(args.mode),
7481
7738
  waitTimeoutMs: args.wait_timeout_ms
@@ -7483,10 +7740,10 @@ function createSymbolCallersTool(pkgseerService) {
7483
7740
  const graphqlError = handleGraphQLErrors(result.errors);
7484
7741
  if (graphqlError)
7485
7742
  return graphqlError;
7486
- if (!result.data.symbolDependents) {
7743
+ if (!result.data?.symbolDependents) {
7487
7744
  return errorResult("Symbol not found. Verify the symbol reference and that the package is indexed.");
7488
7745
  }
7489
- return textResult(JSON.stringify(result.data.symbolDependents, null, 2));
7746
+ return textResult(JSON.stringify(result.data?.symbolDependents, null, 2));
7490
7747
  });
7491
7748
  }
7492
7749
  };
@@ -7515,7 +7772,7 @@ function createTriggerIndexingTool(pkgseerService) {
7515
7772
  handler: async (args, _extra) => {
7516
7773
  return withErrorHandling("trigger indexing", async () => {
7517
7774
  const packages = args.packages?.map((p) => ({
7518
- registry: toGraphQLRegistry2(p.registry),
7775
+ registry: toGraphQLRegistry(p.registry),
7519
7776
  name: p.name,
7520
7777
  version: p.version
7521
7778
  }));
@@ -7531,7 +7788,7 @@ function createTriggerIndexingTool(pkgseerService) {
7531
7788
  const graphqlError = handleGraphQLErrors(result.errors);
7532
7789
  if (graphqlError)
7533
7790
  return graphqlError;
7534
- if (!result.data.triggerIndexing) {
7791
+ if (!result.data?.triggerIndexing) {
7535
7792
  return {
7536
7793
  content: [
7537
7794
  {
@@ -7542,7 +7799,7 @@ function createTriggerIndexingTool(pkgseerService) {
7542
7799
  isError: true
7543
7800
  };
7544
7801
  }
7545
- return textResult(JSON.stringify(result.data.triggerIndexing, null, 2));
7802
+ return textResult(JSON.stringify(result.data?.triggerIndexing, null, 2));
7546
7803
  });
7547
7804
  }
7548
7805
  };
@@ -7574,7 +7831,7 @@ function createVersionDiffTool(pkgseerService) {
7574
7831
  schema: argsSchema22,
7575
7832
  handler: async (args, _extra) => {
7576
7833
  return withErrorHandling("version diff", async () => {
7577
- 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, {
7578
7835
  includePrivate: args.include_private,
7579
7836
  kind: toSymbolKind(args.kind),
7580
7837
  limit: args.limit,
@@ -7583,10 +7840,10 @@ function createVersionDiffTool(pkgseerService) {
7583
7840
  const graphqlError = handleGraphQLErrors(result.errors);
7584
7841
  if (graphqlError)
7585
7842
  return graphqlError;
7586
- if (!result.data.versionDiff) {
7843
+ if (!result.data?.versionDiff) {
7587
7844
  return notFoundError(args.package_name, args.registry);
7588
7845
  }
7589
- return textResult(JSON.stringify(result.data.versionDiff, null, 2));
7846
+ return textResult(JSON.stringify(result.data?.versionDiff, null, 2));
7590
7847
  });
7591
7848
  }
7592
7849
  };
@@ -7779,12 +8036,12 @@ async function pkgCompareAction(packages, options, deps) {
7779
8036
  });
7780
8037
  const result = await pkgseerService.cliComparePackages(input2);
7781
8038
  handleErrors(result.errors, options.json ?? false);
7782
- if (!result.data.comparePackages) {
8039
+ if (!result.data?.comparePackages) {
7783
8040
  outputError("Comparison failed", options.json ?? false);
7784
8041
  return;
7785
8042
  }
7786
8043
  if (options.json) {
7787
- const pkgs = result.data.comparePackages.packages?.filter((p) => p) ?? [];
8044
+ const pkgs = result.data?.comparePackages.packages?.filter((p) => p) ?? [];
7788
8045
  const slim = pkgs.map((p) => ({
7789
8046
  package: `${p?.packageName}@${p?.version}`,
7790
8047
  quality: p?.quality?.score,
@@ -7793,7 +8050,7 @@ async function pkgCompareAction(packages, options, deps) {
7793
8050
  }));
7794
8051
  output(slim, true);
7795
8052
  } else {
7796
- console.log(formatPackageComparison(result.data.comparePackages));
8053
+ console.log(formatPackageComparison(result.data?.comparePackages));
7797
8054
  }
7798
8055
  }
7799
8056
  var COMPARE_DESCRIPTION = `Compare multiple packages.
@@ -7862,13 +8119,13 @@ async function pkgDepsAction(packageArg, options, deps) {
7862
8119
  const transitiveRequested = options.transitive ?? false;
7863
8120
  const result = await pkgseerService.cliPackageDeps(registry, parsed.name, version2, options.transitive, options.maxDepth ? Number.parseInt(options.maxDepth, 10) : undefined);
7864
8121
  handleErrors(result.errors, options.json ?? false);
7865
- if (!result.data.packageDependencies) {
8122
+ if (!result.data?.packageDependencies) {
7866
8123
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
7867
8124
  return;
7868
8125
  }
7869
8126
  const format = options.json ? "json" : options.format ?? "human";
7870
8127
  if (format === "json") {
7871
- const data = result.data.packageDependencies;
8128
+ const data = result.data?.packageDependencies;
7872
8129
  output({
7873
8130
  package: `${data.package?.name}@${data.package?.version}`,
7874
8131
  directCount: data.dependencies?.summary?.directCount ?? 0,
@@ -7881,7 +8138,7 @@ async function pkgDepsAction(packageArg, options, deps) {
7881
8138
  }))
7882
8139
  }, true);
7883
8140
  } else if (format === "summary") {
7884
- const data = result.data.packageDependencies;
8141
+ const data = result.data?.packageDependencies;
7885
8142
  const deps2 = data.dependencies;
7886
8143
  const directCount = deps2?.summary?.directCount ?? 0;
7887
8144
  const uniquePackagesCount = deps2?.summary?.uniquePackagesCount ?? 0;
@@ -7894,7 +8151,7 @@ async function pkgDepsAction(packageArg, options, deps) {
7894
8151
  console.log(lines.join(`
7895
8152
  `));
7896
8153
  } else {
7897
- console.log(formatPackageDependencies(result.data.packageDependencies, transitiveRequested));
8154
+ console.log(formatPackageDependencies(result.data?.packageDependencies, transitiveRequested));
7898
8155
  }
7899
8156
  }
7900
8157
  var DEPS_DESCRIPTION = `Get package dependencies.
@@ -7978,12 +8235,12 @@ async function pkgInfoAction(packageArg, options, deps) {
7978
8235
  const registry = toGraphQLRegistry(parsed.registry !== "npm" ? parsed.registry : options.registry);
7979
8236
  const result = await pkgseerService.cliPackageInfo(registry, parsed.name);
7980
8237
  handleErrors(result.errors, options.json ?? false);
7981
- if (!result.data.packageSummary) {
8238
+ if (!result.data?.packageSummary) {
7982
8239
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
7983
8240
  return;
7984
8241
  }
7985
8242
  if (options.json) {
7986
- const data = result.data.packageSummary;
8243
+ const data = result.data?.packageSummary;
7987
8244
  const pkg = data.package;
7988
8245
  const slim = {
7989
8246
  name: pkg?.name,
@@ -7995,7 +8252,7 @@ async function pkgInfoAction(packageArg, options, deps) {
7995
8252
  };
7996
8253
  output(slim, true);
7997
8254
  } else {
7998
- console.log(formatPackageSummary(result.data.packageSummary));
8255
+ console.log(formatPackageSummary(result.data?.packageSummary));
7999
8256
  }
8000
8257
  }
8001
8258
  var INFO_DESCRIPTION = `Get package summary and metadata.
@@ -8046,15 +8303,15 @@ async function pkgQualityAction(packageArg, options, deps) {
8046
8303
  const version2 = parsed.version ?? options.pkgVersion;
8047
8304
  const result = await pkgseerService.cliPackageQuality(registry, parsed.name, version2);
8048
8305
  handleErrors(result.errors, options.json ?? false);
8049
- if (!result.data.packageQuality) {
8306
+ if (!result.data?.packageQuality) {
8050
8307
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
8051
8308
  return;
8052
8309
  }
8053
8310
  const format = options.json ? "json" : options.format ?? "human";
8054
8311
  if (format === "json") {
8055
- const quality = result.data.packageQuality.quality;
8312
+ const quality = result.data?.packageQuality.quality;
8056
8313
  const slim = {
8057
- package: `${result.data.packageQuality.package?.name}@${result.data.packageQuality.package?.version}`,
8314
+ package: `${result.data?.packageQuality.package?.name}@${result.data?.packageQuality.package?.version}`,
8058
8315
  score: quality?.overallScore,
8059
8316
  grade: quality?.grade,
8060
8317
  categories: quality?.categories?.filter((c) => c).map((c) => ({
@@ -8064,7 +8321,7 @@ async function pkgQualityAction(packageArg, options, deps) {
8064
8321
  };
8065
8322
  output(slim, true);
8066
8323
  } else {
8067
- console.log(formatPackageQuality(result.data.packageQuality));
8324
+ console.log(formatPackageQuality(result.data?.packageQuality));
8068
8325
  }
8069
8326
  }
8070
8327
  var QUALITY_DESCRIPTION = `Get package quality score and breakdown.
@@ -8149,12 +8406,12 @@ async function pkgVulnsAction(packageArg, options, deps) {
8149
8406
  const version2 = parsed.version ?? options.pkgVersion;
8150
8407
  const result = await pkgseerService.cliPackageVulns(registry, parsed.name, version2);
8151
8408
  handleErrors(result.errors, options.json ?? false);
8152
- if (!result.data.packageVulnerabilities) {
8409
+ if (!result.data?.packageVulnerabilities) {
8153
8410
  outputError(`Package not found: ${parsed.name} in ${parsed.registry}`, options.json ?? false);
8154
8411
  return;
8155
8412
  }
8156
8413
  if (options.json) {
8157
- const data = result.data.packageVulnerabilities;
8414
+ const data = result.data?.packageVulnerabilities;
8158
8415
  const vulns = data.security?.vulnerabilities ?? [];
8159
8416
  const slim = {
8160
8417
  package: `${data.package?.name}@${data.package?.version}`,
@@ -8168,7 +8425,7 @@ async function pkgVulnsAction(packageArg, options, deps) {
8168
8425
  };
8169
8426
  output(slim, true);
8170
8427
  } else {
8171
- console.log(formatPackageVulnerabilities(result.data.packageVulnerabilities));
8428
+ console.log(formatPackageVulnerabilities(result.data?.packageVulnerabilities));
8172
8429
  }
8173
8430
  }
8174
8431
  var VULNS_DESCRIPTION = `Check package for security vulnerabilities.