@justmpm/ai-tool 0.8.2 → 0.9.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.
package/dist/cli.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ describe
4
+ } from "./chunk-CACALWH5.js";
2
5
  import {
3
6
  VERSION,
4
7
  area,
@@ -13,7 +16,7 @@ import {
13
16
  impact,
14
17
  map,
15
18
  suggest
16
- } from "./chunk-OMEBMR2V.js";
19
+ } from "./chunk-NVJXCSJF.js";
17
20
 
18
21
  // src/cli.ts
19
22
  import { resolve } from "path";
@@ -30,6 +33,7 @@ COMANDOS:
30
33
  context <arquivo> Extrai assinaturas de um arquivo (funcoes, tipos)
31
34
  context --area=<nome> Contexto consolidado de toda uma area
32
35
  find <termo> Busca simbolos no codigo (funcoes, tipos, etc)
36
+ describe <termo> Busca areas por descricao em linguagem natural
33
37
 
34
38
  AREAS:
35
39
  areas Lista todas as areas/dominios do projeto
@@ -83,6 +87,7 @@ EXEMPLOS:
83
87
  ai-tool find useAuth # Busca definicao e usos
84
88
  ai-tool find User --type=type # Busca apenas tipos
85
89
  ai-tool find login --area=auth # Busca na area auth
90
+ ai-tool describe cache # Busca areas por descricao
86
91
  ai-tool areas
87
92
  ai-tool area auth
88
93
  ai-tool area auth --type=hook
@@ -108,7 +113,7 @@ async function main() {
108
113
  }
109
114
  }
110
115
  if (flags.mcp) {
111
- const { startMcpServer } = await import("./server-JLK3OH5F.js");
116
+ const { startMcpServer } = await import("./server-OMKVOYK7.js");
112
117
  await startMcpServer();
113
118
  return;
114
119
  }
@@ -222,6 +227,15 @@ async function main() {
222
227
  trigger: flags.trigger
223
228
  });
224
229
  break;
230
+ case "describe":
231
+ if (!target) {
232
+ console.error("\u274C Erro: termo de busca \xE9 obrigat\xF3rio para o comando describe");
233
+ console.error(" Exemplo: ai-tool describe cache");
234
+ console.error(" Exemplo: ai-tool describe login");
235
+ process.exit(1);
236
+ }
237
+ result = await describe(target, { format, cwd });
238
+ break;
225
239
  default:
226
240
  console.error(`\u274C Comando desconhecido: ${command}`);
227
241
  console.error(" Use 'ai-tool --help' para ver comandos dispon\xEDveis.");
package/dist/index.d.ts CHANGED
@@ -103,6 +103,16 @@ interface ImpactResult {
103
103
  };
104
104
  risks: RiskInfo[];
105
105
  suggestions: string[];
106
+ gitHistory?: {
107
+ hasGitRepo: boolean;
108
+ recentCommits: Array<{
109
+ hash: string;
110
+ shortHash: string;
111
+ message: string;
112
+ date: string;
113
+ author: string;
114
+ }>;
115
+ };
106
116
  }
