@justmpm/ai-tool 0.7.1 → 0.7.2

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
- const timestamps = [];
1333
- function scanDir(dir) {
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 (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".next" || entry.name === "dist" || entry.name === ".analyze") {
1340
- continue;
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.includes(ext)) {
1367
+ if (extensions.has(ext)) {
1346
1368
  try {
1347
1369
  const stat = statSync(fullPath);
1348
- timestamps.push(stat.mtimeMs);
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
- timestamps.push(stat.mtimeMs);
1389
+ hashAccumulator ^= Math.floor(stat.mtimeMs);
1363
1390
  }
1364
1391
  } catch {
1365
1392
  }
1366
- const sum = timestamps.reduce((a, b) => a + b, 0);
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 targetName = normalizedTarget.split("/").pop()?.toLowerCase() || "";
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 fileName = file.split("/").pop()?.toLowerCase() || "";
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
- if (fileNameNoExt === targetNameNoExt) {
2722
- matches.unshift(file);
2723
- } else if (file.toLowerCase().includes(normalizedTarget.toLowerCase())) {
2724
- matches.push(file);
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 === 1) {
2728
- return matches[0];
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 > 1) {
2731
- return matches[0];
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 targetName = normalizedTarget.split("/").pop()?.toLowerCase() || "";
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 fileName = file.split("/").pop()?.toLowerCase() || "";
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
- if (fileNameNoExt === targetNameNoExt) {
2975
- matches.unshift(file);
2976
- } else if (file.toLowerCase().includes(normalizedTarget.toLowerCase())) {
2977
- matches.push(file);
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 === 1) {
2981
- return matches[0];
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 > 1) {
2984
- return matches[0];
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
  }
@@ -3275,7 +3345,17 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
3275
3345
  "coverage",
3276
3346
  ".turbo",
3277
3347
  ".vercel",
3278
- ".analyze"
3348
+ ".analyze",
3349
+ // Firebase Functions output
3350
+ "functions/lib",
3351
+ "lib",
3352
+ // Outros outputs comuns
3353
+ ".output",
3354
+ "out",
3355
+ ".firebase",
3356
+ "firebase-debug.log",
3357
+ "firestore-debug.log",
3358
+ "pubsub-debug.log"
3279
3359
  ]);
3280
3360
  var FIREBASE_V2_TRIGGERS = /* @__PURE__ */ new Set([
3281
3361
  // HTTPS (firebase-functions/v2/https)
package/dist/cli.js CHANGED
@@ -13,9 +13,10 @@ import {
13
13
  impact,
14
14
  map,
15
15
  suggest
16
- } from "./chunk-SVY7A47I.js";
16
+ } from "./chunk-XEFS66GU.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-URRJAR75.js");
111
+ const { startMcpServer } = await import("./server-XR6C3XM3.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 || process.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
@@ -47,7 +47,7 @@ import {
47
47
  setFileDescription,
48
48
  suggest,
49
49
  writeConfig
50
- } from "./chunk-SVY7A47I.js";
50
+ } from "./chunk-XEFS66GU.js";
51
51
  export {
52
52
  AREA_DESCRIPTIONS,
53
53
  AREA_NAMES,
@@ -11,7 +11,7 @@ import {
11
11
  impact,
12
12
  map,
13
13
  suggest
14
- } from "./chunk-SVY7A47I.js";
14
+ } from "./chunk-XEFS66GU.js";
15
15
 
16
16
  // src/mcp/server.ts
17
17
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justmpm/ai-tool",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Ferramenta de análise de dependências e impacto para projetos TypeScript/JavaScript. Usa Skott + Knip internamente.",
5
5
  "keywords": [
6
6
  "dependency-analysis",