@justmpm/ai-tool 0.7.0 → 0.7.1

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.
@@ -379,12 +379,93 @@ function formatDeadText(result) {
379
379
  out += `
380
380
  `;
381
381
  }
382
- out += `\u{1F4A1} SUGEST\xC3O
382
+ out += `\u{1F4A1} COMO RESOLVER
383
+
384
+ `;
385
+ out += ` 1. Falsos positivos? Adicione ao .analyze/areas.config.json:
386
+ `;
387
+ out += ` { "ignore": ["functions/lib/**", "**/*.test.ts"] }
388
+
389
+ `;
390
+ out += ` 2. Remover automaticamente:
391
+ `;
392
+ out += ` npx knip --fix
393
+
383
394
  `;
384
- out += ` Execute 'npx knip --fix' para remover automaticamente.
395
+ out += ` 3. Ver detalhes em JSON:
385
396
  `;
397
+ out += ` ai-tool dead --format=json
398
+ `;
399
+ const suggestions = generateIgnoreSuggestions(result);
400
+ if (suggestions.length > 0) {
401
+ out += `
402
+ \u{1F3AF} SUGEST\xD5ES INTELIGENTES
403
+
404
+ `;
405
+ for (const suggestion of suggestions) {
406
+ out += ` ${suggestion.icon} ${suggestion.pattern}
407
+ `;
408
+ out += ` Motivo: ${suggestion.reason}
409
+ `;
410
+ out += ` Arquivos afetados: ${suggestion.count}
411
+
412
+ `;
413
+ }
414
+ }
386
415
  return out;
387
416
  }
417
+ function generateIgnoreSuggestions(result) {
418
+ const suggestions = [];
419
+ const files = result.files.map((f) => f.path);
420
+ const libFiles = files.filter((f) => f.includes("functions/lib/"));
421
+ if (libFiles.length > 0) {
422
+ suggestions.push({
423
+ icon: "\u{1F4E6}",
424
+ pattern: "functions/lib/**",
425
+ reason: "Build compilado do Firebase Functions",
426
+ count: libFiles.length
427
+ });
428
+ }
429
+ const testFiles = files.filter((f) => /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(f));
430
+ if (testFiles.length > 3) {
431
+ suggestions.push({
432
+ icon: "\u{1F9EA}",
433
+ pattern: "**/*.(test|spec).(ts|tsx|js|jsx)",
434
+ reason: "Arquivos de teste geralmente s\xE3o entry points pr\xF3prios",
435
+ count: testFiles.length
436
+ });
437
+ }
438
+ const configFiles = files.filter(
439
+ (f) => f.includes("vite.config") || f.includes("next.config") || f.includes("tailwind.config") || f.includes("jest.config") || f.includes("eslint.config")
440
+ );
441
+ if (configFiles.length > 0) {
442
+ suggestions.push({
443
+ icon: "\u2699\uFE0F",
444
+ pattern: "**/*.config.(ts|js|mjs|cjs)",
445
+ reason: "Arquivos de configura\xE7\xE3o s\xE3o entry points",
446
+ count: configFiles.length
447
+ });
448
+ }
449
+ const dtsFiles = files.filter((f) => f.endsWith(".d.ts"));
450
+ if (dtsFiles.length > 0) {
451
+ suggestions.push({
452
+ icon: "\u{1F4D8}",
453
+ pattern: "**/*.d.ts",
454
+ reason: "Arquivos de defini\xE7\xE3o TypeScript",
455
+ count: dtsFiles.length
456
+ });
457
+ }
458
+ const scriptFiles = files.filter((f) => f.startsWith("scripts/") || f.includes("/scripts/"));
459
+ if (scriptFiles.length > 0) {
460
+ suggestions.push({
461
+ icon: "\u{1F4DC}",
462
+ pattern: "scripts/**",
463
+ reason: "Scripts de automa\xE7\xE3o s\xE3o entry points",
464
+ count: scriptFiles.length
465
+ });
466
+ }
467
+ return suggestions;
468
+ }
388
469
  function formatImpactText(result) {
389
470
  let out = "";
390
471
  out += `
@@ -893,20 +974,32 @@ function formatFindText(result) {
893
974
  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
894
975
 
895
976
  `;
896
- out += `\u{1F50D} "${result.query}"`;
897
- if (result.filters.type) {
898
- out += ` [type: ${result.filters.type}]`;
899
- }
900
- if (result.filters.area) {
901
- out += ` [area: ${result.filters.area}]`;
977
+ if (result.query) {
978
+ out += `\u{1F50D} "${result.query}"`;
979
+ if (result.filters.type) {
980
+ out += ` [type: ${result.filters.type}]`;
981
+ }
982
+ if (result.filters.area) {
983
+ out += ` [area: ${result.filters.area}]`;
984
+ }
985
+ out += `
986
+
987
+ `;
988
+ } else {
989
+ out += `\u{1F4CB} Listando todos os s\xEDmbolos do tipo: ${result.filters.type || "all"}
990
+
991
+ `;
902
992
  }
903
- out += `
993
+ if (!result.definition && result.references.length === 0 && result.summary.definitions === 0) {
994
+ if (result.query) {
995
+ out += `\u274C Nenhum resultado encontrado para "${result.query}"
904
996
 
905
997
  `;
906
- if (!result.definition && result.references.length === 0) {
907
- out += `\u274C Nenhum resultado encontrado para "${result.query}"
998
+ } else {
999
+ out += `\u274C Nenhum s\xEDmbolo do tipo "${result.filters.type}" encontrado
908
1000
 
909
1001
  `;
1002
+ }
910
1003
  out += `\u{1F4A1} Dicas:
911
1004
  `;
912
1005
  out += ` \u2022 Verifique a ortografia
@@ -3166,6 +3259,12 @@ import { readdirSync as readdirSync2, statSync as statSync2 } from "fs";
3166
3259
  import { join as join4, extname as extname2, resolve } from "path";
3167
3260
  import { Project as Project2, SyntaxKind as SyntaxKind2 } from "ts-morph";
3168
3261
  var CODE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
3262
+ var DEBUG = process.env.DEBUG_ANALYZE === "true";
3263
+ function debugLog(...args) {
3264
+ if (DEBUG) {
3265
+ console.error("[analyze:debug]", ...args);
3266
+ }
3267
+ }
3169
3268
  var IGNORED_DIRS = /* @__PURE__ */ new Set([
3170
3269
  "node_modules",
3171
3270
  "dist",
@@ -3236,6 +3335,11 @@ var FIREBASE_V2_TRIGGERS = /* @__PURE__ */ new Set([
3236
3335
  ]);
3237
3336
  function indexProject(cwd) {
3238
3337
  const allFiles = getAllCodeFiles(cwd);
3338
+ debugLog(`Indexando ${allFiles.length} arquivos em ${cwd}`);
3339
+ const functionFiles = allFiles.filter((f) => f.includes("functions/src/"));
3340
+ if (functionFiles.length > 0) {
3341
+ debugLog(`Encontrados ${functionFiles.length} arquivos em functions/src/:`, functionFiles);
3342
+ }
3239
3343
  const project = createProject2(cwd);
3240
3344
  for (const file of allFiles) {
3241
3345
  try {
@@ -3337,6 +3441,13 @@ function indexProject(cwd) {
3337
3441
  }
3338
3442
  } else if (initKind === SyntaxKind2.CallExpression) {
3339
3443
  const triggerName = extractFirebaseTriggerName(init);
3444
+ if (DEBUG && filePath.includes("functions/src/")) {
3445
+ const initText = init.getText().slice(0, 50);
3446
+ debugLog(`[CF] Analisando: ${name} = ${initText}...`);
3447
+ if (triggerName) {
3448
+ debugLog(`[CF] \u2713 Trigger detectado: ${triggerName}`);
3449
+ }
3450
+ }
3340
3451
  if (triggerName && FIREBASE_V2_TRIGGERS.has(triggerName)) {
3341
3452
  const triggerInfo = extractTriggerInfo(init, triggerName);
3342
3453
  const symbol = {
@@ -3534,7 +3645,7 @@ function inferSymbolKind(name, context2) {
3534
3645
  function extractFirebaseTriggerName(init) {
3535
3646
  const text = init.getText();
3536
3647
  for (const trigger of FIREBASE_V2_TRIGGERS) {
3537
- const pattern = new RegExp(`(?:^|\\.)${trigger}\\s*\\(`);
3648
+ const pattern = new RegExp(`(?:^|\\.|\\s)${trigger}(?:<[^>]*>)?\\s*\\(`);
3538
3649
  if (pattern.test(text)) {
3539
3650
  return trigger;
3540
3651
  }
@@ -4032,6 +4143,42 @@ var IGNORED_DIRS3 = /* @__PURE__ */ new Set([
4032
4143
  ".vercel",
4033
4144
  ".analyze"
4034
4145
  ]);
4146
+ function resolveAreaId(target, config, allFiles) {
4147
+ const targetLower = target.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
4148
+ if (config.areas[target]) {
4149
+ return target;
4150
+ }
4151
+ for (const [id, areaConfig] of Object.entries(config.areas)) {
4152
+ const name = areaConfig.name?.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
4153
+ if (name === targetLower) {
4154
+ return id;
4155
+ }
4156
+ }
4157
+ for (const [id, name] of Object.entries(AREA_NAMES)) {
4158
+ const nameNormalized = name.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
4159
+ if (nameNormalized === targetLower) {
4160
+ return id;
4161
+ }
4162
+ }
4163
+ for (const id of Object.keys(config.areas)) {
4164
+ if (id.toLowerCase().includes(targetLower)) {
4165
+ return id;
4166
+ }
4167
+ }
4168
+ const detectedAreas = /* @__PURE__ */ new Set();
4169
+ for (const filePath of allFiles) {
4170
+ const areas2 = detectFileAreas(filePath, config);
4171
+ for (const areaId of areas2) {
4172
+ if (areaId.toLowerCase().includes(targetLower)) {
4173
+ detectedAreas.add(areaId);
4174
+ }
4175
+ }
4176
+ }
4177
+ if (detectedAreas.size > 0) {
4178
+ return [...detectedAreas][0];
4179
+ }
4180
+ return target;
4181
+ }
4035
4182
  async function area(target, options = {}) {
4036
4183
  const cwd = options.cwd || process.cwd();
4037
4184
  const format = options.format || "text";
@@ -4043,9 +4190,10 @@ async function area(target, options = {}) {
4043
4190
  try {
4044
4191
  const config = readConfig(cwd);
4045
4192
  const allFiles = getAllCodeFiles4(cwd);
4193
+ const resolvedTarget = resolveAreaId(target, config, allFiles);
4046
4194
  const filteredFiles = allFiles.filter((filePath) => !isFileIgnored(filePath, config));
4047
4195
  const areaFiles = [];
4048
- const targetLower = target.toLowerCase();
4196
+ const targetLower = resolvedTarget.toLowerCase();
4049
4197
  for (const filePath of filteredFiles) {
4050
4198
  const fileAreas = detectFileAreas(filePath, config);
4051
4199
  const belongsToArea = fileAreas.some(
@@ -4083,15 +4231,19 @@ async function area(target, options = {}) {
4083
4231
  for (const cat of Object.keys(byCategory)) {
4084
4232
  byCategory[cat].sort((a, b) => a.path.localeCompare(b.path));
4085
4233
  }
4086
- const realAreaId = findRealAreaId(target, filteredFiles, config);
4234
+ const realAreaId = resolvedTarget !== target ? resolvedTarget : findRealAreaId(target, filteredFiles, config);
4235
+ const finalAreaId = realAreaId || resolvedTarget;
4236
+ const nameConversionMsg = resolvedTarget !== target ? `
4237
+ \u{1F4A1} Buscando \xE1rea "${getAreaName(finalAreaId, config)}" (ID: ${finalAreaId})
4238
+ ` : "";
4087
4239
  const detectedArea = {
4088
- id: realAreaId || target,
4089
- name: getAreaName(realAreaId || target, config),
4090
- description: getAreaDescription(realAreaId || target, config),
4240
+ id: finalAreaId,
4241
+ name: getAreaName(finalAreaId, config),
4242
+ description: getAreaDescription(finalAreaId, config),
4091
4243
  files: areaFiles,
4092
4244
  fileCount: areaFiles.length,
4093
4245
  categories,
4094
- isAutoDetected: !config.areas[realAreaId || target]
4246
+ isAutoDetected: !config.areas[finalAreaId]
4095
4247
  };
4096
4248
  const result = {
4097
4249
  version: "1.0.0",
@@ -4102,7 +4254,8 @@ async function area(target, options = {}) {
4102
4254
  if (format === "json") {
4103
4255
  return JSON.stringify(result, null, 2);
4104
4256
  }
4105
- return formatAreaDetailText(result, { full, filterType });
4257
+ const output = formatAreaDetailText(result, { full, filterType });
4258
+ return nameConversionMsg + output;
4106
4259
  } catch (error) {
4107
4260
  const message = error instanceof Error ? error.message : String(error);
4108
4261
  throw new Error(`Erro ao executar area: ${message}`);
@@ -4217,9 +4370,11 @@ Ou edite manualmente o arquivo existente.
4217
4370
  patterns
4218
4371
  };
4219
4372
  }
4373
+ const suggestedIgnore = detectSuggestedIgnorePatterns(allFiles);
4220
4374
  const newConfig = {
4221
4375
  $schema: "./areas.schema.json",
4222
4376
  version: "1.0.0",
4377
+ ignore: suggestedIgnore,
4223
4378
  areas: generatedAreas,
4224
4379
  descriptions: {},
4225
4380
  settings: {
@@ -4234,7 +4389,12 @@ Ou edite manualmente o arquivo existente.
4234
4389
  \u2705 Arquivo criado: .analyze/areas.config.json
4235
4390
 
4236
4391
  \u{1F4E6} \xC1reas detectadas: ${sortedAreas.length}
4237
-
4392
+ `;
4393
+ if (suggestedIgnore.length > 0) {
4394
+ out += `\u{1F6AB} Padr\xF5es ignorados: ${suggestedIgnore.length}
4395
+ `;
4396
+ }
4397
+ out += `
4238
4398
  `;
4239
4399
  for (const [areaId, files] of sortedAreas.slice(0, 15)) {
4240
4400
  const name = getAreaName(areaId, newConfig);
@@ -4254,6 +4414,15 @@ Ou edite manualmente o arquivo existente.
4254
4414
  Use 'ai-tool areas' para ver detalhes
4255
4415
  `;
4256
4416
  }
4417
+ if (suggestedIgnore.length > 0) {
4418
+ out += `
4419
+ \u{1F4CB} Padr\xF5es adicionados ao ignore:
4420
+ `;
4421
+ for (const pattern of suggestedIgnore) {
4422
+ out += ` \u2022 ${pattern}
4423
+ `;
4424
+ }
4425
+ }
4257
4426
  out += `
4258
4427
  \u{1F4A1} Edite o arquivo para:
4259
4428
  - Renomear \xE1reas (campo "name")
@@ -4295,6 +4464,28 @@ function inferPatternsFromFiles(files) {
4295
4464
  }
4296
4465
  return [...patterns].sort();
4297
4466
  }
4467
+ function detectSuggestedIgnorePatterns(files) {
4468
+ const patterns = [];
4469
+ if (files.some((f) => f.includes("functions/lib/"))) {
4470
+ patterns.push("functions/lib/**");
4471
+ }
4472
+ const testCount = files.filter((f) => /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(f)).length;
4473
+ if (testCount > 3) {
4474
+ patterns.push("**/*.test.{ts,tsx,js,jsx}");
4475
+ patterns.push("**/*.spec.{ts,tsx,js,jsx}");
4476
+ }
4477
+ const dtsCount = files.filter((f) => f.endsWith(".d.ts")).length;
4478
+ if (dtsCount > 2) {
4479
+ patterns.push("**/*.d.ts");
4480
+ }
4481
+ const configCount = files.filter(
4482
+ (f) => /\.(config|conf)\.(ts|js|mjs|cjs)$/.test(f)
4483
+ ).length;
4484
+ if (configCount > 2) {
4485
+ patterns.push("**/*.config.{ts,js,mjs,cjs}");
4486
+ }
4487
+ return patterns;
4488
+ }
4298
4489
  function getAllCodeFiles5(dir, files = [], baseDir = dir) {
4299
4490
  try {
4300
4491
  const entries = readdirSync6(dir);
@@ -4423,12 +4614,43 @@ function formatFunctionsText(result) {
4423
4614
  out += ` Total: ${result.summary.total} functions
4424
4615
  `;
4425
4616
  out += ` Exportadas: ${result.summary.exported}
4426
-
4617
+ `;
4618
+ if (result.summary.total > 0) {
4619
+ out += `
4620
+ \u{1F4A1} Filtros dispon\xEDveis:
4621
+ `;
4622
+ out += ` ai-tool functions --trigger=onCall
4623
+ `;
4624
+ out += ` ai-tool functions --trigger=onDocumentCreated
4625
+ `;
4626
+ }
4627
+ out += `
4427
4628
  `;
4428
4629
  if (result.summary.total === 0) {
4429
- out += ` \u26A0\uFE0F Nenhuma Cloud Function detectada.
4630
+ out += ` \u26A0\uFE0F NENHUMA CLOUD FUNCTION DETECTADA
4631
+
4632
+ `;
4633
+ out += ` Poss\xEDveis causas:
4634
+ `;
4635
+ out += ` 1. O projeto n\xE3o \xE9 Firebase (n\xE3o encontrou .firebaserc ou firebase.json)
4636
+ `;
4637
+ out += ` 2. N\xE3o h\xE1 arquivo functions/src/index.ts
4430
4638
  `;
4431
- out += ` Verifique se seus triggers usam padr\xE3o Firebase v2 (onCall, onDocumentCreated, etc).
4639
+ out += ` 3. Os triggers n\xE3o usam padr\xF5es v2 (onCall, onDocumentCreated, etc)
4640
+ `;
4641
+ out += ` 4. O cache est\xE1 desatualizado \u2192 tente: ai-tool functions --no-cache
4642
+ `;
4643
+ out += ` 5. Para debug: DEBUG_ANALYZE=true ai-tool functions
4644
+
4645
+ `;
4646
+ out += ` Padr\xF5es suportados:
4647
+ `;
4648
+ out += ` export const minhaFunc = onCall((request) => { ... })
4649
+ `;
4650
+ out += ` export const minhaFunc = onDocumentCreated("path", (event) => { ... })
4651
+
4652
+ `;
4653
+ out += ` Documenta\xE7\xE3o: https://firebase.google.com/docs/functions
4432
4654
  `;
4433
4655
  return out;
4434
4656
  }
@@ -4523,8 +4745,9 @@ async function find(query, options = {}) {
4523
4745
  const defOnly = options.def ?? false;
4524
4746
  const refsOnly = options.refs ?? false;
4525
4747
  const useCache = options.cache !== false;
4526
- if (!query || query.trim().length === 0) {
4527
- throw new Error("Query \xE9 obrigat\xF3ria. Exemplo: ai-tool find useAuth");
4748
+ const listAllMode = !query && defOnly && filterType && filterType !== "all";
4749
+ if (!query && !listAllMode) {
4750
+ throw new Error("Query \xE9 obrigat\xF3ria. Exemplo: ai-tool find useAuth\n Ou use --def para listar todos de um tipo: ai-tool find --type=trigger --def");
4528
4751
  }
4529
4752
  try {
4530
4753
  let index;
@@ -4618,11 +4841,13 @@ async function find(query, options = {}) {
4618
4841
  }
4619
4842
  function searchInIndex(index, query, filterType, allowedFiles) {
4620
4843
  const matches = [];
4621
- const queryLower = query.toLowerCase();
4844
+ const queryLower = query?.toLowerCase() || "";
4622
4845
  const processedSymbols = /* @__PURE__ */ new Set();
4846
+ const listAllMode = !query && filterType && filterType !== "all";
4623
4847
  for (const [name, symbols] of Object.entries(index.symbolsByName)) {
4624
4848
  const nameLower = name.toLowerCase();
4625
- if (nameLower === queryLower || nameLower.includes(queryLower)) {
4849
+ const shouldInclude = listAllMode || nameLower === queryLower || nameLower.includes(queryLower);
4850
+ if (shouldInclude) {
4626
4851
  for (const symbol of symbols) {
4627
4852
  if (allowedFiles && !allowedFiles.has(symbol.file)) continue;
4628
4853
  if (!matchesType(symbol.kind, filterType)) continue;
@@ -4642,25 +4867,27 @@ function searchInIndex(index, query, filterType, allowedFiles) {
4642
4867
  }
4643
4868
  }
4644
4869
  }
4645
- for (const [filePath, fileData] of Object.entries(index.files)) {
4646
- if (allowedFiles && !allowedFiles.has(filePath)) continue;
4647
- for (const imp of fileData.imports) {
4648
- for (const spec of imp.specifiers) {
4649
- const specLower = spec.toLowerCase();
4650
- if (specLower === queryLower || specLower.includes(queryLower)) {
4651
- const key = `import:${filePath}:${spec}:${imp.source}`;
4652
- if (processedSymbols.has(key)) continue;
4653
- processedSymbols.add(key);
4654
- matches.push({
4655
- file: filePath,
4656
- line: 1,
4657
- // Imports geralmente estão no topo
4658
- column: 0,
4659
- code: `import { ${spec} } from '${imp.source}'`,
4660
- matchType: "import",
4661
- symbolType: inferSymbolTypeFromName(spec),
4662
- category: fileData.category
4663
- });
4870
+ if (!listAllMode) {
4871
+ for (const [filePath, fileData] of Object.entries(index.files)) {
4872
+ if (allowedFiles && !allowedFiles.has(filePath)) continue;
4873
+ for (const imp of fileData.imports) {
4874
+ for (const spec of imp.specifiers) {
4875
+ const specLower = spec.toLowerCase();
4876
+ if (specLower === queryLower || specLower.includes(queryLower)) {
4877
+ const key = `import:${filePath}:${spec}:${imp.source}`;
4878
+ if (processedSymbols.has(key)) continue;
4879
+ processedSymbols.add(key);
4880
+ matches.push({
4881
+ file: filePath,
4882
+ line: 1,
4883
+ // Imports geralmente estão no topo
4884
+ column: 0,
4885
+ code: `import { ${spec} } from '${imp.source}'`,
4886
+ matchType: "import",
4887
+ symbolType: inferSymbolTypeFromName(spec),
4888
+ category: fileData.category
4889
+ });
4890
+ }
4664
4891
  }
4665
4892
  }
4666
4893
  }
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  impact,
14
14
  map,
15
15
  suggest
16
- } from "./chunk-CRVOX3U4.js";
16
+ } from "./chunk-SVY7A47I.js";
17
17
 
18
18
  // src/cli.ts
19
19
  var HELP = `
@@ -107,7 +107,7 @@ async function main() {
107
107
  }
108
108
  }
109
109
  if (flags.mcp) {
110
- const { startMcpServer } = await import("./server-SZHX26N6.js");
110
+ const { startMcpServer } = await import("./server-URRJAR75.js");
111
111
  await startMcpServer();
112
112
  return;
113
113
  }
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ import {
47
47
  setFileDescription,
48
48
  suggest,
49
49
  writeConfig
50
- } from "./chunk-CRVOX3U4.js";
50
+ } from "./chunk-SVY7A47I.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-CRVOX3U4.js";
14
+ } from "./chunk-SVY7A47I.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.0",
3
+ "version": "0.7.1",
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",