@justmpm/ai-tool 3.20.1 → 3.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
readConfig,
|
|
21
21
|
recoveryHint,
|
|
22
22
|
simplifyType
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZNVZNLRQ.js";
|
|
24
24
|
|
|
25
25
|
// src/commands/describe.ts
|
|
26
26
|
var STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -641,6 +641,23 @@ function resolveEntryPointFile(packageName, entry, cwd) {
|
|
|
641
641
|
`Nao foi possivel resolver o arquivo de tipos para "${packageName}/${entry}". Tente usar "deps api ${packageName}" para ver todos os exports disponiveis.`
|
|
642
642
|
);
|
|
643
643
|
}
|
|
644
|
+
function getSubExportPaths(packageName, cwd) {
|
|
645
|
+
try {
|
|
646
|
+
const pkgPath = resolvePackagePath(packageName, cwd);
|
|
647
|
+
const pkgJsonPath = join(pkgPath, "package.json");
|
|
648
|
+
if (!existsSync(pkgJsonPath)) return [];
|
|
649
|
+
const raw = readFileSync(pkgJsonPath, "utf-8");
|
|
650
|
+
const pkg = JSON.parse(raw);
|
|
651
|
+
const exportsField = pkg.exports;
|
|
652
|
+
if (!exportsField || typeof exportsField !== "object" || exportsField === null) {
|
|
653
|
+
return [];
|
|
654
|
+
}
|
|
655
|
+
const exports = exportsField;
|
|
656
|
+
return Object.keys(exports).filter((k) => k.startsWith("./")).map((k) => k.slice(2));
|
|
657
|
+
} catch {
|
|
658
|
+
return [];
|
|
659
|
+
}
|
|
660
|
+
}
|
|
644
661
|
function resolveEntryPoints(pkgPath, fields) {
|
|
645
662
|
const raw = [];
|
|
646
663
|
if (fields.types) {
|
|
@@ -930,21 +947,30 @@ function collectRemainingIndexFiles(packagePath, existingFiles, results, maxFile
|
|
|
930
947
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
931
948
|
import { dirname, join as join2, resolve as resolve2 } from "path";
|
|
932
949
|
import { Project } from "ts-morph";
|
|
933
|
-
|
|
950
|
+
|
|
951
|
+
// src/ts/kind-resolvers.ts
|
|
952
|
+
var REACT_COMPONENT_FACTORIES = /* @__PURE__ */ new Set([
|
|
953
|
+
// React API principal
|
|
954
|
+
"memo",
|
|
955
|
+
"forwardRef",
|
|
956
|
+
"lazy",
|
|
957
|
+
"createContext",
|
|
958
|
+
"createElement",
|
|
959
|
+
"cloneElement",
|
|
960
|
+
"createFactory",
|
|
961
|
+
// Hooks que retornam componentes
|
|
962
|
+
"useCallback",
|
|
963
|
+
"useMemo",
|
|
964
|
+
// Suspense e ErrorBoundary
|
|
965
|
+
"Suspense",
|
|
966
|
+
"ErrorBoundary",
|
|
967
|
+
// Factory patterns
|
|
968
|
+
"createComponent",
|
|
969
|
+
"forwardRefLazy"
|
|
970
|
+
]);
|
|
971
|
+
function isReactComponentFactory(name) {
|
|
934
972
|
const cleanName = stripModulePrefix(name);
|
|
935
|
-
|
|
936
|
-
return "hook";
|
|
937
|
-
}
|
|
938
|
-
if (/^[A-Z]/.test(cleanName)) {
|
|
939
|
-
if (returnType) {
|
|
940
|
-
const rt = returnType.toLowerCase();
|
|
941
|
-
if (rt.includes("jsx.element") || rt.includes("reactelement") || rt.includes("reactnode") || rt.includes("react.fc") || rt.includes("elementtype")) {
|
|
942
|
-
return "component";
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
return "function";
|
|
946
|
-
}
|
|
947
|
-
return "function";
|
|
973
|
+
return REACT_COMPONENT_FACTORIES.has(cleanName);
|
|
948
974
|
}
|
|
949
975
|
function stripModulePrefix(name) {
|
|
950
976
|
const dotIdx = name.indexOf(".");
|
|
@@ -958,6 +984,144 @@ function stripModulePrefix(name) {
|
|
|
958
984
|
}
|
|
959
985
|
return name;
|
|
960
986
|
}
|
|
987
|
+
var defaultResolver = {
|
|
988
|
+
canHandle: () => true,
|
|
989
|
+
// Fallback - sempre se aplica
|
|
990
|
+
classifyFunction(name, returnType) {
|
|
991
|
+
const cleanName = stripModulePrefix(name);
|
|
992
|
+
if (cleanName.startsWith("use") && cleanName.length > 3 && cleanName[3] === cleanName[3].toUpperCase()) {
|
|
993
|
+
return "hook";
|
|
994
|
+
}
|
|
995
|
+
if (isReactComponentFactory(name)) {
|
|
996
|
+
return "component";
|
|
997
|
+
}
|
|
998
|
+
if (/^[A-Z]/.test(cleanName)) {
|
|
999
|
+
if (returnType) {
|
|
1000
|
+
const rt = returnType.toLowerCase();
|
|
1001
|
+
if (rt.includes("jsx.element") || rt.includes("reactelement") || rt.includes("reactnode") || rt.includes("react.fc") || rt.includes("elementtype") || rt.includes("react.componenttype") || rt.includes("fc<") || rt.includes(".element")) {
|
|
1002
|
+
return "component";
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return "function";
|
|
1006
|
+
}
|
|
1007
|
+
return "function";
|
|
1008
|
+
},
|
|
1009
|
+
classifyType(_name, kind) {
|
|
1010
|
+
return kind;
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
var reactResolver = {
|
|
1014
|
+
canHandle(packageName) {
|
|
1015
|
+
return packageName === "react" || packageName === "@types/react" || packageName === "react-dom" || packageName === "@types/react-dom";
|
|
1016
|
+
},
|
|
1017
|
+
classifyFunction(name, returnType) {
|
|
1018
|
+
const cleanName = stripModulePrefix(name);
|
|
1019
|
+
const reactHooks = /* @__PURE__ */ new Set([
|
|
1020
|
+
// Hooks basicos
|
|
1021
|
+
"useState",
|
|
1022
|
+
"useEffect",
|
|
1023
|
+
"useContext",
|
|
1024
|
+
"useReducer",
|
|
1025
|
+
"useCallback",
|
|
1026
|
+
"useMemo",
|
|
1027
|
+
"useRef",
|
|
1028
|
+
"useImperativeHandle",
|
|
1029
|
+
"useLayoutEffect",
|
|
1030
|
+
"useDebugValue",
|
|
1031
|
+
"useId",
|
|
1032
|
+
// Hooks adicionais
|
|
1033
|
+
"useTransition",
|
|
1034
|
+
"useDeferredValue",
|
|
1035
|
+
"useSyncExternalStore",
|
|
1036
|
+
"useInsertionEffect",
|
|
1037
|
+
"useFormStatus",
|
|
1038
|
+
"useActionState",
|
|
1039
|
+
"useOptimistic",
|
|
1040
|
+
"use"
|
|
1041
|
+
]);
|
|
1042
|
+
if (reactHooks.has(cleanName)) {
|
|
1043
|
+
return "hook";
|
|
1044
|
+
}
|
|
1045
|
+
if (isReactComponentFactory(name)) {
|
|
1046
|
+
return "component";
|
|
1047
|
+
}
|
|
1048
|
+
if (cleanName.startsWith("use") && cleanName.length > 3 && cleanName[3] === cleanName[3].toUpperCase()) {
|
|
1049
|
+
return "hook";
|
|
1050
|
+
}
|
|
1051
|
+
if (/^[A-Z]/.test(cleanName)) {
|
|
1052
|
+
if (returnType) {
|
|
1053
|
+
const rt = returnType.toLowerCase();
|
|
1054
|
+
if (rt.includes("jsx.element") || rt.includes("reactelement") || rt.includes("reactnode") || rt.includes("react.fc") || rt.includes("elementtype") || rt.includes("react.componenttype") || rt.includes("fc<") || rt.includes(".element")) {
|
|
1055
|
+
return "component";
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return "function";
|
|
1059
|
+
}
|
|
1060
|
+
return "function";
|
|
1061
|
+
},
|
|
1062
|
+
classifyType(name, kind) {
|
|
1063
|
+
const cleanName = stripModulePrefix(name);
|
|
1064
|
+
const reactComponentInterfaces = /* @__PURE__ */ new Set([
|
|
1065
|
+
"FC",
|
|
1066
|
+
"FunctionComponent",
|
|
1067
|
+
"ComponentType",
|
|
1068
|
+
"ElementType",
|
|
1069
|
+
"Element",
|
|
1070
|
+
"ReactElement",
|
|
1071
|
+
"ReactNode",
|
|
1072
|
+
"Component",
|
|
1073
|
+
"PureComponent",
|
|
1074
|
+
"ForwardRefExoticComponent",
|
|
1075
|
+
"ExoticComponent"
|
|
1076
|
+
]);
|
|
1077
|
+
if (reactComponentInterfaces.has(cleanName)) {
|
|
1078
|
+
return "component";
|
|
1079
|
+
}
|
|
1080
|
+
return kind;
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
var resolvers = [
|
|
1084
|
+
reactResolver,
|
|
1085
|
+
defaultResolver
|
|
1086
|
+
// Fallback - deve ser o ultimo
|
|
1087
|
+
];
|
|
1088
|
+
function getResolver(packageName) {
|
|
1089
|
+
for (const resolver of resolvers) {
|
|
1090
|
+
if (resolver.canHandle(packageName)) {
|
|
1091
|
+
return resolver;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return defaultResolver;
|
|
1095
|
+
}
|
|
1096
|
+
function classifyFunctionKind(name, returnType, packageName) {
|
|
1097
|
+
const resolver = packageName ? getResolver(packageName) : defaultResolver;
|
|
1098
|
+
return resolver.classifyFunction(name, returnType);
|
|
1099
|
+
}
|
|
1100
|
+
function classifyTypeKind(name, kind, packageName) {
|
|
1101
|
+
const resolver = packageName ? getResolver(packageName) : defaultResolver;
|
|
1102
|
+
return resolver.classifyType(name, kind);
|
|
1103
|
+
}
|
|
1104
|
+
function classifySymbol(symbolKind, name, returnType, packageName) {
|
|
1105
|
+
if (symbolKind === "function") {
|
|
1106
|
+
return classifyFunctionKind(name, returnType, packageName);
|
|
1107
|
+
}
|
|
1108
|
+
if (symbolKind === "type" || symbolKind === "interface" || symbolKind === "enum") {
|
|
1109
|
+
return classifyTypeKind(name, symbolKind, packageName);
|
|
1110
|
+
}
|
|
1111
|
+
return "const";
|
|
1112
|
+
}
|
|
1113
|
+
function isSemanticKindMatch(actualKind, requestedKind) {
|
|
1114
|
+
if (actualKind === requestedKind) return true;
|
|
1115
|
+
if (requestedKind === "type") {
|
|
1116
|
+
return actualKind === "interface" || actualKind === "enum" || actualKind === "const";
|
|
1117
|
+
}
|
|
1118
|
+
if (requestedKind === "function") {
|
|
1119
|
+
return actualKind === "component" || actualKind === "hook";
|
|
1120
|
+
}
|
|
1121
|
+
return false;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// src/ts/package-extractor.ts
|
|
961
1125
|
var MAX_REEXPORT_DEPTH = 3;
|
|
962
1126
|
var MAX_TOTAL_FILES = 1200;
|
|
963
1127
|
var TYPE_DECLARATION_EXTENSIONS = [".d.ts", ".d.cts", ".d.mts", ".d.tsx"];
|
|
@@ -1284,7 +1448,7 @@ function extractPackageApiImpl(project, typeFiles, packagePath, limit, jsFallbac
|
|
|
1284
1448
|
allFunctions.push({
|
|
1285
1449
|
...fn,
|
|
1286
1450
|
sourceFile: relativeSource,
|
|
1287
|
-
kind:
|
|
1451
|
+
kind: classifySymbol("function", fn.name, fn.returnType)
|
|
1288
1452
|
});
|
|
1289
1453
|
}
|
|
1290
1454
|
}
|
|
@@ -1386,38 +1550,106 @@ function sortByRelevance(items, publicApiNames) {
|
|
|
1386
1550
|
});
|
|
1387
1551
|
}
|
|
1388
1552
|
|
|
1389
|
-
// src/
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1553
|
+
// src/ts/symbol-aliases.ts
|
|
1554
|
+
var ZUSTAND_ALIASES = {
|
|
1555
|
+
package: "zustand",
|
|
1556
|
+
aliases: {
|
|
1557
|
+
middleware: ["StateCreator", "persist", "combine", "devtools", "subscribeWithSelector", "Immer", "devtools"],
|
|
1558
|
+
store: ["create", "useStore", "createStore"],
|
|
1559
|
+
state: ["State", "PartialState", "SetState", "GetState", "StoreState"],
|
|
1560
|
+
subscribe: ["subscribe", "subscribeWithSelector"],
|
|
1561
|
+
immer: ["Immer", "createWithImmer"],
|
|
1562
|
+
devtools: ["devtools", "redux"],
|
|
1563
|
+
persist: ["persist", "createPersist", "PersistStorage"]
|
|
1396
1564
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1565
|
+
};
|
|
1566
|
+
var MUI_ALIASES = {
|
|
1567
|
+
package: "@mui/material",
|
|
1568
|
+
aliases: {
|
|
1569
|
+
styled: ["styled", "sx", "SxProps", "Theme"],
|
|
1570
|
+
theme: ["Theme", "ThemeOptions", "createTheme", "useTheme", "ThemeProvider"],
|
|
1571
|
+
props: ["Props", "PropsWithRef", "SxProps", "HTMLProps", "ComponentProps"],
|
|
1572
|
+
slot: ["Slot", "Slots", "SlotProps"],
|
|
1573
|
+
component: ["ComponentType", "ElementType", "FC", "ForwardRefExoticComponent"]
|
|
1399
1574
|
}
|
|
1400
|
-
|
|
1575
|
+
};
|
|
1576
|
+
var REACT_ALIASES = {
|
|
1577
|
+
package: "react",
|
|
1578
|
+
aliases: {
|
|
1579
|
+
hook: ["useState", "useEffect", "useContext", "useReducer", "useCallback", "useMemo", "useRef", "useImperativeHandle", "useLayoutEffect", "useDebugValue", "useId", "useTransition", "useDeferredValue", "useSyncExternalStore", "useInsertionEffect", "useFormStatus", "useActionState", "useOptimistic", "use"],
|
|
1580
|
+
component: ["Component", "PureComponent", "FC", "FunctionComponent", "forwardRef", "lazy", "memo", "createContext", "createElement", "cloneElement"],
|
|
1581
|
+
context: ["createContext", "useContext"],
|
|
1582
|
+
element: ["createElement", "cloneElement", "isValidElement"]
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
var FIREBASE_ALIASES = {
|
|
1586
|
+
package: "firebase",
|
|
1587
|
+
aliases: {
|
|
1588
|
+
auth: ["getAuth", "signInWithPopup", "signInWithEmailAndPassword", "createUserWithEmailAndPassword", "signOut", "onAuthStateChanged"],
|
|
1589
|
+
firestore: ["getFirestore", "collection", "doc", "getDoc", "getDocs", "setDoc", "addDoc", "updateDoc", "deleteDoc", "onSnapshot", "query", "where", "orderBy"],
|
|
1590
|
+
storage: ["getStorage", "ref", "uploadBytes", "uploadString", "getDownloadURL", "deleteObject"],
|
|
1591
|
+
messaging: ["getMessaging", "getToken", "onMessage"]
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
var ALIAS_REGISTRY = [
|
|
1595
|
+
ZUSTAND_ALIASES,
|
|
1596
|
+
MUI_ALIASES,
|
|
1597
|
+
REACT_ALIASES,
|
|
1598
|
+
FIREBASE_ALIASES
|
|
1599
|
+
];
|
|
1600
|
+
function getAliasesForPackage(packageName) {
|
|
1601
|
+
return ALIAS_REGISTRY.find((a) => a.package === packageName);
|
|
1401
1602
|
}
|
|
1402
|
-
function
|
|
1403
|
-
const
|
|
1404
|
-
if (
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
return "component";
|
|
1412
|
-
}
|
|
1603
|
+
function resolveConceptualQuery(query, packageName, extracted) {
|
|
1604
|
+
const aliases = getAliasesForPackage(packageName);
|
|
1605
|
+
if (!aliases) return [];
|
|
1606
|
+
const aliasList = aliases.aliases[query.toLowerCase()];
|
|
1607
|
+
if (!aliasList) return [];
|
|
1608
|
+
const results = [];
|
|
1609
|
+
for (const fn of extracted.functions) {
|
|
1610
|
+
if (aliasList.includes(fn.name)) {
|
|
1611
|
+
results.push({ name: fn.name, kind: "function", file: fn.sourceFile ?? "" });
|
|
1413
1612
|
}
|
|
1414
|
-
return "function";
|
|
1415
1613
|
}
|
|
1416
|
-
|
|
1614
|
+
for (const t of extracted.types) {
|
|
1615
|
+
if (aliasList.includes(t.name)) {
|
|
1616
|
+
results.push({ name: t.name, kind: t.kind, file: t.sourceFile ?? "" });
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
return results;
|
|
1417
1620
|
}
|
|
1621
|
+
function isConceptualQuery(query, packageName) {
|
|
1622
|
+
const aliases = getAliasesForPackage(packageName);
|
|
1623
|
+
if (!aliases) return false;
|
|
1624
|
+
return query.toLowerCase() in aliases.aliases;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// src/commands/deps.ts
|
|
1418
1628
|
function normalizePath(p) {
|
|
1419
1629
|
return p.replace(/\\/g, "/");
|
|
1420
1630
|
}
|
|
1631
|
+
function computeAvailableKinds(extracted, requestedKind) {
|
|
1632
|
+
const kindCounts = /* @__PURE__ */ new Map();
|
|
1633
|
+
for (const fn of extracted.functions) {
|
|
1634
|
+
const kind = classifySymbol("function", fn.name, fn.returnType);
|
|
1635
|
+
if (isSemanticKindMatch(kind, requestedKind)) {
|
|
1636
|
+
kindCounts.set(kind, (kindCounts.get(kind) ?? 0) + 1);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
for (const t of extracted.types) {
|
|
1640
|
+
const kind = classifySymbol("type", t.name);
|
|
1641
|
+
if (isSemanticKindMatch(kind, requestedKind)) {
|
|
1642
|
+
kindCounts.set(kind, (kindCounts.get(kind) ?? 0) + 1);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
for (const c of extracted.constants) {
|
|
1646
|
+
const kind = classifySymbol("const", c.name);
|
|
1647
|
+
if (isSemanticKindMatch(kind, requestedKind)) {
|
|
1648
|
+
kindCounts.set(kind, (kindCounts.get(kind) ?? 0) + 1);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return Array.from(kindCounts.entries()).map(([kind, count]) => ({ kind, count })).sort((a, b) => b.count - a.count);
|
|
1652
|
+
}
|
|
1421
1653
|
function relativeTypeFile(typeFiles, normalizedPkgPath, packageName, sourceFile) {
|
|
1422
1654
|
if (sourceFile) {
|
|
1423
1655
|
return `${packageName}/${sourceFile}`;
|
|
@@ -1427,16 +1659,6 @@ function relativeTypeFile(typeFiles, normalizedPkgPath, packageName, sourceFile)
|
|
|
1427
1659
|
}
|
|
1428
1660
|
return normalizePath(typeFiles[0]).replace(normalizedPkgPath, packageName);
|
|
1429
1661
|
}
|
|
1430
|
-
function isKindMatch(actualKind, requestedKind) {
|
|
1431
|
-
if (actualKind === requestedKind) return true;
|
|
1432
|
-
if (requestedKind === "type") {
|
|
1433
|
-
return actualKind === "interface" || actualKind === "enum" || actualKind === "const";
|
|
1434
|
-
}
|
|
1435
|
-
if (requestedKind === "function") {
|
|
1436
|
-
return actualKind === "component" || actualKind === "hook";
|
|
1437
|
-
}
|
|
1438
|
-
return false;
|
|
1439
|
-
}
|
|
1440
1662
|
var TYPE_FILES_COMPACT_THRESHOLD = 10;
|
|
1441
1663
|
var TYPE_FILES_PREVIEW_COUNT = 5;
|
|
1442
1664
|
function buildTypeFilesMeta(typeFiles, pkgPath) {
|
|
@@ -1543,22 +1765,31 @@ async function depsApi(packageName, options = {}) {
|
|
|
1543
1765
|
let filteredConstants = extracted.constants;
|
|
1544
1766
|
if (options.kind) {
|
|
1545
1767
|
const kind = options.kind;
|
|
1546
|
-
filteredFunctions = extracted.functions.filter((fn) =>
|
|
1768
|
+
filteredFunctions = extracted.functions.filter((fn) => classifySymbol("function", fn.name, fn.returnType) === kind);
|
|
1547
1769
|
filteredTypes = extracted.types.filter((t) => {
|
|
1548
|
-
const resolvedKind =
|
|
1770
|
+
const resolvedKind = classifySymbol("type", t.name) === "hook" ? "hook" : t.kind;
|
|
1549
1771
|
return resolvedKind === kind;
|
|
1550
1772
|
});
|
|
1551
1773
|
filteredConstants = extracted.constants.filter(() => kind === "const");
|
|
1552
1774
|
const realLimit = options.limit ?? 50;
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1775
|
+
const realOffset = options.offset ?? 0;
|
|
1776
|
+
filteredFunctions = filteredFunctions.slice(realOffset, realOffset + realLimit);
|
|
1777
|
+
filteredTypes = filteredTypes.slice(realOffset, realOffset + realLimit);
|
|
1778
|
+
filteredConstants = filteredConstants.slice(realOffset, realOffset + realLimit);
|
|
1779
|
+
} else {
|
|
1780
|
+
const realOffset = options.offset ?? 0;
|
|
1781
|
+
const realLimit = options.limit ?? 50;
|
|
1782
|
+
filteredFunctions = filteredFunctions.slice(realOffset, realOffset + realLimit);
|
|
1783
|
+
filteredTypes = filteredTypes.slice(realOffset, realOffset + realLimit);
|
|
1784
|
+
filteredConstants = filteredConstants.slice(realOffset, realOffset + realLimit);
|
|
1556
1785
|
}
|
|
1786
|
+
const availableKindsWhenFilteredEmpty = options.kind && filteredFunctions.length === 0 && filteredTypes.length === 0 ? computeAvailableKinds(extracted, options.kind) : void 0;
|
|
1557
1787
|
const jsFallback = typeFiles.length > 0 && typeFiles.every(
|
|
1558
1788
|
(f) => f.endsWith(".js") || f.endsWith(".mjs") || f.endsWith(".cjs")
|
|
1559
1789
|
);
|
|
1560
1790
|
const pkgVersion = readPackageJson(packageName, cwd).version;
|
|
1561
1791
|
const typeFilesMeta = buildTypeFilesMeta(typeFiles, pkgPath);
|
|
1792
|
+
const byKind = options.kind ? computeAvailableKinds(extracted, options.kind) : void 0;
|
|
1562
1793
|
const result = {
|
|
1563
1794
|
version: pkgVersion,
|
|
1564
1795
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1573,8 +1804,16 @@ async function depsApi(packageName, options = {}) {
|
|
|
1573
1804
|
types: filteredTypes.length >= (options.limit ?? 50),
|
|
1574
1805
|
totalFunctions: filteredFunctions.length,
|
|
1575
1806
|
totalTypes: filteredTypes.length,
|
|
1576
|
-
shown: Math.min(filteredFunctions.length, options.limit ?? 50)
|
|
1577
|
-
|
|
1807
|
+
shown: Math.min(filteredFunctions.length, options.limit ?? 50),
|
|
1808
|
+
functionsOffset: options.offset,
|
|
1809
|
+
typesOffset: options.offset,
|
|
1810
|
+
byKind
|
|
1811
|
+
} : {
|
|
1812
|
+
...extracted.truncated,
|
|
1813
|
+
functionsOffset: options.offset,
|
|
1814
|
+
typesOffset: options.offset
|
|
1815
|
+
},
|
|
1816
|
+
availableKindsWhenFilteredEmpty,
|
|
1578
1817
|
typeFilesSummary: typeFilesMeta.summary,
|
|
1579
1818
|
typeFilesPreview: typeFilesMeta.preview,
|
|
1580
1819
|
jsFallback: jsFallback || void 0,
|
|
@@ -1602,7 +1841,8 @@ async function depsApi(packageName, options = {}) {
|
|
|
1602
1841
|
throw new Error(`Erro ao executar deps api: ${message}`);
|
|
1603
1842
|
}
|
|
1604
1843
|
}
|
|
1605
|
-
var
|
|
1844
|
+
var DEFAULT_SEARCH_LIMIT = 15;
|
|
1845
|
+
var MAX_SEARCH_LIMIT = 200;
|
|
1606
1846
|
var AUXILIARY_TYPE_SUFFIXES = [
|
|
1607
1847
|
"Props",
|
|
1608
1848
|
"PropsWithRef",
|
|
@@ -1739,20 +1979,20 @@ async function depsSearch(packageName, query, options = {}) {
|
|
|
1739
1979
|
const filesSet = /* @__PURE__ */ new Set();
|
|
1740
1980
|
const normalizedPkgPath = normalizePath(pkgPath);
|
|
1741
1981
|
const useWildcard = hasWildcard(query);
|
|
1742
|
-
const matchFn = useWildcard ? (name) => matchWithWildcard(name, query) || matchWithWildcard(
|
|
1982
|
+
const matchFn = useWildcard ? (name) => matchWithWildcard(name, query) || matchWithWildcard(stripModulePrefix(name), query) : (name) => {
|
|
1743
1983
|
const n = name.toLowerCase();
|
|
1744
|
-
const s =
|
|
1984
|
+
const s = stripModulePrefix(name).toLowerCase();
|
|
1745
1985
|
return n === queryLower || s === queryLower;
|
|
1746
1986
|
};
|
|
1747
1987
|
const scoreFn = useWildcard ? (name, kind, isExported) => calculateWildcardMatchScore(name, query, kind, isExported) : (name, kind, isExported) => calculateMatchScore(name, queryLower, kind, isExported);
|
|
1748
1988
|
const fuzzyMatchFn = (name) => {
|
|
1749
1989
|
const n = name.toLowerCase();
|
|
1750
|
-
const s =
|
|
1990
|
+
const s = stripModulePrefix(name).toLowerCase();
|
|
1751
1991
|
return (n.includes(queryLower) || s.includes(queryLower)) && n !== queryLower && s !== queryLower;
|
|
1752
1992
|
};
|
|
1753
1993
|
for (const fn of extracted.functions) {
|
|
1754
1994
|
if (matchFn(fn.name)) {
|
|
1755
|
-
const kind =
|
|
1995
|
+
const kind = classifySymbol("function", fn.name, fn.returnType, packageName);
|
|
1756
1996
|
const score = scoreFn(fn.name, kind, fn.isExported);
|
|
1757
1997
|
const params = fn.params.map((p) => `${p.name}: ${p.type}`).join(", ");
|
|
1758
1998
|
const signature = `${fn.name}(${params}): ${fn.returnType}`;
|
|
@@ -1763,7 +2003,7 @@ async function depsSearch(packageName, query, options = {}) {
|
|
|
1763
2003
|
}
|
|
1764
2004
|
for (const t of extracted.types) {
|
|
1765
2005
|
if (matchFn(t.name)) {
|
|
1766
|
-
const kind =
|
|
2006
|
+
const kind = classifySymbol("type", t.name, void 0, packageName) === "hook" ? "hook" : t.kind;
|
|
1767
2007
|
const score = scoreFn(t.name, kind, t.isExported);
|
|
1768
2008
|
const file = relativeTypeFile(typeFiles, normalizedPkgPath, packageName, t.sourceFile);
|
|
1769
2009
|
scored.push({ name: t.name, kind, file, signature: t.definition, _score: score });
|
|
@@ -1783,7 +2023,7 @@ async function depsSearch(packageName, query, options = {}) {
|
|
|
1783
2023
|
const matchedNames = new Set(scored.map((m) => m.name));
|
|
1784
2024
|
for (const fn of extracted.functions) {
|
|
1785
2025
|
if (matchedNames.has(fn.name)) continue;
|
|
1786
|
-
const kind =
|
|
2026
|
+
const kind = classifySymbol("function", fn.name, fn.returnType, packageName);
|
|
1787
2027
|
if (exactKinds.has(kind)) continue;
|
|
1788
2028
|
if (!fuzzyMatchFn(fn.name)) continue;
|
|
1789
2029
|
const score = scoreFn(fn.name, kind, fn.isExported);
|
|
@@ -1797,7 +2037,7 @@ async function depsSearch(packageName, query, options = {}) {
|
|
|
1797
2037
|
}
|
|
1798
2038
|
for (const t of extracted.types) {
|
|
1799
2039
|
if (matchedNames.has(t.name)) continue;
|
|
1800
|
-
const kind =
|
|
2040
|
+
const kind = classifySymbol("type", t.name, void 0, packageName) === "hook" ? "hook" : t.kind;
|
|
1801
2041
|
if (exactKinds.has(kind)) continue;
|
|
1802
2042
|
if (!fuzzyMatchFn(t.name)) continue;
|
|
1803
2043
|
const score = scoreFn(t.name, kind, t.isExported);
|
|
@@ -1820,19 +2060,101 @@ async function depsSearch(packageName, query, options = {}) {
|
|
|
1820
2060
|
}
|
|
1821
2061
|
}
|
|
1822
2062
|
scored.sort((a, b) => b._score - a._score);
|
|
1823
|
-
const
|
|
1824
|
-
const
|
|
2063
|
+
const effectiveOffset = options.offset ?? 0;
|
|
2064
|
+
const effectiveLimit = Math.min(options.limit ?? DEFAULT_SEARCH_LIMIT, MAX_SEARCH_LIMIT);
|
|
2065
|
+
const kindCountMap = /* @__PURE__ */ new Map();
|
|
2066
|
+
for (const m of scored) {
|
|
2067
|
+
const key = m.kind;
|
|
2068
|
+
const existing = kindCountMap.get(key);
|
|
2069
|
+
if (existing) {
|
|
2070
|
+
existing.total++;
|
|
2071
|
+
} else {
|
|
2072
|
+
kindCountMap.set(key, { total: 1, shown: 0 });
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
const fileCountMap = /* @__PURE__ */ new Map();
|
|
2076
|
+
for (const m of scored) {
|
|
2077
|
+
fileCountMap.set(m.file, (fileCountMap.get(m.file) ?? 0) + 1);
|
|
2078
|
+
}
|
|
2079
|
+
const filtered = options.kind ? scored.filter((m) => isSemanticKindMatch(m.kind, options.kind)) : scored;
|
|
2080
|
+
const pageMatches = filtered.slice(effectiveOffset, effectiveOffset + effectiveLimit);
|
|
2081
|
+
for (const m of pageMatches) {
|
|
2082
|
+
const k = kindCountMap.get(m.kind);
|
|
2083
|
+
if (k) k.shown++;
|
|
2084
|
+
}
|
|
2085
|
+
const byKind = [];
|
|
2086
|
+
for (const [kind, counts] of kindCountMap.entries()) {
|
|
2087
|
+
byKind.push({ kind, total: counts.total, shown: counts.shown });
|
|
2088
|
+
}
|
|
2089
|
+
byKind.sort((a, b) => b.total - a.total);
|
|
2090
|
+
const byFile = Array.from(fileCountMap.entries()).map(([file, count]) => ({ file, count })).sort((a, b) => b.count - a.count).slice(0, 10);
|
|
2091
|
+
const availableKindsWhenEmpty = options.kind && filtered.length === 0 && scored.length > 0 ? [...new Set(scored.map((m) => m.kind))] : void 0;
|
|
2092
|
+
const allMatches = pageMatches.map(({ _score: _, ...match }) => match);
|
|
2093
|
+
if (allMatches.length > 0 && allMatches.length < 3 && !useWildcard) {
|
|
2094
|
+
const isConcept = isConceptualQuery(query, packageName);
|
|
2095
|
+
if (!isConcept) {
|
|
2096
|
+
const aliasResults = resolveConceptualQuery(query, packageName, {
|
|
2097
|
+
functions: extracted.functions,
|
|
2098
|
+
types: extracted.types
|
|
2099
|
+
});
|
|
2100
|
+
for (const r of aliasResults) {
|
|
2101
|
+
if (!allMatches.some((m) => m.name === r.name)) {
|
|
2102
|
+
const fn = extracted.functions.find((f) => f.name === r.name);
|
|
2103
|
+
const t = extracted.types.find((t2) => t2.name === r.name);
|
|
2104
|
+
const signature = fn ? `${fn.name}(${fn.params.map((p) => `${p.name}: ${p.type}`).join(", ")}): ${fn.returnType}` : t?.definition ?? r.name;
|
|
2105
|
+
allMatches.push({ name: r.name, kind: r.kind, file: r.file, signature, fromConcept: query });
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
if (allMatches.length > 0 && allMatches.length < 3) {
|
|
2111
|
+
const subPaths = getSubExportPaths(packageName, cwd);
|
|
2112
|
+
for (const subPath of subPaths) {
|
|
2113
|
+
try {
|
|
2114
|
+
const subEntryFile = resolveEntryPointFile(packageName, subPath, cwd);
|
|
2115
|
+
const subExtracted = extractPackageApi([subEntryFile], pkgPath, { limit: 200 });
|
|
2116
|
+
const subMatchFn = useWildcard ? (name) => matchWithWildcard(name, query) || matchWithWildcard(stripModulePrefix(name), query) : (name) => {
|
|
2117
|
+
const n = name.toLowerCase();
|
|
2118
|
+
const s = stripModulePrefix(name).toLowerCase();
|
|
2119
|
+
return n === queryLower || s === queryLower;
|
|
2120
|
+
};
|
|
2121
|
+
for (const fn of subExtracted.functions) {
|
|
2122
|
+
if (subMatchFn(fn.name) && !allMatches.some((m) => m.name === fn.name)) {
|
|
2123
|
+
const kind = classifySymbol("function", fn.name, fn.returnType, packageName);
|
|
2124
|
+
const params = fn.params.map((p) => `${p.name}: ${p.type}`).join(", ");
|
|
2125
|
+
const signature = `${fn.name}(${params}): ${fn.returnType}`;
|
|
2126
|
+
const file = relativeTypeFile([subEntryFile], normalizePath(subEntryFile), `${packageName}/${subPath}`, fn.sourceFile);
|
|
2127
|
+
allMatches.push({ name: fn.name, kind, file, signature });
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
for (const t of subExtracted.types) {
|
|
2131
|
+
if (subMatchFn(t.name) && !allMatches.some((m) => m.name === t.name)) {
|
|
2132
|
+
const kind = classifySymbol("type", t.name, void 0, packageName) === "hook" ? "hook" : t.kind;
|
|
2133
|
+
const file = relativeTypeFile([subEntryFile], normalizePath(subEntryFile), `${packageName}/${subPath}`, t.sourceFile);
|
|
2134
|
+
allMatches.push({ name: t.name, kind, file, signature: t.definition });
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
} catch {
|
|
2138
|
+
}
|
|
2139
|
+
if (allMatches.length >= 10) break;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
1825
2142
|
const pkgVersion = readPackageJson(packageName, cwd).version;
|
|
1826
2143
|
const result = {
|
|
1827
2144
|
version: pkgVersion,
|
|
1828
2145
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1829
2146
|
package: packageName,
|
|
1830
2147
|
query,
|
|
1831
|
-
matches,
|
|
2148
|
+
matches: allMatches,
|
|
1832
2149
|
summary: {
|
|
1833
2150
|
total: scored.length,
|
|
1834
|
-
files: filesSet.size
|
|
2151
|
+
files: filesSet.size,
|
|
2152
|
+
shown: allMatches.length,
|
|
2153
|
+
hidden: Math.max(0, filtered.length - effectiveOffset - effectiveLimit),
|
|
2154
|
+
byKind: byKind.length > 1 ? byKind : void 0,
|
|
2155
|
+
byFile: byFile.length > 1 ? byFile : void 0
|
|
1835
2156
|
},
|
|
2157
|
+
availableKindsWhenEmpty,
|
|
1836
2158
|
jsFallback: jsFallback || void 0,
|
|
1837
2159
|
typesSource: resolved.source,
|
|
1838
2160
|
typesPackage: resolved.typesPackage
|
|
@@ -2337,6 +2337,16 @@ function formatDepsApiText(result, ctx = "cli") {
|
|
|
2337
2337
|
`;
|
|
2338
2338
|
}
|
|
2339
2339
|
out += `Use ${hint("deps_search", ctx, { "<pacote>": result.package, "<termo>": "*Symbol*" })} para buscar simbolos especificos
|
|
2340
|
+
`;
|
|
2341
|
+
}
|
|
2342
|
+
if (result.availableKindsWhenFilteredEmpty && result.availableKindsWhenFilteredEmpty.length > 0) {
|
|
2343
|
+
const kinds = result.availableKindsWhenFilteredEmpty.map((k) => `${k.kind} (${k.count})`).join(", ");
|
|
2344
|
+
out += `
|
|
2345
|
+
Filtro --kind nao encontrou simbolos, mas ha outros tipos disponiveis:
|
|
2346
|
+
`;
|
|
2347
|
+
out += ` ${kinds}
|
|
2348
|
+
`;
|
|
2349
|
+
out += ` Use ${hint("deps_api", ctx, { "<pacote>": result.package })} sem filtro --kind para ver tudo
|
|
2340
2350
|
`;
|
|
2341
2351
|
}
|
|
2342
2352
|
out += nextSteps("deps_api", ctx);
|
|
@@ -2364,6 +2374,16 @@ function formatDepsSearchText(result, ctx = "cli") {
|
|
|
2364
2374
|
if (result.matches.length === 0) {
|
|
2365
2375
|
out += `Nenhum simbolo encontrado para "${result.query}".
|
|
2366
2376
|
`;
|
|
2377
|
+
if (result.availableKindsWhenEmpty && result.availableKindsWhenEmpty.length > 0) {
|
|
2378
|
+
const kinds = result.availableKindsWhenEmpty.map((k) => `"${k}"`).join(", ");
|
|
2379
|
+
out += `
|
|
2380
|
+
Simbolos encontrados, mas como tipo diferente:
|
|
2381
|
+
`;
|
|
2382
|
+
out += ` Kinds disponiveis: ${kinds}
|
|
2383
|
+
`;
|
|
2384
|
+
out += ` Tente: ${hint("deps_search", ctx, { "<pacote>": result.package, "<termo>": result.query })} sem filtro --kind
|
|
2385
|
+
`;
|
|
2386
|
+
}
|
|
2367
2387
|
if (result.typesSource === void 0 && !result.jsFallback) {
|
|
2368
2388
|
out += `
|
|
2369
2389
|
Pacote "${result.package}" nao possui TypeScript declarations.
|
|
@@ -2384,7 +2404,11 @@ function formatDepsSearchText(result, ctx = "cli") {
|
|
|
2384
2404
|
}
|
|
2385
2405
|
for (let i = 0; i < result.matches.length; i++) {
|
|
2386
2406
|
const match = result.matches[i];
|
|
2387
|
-
out += `${i + 1}. ${match.name} (${match.kind})
|
|
2407
|
+
out += `${i + 1}. ${match.name} (${match.kind})`;
|
|
2408
|
+
if (match.fromConcept) {
|
|
2409
|
+
out += ` [conceito: "${match.fromConcept}"]`;
|
|
2410
|
+
}
|
|
2411
|
+
out += `
|
|
2388
2412
|
`;
|
|
2389
2413
|
out += ` ${match.file}
|
|
2390
2414
|
`;
|
|
@@ -2394,12 +2418,36 @@ function formatDepsSearchText(result, ctx = "cli") {
|
|
|
2394
2418
|
out += `
|
|
2395
2419
|
`;
|
|
2396
2420
|
}
|
|
2397
|
-
|
|
2421
|
+
if (result.summary.byKind && result.summary.byKind.length > 1) {
|
|
2422
|
+
out += `POR KIND:
|
|
2423
|
+
`;
|
|
2424
|
+
for (const k of result.summary.byKind) {
|
|
2425
|
+
if (k.total > 0) {
|
|
2426
|
+
const truncInfo = k.shown < k.total ? ` (${k.shown}/${k.total})` : "";
|
|
2427
|
+
out += ` ${k.kind}: ${k.total}${truncInfo}
|
|
2428
|
+
`;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
if (result.summary.byFile && result.summary.byFile.length > 1) {
|
|
2433
|
+
out += `POR ARQUIVO:
|
|
2434
|
+
`;
|
|
2435
|
+
for (const f of result.summary.byFile) {
|
|
2436
|
+
if (f.count > 1) {
|
|
2437
|
+
out += ` ${f.file}: ${f.count} matches
|
|
2438
|
+
`;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
const shown = result.summary.shown;
|
|
2398
2443
|
const total = result.summary.total;
|
|
2444
|
+
const hidden = result.summary.hidden;
|
|
2399
2445
|
const pluralTotal = total !== 1 ? "s" : "";
|
|
2400
2446
|
const pluralFiles = result.summary.files !== 1 ? "s" : "";
|
|
2401
|
-
if (
|
|
2402
|
-
out += `${shown} de ${total} resultado${pluralTotal}
|
|
2447
|
+
if (hidden > 0) {
|
|
2448
|
+
out += `${shown} de ${total} resultado${pluralTotal} (${hidden} hidden)
|
|
2449
|
+
`;
|
|
2450
|
+
out += ` em ${result.summary.files} arquivo${pluralFiles}
|
|
2403
2451
|
`;
|
|
2404
2452
|
} else {
|
|
2405
2453
|
out += `${total} resultado${pluralTotal} em ${result.summary.files} arquivo${pluralFiles}
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
depsInfo,
|
|
5
5
|
depsSearch,
|
|
6
6
|
describe
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CFJB2JDZ.js";
|
|
8
8
|
import {
|
|
9
9
|
VERSION,
|
|
10
10
|
area,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
impact,
|
|
21
21
|
map,
|
|
22
22
|
suggest
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-ZNVZNLRQ.js";
|
|
24
24
|
|
|
25
25
|
// src/cli.ts
|
|
26
26
|
import { resolve } from "path";
|
|
@@ -131,7 +131,7 @@ async function main() {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
if (flags.mcp) {
|
|
134
|
-
const { startMcpServer } = await import("./server-
|
|
134
|
+
const { startMcpServer } = await import("./server-QI5WOPV5.js");
|
|
135
135
|
await startMcpServer();
|
|
136
136
|
return;
|
|
137
137
|
}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
depsInfo,
|
|
4
4
|
depsSearch,
|
|
5
5
|
describe
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CFJB2JDZ.js";
|
|
7
7
|
import {
|
|
8
8
|
VERSION,
|
|
9
9
|
area,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
map,
|
|
20
20
|
recoveryHint,
|
|
21
21
|
suggest
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZNVZNLRQ.js";
|
|
23
23
|
|
|
24
24
|
// src/mcp/server.ts
|
|
25
25
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -691,7 +691,8 @@ Dica: Se a API estiver truncada, use deps_search com wildcards: "Button" (exato)
|
|
|
691
691
|
Dica: Para libs muito grandes (MUI, React), use --limit para controlar o output.`,
|
|
692
692
|
inputSchema: {
|
|
693
693
|
package: z.string().min(1).describe("Nome do pacote"),
|
|
694
|
-
limit: z.number().int().min(1).max(
|
|
694
|
+
limit: z.number().int().min(1).max(500).optional().describe("Limite de simbolos por tipo (default: 50)"),
|
|
695
|
+
offset: z.number().int().min(0).optional().describe("Offset para paginacao (default: 0)"),
|
|
695
696
|
entry: z.string().optional().describe("Sub-export especifico (ex: 'auth' para firebase/firestore)"),
|
|
696
697
|
kind: z.enum(["component", "hook", "function", "type", "interface", "enum", "const"]).optional().describe("Filtrar por tipo de simbolo (component|hook|function|type|interface|enum|const)"),
|
|
697
698
|
format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
|
|
@@ -711,6 +712,7 @@ Dica: Para libs muito grandes (MUI, React), use --limit para controlar o output.
|
|
|
711
712
|
format: params.format,
|
|
712
713
|
cwd: params.cwd,
|
|
713
714
|
limit: params.limit,
|
|
715
|
+
offset: params.offset,
|
|
714
716
|
entry: params.entry,
|
|
715
717
|
kind: params.kind,
|
|
716
718
|
ctx: "mcp"
|
|
@@ -747,6 +749,8 @@ Workflow: deps_info (overview) -> deps_api (API completa) -> deps_search (simbol
|
|
|
747
749
|
package: z.string().min(1).describe("Nome do pacote"),
|
|
748
750
|
query: z.string().min(1).describe("Termo de busca (nome do simbolo)"),
|
|
749
751
|
kind: z.enum(["component", "hook", "function", "type", "interface", "enum", "const"]).optional().describe("Filtrar por tipo de simbolo (component|hook|function|type|interface|enum|const)"),
|
|
752
|
+
offset: z.number().int().min(0).optional().describe("Offset para paginacao (default: 0)"),
|
|
753
|
+
limit: z.number().int().min(1).max(200).optional().describe("Limite de resultados (default: 15)"),
|
|
750
754
|
format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
|
|
751
755
|
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
752
756
|
},
|
|
@@ -764,6 +768,8 @@ Workflow: deps_info (overview) -> deps_api (API completa) -> deps_search (simbol
|
|
|
764
768
|
format: params.format,
|
|
765
769
|
cwd: params.cwd,
|
|
766
770
|
kind: params.kind,
|
|
771
|
+
offset: params.offset,
|
|
772
|
+
limit: params.limit,
|
|
767
773
|
ctx: "mcp"
|
|
768
774
|
});
|
|
769
775
|
return { content: [{ type: "text", text: result }] };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justmpm/ai-tool",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0",
|
|
4
4
|
"description": "Ferramenta de análise de dependências e impacto para projetos TypeScript/JavaScript. Usa Skott + Knip internamente. Inclui busca por descrição, integração Git e testes inteligentes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency-analysis",
|