@justmpm/ai-tool 0.7.1 → 0.7.3
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.
|
@@ -1327,25 +1327,52 @@ var GRAPH_FILE = "graph.json";
|
|
|
1327
1327
|
var MAP_FILE = "map.json";
|
|
1328
1328
|
var DEAD_FILE = "dead.json";
|
|
1329
1329
|
var SYMBOLS_FILE = "symbols.json";
|
|
1330
|
+
var HASH_IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
1331
|
+
"node_modules",
|
|
1332
|
+
".git",
|
|
1333
|
+
".next",
|
|
1334
|
+
"dist",
|
|
1335
|
+
"build",
|
|
1336
|
+
".analyze",
|
|
1337
|
+
".vercel",
|
|
1338
|
+
".turbo",
|
|
1339
|
+
".cache",
|
|
1340
|
+
"coverage",
|
|
1341
|
+
"functions/lib",
|
|
1342
|
+
"lib",
|
|
1343
|
+
".output",
|
|
1344
|
+
"out",
|
|
1345
|
+
".firebase"
|
|
1346
|
+
]);
|
|
1330
1347
|
function calculateFilesHash(cwd) {
|
|
1331
|
-
const extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
1332
|
-
|
|
1333
|
-
|
|
1348
|
+
const extensions = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
1349
|
+
let hashAccumulator = 0;
|
|
1350
|
+
let fileCount = 0;
|
|
1351
|
+
let maxTimestamp = 0;
|
|
1352
|
+
const MAX_DEPTH = 6;
|
|
1353
|
+
function scanDir(dir, depth) {
|
|
1354
|
+
if (depth > MAX_DEPTH) return;
|
|
1334
1355
|
try {
|
|
1335
1356
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
1336
1357
|
for (const entry of entries) {
|
|
1358
|
+
if (entry.name.startsWith(".")) continue;
|
|
1337
1359
|
const fullPath = join2(dir, entry.name);
|
|
1338
1360
|
if (entry.isDirectory()) {
|
|
1339
|
-
if (
|
|
1340
|
-
|
|
1361
|
+
if (HASH_IGNORED_DIRS.has(entry.name)) continue;
|
|
1362
|
+
if (depth < MAX_DEPTH) {
|
|
1363
|
+
scanDir(fullPath, depth + 1);
|
|
1341
1364
|
}
|
|
1342
|
-
scanDir(fullPath);
|
|
1343
1365
|
} else if (entry.isFile()) {
|
|
1344
1366
|
const ext = extname(entry.name).toLowerCase();
|
|
1345
|
-
if (extensions.
|
|
1367
|
+
if (extensions.has(ext)) {
|
|
1346
1368
|
try {
|
|
1347
1369
|
const stat = statSync(fullPath);
|
|
1348
|
-
|
|
1370
|
+
const mtime = stat.mtimeMs;
|
|
1371
|
+
hashAccumulator ^= Math.floor(mtime);
|
|
1372
|
+
fileCount++;
|
|
1373
|
+
if (mtime > maxTimestamp) {
|
|
1374
|
+
maxTimestamp = mtime;
|
|
1375
|
+
}
|
|
1349
1376
|
} catch {
|
|
1350
1377
|
}
|
|
1351
1378
|
}
|
|
@@ -1354,17 +1381,16 @@ function calculateFilesHash(cwd) {
|
|
|
1354
1381
|
} catch {
|
|
1355
1382
|
}
|
|
1356
1383
|
}
|
|
1357
|
-
scanDir(cwd);
|
|
1384
|
+
scanDir(cwd, 0);
|
|
1358
1385
|
try {
|
|
1359
1386
|
const configPath = join2(cwd, CACHE_DIR, "areas.config.json");
|
|
1360
1387
|
if (existsSync2(configPath)) {
|
|
1361
1388
|
const stat = statSync(configPath);
|
|
1362
|
-
|
|
1389
|
+
hashAccumulator ^= Math.floor(stat.mtimeMs);
|
|
1363
1390
|
}
|
|
1364
1391
|
} catch {
|
|
1365
1392
|
}
|
|
1366
|
-
|
|
1367
|
-
return `${timestamps.length}-${Math.floor(sum)}`;
|
|
1393
|
+
return `${fileCount}-${hashAccumulator}-${maxTimestamp}`;
|
|
1368
1394
|
}
|
|
1369
1395
|
function getCacheDir(cwd) {
|
|
1370
1396
|
return join2(cwd, CACHE_DIR);
|
|
@@ -2708,27 +2734,49 @@ function findCircularFromGraph(graph) {
|
|
|
2708
2734
|
return cycles;
|
|
2709
2735
|
}
|
|
2710
2736
|
function findTargetFile(target, allFiles) {
|
|
2711
|
-
const normalizedTarget = target.replace(/\\/g, "/");
|
|
2737
|
+
const normalizedTarget = target.replace(/\\/g, "/").toLowerCase();
|
|
2712
2738
|
if (allFiles.includes(normalizedTarget)) {
|
|
2713
2739
|
return normalizedTarget;
|
|
2714
2740
|
}
|
|
2715
|
-
const
|
|
2741
|
+
const exactMatch = allFiles.find((f) => f.toLowerCase() === normalizedTarget);
|
|
2742
|
+
if (exactMatch) {
|
|
2743
|
+
return exactMatch;
|
|
2744
|
+
}
|
|
2745
|
+
const targetParts = normalizedTarget.split("/");
|
|
2746
|
+
const targetName = targetParts.pop() || "";
|
|
2716
2747
|
const targetNameNoExt = targetName.replace(/\.(tsx?|jsx?|mjs|cjs)$/, "");
|
|
2748
|
+
const targetDir = targetParts.join("/");
|
|
2717
2749
|
const matches = [];
|
|
2718
2750
|
for (const file of allFiles) {
|
|
2719
|
-
const
|
|
2751
|
+
const fileLower = file.toLowerCase();
|
|
2752
|
+
const fileParts = fileLower.split("/");
|
|
2753
|
+
const fileName = fileParts.pop() || "";
|
|
2720
2754
|
const fileNameNoExt = fileName.replace(/\.(tsx?|jsx?|mjs|cjs)$/, "");
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2755
|
+
const fileDir = fileParts.join("/");
|
|
2756
|
+
if (fileLower === normalizedTarget) {
|
|
2757
|
+
matches.push({ file, priority: 1 });
|
|
2758
|
+
} else if (fileNameNoExt === targetNameNoExt) {
|
|
2759
|
+
if (targetDir && fileDir.includes(targetDir)) {
|
|
2760
|
+
matches.push({ file, priority: 2 });
|
|
2761
|
+
} else if (targetDir && normalizedTarget.includes(fileDir)) {
|
|
2762
|
+
matches.push({ file, priority: 3 });
|
|
2763
|
+
} else {
|
|
2764
|
+
matches.push({ file, priority: 4 });
|
|
2765
|
+
}
|
|
2766
|
+
} else if (fileLower.includes(normalizedTarget)) {
|
|
2767
|
+
matches.push({ file, priority: 5 });
|
|
2725
2768
|
}
|
|
2726
2769
|
}
|
|
2727
|
-
if (matches.length ===
|
|
2728
|
-
|
|
2770
|
+
if (matches.length === 0) {
|
|
2771
|
+
for (const file of allFiles) {
|
|
2772
|
+
if (file.toLowerCase().includes(targetNameNoExt)) {
|
|
2773
|
+
matches.push({ file, priority: 6 });
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2729
2776
|
}
|
|
2730
|
-
if (matches.length >
|
|
2731
|
-
|
|
2777
|
+
if (matches.length > 0) {
|
|
2778
|
+
matches.sort((a, b) => a.priority - b.priority);
|
|
2779
|
+
return matches[0].file;
|
|
2732
2780
|
}
|
|
2733
2781
|
return null;
|
|
2734
2782
|
}
|
|
@@ -2961,27 +3009,49 @@ function findRelatedTests(targetPath, allFiles) {
|
|
|
2961
3009
|
return tests;
|
|
2962
3010
|
}
|
|
2963
3011
|
function findTargetFile2(target, allFiles) {
|
|
2964
|
-
const normalizedTarget = target.replace(/\\/g, "/");
|
|
3012
|
+
const normalizedTarget = target.replace(/\\/g, "/").toLowerCase();
|
|
2965
3013
|
if (allFiles.includes(normalizedTarget)) {
|
|
2966
3014
|
return normalizedTarget;
|
|
2967
3015
|
}
|
|
2968
|
-
const
|
|
3016
|
+
const exactMatch = allFiles.find((f) => f.toLowerCase() === normalizedTarget);
|
|
3017
|
+
if (exactMatch) {
|
|
3018
|
+
return exactMatch;
|
|
3019
|
+
}
|
|
3020
|
+
const targetParts = normalizedTarget.split("/");
|
|
3021
|
+
const targetName = targetParts.pop() || "";
|
|
2969
3022
|
const targetNameNoExt = targetName.replace(/\.(tsx?|jsx?|mjs|cjs)$/, "");
|
|
3023
|
+
const targetDir = targetParts.join("/");
|
|
2970
3024
|
const matches = [];
|
|
2971
3025
|
for (const file of allFiles) {
|
|
2972
|
-
const
|
|
3026
|
+
const fileLower = file.toLowerCase();
|
|
3027
|
+
const fileParts = fileLower.split("/");
|
|
3028
|
+
const fileName = fileParts.pop() || "";
|
|
2973
3029
|
const fileNameNoExt = fileName.replace(/\.(tsx?|jsx?|mjs|cjs)$/, "");
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
3030
|
+
const fileDir = fileParts.join("/");
|
|
3031
|
+
if (fileLower === normalizedTarget) {
|
|
3032
|
+
matches.push({ file, priority: 1 });
|
|
3033
|
+
} else if (fileNameNoExt === targetNameNoExt) {
|
|
3034
|
+
if (targetDir && fileDir.includes(targetDir)) {
|
|
3035
|
+
matches.push({ file, priority: 2 });
|
|
3036
|
+
} else if (targetDir && normalizedTarget.includes(fileDir)) {
|
|
3037
|
+
matches.push({ file, priority: 3 });
|
|
3038
|
+
} else {
|
|
3039
|
+
matches.push({ file, priority: 4 });
|
|
3040
|
+
}
|
|
3041
|
+
} else if (fileLower.includes(normalizedTarget)) {
|
|
3042
|
+
matches.push({ file, priority: 5 });
|
|
2978
3043
|
}
|
|
2979
3044
|
}
|
|
2980
|
-
if (matches.length ===
|
|
2981
|
-
|
|
3045
|
+
if (matches.length === 0) {
|
|
3046
|
+
for (const file of allFiles) {
|
|
3047
|
+
if (file.toLowerCase().includes(targetNameNoExt)) {
|
|
3048
|
+
matches.push({ file, priority: 6 });
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
2982
3051
|
}
|
|
2983
|
-
if (matches.length >
|
|
2984
|
-
|
|
3052
|
+
if (matches.length > 0) {
|
|
3053
|
+
matches.sort((a, b) => a.priority - b.priority);
|
|
3054
|
+
return matches[0].file;
|
|
2985
3055
|
}
|
|
2986
3056
|
return null;
|
|
2987
3057
|
}
|
|
@@ -3260,11 +3330,17 @@ import { join as join4, extname as extname2, resolve } from "path";
|
|
|
3260
3330
|
import { Project as Project2, SyntaxKind as SyntaxKind2 } from "ts-morph";
|
|
3261
3331
|
var CODE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
3262
3332
|
var DEBUG = process.env.DEBUG_ANALYZE === "true";
|
|
3333
|
+
var DEBUG_FUNCTIONS = process.env.DEBUG_FUNCTIONS === "true" || DEBUG;
|
|
3263
3334
|
function debugLog(...args) {
|
|
3264
3335
|
if (DEBUG) {
|
|
3265
3336
|
console.error("[analyze:debug]", ...args);
|
|
3266
3337
|
}
|
|
3267
3338
|
}
|
|
3339
|
+
function debugFunctions(...args) {
|
|
3340
|
+
if (DEBUG_FUNCTIONS) {
|
|
3341
|
+
console.error("[functions:debug]", ...args);
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3268
3344
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
3269
3345
|
"node_modules",
|
|
3270
3346
|
"dist",
|
|
@@ -3275,7 +3351,17 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
3275
3351
|
"coverage",
|
|
3276
3352
|
".turbo",
|
|
3277
3353
|
".vercel",
|
|
3278
|
-
".analyze"
|
|
3354
|
+
".analyze",
|
|
3355
|
+
// Firebase Functions output
|
|
3356
|
+
"functions/lib",
|
|
3357
|
+
"lib",
|
|
3358
|
+
// Outros outputs comuns
|
|
3359
|
+
".output",
|
|
3360
|
+
"out",
|
|
3361
|
+
".firebase",
|
|
3362
|
+
"firebase-debug.log",
|
|
3363
|
+
"firestore-debug.log",
|
|
3364
|
+
"pubsub-debug.log"
|
|
3279
3365
|
]);
|
|
3280
3366
|
var FIREBASE_V2_TRIGGERS = /* @__PURE__ */ new Set([
|
|
3281
3367
|
// HTTPS (firebase-functions/v2/https)
|
|
@@ -3339,6 +3425,8 @@ function indexProject(cwd) {
|
|
|
3339
3425
|
const functionFiles = allFiles.filter((f) => f.includes("functions/src/"));
|
|
3340
3426
|
if (functionFiles.length > 0) {
|
|
3341
3427
|
debugLog(`Encontrados ${functionFiles.length} arquivos em functions/src/:`, functionFiles);
|
|
3428
|
+
debugFunctions(`Arquivos em functions/src/:`);
|
|
3429
|
+
functionFiles.forEach((f) => debugFunctions(` - ${f}`));
|
|
3342
3430
|
}
|
|
3343
3431
|
const project = createProject2(cwd);
|
|
3344
3432
|
for (const file of allFiles) {
|
|
@@ -3441,11 +3529,14 @@ function indexProject(cwd) {
|
|
|
3441
3529
|
}
|
|
3442
3530
|
} else if (initKind === SyntaxKind2.CallExpression) {
|
|
3443
3531
|
const triggerName = extractFirebaseTriggerName(init);
|
|
3444
|
-
if (
|
|
3445
|
-
const initText = init.getText().slice(0,
|
|
3446
|
-
|
|
3532
|
+
if (filePath.includes("functions/src/")) {
|
|
3533
|
+
const initText = init.getText().slice(0, 80).replace(/\s+/g, " ");
|
|
3534
|
+
debugFunctions(`Analisando: ${filePath}:${varDecl.getStartLineNumber()} - ${name} = ${initText}...`);
|
|
3447
3535
|
if (triggerName) {
|
|
3448
|
-
|
|
3536
|
+
debugFunctions(` \u2713 Trigger detectado: ${triggerName}`);
|
|
3537
|
+
} else {
|
|
3538
|
+
const allText = init.getText().slice(0, 100);
|
|
3539
|
+
debugFunctions(` \u2717 N\xE3o \xE9 trigger. Texto: ${allText}...`);
|
|
3449
3540
|
}
|
|
3450
3541
|
}
|
|
3451
3542
|
if (triggerName && FIREBASE_V2_TRIGGERS.has(triggerName)) {
|
|
@@ -4545,11 +4636,15 @@ async function functions(options = {}) {
|
|
|
4545
4636
|
updateCacheMeta(cwd);
|
|
4546
4637
|
}
|
|
4547
4638
|
}
|
|
4639
|
+
const functionFiles = Object.values(index.files).filter((f) => f.path.includes("functions/src/"));
|
|
4548
4640
|
const funcs = [];
|
|
4549
|
-
|
|
4550
|
-
|
|
4641
|
+
let totalSymbolsInFunctions = 0;
|
|
4642
|
+
let triggerSymbolsFound = 0;
|
|
4643
|
+
for (const fileData of functionFiles) {
|
|
4644
|
+
totalSymbolsInFunctions += fileData.symbols.length;
|
|
4551
4645
|
for (const symbol of fileData.symbols) {
|
|
4552
4646
|
if (symbol.kind === "trigger") {
|
|
4647
|
+
triggerSymbolsFound++;
|
|
4553
4648
|
funcs.push({
|
|
4554
4649
|
name: symbol.name,
|
|
4555
4650
|
file: symbol.file,
|
|
@@ -4562,6 +4657,18 @@ async function functions(options = {}) {
|
|
|
4562
4657
|
}
|
|
4563
4658
|
}
|
|
4564
4659
|
}
|
|
4660
|
+
if (funcs.length === 0 && (process.env.DEBUG_FUNCTIONS === "true" || process.env.DEBUG_ANALYZE === "true")) {
|
|
4661
|
+
console.error(`[functions:debug] Total de arquivos indexados: ${Object.keys(index.files).length}`);
|
|
4662
|
+
console.error(`[functions:debug] Arquivos em functions/src/: ${functionFiles.length}`);
|
|
4663
|
+
console.error(`[functions:debug] Total de s\xEDmbolos em functions/src/: ${totalSymbolsInFunctions}`);
|
|
4664
|
+
console.error(`[functions:debug] S\xEDmbolos do tipo 'trigger': ${triggerSymbolsFound}`);
|
|
4665
|
+
functionFiles.forEach((f) => {
|
|
4666
|
+
console.error(`[functions:debug] ${f.path}: ${f.symbols.length} s\xEDmbolos`);
|
|
4667
|
+
f.symbols.forEach((s) => {
|
|
4668
|
+
console.error(`[functions:debug] - ${s.name} (${s.kind})${s.isExported ? " [exported]" : ""}`);
|
|
4669
|
+
});
|
|
4670
|
+
});
|
|
4671
|
+
}
|
|
4565
4672
|
const filtered = filterTrigger ? funcs.filter(
|
|
4566
4673
|
(f) => f.triggerType.toLowerCase().includes(filterTrigger.toLowerCase())
|
|
4567
4674
|
) : funcs;
|
package/dist/cli.js
CHANGED
|
@@ -13,9 +13,10 @@ import {
|
|
|
13
13
|
impact,
|
|
14
14
|
map,
|
|
15
15
|
suggest
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GYLHEJ4E.js";
|
|
17
17
|
|
|
18
18
|
// src/cli.ts
|
|
19
|
+
import { resolve } from "path";
|
|
19
20
|
var HELP = `
|
|
20
21
|
ai-tool v${VERSION} - Analise de dependencias e impacto
|
|
21
22
|
|
|
@@ -107,7 +108,7 @@ async function main() {
|
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
if (flags.mcp) {
|
|
110
|
-
const { startMcpServer } = await import("./server-
|
|
111
|
+
const { startMcpServer } = await import("./server-R6ARDHBW.js");
|
|
111
112
|
await startMcpServer();
|
|
112
113
|
return;
|
|
113
114
|
}
|
|
@@ -122,7 +123,7 @@ async function main() {
|
|
|
122
123
|
const command = positional[0];
|
|
123
124
|
const target = positional[1];
|
|
124
125
|
const format = flags.format || "text";
|
|
125
|
-
const cwd = flags.cwd
|
|
126
|
+
const cwd = flags.cwd ? resolve(flags.cwd) : process.cwd();
|
|
126
127
|
const cache = !flags["no-cache"];
|
|
127
128
|
try {
|
|
128
129
|
let result;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED