@justmpm/ai-tool 1.0.2 → 1.0.4

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 CHANGED
@@ -234,6 +234,7 @@ ai-tool functions --format=json
234
234
  ### `areas` - Áreas/Domínios Funcionais
235
235
 
236
236
  Lista todas as áreas funcionais do projeto (auth, dashboard, stripe, etc).
237
+ **Também mostra arquivos SEM área definida** - útil para identificar gaps na configuração.
237
238
 
238
239
  ```bash
239
240
  ai-tool areas
@@ -244,6 +245,7 @@ ai-tool areas --format=json
244
245
  - Lista de áreas configuradas manualmente
245
246
  - Contagem de arquivos por área
246
247
  - Distribuição de categorias por área
248
+ - **Arquivos sem área (unmapped)** - use para ver o que falta configurar
247
249
 
248
250
  ### `area` - Detalhe de uma Área
249
251
 
@@ -358,7 +360,7 @@ ai-tool --mcp
358
360
  - `aitool_impact_analysis` - Análise de impacto antes de modificar
359
361
  - `aitool_suggest_reads` - Sugere arquivos para ler antes de editar
360
362
  - `aitool_file_context` - Extrai assinaturas de um arquivo
361
- - `aitool_list_areas` - Lista áreas funcionais do projeto
363
+ - `aitool_list_areas` - Lista áreas + arquivos sem área (ver gaps na configuração)
362
364
  - `aitool_area_detail` - Arquivos de uma área específica
363
365
  - `aitool_areas_init` - Gera config de áreas
364
366
  - `aitool_area_context` - Contexto consolidado de toda uma área
@@ -13,7 +13,7 @@ import {
13
13
  parseCommandOptions,
14
14
  readConfig,
15
15
  updateCacheMeta
16
- } from "./chunk-36CYBYVT.js";
16
+ } from "./chunk-RODPJDYQ.js";
17
17
 
18
18
  // src/commands/describe.ts
19
19
  var STOPWORDS = /* @__PURE__ */ new Set([
@@ -1149,6 +1149,45 @@ function formatAreasText(result, ctx = "cli") {
1149
1149
  out += nextSteps("areas", ctx);
1150
1150
  return out;
1151
1151
  }
1152
+ function formatAreasMissingText(result, ctx = "cli") {
1153
+ let out = "";
1154
+ out += `## \u26A0\uFE0F ARQUIVOS SEM \xC1REA (${result.unmapped.length})
1155
+
1156
+ `;
1157
+ if (result.unmapped.length === 0) {
1158
+ out += `\u2705 Todos os arquivos est\xE3o associados a uma \xE1rea!
1159
+ `;
1160
+ out += nextSteps("areas", ctx);
1161
+ return out;
1162
+ }
1163
+ const byFolder = /* @__PURE__ */ new Map();
1164
+ for (const file of result.unmapped) {
1165
+ const folder = file.path.split("/").slice(0, -1).join("/") || ".";
1166
+ if (!byFolder.has(folder)) {
1167
+ byFolder.set(folder, []);
1168
+ }
1169
+ byFolder.get(folder).push(file);
1170
+ }
1171
+ const sortedFolders = [...byFolder.entries()].sort((a, b) => b[1].length - a[1].length);
1172
+ for (const [folder, files] of sortedFolders) {
1173
+ const folderDisplay = folder === "." ? "(raiz)" : `${folder}/`;
1174
+ out += `\u{1F4C1} ${folderDisplay} (${files.length})
1175
+ `;
1176
+ for (const file of files) {
1177
+ const fileIcon = categoryIcons[file.category];
1178
+ const fileName = file.path.split("/").pop() || file.path;
1179
+ out += ` ${fileIcon} ${fileName}
1180
+ `;
1181
+ }
1182
+ out += `
1183
+ `;
1184
+ }
1185
+ out += `\u{1F4A1} Adicione padr\xF5es em .analyze/areas.config.json
1186
+ `;
1187
+ out += ` ou execute ${hint("areas_init", ctx)} para gerar configura\xE7\xE3o
1188
+ `;
1189
+ return out;
1190
+ }
1152
1191
  function formatAreaDetailText(result, options = {}, ctx = "cli") {
1153
1192
  const { full = false, filterType } = options;
1154
1193
  const { area: area2, byCategory } = result;
@@ -4339,6 +4378,32 @@ async function areas(options = {}) {
4339
4378
  const config = readConfig(cwd);
4340
4379
  const allFiles = getAllCodeFiles3(cwd);
4341
4380
  const filteredFiles = allFiles.filter((filePath) => !isFileIgnored(filePath, config));
4381
+ if (options.missing) {
4382
+ const unmapped2 = [];
4383
+ for (const filePath of filteredFiles) {
4384
+ const areas2 = detectFileAreas(filePath, config);
4385
+ if (areas2.length === 0) {
4386
+ const category = detectCategory(filePath);
4387
+ unmapped2.push({ path: filePath, category });
4388
+ }
4389
+ }
4390
+ const result2 = {
4391
+ version: "1.0.0",
4392
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4393
+ cwd,
4394
+ areas: [],
4395
+ unmapped: unmapped2,
4396
+ summary: {
4397
+ totalAreas: 0,
4398
+ totalFiles: filteredFiles.length,
4399
+ unmappedCount: unmapped2.length
4400
+ }
4401
+ };
4402
+ if (format === "json") {
4403
+ return JSON.stringify(result2, null, 2);
4404
+ }
4405
+ return formatAreasMissingText(result2, ctx);
4406
+ }
4342
4407
  const areaMap = /* @__PURE__ */ new Map();
4343
4408
  const unmapped = [];
4344
4409
  for (const filePath of filteredFiles) {
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  describe
4
- } from "./chunk-M32V3QZD.js";
4
+ } from "./chunk-NI3IRPT4.js";
5
5
  import {
6
6
  VERSION,
7
7
  area,
@@ -16,7 +16,7 @@ import {
16
16
  impact,
17
17
  map,
18
18
  suggest
19
- } from "./chunk-36CYBYVT.js";
19
+ } from "./chunk-RODPJDYQ.js";
20
20
 
21
21
  // src/cli.ts
22
22
  import { resolve } from "path";
@@ -37,6 +37,7 @@ COMANDOS:
37
37
 
38
38
  AREAS:
39
39
  areas Lista todas as areas/dominios do projeto
40
+ areas --missing Mostra apenas arquivos sem area definida (lista completa)
40
41
  areas init Gera arquivo de configuracao .analyze/areas.config.json
41
42
  areas init --force Sobrescreve configuracao existente
42
43
  area <nome> Mostra arquivos de uma area especifica
@@ -65,6 +66,7 @@ OPCOES:
65
66
  --type=<categoria> Filtra por categoria (area) ou tipo de simbolo (find)
66
67
  --full Lista completa (map: lista arquivos, area: todos arquivos)
67
68
  --area=<nome> Filtra por area (find, context)
69
+ --missing Mostra apenas arquivos sem area (areas)
68
70
  --def Apenas definicoes (find)
69
71
  --refs Apenas referencias (find)
70
72
  --help, -h Mostra esta ajuda
@@ -113,7 +115,7 @@ async function main() {
113
115
  }
114
116
  }
115
117
  if (flags.mcp) {
116
- const { startMcpServer } = await import("./server-ZWEQAS6N.js");
118
+ const { startMcpServer } = await import("./server-RP4IQ5FW.js");
117
119
  await startMcpServer();
118
120
  return;
119
121
  }
@@ -202,7 +204,7 @@ async function main() {
202
204
  if (target === "init") {
203
205
  result = await areasInit({ cwd, force: !!flags.force });
204
206
  } else {
205
- result = await areas({ format, cwd });
207
+ result = await areas({ format, cwd, missing: !!flags.missing });
206
208
  }
207
209
  break;
208
210
  case "area":
package/dist/index.d.ts CHANGED
@@ -232,6 +232,7 @@ interface AreaDetailResult {
232
232
  interface AreasOptions extends CommandOptions {
233
233
  full?: boolean;
234
234
  type?: FileCategory;
235
+ missing?: boolean;
235
236
  }
236
237
  interface AreaOptions extends CommandOptions {
237
238
  full?: boolean;
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ import {
46
46
  setFileDescription,
47
47
  suggest,
48
48
  writeConfig
49
- } from "./chunk-36CYBYVT.js";
49
+ } from "./chunk-RODPJDYQ.js";
50
50
  export {
51
51
  VERSION,
52
52
  area,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  describe
3
- } from "./chunk-M32V3QZD.js";
3
+ } from "./chunk-NI3IRPT4.js";
4
4
  import {
5
5
  VERSION,
6
6
  area,
@@ -15,7 +15,7 @@ import {
15
15
  map,
16
16
  recoveryHint,
17
17
  suggest
18
- } from "./chunk-36CYBYVT.js";
18
+ } from "./chunk-RODPJDYQ.js";
19
19
 
20
20
  // src/mcp/server.ts
21
21
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -208,8 +208,9 @@ NAO use para: entender uma area/feature inteira (use area_context, que consolida
208
208
 
209
209
  Apos entender o contexto, use find para localizar onde cada export e usado no projeto.`,
