@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 +635 -268
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-w4ht5me5.js → chunk-z0xepgqq.js} +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
version
|
|
4
|
-
} from "./shared/chunk-
|
|
4
|
+
} from "./shared/chunk-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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
794
|
+
symbolRef
|
|
787
795
|
name
|
|
788
796
|
qualifiedPath
|
|
789
797
|
}
|
|
790
798
|
dependencies {
|
|
791
|
-
|
|
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
|
-
|
|
831
|
+
symbolRef
|
|
823
832
|
name
|
|
824
833
|
qualifiedPath
|
|
825
834
|
}
|
|
826
835
|
dependents {
|
|
827
|
-
|
|
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
|
-
|
|
892
|
+
symbolRef
|
|
884
893
|
name
|
|
885
894
|
qualifiedPath
|
|
886
895
|
}
|
|
887
896
|
toSymbol {
|
|
888
|
-
|
|
897
|
+
symbolRef
|
|
889
898
|
name
|
|
890
899
|
qualifiedPath
|
|
891
900
|
}
|
|
892
901
|
paths {
|
|
893
902
|
length
|
|
894
903
|
hops {
|
|
895
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
2440
|
-
|
|
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
|
|
2484
|
-
const
|
|
2485
|
-
if (
|
|
2486
|
-
const messages =
|
|
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
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
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,
|
|
2585
|
-
if (
|
|
2586
|
-
return {
|
|
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 --
|
|
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 = [`
|
|
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.
|
|
2663
|
-
parts.push(`
|
|
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} (
|
|
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.
|
|
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
|
|
2704
|
-
outputError("Symbol not found. Verify the symbol reference or use --
|
|
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
|
|
3015
|
+
output(result.data?.symbolDependencies, true);
|
|
2709
3016
|
} else {
|
|
2710
|
-
console.log(formatCalleesResult(result.data
|
|
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 --
|
|
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 --
|
|
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("--
|
|
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} (
|
|
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.
|
|
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
|
|
2754
|
-
outputError("Symbol not found. Verify the symbol reference or use --
|
|
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
|
|
3066
|
+
output(result.data?.symbolDependents, true);
|
|
2759
3067
|
} else {
|
|
2760
|
-
console.log(formatCallersResult(result.data
|
|
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 --
|
|
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 --
|
|
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("--
|
|
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
|
|
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
|
|
3138
|
+
output(result.data?.versionDiff, true);
|
|
2831
3139
|
} else {
|
|
2832
|
-
console.log(formatDiffResult(result.data
|
|
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
|
|
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(
|
|
3199
|
+
output(data, true);
|
|
2891
3200
|
} else {
|
|
2892
|
-
|
|
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
|
|
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(
|
|
3264
|
+
output(data, true);
|
|
2949
3265
|
} else {
|
|
2950
|
-
|
|
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
|
|
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(
|
|
3338
|
+
output(data, true);
|
|
3016
3339
|
} else {
|
|
3017
|
-
|
|
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
|
|
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
|
|
3424
|
+
output(result.data?.packageImports, true);
|
|
3096
3425
|
} else {
|
|
3097
|
-
console.log(formatImportsResult(result.data
|
|
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
|
|
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
|
|
3493
|
+
output(result.data?.listSymbols, true);
|
|
3168
3494
|
} else {
|
|
3169
|
-
console.log(formatListResult(result.data
|
|
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
|
|
3534
|
+
const refPart = hop.symbolRef ? ` (ref:${hop.symbolRef})` : "";
|
|
3209
3535
|
const arrow = j < callPath.hops.length - 1 ? " ->" : "";
|
|
3210
|
-
lines.push(` ${j + 1}. ${name}${
|
|
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.
|
|
3220
|
-
const toRef = buildSymbolReference(toArg, options.
|
|
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
|
|
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
|
|
3558
|
+
output(result.data?.callPath, true);
|
|
3233
3559
|
} else {
|
|
3234
|
-
console.log(formatPathResult(result.data
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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(
|
|
3639
|
+
output(data, true);
|
|
3313
3640
|
} else {
|
|
3314
|
-
|
|
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
|
|
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
|
|
3549
|
-
page: result2.data
|
|
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
|
|
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
|
|
3592
|
-
page: result.data
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
4320
|
-
outputResults(resultsResponse.data
|
|
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
|
|
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
|
|
4719
|
+
if (resultsResponse.data?.searchResults) {
|
|
4383
4720
|
console.log("");
|
|
4384
|
-
outputResults(resultsResponse.data
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
6436
|
-
registry: ref.registry ?
|
|
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
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
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
|
|
6452
|
-
const
|
|
6453
|
-
const
|
|
6454
|
-
|
|
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
|
|
6481
|
-
to: schemas.symbolReference.describe("Destination symbol. Provide either
|
|
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.
|
|
6496
|
-
return errorResult("Invalid 'from' symbol: provide either
|
|
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.
|
|
6499
|
-
return errorResult("Invalid 'to' symbol: provide either
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
6885
|
+
if (!result.data?.comparePackages) {
|
|
6544
6886
|
return errorResult("Comparison failed: no results returned");
|
|
6545
6887
|
}
|
|
6546
|
-
return textResult(JSON.stringify(result.data
|
|
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
|
|
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
|
|
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
|
|
6940
|
+
if (!result.data?.getDocPage) {
|
|
6599
6941
|
return errorResult(`Documentation page not found: ${page_id}`);
|
|
6600
6942
|
}
|
|
6601
|
-
return textResult(JSON.stringify(result.data
|
|
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
|
|
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(
|
|
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
|
|
6992
|
+
if (!result.data?.findSymbol) {
|
|
6651
6993
|
return notFoundError(args.package_name, args.registry);
|
|
6652
6994
|
}
|
|
6653
|
-
|
|
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(
|
|
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
|
|
7032
|
+
if (!result.data?.grepRepoFile) {
|
|
6687
7033
|
return notFoundError(args.package_name, args.registry);
|
|
6688
7034
|
}
|
|
6689
|
-
|
|
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(
|
|
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
|
|
7061
|
+
if (!result.data?.listPackageDocs) {
|
|
6712
7062
|
return notFoundError(package_name, registry);
|
|
6713
7063
|
}
|
|
6714
|
-
return textResult(JSON.stringify(result.data
|
|
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(
|
|
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
|
|
7095
|
+
if (!result.data?.listRepoFiles) {
|
|
6746
7096
|
return notFoundError(args.package_name, args.registry);
|
|
6747
7097
|
}
|
|
6748
|
-
|
|
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
|
|
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(
|
|
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
|
|
7154
|
+
if (!result.data?.listSymbols) {
|
|
6801
7155
|
return notFoundError(args.package_name, args.registry);
|
|
6802
7156
|
}
|
|
6803
|
-
return textResult(JSON.stringify(result.data
|
|
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(
|
|
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
|
|
7254
|
+
if (!result.data?.packageDependencies) {
|
|
6901
7255
|
return notFoundError(package_name, registry);
|
|
6902
7256
|
}
|
|
6903
|
-
const deps = result.data
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
7314
|
+
if (!result.data?.packageImports) {
|
|
6961
7315
|
return notFoundError(args.package_name, args.registry);
|
|
6962
7316
|
}
|
|
6963
|
-
return textResult(JSON.stringify(result.data
|
|
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(
|
|
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
|
|
7339
|
+
if (!result.data?.packageQuality) {
|
|
6986
7340
|
return notFoundError(package_name, registry);
|
|
6987
7341
|
}
|
|
6988
|
-
return textResult(JSON.stringify(result.data
|
|
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(
|
|
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
|
|
7363
|
+
if (!result.data?.packageSummary) {
|
|
7010
7364
|
return notFoundError(package_name, registry);
|
|
7011
7365
|
}
|
|
7012
|
-
return textResult(JSON.stringify(result.data
|
|
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(
|
|
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
|
|
7388
|
+
if (!result.data?.packageVulnerabilities) {
|
|
7035
7389
|
return notFoundError(package_name, registry);
|
|
7036
7390
|
}
|
|
7037
|
-
return textResult(JSON.stringify(result.data
|
|
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:
|
|
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
|
|
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
|
|
7548
|
+
if (!result.data?.searchProjectDocs) {
|
|
7195
7549
|
return errorResult(`Project not found: ${resolvedProject}`);
|
|
7196
7550
|
}
|
|
7197
|
-
if ((result.data
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
7652
|
+
if (!result.data?.searchSymbols) {
|
|
7299
7653
|
return notFoundError(args.package_name, args.registry);
|
|
7300
7654
|
}
|
|
7301
|
-
|
|
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
|
|
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
|
|
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.
|
|
7326
|
-
return errorResult("Provide either
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
7365
|
-
return errorResult("Provide either
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
7843
|
+
if (!result.data?.versionDiff) {
|
|
7477
7844
|
return notFoundError(args.package_name, args.registry);
|
|
7478
7845
|
}
|
|
7479
|
-
return textResult(JSON.stringify(result.data
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
8312
|
+
const quality = result.data?.packageQuality.quality;
|
|
7946
8313
|
const slim = {
|
|
7947
|
-
package: `${result.data
|
|
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
|
|
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
|
|
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
|
|
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
|
|
8428
|
+
console.log(formatPackageVulnerabilities(result.data?.packageVulnerabilities));
|
|
8062
8429
|
}
|
|
8063
8430
|
}
|
|
8064
8431
|
var VULNS_DESCRIPTION = `Check package for security vulnerabilities.
|