@justmpm/ai-tool 0.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -9
- package/dist/chunk-M7JM3XRW.js +219 -0
- package/dist/{chunk-PHTWZ2JT.js → chunk-UDT7TLSN.js} +769 -55
- package/dist/cli.js +46 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/{server-NIEAOPLJ.js → server-VKLU25E2.js} +89 -1
- package/package.json +1 -1
|
@@ -858,9 +858,237 @@ function formatAreaDetailText(result, options = {}) {
|
|
|
858
858
|
}
|
|
859
859
|
return out;
|
|
860
860
|
}
|
|
861
|
+
function formatFindText(result) {
|
|
862
|
+
let out = "";
|
|
863
|
+
out += `
|
|
864
|
+
`;
|
|
865
|
+
out += `\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
866
|
+
`;
|
|
867
|
+
out += `\u2551 \u{1F50D} FIND \u2551
|
|
868
|
+
`;
|
|
869
|
+
out += `\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
870
|
+
|
|
871
|
+
`;
|
|
872
|
+
out += `\u{1F50D} "${result.query}"`;
|
|
873
|
+
if (result.filters.type) {
|
|
874
|
+
out += ` [type: ${result.filters.type}]`;
|
|
875
|
+
}
|
|
876
|
+
if (result.filters.area) {
|
|
877
|
+
out += ` [area: ${result.filters.area}]`;
|
|
878
|
+
}
|
|
879
|
+
out += `
|
|
880
|
+
|
|
881
|
+
`;
|
|
882
|
+
if (!result.definition && result.references.length === 0) {
|
|
883
|
+
out += `\u274C Nenhum resultado encontrado para "${result.query}"
|
|
884
|
+
|
|
885
|
+
`;
|
|
886
|
+
out += `\u{1F4A1} Dicas:
|
|
887
|
+
`;
|
|
888
|
+
out += ` \u2022 Verifique a ortografia
|
|
889
|
+
`;
|
|
890
|
+
out += ` \u2022 Tente buscar parte do nome
|
|
891
|
+
`;
|
|
892
|
+
out += ` \u2022 Remova filtros de tipo ou \xE1rea
|
|
893
|
+
`;
|
|
894
|
+
return out;
|
|
895
|
+
}
|
|
896
|
+
out += `\u{1F4CA} ${result.summary.definitions} defini\xE7\xE3o, ${result.summary.references} refer\xEAncias em ${result.summary.files} arquivos
|
|
897
|
+
|
|
898
|
+
`;
|
|
899
|
+
out += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
900
|
+
|
|
901
|
+
`;
|
|
902
|
+
if (result.definition) {
|
|
903
|
+
out += `\u{1F4CD} DEFINI\xC7\xC3O
|
|
904
|
+
|
|
905
|
+
`;
|
|
906
|
+
const def = result.definition;
|
|
907
|
+
const icon = categoryIcons[def.category];
|
|
908
|
+
out += ` ${icon} ${def.file}:${def.line}
|
|
909
|
+
`;
|
|
910
|
+
out += ` ${def.code}
|
|
911
|
+
`;
|
|
912
|
+
out += `
|
|
913
|
+
`;
|
|
914
|
+
}
|
|
915
|
+
if (result.references.length > 0) {
|
|
916
|
+
const imports = result.references.filter((r) => r.matchType === "import");
|
|
917
|
+
const usages = result.references.filter((r) => r.matchType === "usage");
|
|
918
|
+
if (imports.length > 0) {
|
|
919
|
+
out += `\u{1F4E5} IMPORTS (${imports.length})
|
|
920
|
+
|
|
921
|
+
`;
|
|
922
|
+
for (const ref of imports.slice(0, 10)) {
|
|
923
|
+
const icon = categoryIcons[ref.category];
|
|
924
|
+
out += ` ${icon} ${ref.file}:${ref.line}
|
|
925
|
+
`;
|
|
926
|
+
out += ` ${ref.code}
|
|
927
|
+
`;
|
|
928
|
+
}
|
|
929
|
+
if (imports.length > 10) {
|
|
930
|
+
out += ` ... e mais ${imports.length - 10}
|
|
931
|
+
`;
|
|
932
|
+
}
|
|
933
|
+
out += `
|
|
934
|
+
`;
|
|
935
|
+
}
|
|
936
|
+
if (usages.length > 0) {
|
|
937
|
+
out += `\u26A1 USOS (${usages.length})
|
|
938
|
+
|
|
939
|
+
`;
|
|
940
|
+
for (const ref of usages.slice(0, 15)) {
|
|
941
|
+
const icon = categoryIcons[ref.category];
|
|
942
|
+
out += ` ${icon} ${ref.file}:${ref.line}
|
|
943
|
+
`;
|
|
944
|
+
out += ` ${ref.code}
|
|
945
|
+
`;
|
|
946
|
+
}
|
|
947
|
+
if (usages.length > 15) {
|
|
948
|
+
out += ` ... e mais ${usages.length - 15}
|
|
949
|
+
`;
|
|
950
|
+
}
|
|
951
|
+
out += `
|
|
952
|
+
`;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return out;
|
|
956
|
+
}
|
|
957
|
+
function formatAreaContextText(result) {
|
|
958
|
+
let out = "";
|
|
959
|
+
out += `
|
|
960
|
+
`;
|
|
961
|
+
out += `\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
962
|
+
`;
|
|
963
|
+
out += `\u2551 \u{1F4E6} AREA CONTEXT \u2551
|
|
964
|
+
`;
|
|
965
|
+
out += `\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
966
|
+
|
|
967
|
+
`;
|
|
968
|
+
out += `\u{1F4E6} ${result.area.name} - Contexto Consolidado (${result.area.fileCount} arquivos)
|
|
969
|
+
`;
|
|
970
|
+
if (result.area.description) {
|
|
971
|
+
out += ` ${result.area.description}
|
|
972
|
+
`;
|
|
973
|
+
}
|
|
974
|
+
out += `
|
|
975
|
+
`;
|
|
976
|
+
out += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
977
|
+
|
|
978
|
+
`;
|
|
979
|
+
if (result.types.length > 0) {
|
|
980
|
+
out += `\u{1F3F7}\uFE0F TYPES (${result.types.length})
|
|
981
|
+
|
|
982
|
+
`;
|
|
983
|
+
for (const t of result.types) {
|
|
984
|
+
const filePart = t.file.split("/").pop() || t.file;
|
|
985
|
+
out += ` ${t.name}`.padEnd(45) + `[${filePart}:${t.line}]
|
|
986
|
+
`;
|
|
987
|
+
out += ` ${t.definition}
|
|
988
|
+
|
|
989
|
+
`;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
if (result.hooks.length > 0) {
|
|
993
|
+
out += `\u{1FA9D} HOOKS (${result.hooks.length})
|
|
994
|
+
|
|
995
|
+
`;
|
|
996
|
+
for (const h of result.hooks) {
|
|
997
|
+
const filePart = h.file.split("/").pop() || h.file;
|
|
998
|
+
const params = h.params.length > 0 ? h.params.join(", ") : "";
|
|
999
|
+
out += ` ${h.name}(${params})`.padEnd(45) + `[${filePart}:${h.line}]
|
|
1000
|
+
`;
|
|
1001
|
+
out += ` \u2192 ${h.returns}
|
|
1002
|
+
|
|
1003
|
+
`;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
if (result.functions.length > 0) {
|
|
1007
|
+
out += `\u26A1 FUNCTIONS (${result.functions.length})
|
|
1008
|
+
|
|
1009
|
+
`;
|
|
1010
|
+
for (const f of result.functions) {
|
|
1011
|
+
const filePart = f.file.split("/").pop() || f.file;
|
|
1012
|
+
const params = f.params.length > 0 ? f.params.join(", ") : "";
|
|
1013
|
+
out += ` ${f.name}(${params})`.padEnd(45) + `[${filePart}:${f.line}]
|
|
1014
|
+
`;
|
|
1015
|
+
out += ` \u2192 ${f.returns}
|
|
1016
|
+
|
|
1017
|
+
`;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (result.components.length > 0) {
|
|
1021
|
+
out += `\u{1F9E9} COMPONENTS (${result.components.length})
|
|
1022
|
+
|
|
1023
|
+
`;
|
|
1024
|
+
for (const c of result.components) {
|
|
1025
|
+
const filePart = c.file.split("/").pop() || c.file;
|
|
1026
|
+
out += ` ${c.name}`.padEnd(45) + `[${filePart}:${c.line}]
|
|
1027
|
+
`;
|
|
1028
|
+
if (c.props) {
|
|
1029
|
+
out += ` props: ${c.props}
|
|
1030
|
+
`;
|
|
1031
|
+
}
|
|
1032
|
+
out += `
|
|
1033
|
+
`;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (result.services.length > 0) {
|
|
1037
|
+
out += `\u{1F527} SERVICES (${result.services.length})
|
|
1038
|
+
|
|
1039
|
+
`;
|
|
1040
|
+
for (const s of result.services) {
|
|
1041
|
+
const filePart = s.file.split("/").pop() || s.file;
|
|
1042
|
+
const params = s.params.length > 0 ? s.params.join(", ") : "";
|
|
1043
|
+
out += ` ${s.name}(${params})`.padEnd(45) + `[${filePart}:${s.line}]
|
|
1044
|
+
`;
|
|
1045
|
+
out += ` \u2192 ${s.returns}
|
|
1046
|
+
|
|
1047
|
+
`;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (result.stores.length > 0) {
|
|
1051
|
+
out += `\u{1F5C3}\uFE0F STORES (${result.stores.length})
|
|
1052
|
+
|
|
1053
|
+
`;
|
|
1054
|
+
for (const st of result.stores) {
|
|
1055
|
+
const filePart = st.file.split("/").pop() || st.file;
|
|
1056
|
+
out += ` ${st.name}`.padEnd(45) + `[${filePart}:${st.line}]
|
|
1057
|
+
`;
|
|
1058
|
+
out += ` state: ${st.state}
|
|
1059
|
+
|
|
1060
|
+
`;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
out += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1064
|
+
|
|
1065
|
+
`;
|
|
1066
|
+
out += `\u{1F4CA} RESUMO
|
|
1067
|
+
`;
|
|
1068
|
+
out += ` Types: ${result.types.length}
|
|
1069
|
+
`;
|
|
1070
|
+
out += ` Hooks: ${result.hooks.length}
|
|
1071
|
+
`;
|
|
1072
|
+
out += ` Functions: ${result.functions.length}
|
|
1073
|
+
`;
|
|
1074
|
+
out += ` Components: ${result.components.length}
|
|
1075
|
+
`;
|
|
1076
|
+
out += ` Services: ${result.services.length}
|
|
1077
|
+
`;
|
|
1078
|
+
out += ` Stores: ${result.stores.length}
|
|
1079
|
+
`;
|
|
1080
|
+
return out;
|
|
1081
|
+
}
|
|
861
1082
|
|
|
862
1083
|
// src/cache/index.ts
|
|
863
|
-
import {
|
|
1084
|
+
import {
|
|
1085
|
+
existsSync as existsSync2,
|
|
1086
|
+
mkdirSync,
|
|
1087
|
+
readFileSync as readFileSync2,
|
|
1088
|
+
writeFileSync,
|
|
1089
|
+
statSync,
|
|
1090
|
+
readdirSync
|
|
1091
|
+
} from "fs";
|
|
864
1092
|
import { join as join2, extname } from "path";
|
|
865
1093
|
|
|
866
1094
|
// src/utils/firebase.ts
|
|
@@ -957,6 +1185,7 @@ var META_FILE = "meta.json";
|
|
|
957
1185
|
var GRAPH_FILE = "graph.json";
|
|
958
1186
|
var MAP_FILE = "map.json";
|
|
959
1187
|
var DEAD_FILE = "dead.json";
|
|
1188
|
+
var SYMBOLS_FILE = "symbols.json";
|
|
960
1189
|
function calculateFilesHash(cwd) {
|
|
961
1190
|
const extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
962
1191
|
const timestamps = [];
|
|
@@ -985,6 +1214,14 @@ function calculateFilesHash(cwd) {
|
|
|
985
1214
|
}
|
|
986
1215
|
}
|
|
987
1216
|
scanDir(cwd);
|
|
1217
|
+
try {
|
|
1218
|
+
const configPath = join2(cwd, CACHE_DIR, "areas.config.json");
|
|
1219
|
+
if (existsSync2(configPath)) {
|
|
1220
|
+
const stat = statSync(configPath);
|
|
1221
|
+
timestamps.push(stat.mtimeMs);
|
|
1222
|
+
}
|
|
1223
|
+
} catch {
|
|
1224
|
+
}
|
|
988
1225
|
const sum = timestamps.reduce((a, b) => a + b, 0);
|
|
989
1226
|
return `${timestamps.length}-${Math.floor(sum)}`;
|
|
990
1227
|
}
|
|
@@ -1071,6 +1308,16 @@ function invalidateCache(cwd) {
|
|
|
1071
1308
|
}
|
|
1072
1309
|
}
|
|
1073
1310
|
}
|
|
1311
|
+
function cacheSymbolsIndex(cwd, index) {
|
|
1312
|
+
writeCache(cwd, SYMBOLS_FILE, index);
|
|
1313
|
+
updateCacheMeta(cwd);
|
|
1314
|
+
}
|
|
1315
|
+
function getCachedSymbolsIndex(cwd) {
|
|
1316
|
+
if (!isCacheValid(cwd)) {
|
|
1317
|
+
return null;
|
|
1318
|
+
}
|
|
1319
|
+
return readCache(cwd, SYMBOLS_FILE);
|
|
1320
|
+
}
|
|
1074
1321
|
|
|
1075
1322
|
// src/areas/config.ts
|
|
1076
1323
|
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
@@ -2564,8 +2811,8 @@ function formatNotFound2(target, allFiles) {
|
|
|
2564
2811
|
}
|
|
2565
2812
|
|
|
2566
2813
|
// src/commands/context.ts
|
|
2567
|
-
import { existsSync as existsSync4, readdirSync as
|
|
2568
|
-
import { join as
|
|
2814
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
|
|
2815
|
+
import { join as join5, resolve as resolve2, basename, extname as extname3 } from "path";
|
|
2569
2816
|
|
|
2570
2817
|
// src/ts/extractor.ts
|
|
2571
2818
|
import { Project, SyntaxKind } from "ts-morph";
|
|
@@ -2771,6 +3018,307 @@ function extractExports(sourceFile) {
|
|
|
2771
3018
|
return [...new Set(exports)];
|
|
2772
3019
|
}
|
|
2773
3020
|
|
|
3021
|
+
// src/ts/indexer.ts
|
|
3022
|
+
import { readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
3023
|
+
import { join as join4, extname as extname2, resolve } from "path";
|
|
3024
|
+
import { Project as Project2, SyntaxKind as SyntaxKind2 } from "ts-morph";
|
|
3025
|
+
var CODE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
3026
|
+
var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
3027
|
+
"node_modules",
|
|
3028
|
+
"dist",
|
|
3029
|
+
"build",
|
|
3030
|
+
".git",
|
|
3031
|
+
".next",
|
|
3032
|
+
".cache",
|
|
3033
|
+
"coverage",
|
|
3034
|
+
".turbo",
|
|
3035
|
+
".vercel",
|
|
3036
|
+
".analyze"
|
|
3037
|
+
]);
|
|
3038
|
+
function indexProject(cwd) {
|
|
3039
|
+
const allFiles = getAllCodeFiles(cwd);
|
|
3040
|
+
const project = createProject2(cwd);
|
|
3041
|
+
for (const file of allFiles) {
|
|
3042
|
+
try {
|
|
3043
|
+
project.addSourceFileAtPath(resolve(cwd, file));
|
|
3044
|
+
} catch {
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
const files = {};
|
|
3048
|
+
const symbolsByName = {};
|
|
3049
|
+
let symbolCount = 0;
|
|
3050
|
+
for (const sourceFile of project.getSourceFiles()) {
|
|
3051
|
+
let filePath = sourceFile.getFilePath().replace(/\\/g, "/");
|
|
3052
|
+
const cwdNormalized = cwd.replace(/\\/g, "/");
|
|
3053
|
+
if (filePath.startsWith(cwdNormalized + "/")) {
|
|
3054
|
+
filePath = filePath.slice(cwdNormalized.length + 1);
|
|
3055
|
+
} else if (filePath.startsWith(cwdNormalized)) {
|
|
3056
|
+
filePath = filePath.slice(cwdNormalized.length);
|
|
3057
|
+
}
|
|
3058
|
+
if (filePath.includes("node_modules")) continue;
|
|
3059
|
+
const category = detectCategory(filePath);
|
|
3060
|
+
const symbols = [];
|
|
3061
|
+
const imports = [];
|
|
3062
|
+
const exports = [];
|
|
3063
|
+
for (const importDecl of sourceFile.getImportDeclarations()) {
|
|
3064
|
+
const specifiers = [];
|
|
3065
|
+
const defaultImport = importDecl.getDefaultImport();
|
|
3066
|
+
if (defaultImport) {
|
|
3067
|
+
specifiers.push(defaultImport.getText());
|
|
3068
|
+
}
|
|
3069
|
+
for (const namedImport of importDecl.getNamedImports()) {
|
|
3070
|
+
specifiers.push(namedImport.getName());
|
|
3071
|
+
}
|
|
3072
|
+
const namespaceImport = importDecl.getNamespaceImport();
|
|
3073
|
+
if (namespaceImport) {
|
|
3074
|
+
specifiers.push(`* as ${namespaceImport.getText()}`);
|
|
3075
|
+
}
|
|
3076
|
+
imports.push({
|
|
3077
|
+
source: importDecl.getModuleSpecifierValue(),
|
|
3078
|
+
specifiers,
|
|
3079
|
+
isTypeOnly: importDecl.isTypeOnly()
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
for (const func of sourceFile.getFunctions()) {
|
|
3083
|
+
const name = func.getName();
|
|
3084
|
+
if (!name) continue;
|
|
3085
|
+
const isExported = func.isExported();
|
|
3086
|
+
const params = func.getParameters().map((p) => p.getName());
|
|
3087
|
+
const returnType = simplifyType2(func.getReturnType().getText());
|
|
3088
|
+
const kind = inferSymbolKind(name, "function");
|
|
3089
|
+
const symbol = {
|
|
3090
|
+
name,
|
|
3091
|
+
file: filePath,
|
|
3092
|
+
line: func.getStartLineNumber(),
|
|
3093
|
+
kind,
|
|
3094
|
+
signature: `${isExported ? "export " : ""}${func.isAsync() ? "async " : ""}function ${name}(${params.join(", ")})`,
|
|
3095
|
+
isExported,
|
|
3096
|
+
params,
|
|
3097
|
+
returnType
|
|
3098
|
+
};
|
|
3099
|
+
symbols.push(symbol);
|
|
3100
|
+
if (!symbolsByName[name]) {
|
|
3101
|
+
symbolsByName[name] = [];
|
|
3102
|
+
}
|
|
3103
|
+
symbolsByName[name].push(symbol);
|
|
3104
|
+
if (isExported) {
|
|
3105
|
+
exports.push(name);
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
for (const varStatement of sourceFile.getVariableStatements()) {
|
|
3109
|
+
const isExported = varStatement.isExported();
|
|
3110
|
+
for (const varDecl of varStatement.getDeclarations()) {
|
|
3111
|
+
const name = varDecl.getName();
|
|
3112
|
+
const init = varDecl.getInitializer();
|
|
3113
|
+
if (!init) continue;
|
|
3114
|
+
const initKind = init.getKind();
|
|
3115
|
+
if (initKind === SyntaxKind2.ArrowFunction || initKind === SyntaxKind2.FunctionExpression) {
|
|
3116
|
+
const funcLike = init.asKind(SyntaxKind2.ArrowFunction) || init.asKind(SyntaxKind2.FunctionExpression);
|
|
3117
|
+
if (!funcLike) continue;
|
|
3118
|
+
const params = funcLike.getParameters().map((p) => p.getName());
|
|
3119
|
+
const returnType = simplifyType2(funcLike.getReturnType().getText());
|
|
3120
|
+
const kind = inferSymbolKind(name, "function");
|
|
3121
|
+
const symbol = {
|
|
3122
|
+
name,
|
|
3123
|
+
file: filePath,
|
|
3124
|
+
line: varDecl.getStartLineNumber(),
|
|
3125
|
+
kind,
|
|
3126
|
+
signature: `${isExported ? "export " : ""}const ${name} = (${params.join(", ")}) => ...`,
|
|
3127
|
+
isExported,
|
|
3128
|
+
params,
|
|
3129
|
+
returnType
|
|
3130
|
+
};
|
|
3131
|
+
symbols.push(symbol);
|
|
3132
|
+
if (!symbolsByName[name]) {
|
|
3133
|
+
symbolsByName[name] = [];
|
|
3134
|
+
}
|
|
3135
|
+
symbolsByName[name].push(symbol);
|
|
3136
|
+
if (isExported) {
|
|
3137
|
+
exports.push(name);
|
|
3138
|
+
}
|
|
3139
|
+
} else {
|
|
3140
|
+
const declKind = varStatement.getDeclarationKind();
|
|
3141
|
+
if (declKind.toString() !== "const") continue;
|
|
3142
|
+
const symbol = {
|
|
3143
|
+
name,
|
|
3144
|
+
file: filePath,
|
|
3145
|
+
line: varDecl.getStartLineNumber(),
|
|
3146
|
+
kind: "const",
|
|
3147
|
+
signature: `${isExported ? "export " : ""}const ${name} = ${truncateCode(init.getText(), 40)}`,
|
|
3148
|
+
isExported
|
|
3149
|
+
};
|
|
3150
|
+
symbols.push(symbol);
|
|
3151
|
+
if (!symbolsByName[name]) {
|
|
3152
|
+
symbolsByName[name] = [];
|
|
3153
|
+
}
|
|
3154
|
+
symbolsByName[name].push(symbol);
|
|
3155
|
+
if (isExported) {
|
|
3156
|
+
exports.push(name);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
for (const iface of sourceFile.getInterfaces()) {
|
|
3162
|
+
const name = iface.getName();
|
|
3163
|
+
const isExported = iface.isExported();
|
|
3164
|
+
const symbol = {
|
|
3165
|
+
name,
|
|
3166
|
+
file: filePath,
|
|
3167
|
+
line: iface.getStartLineNumber(),
|
|
3168
|
+
kind: "interface",
|
|
3169
|
+
signature: `${isExported ? "export " : ""}interface ${name}`,
|
|
3170
|
+
isExported,
|
|
3171
|
+
definition: formatInterfaceDefinition2(iface)
|
|
3172
|
+
};
|
|
3173
|
+
symbols.push(symbol);
|
|
3174
|
+
if (!symbolsByName[name]) {
|
|
3175
|
+
symbolsByName[name] = [];
|
|
3176
|
+
}
|
|
3177
|
+
symbolsByName[name].push(symbol);
|
|
3178
|
+
if (isExported) {
|
|
3179
|
+
exports.push(name);
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
for (const typeAlias of sourceFile.getTypeAliases()) {
|
|
3183
|
+
const name = typeAlias.getName();
|
|
3184
|
+
const isExported = typeAlias.isExported();
|
|
3185
|
+
const symbol = {
|
|
3186
|
+
name,
|
|
3187
|
+
file: filePath,
|
|
3188
|
+
line: typeAlias.getStartLineNumber(),
|
|
3189
|
+
kind: "type",
|
|
3190
|
+
signature: `${isExported ? "export " : ""}type ${name}`,
|
|
3191
|
+
isExported,
|
|
3192
|
+
definition: simplifyType2(typeAlias.getType().getText())
|
|
3193
|
+
};
|
|
3194
|
+
symbols.push(symbol);
|
|
3195
|
+
if (!symbolsByName[name]) {
|
|
3196
|
+
symbolsByName[name] = [];
|
|
3197
|
+
}
|
|
3198
|
+
symbolsByName[name].push(symbol);
|
|
3199
|
+
if (isExported) {
|
|
3200
|
+
exports.push(name);
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
for (const enumDecl of sourceFile.getEnums()) {
|
|
3204
|
+
const name = enumDecl.getName();
|
|
3205
|
+
const isExported = enumDecl.isExported();
|
|
3206
|
+
const symbol = {
|
|
3207
|
+
name,
|
|
3208
|
+
file: filePath,
|
|
3209
|
+
line: enumDecl.getStartLineNumber(),
|
|
3210
|
+
kind: "enum",
|
|
3211
|
+
signature: `${isExported ? "export " : ""}enum ${name}`,
|
|
3212
|
+
isExported,
|
|
3213
|
+
definition: enumDecl.getMembers().map((m) => m.getName()).join(" | ")
|
|
3214
|
+
};
|
|
3215
|
+
symbols.push(symbol);
|
|
3216
|
+
if (!symbolsByName[name]) {
|
|
3217
|
+
symbolsByName[name] = [];
|
|
3218
|
+
}
|
|
3219
|
+
symbolsByName[name].push(symbol);
|
|
3220
|
+
if (isExported) {
|
|
3221
|
+
exports.push(name);
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
symbolCount += symbols.length;
|
|
3225
|
+
files[filePath] = {
|
|
3226
|
+
path: filePath,
|
|
3227
|
+
category,
|
|
3228
|
+
symbols,
|
|
3229
|
+
imports,
|
|
3230
|
+
exports
|
|
3231
|
+
};
|
|
3232
|
+
}
|
|
3233
|
+
return {
|
|
3234
|
+
version: "1.0.0",
|
|
3235
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3236
|
+
files,
|
|
3237
|
+
symbolsByName,
|
|
3238
|
+
fileCount: Object.keys(files).length,
|
|
3239
|
+
symbolCount
|
|
3240
|
+
};
|
|
3241
|
+
}
|
|
3242
|
+
function createProject2(cwd) {
|
|
3243
|
+
try {
|
|
3244
|
+
return new Project2({
|
|
3245
|
+
tsConfigFilePath: `${cwd}/tsconfig.json`,
|
|
3246
|
+
skipAddingFilesFromTsConfig: true
|
|
3247
|
+
});
|
|
3248
|
+
} catch {
|
|
3249
|
+
return new Project2({
|
|
3250
|
+
skipAddingFilesFromTsConfig: true,
|
|
3251
|
+
compilerOptions: {
|
|
3252
|
+
allowJs: true,
|
|
3253
|
+
checkJs: false
|
|
3254
|
+
}
|
|
3255
|
+
});
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
function getAllCodeFiles(dir, files = [], baseDir = dir) {
|
|
3259
|
+
try {
|
|
3260
|
+
const entries = readdirSync2(dir);
|
|
3261
|
+
for (const entry of entries) {
|
|
3262
|
+
const fullPath = join4(dir, entry);
|
|
3263
|
+
if (IGNORED_DIRS.has(entry) || entry.startsWith(".")) {
|
|
3264
|
+
continue;
|
|
3265
|
+
}
|
|
3266
|
+
try {
|
|
3267
|
+
const stat = statSync2(fullPath);
|
|
3268
|
+
if (stat.isDirectory()) {
|
|
3269
|
+
getAllCodeFiles(fullPath, files, baseDir);
|
|
3270
|
+
} else {
|
|
3271
|
+
const ext = extname2(entry).toLowerCase();
|
|
3272
|
+
if (CODE_EXTENSIONS2.has(ext)) {
|
|
3273
|
+
const relativePath = fullPath.slice(baseDir.length + 1).replace(/\\/g, "/");
|
|
3274
|
+
files.push(relativePath);
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
} catch {
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
} catch {
|
|
3281
|
+
}
|
|
3282
|
+
return files;
|
|
3283
|
+
}
|
|
3284
|
+
function inferSymbolKind(name, context2) {
|
|
3285
|
+
if (name.startsWith("use") && name.length > 3 && name[3] === name[3].toUpperCase()) {
|
|
3286
|
+
return "hook";
|
|
3287
|
+
}
|
|
3288
|
+
if (context2 === "function" && name[0] === name[0].toUpperCase() && !name.includes("_")) {
|
|
3289
|
+
return "component";
|
|
3290
|
+
}
|
|
3291
|
+
return context2 === "function" ? "function" : "const";
|
|
3292
|
+
}
|
|
3293
|
+
function simplifyType2(typeText) {
|
|
3294
|
+
let simplified = typeText.replace(/import\([^)]+\)\./g, "");
|
|
3295
|
+
if (simplified.length > 80) {
|
|
3296
|
+
simplified = simplified.slice(0, 77) + "...";
|
|
3297
|
+
}
|
|
3298
|
+
return simplified;
|
|
3299
|
+
}
|
|
3300
|
+
function truncateCode(code, maxLen) {
|
|
3301
|
+
const oneLine = code.replace(/\s+/g, " ").trim();
|
|
3302
|
+
if (oneLine.length <= maxLen) return oneLine;
|
|
3303
|
+
return oneLine.slice(0, maxLen - 3) + "...";
|
|
3304
|
+
}
|
|
3305
|
+
function formatInterfaceDefinition2(iface) {
|
|
3306
|
+
const parts = [];
|
|
3307
|
+
const extendsClauses = iface.getExtends();
|
|
3308
|
+
if (extendsClauses.length > 0) {
|
|
3309
|
+
parts.push(`extends ${extendsClauses.map((e) => e.getText()).join(", ")}`);
|
|
3310
|
+
}
|
|
3311
|
+
const props = iface.getProperties();
|
|
3312
|
+
for (const prop of props.slice(0, 10)) {
|
|
3313
|
+
const propType = simplifyType2(prop.getType().getText());
|
|
3314
|
+
parts.push(`${prop.getName()}: ${propType}`);
|
|
3315
|
+
}
|
|
3316
|
+
if (props.length > 10) {
|
|
3317
|
+
parts.push(`... +${props.length - 10} props`);
|
|
3318
|
+
}
|
|
3319
|
+
return parts.length > 0 ? `{ ${parts.join("; ")} }` : "{}";
|
|
3320
|
+
}
|
|
3321
|
+
|
|
2774
3322
|
// src/commands/context.ts
|
|
2775
3323
|
async function context(target, options = {}) {
|
|
2776
3324
|
const cwd = options.cwd || process.cwd();
|
|
@@ -2784,7 +3332,7 @@ async function context(target, options = {}) {
|
|
|
2784
3332
|
return formatNotFound3(target, cwd);
|
|
2785
3333
|
}
|
|
2786
3334
|
const project = createProject(cwd);
|
|
2787
|
-
const absolutePath =
|
|
3335
|
+
const absolutePath = resolve2(cwd, targetPath);
|
|
2788
3336
|
const sourceFile = addSourceFile(project, absolutePath);
|
|
2789
3337
|
const imports = extractImports(sourceFile);
|
|
2790
3338
|
const functions = extractFunctions(sourceFile);
|
|
@@ -2809,14 +3357,14 @@ async function context(target, options = {}) {
|
|
|
2809
3357
|
throw new Error(`Erro ao executar context: ${message}`);
|
|
2810
3358
|
}
|
|
2811
3359
|
}
|
|
2812
|
-
var
|
|
3360
|
+
var CODE_EXTENSIONS3 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
2813
3361
|
function findTargetFile3(target, cwd) {
|
|
2814
3362
|
const normalizedTarget = target.replace(/\\/g, "/");
|
|
2815
|
-
const directPath =
|
|
3363
|
+
const directPath = resolve2(cwd, normalizedTarget);
|
|
2816
3364
|
if (existsSync4(directPath) && isCodeFile2(directPath)) {
|
|
2817
3365
|
return normalizedTarget;
|
|
2818
3366
|
}
|
|
2819
|
-
for (const ext of
|
|
3367
|
+
for (const ext of CODE_EXTENSIONS3) {
|
|
2820
3368
|
const withExt = directPath + ext;
|
|
2821
3369
|
if (existsSync4(withExt)) {
|
|
2822
3370
|
return normalizedTarget + ext;
|
|
@@ -2824,7 +3372,7 @@ function findTargetFile3(target, cwd) {
|
|
|
2824
3372
|
}
|
|
2825
3373
|
const targetName = basename(normalizedTarget).toLowerCase();
|
|
2826
3374
|
const targetNameNoExt = targetName.replace(/\.(tsx?|jsx?|mjs|cjs)$/, "");
|
|
2827
|
-
const allFiles =
|
|
3375
|
+
const allFiles = getAllCodeFiles2(cwd);
|
|
2828
3376
|
const matches = [];
|
|
2829
3377
|
for (const file of allFiles) {
|
|
2830
3378
|
const fileName = basename(file).toLowerCase();
|
|
@@ -2841,21 +3389,21 @@ function findTargetFile3(target, cwd) {
|
|
|
2841
3389
|
return null;
|
|
2842
3390
|
}
|
|
2843
3391
|
function isCodeFile2(filePath) {
|
|
2844
|
-
const ext =
|
|
2845
|
-
return
|
|
3392
|
+
const ext = extname3(filePath);
|
|
3393
|
+
return CODE_EXTENSIONS3.has(ext);
|
|
2846
3394
|
}
|
|
2847
|
-
function
|
|
3395
|
+
function getAllCodeFiles2(dir, files = [], baseDir = dir) {
|
|
2848
3396
|
try {
|
|
2849
|
-
const entries =
|
|
3397
|
+
const entries = readdirSync3(dir);
|
|
2850
3398
|
for (const entry of entries) {
|
|
2851
|
-
const fullPath =
|
|
3399
|
+
const fullPath = join5(dir, entry);
|
|
2852
3400
|
if (shouldIgnore(entry)) {
|
|
2853
3401
|
continue;
|
|
2854
3402
|
}
|
|
2855
3403
|
try {
|
|
2856
|
-
const stat =
|
|
3404
|
+
const stat = statSync3(fullPath);
|
|
2857
3405
|
if (stat.isDirectory()) {
|
|
2858
|
-
|
|
3406
|
+
getAllCodeFiles2(fullPath, files, baseDir);
|
|
2859
3407
|
} else if (isCodeFile2(entry)) {
|
|
2860
3408
|
const relativePath = fullPath.slice(baseDir.length + 1).replace(/\\/g, "/");
|
|
2861
3409
|
files.push(relativePath);
|
|
@@ -2882,15 +3430,174 @@ function shouldIgnore(name) {
|
|
|
2882
3430
|
return ignoredDirs.includes(name) || name.startsWith(".");
|
|
2883
3431
|
}
|
|
2884
3432
|
function formatNotFound3(target, cwd) {
|
|
2885
|
-
const allFiles =
|
|
3433
|
+
const allFiles = getAllCodeFiles2(cwd);
|
|
2886
3434
|
return formatFileNotFound({ target, allFiles, command: "context" });
|
|
2887
3435
|
}
|
|
3436
|
+
async function areaContext(areaName, options = {}) {
|
|
3437
|
+
const cwd = options.cwd || process.cwd();
|
|
3438
|
+
const format = options.format || "text";
|
|
3439
|
+
const useCache = options.cache !== false;
|
|
3440
|
+
if (!areaName) {
|
|
3441
|
+
throw new Error("Nome da \xE1rea \xE9 obrigat\xF3rio. Exemplo: ai-tool context --area=auth");
|
|
3442
|
+
}
|
|
3443
|
+
try {
|
|
3444
|
+
const config = readConfig(cwd);
|
|
3445
|
+
let index;
|
|
3446
|
+
if (useCache && isCacheValid(cwd)) {
|
|
3447
|
+
const cached = getCachedSymbolsIndex(cwd);
|
|
3448
|
+
if (cached && cached.files) {
|
|
3449
|
+
index = cached;
|
|
3450
|
+
} else {
|
|
3451
|
+
index = indexProject(cwd);
|
|
3452
|
+
cacheSymbolsIndex(cwd, index);
|
|
3453
|
+
updateCacheMeta(cwd);
|
|
3454
|
+
}
|
|
3455
|
+
} else {
|
|
3456
|
+
index = indexProject(cwd);
|
|
3457
|
+
if (useCache) {
|
|
3458
|
+
cacheSymbolsIndex(cwd, index);
|
|
3459
|
+
updateCacheMeta(cwd);
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
const areaLower = areaName.toLowerCase();
|
|
3463
|
+
const areaFiles = [];
|
|
3464
|
+
for (const filePath of Object.keys(index.files)) {
|
|
3465
|
+
if (isFileIgnored(filePath, config)) continue;
|
|
3466
|
+
const fileAreas = detectFileAreas(filePath, config);
|
|
3467
|
+
const belongsToArea = fileAreas.some(
|
|
3468
|
+
(a) => a.toLowerCase() === areaLower || a.toLowerCase().includes(areaLower)
|
|
3469
|
+
);
|
|
3470
|
+
if (belongsToArea) {
|
|
3471
|
+
areaFiles.push(filePath);
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
if (areaFiles.length === 0) {
|
|
3475
|
+
return format === "json" ? JSON.stringify({ error: `\xC1rea n\xE3o encontrada: "${areaName}"` }) : `\u274C \xC1rea n\xE3o encontrada: "${areaName}"
|
|
3476
|
+
|
|
3477
|
+
\u{1F4A1} Use 'ai-tool areas' para listar \xE1reas dispon\xEDveis`;
|
|
3478
|
+
}
|
|
3479
|
+
const types = [];
|
|
3480
|
+
const hooks = [];
|
|
3481
|
+
const functions = [];
|
|
3482
|
+
const components = [];
|
|
3483
|
+
const services = [];
|
|
3484
|
+
const stores = [];
|
|
3485
|
+
for (const filePath of areaFiles) {
|
|
3486
|
+
const fileData = index.files[filePath];
|
|
3487
|
+
if (!fileData) continue;
|
|
3488
|
+
const category = fileData.category;
|
|
3489
|
+
for (const symbol of fileData.symbols) {
|
|
3490
|
+
if (!symbol.isExported) continue;
|
|
3491
|
+
switch (symbol.kind) {
|
|
3492
|
+
case "type":
|
|
3493
|
+
case "interface":
|
|
3494
|
+
case "enum":
|
|
3495
|
+
types.push({
|
|
3496
|
+
name: symbol.name,
|
|
3497
|
+
file: filePath,
|
|
3498
|
+
line: symbol.line,
|
|
3499
|
+
definition: symbol.definition || symbol.signature
|
|
3500
|
+
});
|
|
3501
|
+
break;
|
|
3502
|
+
case "hook":
|
|
3503
|
+
hooks.push({
|
|
3504
|
+
name: symbol.name,
|
|
3505
|
+
file: filePath,
|
|
3506
|
+
line: symbol.line,
|
|
3507
|
+
params: symbol.params || [],
|
|
3508
|
+
returns: symbol.returnType || "unknown"
|
|
3509
|
+
});
|
|
3510
|
+
break;
|
|
3511
|
+
case "component":
|
|
3512
|
+
components.push({
|
|
3513
|
+
name: symbol.name,
|
|
3514
|
+
file: filePath,
|
|
3515
|
+
line: symbol.line,
|
|
3516
|
+
props: symbol.params?.join(", ")
|
|
3517
|
+
});
|
|
3518
|
+
break;
|
|
3519
|
+
case "function":
|
|
3520
|
+
if (category === "service" || filePath.includes("service")) {
|
|
3521
|
+
services.push({
|
|
3522
|
+
name: symbol.name,
|
|
3523
|
+
file: filePath,
|
|
3524
|
+
line: symbol.line,
|
|
3525
|
+
params: symbol.params || [],
|
|
3526
|
+
returns: symbol.returnType || "unknown"
|
|
3527
|
+
});
|
|
3528
|
+
} else {
|
|
3529
|
+
functions.push({
|
|
3530
|
+
name: symbol.name,
|
|
3531
|
+
file: filePath,
|
|
3532
|
+
line: symbol.line,
|
|
3533
|
+
params: symbol.params || [],
|
|
3534
|
+
returns: symbol.returnType || "unknown"
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3537
|
+
break;
|
|
3538
|
+
case "const":
|
|
3539
|
+
if ((category === "store" || filePath.includes("store")) && symbol.name.startsWith("use")) {
|
|
3540
|
+
stores.push({
|
|
3541
|
+
name: symbol.name,
|
|
3542
|
+
file: filePath,
|
|
3543
|
+
line: symbol.line,
|
|
3544
|
+
state: symbol.definition || "unknown"
|
|
3545
|
+
});
|
|
3546
|
+
}
|
|
3547
|
+
break;
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
const realAreaId = findRealAreaIdFromIndex(areaName, areaFiles, config);
|
|
3552
|
+
const result = {
|
|
3553
|
+
version: "1.0.0",
|
|
3554
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3555
|
+
area: {
|
|
3556
|
+
id: realAreaId || areaName,
|
|
3557
|
+
name: getAreaName(realAreaId || areaName, config),
|
|
3558
|
+
description: getAreaDescription(realAreaId || areaName, config),
|
|
3559
|
+
fileCount: areaFiles.length
|
|
3560
|
+
},
|
|
3561
|
+
types,
|
|
3562
|
+
hooks,
|
|
3563
|
+
functions,
|
|
3564
|
+
components,
|
|
3565
|
+
services,
|
|
3566
|
+
stores
|
|
3567
|
+
};
|
|
3568
|
+
if (format === "json") {
|
|
3569
|
+
return JSON.stringify(result, null, 2);
|
|
3570
|
+
}
|
|
3571
|
+
return formatAreaContextText(result);
|
|
3572
|
+
} catch (error) {
|
|
3573
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3574
|
+
throw new Error(`Erro ao executar context --area: ${message}`);
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
function findRealAreaIdFromIndex(target, areaFiles, config) {
|
|
3578
|
+
const targetLower = target.toLowerCase();
|
|
3579
|
+
for (const areaId of Object.keys(config.areas)) {
|
|
3580
|
+
if (areaId.toLowerCase() === targetLower || areaId.toLowerCase().includes(targetLower)) {
|
|
3581
|
+
return areaId;
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3584
|
+
const detectedAreas = /* @__PURE__ */ new Set();
|
|
3585
|
+
for (const filePath of areaFiles) {
|
|
3586
|
+
const areas2 = detectFileAreas(filePath, config);
|
|
3587
|
+
for (const areaId of areas2) {
|
|
3588
|
+
if (areaId.toLowerCase() === targetLower || areaId.toLowerCase().includes(targetLower)) {
|
|
3589
|
+
detectedAreas.add(areaId);
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
return detectedAreas.size > 0 ? [...detectedAreas][0] : null;
|
|
3594
|
+
}
|
|
2888
3595
|
|
|
2889
3596
|
// src/commands/areas.ts
|
|
2890
|
-
import { readdirSync as
|
|
2891
|
-
import { join as
|
|
2892
|
-
var
|
|
2893
|
-
var
|
|
3597
|
+
import { readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
3598
|
+
import { join as join6, extname as extname4 } from "path";
|
|
3599
|
+
var CODE_EXTENSIONS4 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
3600
|
+
var IGNORED_DIRS2 = /* @__PURE__ */ new Set([
|
|
2894
3601
|
"node_modules",
|
|
2895
3602
|
"dist",
|
|
2896
3603
|
"build",
|
|
@@ -2907,7 +3614,7 @@ async function areas(options = {}) {
|
|
|
2907
3614
|
const format = options.format || "text";
|
|
2908
3615
|
try {
|
|
2909
3616
|
const config = readConfig(cwd);
|
|
2910
|
-
const allFiles =
|
|
3617
|
+
const allFiles = getAllCodeFiles3(cwd);
|
|
2911
3618
|
const filteredFiles = allFiles.filter((filePath) => !isFileIgnored(filePath, config));
|
|
2912
3619
|
const areaMap = /* @__PURE__ */ new Map();
|
|
2913
3620
|
const unmapped = [];
|
|
@@ -2972,21 +3679,21 @@ async function areas(options = {}) {
|
|
|
2972
3679
|
throw new Error(`Erro ao executar areas: ${message}`);
|
|
2973
3680
|
}
|
|
2974
3681
|
}
|
|
2975
|
-
function
|
|
3682
|
+
function getAllCodeFiles3(dir, files = [], baseDir = dir) {
|
|
2976
3683
|
try {
|
|
2977
|
-
const entries =
|
|
3684
|
+
const entries = readdirSync4(dir);
|
|
2978
3685
|
for (const entry of entries) {
|
|
2979
|
-
const fullPath =
|
|
2980
|
-
if (
|
|
3686
|
+
const fullPath = join6(dir, entry);
|
|
3687
|
+
if (IGNORED_DIRS2.has(entry) || entry.startsWith(".")) {
|
|
2981
3688
|
continue;
|
|
2982
3689
|
}
|
|
2983
3690
|
try {
|
|
2984
|
-
const stat =
|
|
3691
|
+
const stat = statSync4(fullPath);
|
|
2985
3692
|
if (stat.isDirectory()) {
|
|
2986
|
-
|
|
3693
|
+
getAllCodeFiles3(fullPath, files, baseDir);
|
|
2987
3694
|
} else {
|
|
2988
|
-
const ext =
|
|
2989
|
-
if (
|
|
3695
|
+
const ext = extname4(entry).toLowerCase();
|
|
3696
|
+
if (CODE_EXTENSIONS4.has(ext)) {
|
|
2990
3697
|
const relativePath = fullPath.slice(baseDir.length + 1).replace(/\\/g, "/");
|
|
2991
3698
|
files.push(relativePath);
|
|
2992
3699
|
}
|
|
@@ -3000,10 +3707,10 @@ function getAllCodeFiles2(dir, files = [], baseDir = dir) {
|
|
|
3000
3707
|
}
|
|
3001
3708
|
|
|
3002
3709
|
// src/commands/area.ts
|
|
3003
|
-
import { readdirSync as
|
|
3004
|
-
import { join as
|
|
3005
|
-
var
|
|
3006
|
-
var
|
|
3710
|
+
import { readdirSync as readdirSync5, statSync as statSync5 } from "fs";
|
|
3711
|
+
import { join as join7, extname as extname5 } from "path";
|
|
3712
|
+
var CODE_EXTENSIONS5 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
3713
|
+
var IGNORED_DIRS3 = /* @__PURE__ */ new Set([
|
|
3007
3714
|
"node_modules",
|
|
3008
3715
|
"dist",
|
|
3009
3716
|
"build",
|
|
@@ -3025,7 +3732,7 @@ async function area(target, options = {}) {
|
|
|
3025
3732
|
}
|
|
3026
3733
|
try {
|
|
3027
3734
|
const config = readConfig(cwd);
|
|
3028
|
-
const allFiles =
|
|
3735
|
+
const allFiles = getAllCodeFiles4(cwd);
|
|
3029
3736
|
const filteredFiles = allFiles.filter((filePath) => !isFileIgnored(filePath, config));
|
|
3030
3737
|
const areaFiles = [];
|
|
3031
3738
|
const targetLower = target.toLowerCase();
|
|
@@ -3122,21 +3829,21 @@ function getAvailableAreas(allFiles, config) {
|
|
|
3122
3829
|
function formatAreaNotFound2(target, availableAreas) {
|
|
3123
3830
|
return formatAreaNotFound({ target, availableAreas });
|
|
3124
3831
|
}
|
|
3125
|
-
function
|
|
3832
|
+
function getAllCodeFiles4(dir, files = [], baseDir = dir) {
|
|
3126
3833
|
try {
|
|
3127
|
-
const entries =
|
|
3834
|
+
const entries = readdirSync5(dir);
|
|
3128
3835
|
for (const entry of entries) {
|
|
3129
|
-
const fullPath =
|
|
3130
|
-
if (
|
|
3836
|
+
const fullPath = join7(dir, entry);
|
|
3837
|
+
if (IGNORED_DIRS3.has(entry) || entry.startsWith(".")) {
|
|
3131
3838
|
continue;
|
|
3132
3839
|
}
|
|
3133
3840
|
try {
|
|
3134
|
-
const stat =
|
|
3841
|
+
const stat = statSync5(fullPath);
|
|
3135
3842
|
if (stat.isDirectory()) {
|
|
3136
|
-
|
|
3843
|
+
getAllCodeFiles4(fullPath, files, baseDir);
|
|
3137
3844
|
} else {
|
|
3138
|
-
const ext =
|
|
3139
|
-
if (
|
|
3845
|
+
const ext = extname5(entry).toLowerCase();
|
|
3846
|
+
if (CODE_EXTENSIONS5.has(ext)) {
|
|
3140
3847
|
const relativePath = fullPath.slice(baseDir.length + 1).replace(/\\/g, "/");
|
|
3141
3848
|
files.push(relativePath);
|
|
3142
3849
|
}
|
|
@@ -3150,10 +3857,10 @@ function getAllCodeFiles3(dir, files = [], baseDir = dir) {
|
|
|
3150
3857
|
}
|
|
3151
3858
|
|
|
3152
3859
|
// src/commands/areas-init.ts
|
|
3153
|
-
import { readdirSync as
|
|
3154
|
-
import { join as
|
|
3155
|
-
var
|
|
3156
|
-
var
|
|
3860
|
+
import { readdirSync as readdirSync6, statSync as statSync6 } from "fs";
|
|
3861
|
+
import { join as join8, extname as extname6 } from "path";
|
|
3862
|
+
var CODE_EXTENSIONS6 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
3863
|
+
var IGNORED_DIRS4 = /* @__PURE__ */ new Set([
|
|
3157
3864
|
"node_modules",
|
|
3158
3865
|
"dist",
|
|
3159
3866
|
"build",
|
|
@@ -3179,7 +3886,7 @@ Use --force para sobrescrever:
|
|
|
3179
3886
|
Ou edite manualmente o arquivo existente.
|
|
3180
3887
|
`.trim();
|
|
3181
3888
|
}
|
|
3182
|
-
const allFiles =
|
|
3889
|
+
const allFiles = getAllCodeFiles5(cwd);
|
|
3183
3890
|
const currentConfig = readConfig(cwd);
|
|
3184
3891
|
const areaCounts = /* @__PURE__ */ new Map();
|
|
3185
3892
|
for (const filePath of allFiles) {
|
|
@@ -3278,21 +3985,21 @@ function inferPatternsFromFiles(files) {
|
|
|
3278
3985
|
}
|
|
3279
3986
|
return [...patterns].sort();
|
|
3280
3987
|
}
|
|
3281
|
-
function
|
|
3988
|
+
function getAllCodeFiles5(dir, files = [], baseDir = dir) {
|
|
3282
3989
|
try {
|
|
3283
|
-
const entries =
|
|
3990
|
+
const entries = readdirSync6(dir);
|
|
3284
3991
|
for (const entry of entries) {
|
|
3285
|
-
const fullPath =
|
|
3286
|
-
if (
|
|
3992
|
+
const fullPath = join8(dir, entry);
|
|
3993
|
+
if (IGNORED_DIRS4.has(entry) || entry.startsWith(".")) {
|
|
3287
3994
|
continue;
|
|
3288
3995
|
}
|
|
3289
3996
|
try {
|
|
3290
|
-
const stat =
|
|
3997
|
+
const stat = statSync6(fullPath);
|
|
3291
3998
|
if (stat.isDirectory()) {
|
|
3292
|
-
|
|
3999
|
+
getAllCodeFiles5(fullPath, files, baseDir);
|
|
3293
4000
|
} else {
|
|
3294
|
-
const ext =
|
|
3295
|
-
if (
|
|
4001
|
+
const ext = extname6(entry).toLowerCase();
|
|
4002
|
+
if (CODE_EXTENSIONS6.has(ext)) {
|
|
3296
4003
|
const relativePath = fullPath.slice(baseDir.length + 1).replace(/\\/g, "/");
|
|
3297
4004
|
files.push(relativePath);
|
|
3298
4005
|
}
|
|
@@ -3316,6 +4023,7 @@ export {
|
|
|
3316
4023
|
categoryIcons,
|
|
3317
4024
|
isEntryPoint,
|
|
3318
4025
|
isCodeFile,
|
|
4026
|
+
formatFindText,
|
|
3319
4027
|
isFirebaseProject,
|
|
3320
4028
|
hasFirebaseFunctions,
|
|
3321
4029
|
isExportedCloudFunction,
|
|
@@ -3323,7 +4031,10 @@ export {
|
|
|
3323
4031
|
clearFirebaseCache,
|
|
3324
4032
|
getCacheDir,
|
|
3325
4033
|
isCacheValid,
|
|
4034
|
+
updateCacheMeta,
|
|
3326
4035
|
invalidateCache,
|
|
4036
|
+
cacheSymbolsIndex,
|
|
4037
|
+
getCachedSymbolsIndex,
|
|
3327
4038
|
configExists,
|
|
3328
4039
|
readConfig,
|
|
3329
4040
|
writeConfig,
|
|
@@ -3335,6 +4046,7 @@ export {
|
|
|
3335
4046
|
KEYWORD_PATTERNS,
|
|
3336
4047
|
AREA_NAMES,
|
|
3337
4048
|
AREA_DESCRIPTIONS,
|
|
4049
|
+
isFileIgnored,
|
|
3338
4050
|
detectFileAreas,
|
|
3339
4051
|
getAreaName,
|
|
3340
4052
|
getAreaDescription,
|
|
@@ -3353,7 +4065,9 @@ export {
|
|
|
3353
4065
|
formatInvalidCommand,
|
|
3354
4066
|
impact,
|
|
3355
4067
|
suggest,
|
|
4068
|
+
indexProject,
|
|
3356
4069
|
context,
|
|
4070
|
+
areaContext,
|
|
3357
4071
|
areas,
|
|
3358
4072
|
area,
|
|
3359
4073
|
areasInit,
|