107
117
  interface SuggestOptions extends CommandOptions {
108
118
  limit?: number;
@@ -120,6 +130,7 @@ interface SuggestResult {
120
130
  target: string;
121
131
  category: FileCategory;
122
132
  suggestions: Suggestion[];
133
+ testSuggestions: string[];
123
134
  }
124
135
  interface ContextOptions extends CommandOptions {
125
136
  depth?: number;
@@ -471,62 +482,99 @@ interface FindResult {
471
482
  declare function find(query: string, options?: FindOptions): Promise<string>;
472
483
 
473
484
  /**
474
- * Indexador de Projeto - Parseia todos os arquivos e extrai símbolos
485
+ * Detecção de Triggers Firebase
475
486
  *
476
- * Cria um índice completo do projeto que pode ser cacheado e reutilizado
477
- * pelos comandos find e context --area.
487
+ * Identifica e extrai informações de Cloud Functions v2 do Firebase
488
+ * (onCall, onDocumentCreated, onSchedule, etc) durante a indexação do projeto.
478
489
  */
479
490
 
480
491
  /**
481
492
  * Metadados de um trigger Firebase
482
493
  */
483
494
  interface TriggerInfo {
495
+ /** Tipo do trigger (ex: "onDocumentCreated", "onCall") */
484
496
  triggerType: string;
497
+ /** Path para Firestore/RTDB (ex: "users/{userId}") */
485
498
  triggerPath?: string;
499
+ /** Schedule expression para onSchedule (ex: "every 5 minutes") */
486
500
  triggerSchedule?: string;
487
501
  }
502
+
503
+ /**
504
+ * Cache de Símbolos do Projeto
505
+ *
506
+ * Indexa todos os arquivos do projeto e extrai símbolos
507
+ * (funções, tipos, interfaces, enums, componentes, hooks, triggers Firebase)
508
+ *
509
+ * O índice resultante pode ser cacheado e reutilizado pelos comandos find e context.
510
+ */
511
+
488
512
  /**
489
513
  * Informação de um símbolo (função, tipo, constante, etc)
490
514
  */
491
515
  interface SymbolInfo {
516
+ /** Nome do símbolo */
492
517
  name: string;
518
+ /** Caminho do arquivo relativo ao projeto */
493
519
  file: string;
520
+ /** Número da linha onde o símbolo está definido */
494
521
  line: number;
522
+ /** Tipo do símbolo */
495
523
  kind: "function" | "type" | "interface" | "enum" | "const" | "component" | "hook" | "trigger";
524
+ /** Assinatura do símbolo */
496
525
  signature: string;
526
+ /** Se o símbolo é exportado */
497
527
  isExported: boolean;
528
+ /** Parâmetros da função (se aplicável) */
498
529
  params?: string[];
530
+ /** Tipo de retorno da função (se aplicável) */
499
531
  returnType?: string;
532
+ /** Definição completa (para tipos, interfaces, enums) */
500
533
  definition?: string;
534
+ /** Metadados específicos para triggers Firebase */
501
535
  triggerInfo?: TriggerInfo;
502
536
  }
503
537
  /**
504
538
  * Informação de import
505
539
  */
506
540
  interface ImportInfo {
541
+ /** Caminho do módulo importado */
507
542
  source: string;
543
+ /** Especificadores importados */
508
544
  specifiers: string[];
545
+ /** Se é um import type-only */
509
546
  isTypeOnly: boolean;
510
547
  }
511
548
  /**
512
549
  * Dados extraídos de um arquivo
513
550
  */
514
551
  interface FileSymbols {
552
+ /** Caminho do arquivo relativo ao projeto */
515
553
  path: string;
554
+ /** Categoria do arquivo (component, page, hook, etc) */
516
555
  category: FileCategory;
556
+ /** Lista de símbolos encontrados no arquivo */
517
557
  symbols: SymbolInfo[];
558
+ /** Lista de imports do arquivo */
518
559
  imports: ImportInfo[];
560
+ /** Lista de exports do arquivo */
519
561
  exports: string[];
520
562
  }
521
563
  /**
522
564
  * Índice completo do projeto
523
565
  */
524
566
  interface ProjectIndex {
567
+ /** Versão do formato do índice */
525
568
  version: string;
569
+ /** Timestamp de quando o índice foi criado */
526
570
  timestamp: string;
571
+ /** Mapa de caminho → dados do arquivo */
527
572
  files: Record<string, FileSymbols>;
573
+ /** Índice para busca rápida por nome do símbolo */
528
574
  symbolsByName: Record<string, SymbolInfo[]>;
575
+ /** Número total de arquivos indexados */
529
576
  fileCount: number;
577
+ /** Número total de símbolos encontrados */
530
578
  symbolCount: number;
531
579
  }
532
580
 
package/dist/index.js CHANGED
@@ -44,7 +44,7 @@ import {
44
44
  setFileDescription,
45
45
  suggest,
46
46
  writeConfig
47
- } from "./chunk-OMEBMR2V.js";
47
+ } from "./chunk-NVJXCSJF.js";
48
48
  export {
49
49
  COMMAND_REFERENCE,
50
50
  VERSION,
@@ -0,0 +1,511 @@
1
+ import {
2
+ describe
3
+ } from "./chunk-CACALWH5.js";
4
+ import {
5
+ VERSION,
6
+ area,
7
+ areaContext,
8
+ areas,
9
+ areasInit,
10
+ context,
11
+ dead,
12
+ find,
13
+ functions,
14
+ impact,
15
+ map,
16
+ suggest
17
+ } from "./chunk-NVJXCSJF.js";
18
+
19
+ // src/mcp/server.ts
20
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
21
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
22
+
23
+ // src/mcp/tools.ts
24
+ import { z } from "zod";
25
+ function registerAllTools(server2) {
26
+ server2.registerTool(
27
+ "aitool_project_map",
28
+ {
29
+ title: "Project Map",
30
+ description: `Mapeia projeto e retorna resumo: contagens por categoria, areas detectadas, alertas.
31
+ Use no inicio da sessao. Para detalhes: area_detail, file_context, suggest_reads.
32
+
33
+ Parametros:
34
+ - format: text (legivel) ou json (estruturado)
35
+ - cwd: Diretorio do projeto a analisar`,
36
+ inputSchema: {
37
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
38
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
39
+ },
40
+ annotations: {
41
+ title: "Project Map",
42
+ readOnlyHint: true,
43
+ destructiveHint: false,
44
+ idempotentHint: true,
45
+ openWorldHint: false
46
+ }
47
+ },
48
+ async (params) => {
49
+ try {
50
+ const result = await map({
51
+ format: params.format,
52
+ cwd: params.cwd,
53
+ full: false
54
+ });
55
+ return { content: [{ type: "text", text: result }] };
56
+ } catch (error) {
57
+ return {
58
+ content: [{ type: "text", text: `Erro ao executar map: ${error instanceof Error ? error.message : String(error)}` }],
59
+ isError: true
60
+ };
61
+ }
62
+ }
63
+ );
64
+ server2.registerTool(
65
+ "aitool_dead_code",
66
+ {
67
+ title: "Dead Code Detector",
68
+ description: `Detecta codigo morto: arquivos orfaos, exports nao usados, deps npm mortas.
69
+ Use antes de refatoracoes ou periodicamente para limpeza.
70
+
71
+ Parametros:
72
+ - format: text (legivel) ou json (estruturado)
73
+ - cwd: Diretorio do projeto a analisar`,
74
+ inputSchema: {
75
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
76
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
77
+ },
78
+ annotations: {
79
+ title: "Dead Code Detector",
80
+ readOnlyHint: true,
81
+ destructiveHint: false,
82
+ idempotentHint: true,
83
+ openWorldHint: false
84
+ }
85
+ },
86
+ async (params) => {
87
+ try {
88
+ const result = await dead({
89
+ format: params.format,
90
+ cwd: params.cwd
91
+ });
92
+ return { content: [{ type: "text", text: result }] };
93
+ } catch (error) {
94
+ return {
95
+ content: [{ type: "text", text: `Erro ao executar dead: ${error instanceof Error ? error.message : String(error)}` }],
96
+ isError: true
97
+ };
98
+ }
99
+ }
100
+ );
101
+ server2.registerTool(
102
+ "aitool_impact_analysis",
103
+ {
104
+ title: "Impact Analysis",
105
+ description: `Analisa impacto de modificar um arquivo: upstream (quem importa), downstream (o que importa), riscos.
106
+ Use ANTES de editar arquivos para planejar mudancas seguras.
107
+
108
+ Parametros:
109
+ - target: Arquivo a analisar (caminho completo, parcial ou nome)
110
+ - format: text (legivel) ou json (estruturado)
111
+ - cwd: Diretorio do projeto a analisar`,
112
+ inputSchema: {
113
+ target: z.string().min(1).describe("Arquivo a analisar: caminho completo, parcial ou nome do arquivo"),
114
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
115
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
116
+ },
117
+ annotations: {
118
+ title: "Impact Analysis",
119
+ readOnlyHint: true,
120
+ destructiveHint: false,
121
+ idempotentHint: true,
122
+ openWorldHint: false
123
+ }
124
+ },
125
+ async (params) => {
126
+ try {
127
+ const result = await impact(params.target, {
128
+ format: params.format,
129
+ cwd: params.cwd
130
+ });
131
+ return { content: [{ type: "text", text: result }] };
132
+ } catch (error) {
133
+ return {
134
+ content: [{ type: "text", text: `Erro ao executar impact: ${error instanceof Error ? error.message : String(error)}` }],
135
+ isError: true
136
+ };
137
+ }
138
+ }
139
+ );
140
+ server2.registerTool(
141
+ "aitool_suggest_reads",
142
+ {
143
+ title: "Suggest Files to Read",
144
+ description: `Sugere arquivos para ler ANTES de modificar um arquivo.
145
+ Prioriza: tipos usados, dependencias diretas, upstream, testes.
146
+
147
+ Parametros:
148
+ - target: Arquivo que sera modificado (caminho completo, parcial ou nome)
149
+ - limit: Numero maximo de sugestoes (default: 10, max: 50)`,
150
+ inputSchema: {
151
+ target: z.string().min(1).describe("Arquivo que sera modificado: caminho completo, parcial ou nome"),
152
+ limit: z.number().int().min(1).max(50).default(10).describe("Numero maximo de sugestoes (default: 10, max: 50)"),
153
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
154
+ },
155
+ annotations: {
156
+ title: "Suggest Files to Read",
157
+ readOnlyHint: true,
158
+ destructiveHint: false,
159
+ idempotentHint: true,
160
+ openWorldHint: false
161
+ }
162
+ },
163
+ async (params) => {
164
+ try {
165
+ const result = await suggest(params.target, {
166
+ limit: params.limit,
167
+ cwd: params.cwd,
168
+ format: "text"
169
+ });
170
+ return { content: [{ type: "text", text: result }] };
171
+ } catch (error) {
172
+ return {
173
+ content: [{ type: "text", text: `Erro ao executar suggest: ${error instanceof Error ? error.message : String(error)}` }],
174
+ isError: true
175
+ };
176
+ }
177
+ }
178
+ );
179
+ server2.registerTool(
180
+ "aitool_file_context",
181
+ {
182
+ title: "Extract File Context",
183
+ description: `Extrai assinaturas de funcoes e tipos de um arquivo (sem implementacao).
184
+ Use para entender a API publica antes de usar ou modificar.
185
+
186
+ Parametros:
187
+ - target: Arquivo para extrair contexto (caminho completo, parcial ou nome)
188
+ - cwd: Diretorio do projeto a analisar`,
189
+ inputSchema: {
190
+ target: z.string().min(1).describe("Arquivo para extrair contexto: caminho completo, parcial ou nome"),
191
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
192
+ },
193
+ annotations: {
194
+ title: "Extract File Context",
195
+ readOnlyHint: true,
196
+ destructiveHint: false,
197
+ idempotentHint: true,
198
+ openWorldHint: false
199
+ }
200
+ },
201
+ async (params) => {
202
+ try {
203
+ const result = await context(params.target, {
204
+ cwd: params.cwd,
205
+ format: "text"
206
+ });
207
+ return { content: [{ type: "text", text: result }] };
208
+ } catch (error) {
209
+ return {
210
+ content: [{ type: "text", text: `Erro ao executar context: ${error instanceof Error ? error.message : String(error)}` }],
211
+ isError: true
212
+ };
213
+ }
214
+ }
215
+ );
216
+ server2.registerTool(
217
+ "aitool_list_areas",
218
+ {
219
+ title: "List Project Areas",
220
+ description: `Lista areas/dominios funcionais do projeto (auth, pets, stripe...).
221
+ Diferente de categorias (hook, component). Use area_detail para ver arquivos.
222
+
223
+ Parametros:
224
+ - format: text (legivel) ou json (estruturado)
225
+ - cwd: Diretorio do projeto a analisar`,
226
+ inputSchema: {
227
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
228
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
229
+ },
230
+ annotations: {
231
+ title: "List Project Areas",
232
+ readOnlyHint: true,
233
+ destructiveHint: false,
234
+ idempotentHint: true,
235
+ openWorldHint: false
236
+ }
237
+ },
238
+ async (params) => {
239
+ try {
240
+ const result = await areas({
241
+ format: params.format,
242
+ cwd: params.cwd
243
+ });
244
+ return { content: [{ type: "text", text: result }] };
245
+ } catch (error) {
246
+ return {
247
+ content: [{ type: "text", text: `Erro ao executar areas: ${error instanceof Error ? error.message : String(error)}` }],
248
+ isError: true
249
+ };
250
+ }
251
+ }
252
+ );
253
+ server2.registerTool(
254
+ "aitool_area_detail",
255
+ {
256
+ title: "Area Detail",
257
+ description: `Mostra arquivos de uma area especifica, agrupados por categoria.
258
+ Use ID (ex: auth) ou Name (ex: Autentica\xE7\xE3o) para identificar a area.
259
+
260
+ Parametros:
261
+ - target: Nome da area (ex: auth, dashboard, billing)
262
+ - type: Filtrar por categoria (page, component, hook, service, etc)
263
+ - full: Mostrar todos os arquivos (default: resumido)
264
+ - cwd: Diretorio do projeto a analisar`,
265
+ inputSchema: {
266
+ target: z.string().min(1).describe("Nome da area: auth, dashboard, billing, etc"),
267
+ type: z.enum(["page", "layout", "route", "component", "hook", "service", "store", "util", "type", "config", "test", "other"]).optional().describe("Filtrar por categoria especifica"),
268
+ full: z.boolean().default(false).describe("Mostrar todos os arquivos (default: resumido)"),
269
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
270
+ },
271
+ annotations: {
272
+ title: "Area Detail",
273
+ readOnlyHint: true,
274
+ destructiveHint: false,
275
+ idempotentHint: true,
276
+ openWorldHint: false
277
+ }
278
+ },
279
+ async (params) => {
280
+ try {
281
+ const result = await area(params.target, {
282
+ type: params.type,
283
+ full: params.full,
284
+ cwd: params.cwd,
285
+ format: "text"
286
+ });
287
+ return { content: [{ type: "text", text: result }] };
288
+ } catch (error) {
289
+ return {
290
+ content: [{ type: "text", text: `Erro ao executar area: ${error instanceof Error ? error.message : String(error)}` }],
291
+ isError: true
292
+ };
293
+ }
294
+ }
295
+ );
296
+ server2.registerTool(
297
+ "aitool_areas_init",
298
+ {
299
+ title: "Initialize Areas Config",
300
+ description: `Gera .analyze/areas.config.json para customizar deteccao de areas.
301
+ Use quando houver arquivos sem area ou precisar ajustar deteccao.
302
+
303
+ Parametros:
304
+ - force: Sobrescrever config existente
305
+ - cwd: Diretorio do projeto`,
306
+ inputSchema: {
307
+ force: z.boolean().default(false).describe("Sobrescrever config existente"),
308
+ cwd: z.string().optional().describe("Diretorio do projeto")
309
+ },
310
+ annotations: {
311
+ title: "Initialize Areas Config",
312
+ readOnlyHint: false,
313
+ destructiveHint: false,
314
+ idempotentHint: false,
315
+ openWorldHint: false
316
+ }
317
+ },
318
+ async (params) => {
319
+ try {
320
+ const result = await areasInit({
321
+ force: params.force,
322
+ cwd: params.cwd
323
+ });
324
+ return { content: [{ type: "text", text: result }] };
325
+ } catch (error) {
326
+ return {
327
+ content: [{ type: "text", text: `Erro ao executar areas init: ${error instanceof Error ? error.message : String(error)}` }],
328
+ isError: true
329
+ };
330
+ }
331
+ }
332
+ );
333
+ server2.registerTool(
334
+ "aitool_find",
335
+ {
336
+ title: "Find Symbol",
337
+ description: `Busca simbolos no codigo: funcoes, tipos, componentes, hooks, constantes.
338
+ Retorna definicao + referencias/usos. Diferente de grep, entende o AST do TypeScript.
339
+
340
+ Parametros:
341
+ - query: Termo a buscar (ex: useAuth, User, login)
342
+ - type: Filtrar por tipo (function, type, const, component, hook, trigger, all)
343
+ - area: Buscar apenas em uma area especifica (ex: auth, dashboard)
344
+ - def: Mostrar apenas definicoes (onde e declarado)
345
+ - refs: Mostrar apenas referencias/usos`,
346
+ inputSchema: {
347
+ query: z.string().min(1).describe("Termo a buscar (nome de funcao, tipo, componente, etc)"),
348
+ type: z.enum(["function", "type", "const", "component", "hook", "trigger", "all"]).default("all").describe("Filtrar por tipo de simbolo (use trigger para Cloud Functions)"),
349
+ area: z.string().optional().describe("Filtrar busca por area especifica (ex: auth, dashboard)"),
350
+ def: z.boolean().default(false).describe("Mostrar apenas definicoes (onde e declarado)"),
351
+ refs: z.boolean().default(false).describe("Mostrar apenas referencias (onde e usado)"),
352
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
353
+ },
354
+ annotations: {
355
+ title: "Find Symbol",
356
+ readOnlyHint: true,
357
+ destructiveHint: false,
358
+ idempotentHint: true,
359
+ openWorldHint: false
360
+ }
361
+ },
362
+ async (params) => {
363
+ try {
364
+ const result = await find(params.query, {
365
+ type: params.type,
366
+ area: params.area,
367
+ def: params.def,
368
+ refs: params.refs,
369
+ cwd: params.cwd,
370
+ format: "text"
371
+ });
372
+ return { content: [{ type: "text", text: result }] };
373
+ } catch (error) {
374
+ return {
375
+ content: [{ type: "text", text: `Erro ao executar find: ${error instanceof Error ? error.message : String(error)}` }],
376
+ isError: true
377
+ };
378
+ }
379
+ }
380
+ );
381
+ server2.registerTool(
382
+ "aitool_area_context",
383
+ {
384
+ title: "Area Context",
385
+ description: `Contexto consolidado de toda uma area: tipos, hooks, funcoes, componentes, services, stores.
386
+ Uma chamada = entender toda a feature. Muito mais eficiente que chamar context em cada arquivo.
387
+
388
+ Parametros:
389
+ - area: Nome da area (ex: auth, dashboard, payments)
390
+ - cwd: Diretorio do projeto a analisar`,
391
+ inputSchema: {
392
+ area: z.string().min(1).describe("Nome da area: auth, dashboard, payments, etc"),
393
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
394
+ },
395
+ annotations: {
396
+ title: "Area Context",
397
+ readOnlyHint: true,
398
+ destructiveHint: false,
399
+ idempotentHint: true,
400
+ openWorldHint: false
401
+ }
402
+ },
403
+ async (params) => {
404
+ try {
405
+ const result = await areaContext(params.area, {
406
+ cwd: params.cwd,
407
+ format: "text"
408
+ });
409
+ return { content: [{ type: "text", text: result }] };
410
+ } catch (error) {
411
+ return {
412
+ content: [{ type: "text", text: `Erro ao executar area context: ${error instanceof Error ? error.message : String(error)}` }],
413
+ isError: true
414
+ };
415
+ }
416
+ }
417
+ );
418
+ server2.registerTool(
419
+ "aitool_list_functions",
420
+ {
421
+ title: "List Cloud Functions",
422
+ description: `Lista todas as Cloud Functions Firebase do projeto.
423
+ Agrupa por tipo de trigger (onCall, onDocumentCreated, onSchedule, etc).
424
+ Use para entender a arquitetura serverless antes de modificar triggers.
425
+
426
+ Parametros:
427
+ - trigger: Filtrar por tipo de trigger (ex: onCall, onDocumentCreated, onSchedule)
428
+ - format: text (legivel) ou json (estruturado)`,
429
+ inputSchema: {
430
+ trigger: z.string().optional().describe("Filtrar por tipo de trigger (ex: onCall, onDocumentCreated, onSchedule)"),
431
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
432
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
433
+ },
434
+ annotations: {
435
+ title: "List Cloud Functions",
436
+ readOnlyHint: true,
437
+ destructiveHint: false,
438
+ idempotentHint: true,
439
+ openWorldHint: false
440
+ }
441
+ },
442
+ async (params) => {
443
+ try {
444
+ const result = await functions({
445
+ format: params.format,
446
+ trigger: params.trigger,
447
+ cwd: params.cwd
448
+ });
449
+ return { content: [{ type: "text", text: result }] };
450
+ } catch (error) {
451
+ return {
452
+ content: [{ type: "text", text: `Erro ao executar functions: ${error instanceof Error ? error.message : String(error)}` }],
453
+ isError: true
454
+ };
455
+ }
456
+ }
457
+ );
458
+ server2.registerTool(
459
+ "aitool_describe",
460
+ {
461
+ title: "Search by Description",
462
+ description: `Busca \xE1reas por descri\xE7\xE3o em linguagem natural.
463
+ Ex: "Onde implementou login?" \u2192 encontra \xE1rea de autentica\xE7\xE3o.
464
+
465
+ Parametros:
466
+ - query: Descri\xE7\xE3o ou keyword
467
+ - cwd: Diretorio do projeto`,
468
+ inputSchema: {
469
+ query: z.string().min(1).describe("Descri\xE7\xE3o ou keyword para buscar \xE1reas"),
470
+ format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
471
+ cwd: z.string().optional().describe("Diretorio do projeto a analisar")
472
+ },
473
+ annotations: {
474
+ title: "Search by Description",
475
+ readOnlyHint: true,
476
+ destructiveHint: false,
477
+ idempotentHint: true,
478
+ openWorldHint: false
479
+ }
480
+ },
481
+ async (params) => {
482
+ try {
483
+ const result = await describe(params.query, {
484
+ format: params.format,
485
+ cwd: params.cwd
486
+ });
487
+ return { content: [{ type: "text", text: result }] };
488
+ } catch (error) {
489
+ return {
490
+ content: [{ type: "text", text: `Erro ao executar describe: ${error instanceof Error ? error.message : String(error)}` }],
491
+ isError: true
492
+ };
493
+ }
494
+ }
495
+ );
496
+ }
497
+
498
+ // src/mcp/server.ts
499
+ var server = new McpServer({
500
+ name: "ai-tool-mcp-server",
501
+ version: VERSION
502
+ });
503
+ registerAllTools(server);
504
+ async function startMcpServer() {
505
+ const transport = new StdioServerTransport();
506
+ await server.connect(transport);
507
+ console.error(`[ai-tool] MCP server v${VERSION} running via stdio`);
508
+ }
509
+ export {
510
+ startMcpServer
511
+ };