210
210
  inputSchema: {
211
- target: z.string().min(1).describe("Arquivo para extrair contexto: caminho completo, parcial ou nome"),
212
- cwd: z.string().optional().describe("Diretorio do projeto a analisar")
211
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
212
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar"),
213
+ missing: z.boolean().default(false).describe("Mostrar apenas arquivos sem area definida")
213
214
  },
214
215
  annotations: {
215
216
  title: "Extract File Context",
@@ -243,10 +244,11 @@ ${hint}` }],
243
244
  {
244
245
  title: "List Project Areas",
245
246
  description: `Lista areas/dominios funcionais do projeto (auth, pets, stripe, dashboard...).
247
+ Tambem mostra arquivos SEM area definida (unmapped) - util para identificar gaps na configuracao.
246
248
  Areas sao diferentes de categorias (hook, component, page).
247
249
  Requer configuracao manual em .analyze/areas.config.json (use areas_init para gerar o template).
248
250
 
249
- Quando usar: ver todas as areas disponiveis, entender a organizacao do projeto por dominio de negocio.
251
+ Quando usar: ver todas as areas disponiveis, entender a organizacao do projeto por dominio, VER QUAIS ARQUIVOS ESTAO SEM AREA.
250
252
  NAO use para: buscar uma area pelo nome/descricao (use describe) ou ver os arquivos de uma area (use area_detail).`,
251
253
  inputSchema: {
252
254
  format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
@@ -265,7 +267,8 @@ NAO use para: buscar uma area pelo nome/descricao (use describe) ou ver os arqui
265
267
  const result = await areas({
266
268
  format: params.format,
267
269
  cwd: params.cwd,
268
- ctx: "mcp"
270
+ ctx: "mcp",
271
+ missing: params.missing
269
272
  });
270
273
  return { content: [{ type: "text", text: result }] };
271
274
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justmpm/ai-tool",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
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",