@justmpm/ai-tool 0.2.0 → 0.3.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/LICENSE +21 -0
- package/dist/{chunk-HOVHD2N4.js → chunk-4HXWM7PK.js} +824 -1
- package/dist/cli.js +56 -15
- package/dist/index.d.ts +75 -2
- package/dist/index.js +7 -3
- package/dist/server-YV4BWISA.js +343 -0
- package/package.json +5 -2
package/dist/cli.js
CHANGED
|
@@ -1,33 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
VERSION,
|
|
4
|
+
context,
|
|
4
5
|
dead,
|
|
5
6
|
deadFix,
|
|
6
7
|
impact,
|
|
7
|
-
map
|
|
8
|
-
|
|
8
|
+
map,
|
|
9
|
+
suggest
|
|
10
|
+
} from "./chunk-4HXWM7PK.js";
|
|
9
11
|
|
|
10
12
|
// src/cli.ts
|
|
11
13
|
var HELP = `
|
|
12
|
-
ai-tool v${VERSION} -
|
|
14
|
+
ai-tool v${VERSION} - Analise de dependencias e impacto
|
|
13
15
|
|
|
14
16
|
COMANDOS:
|
|
15
17
|
map Mapa completo do projeto (usa Skott)
|
|
16
|
-
dead Detecta
|
|
17
|
-
dead --fix Remove
|
|
18
|
-
impact <arquivo>
|
|
18
|
+
dead Detecta codigo morto (usa Knip)
|
|
19
|
+
dead --fix Remove codigo morto automaticamente
|
|
20
|
+
impact <arquivo> Analise de impacto antes de modificar
|
|
21
|
+
suggest <arquivo> Sugere arquivos para ler antes de modificar
|
|
22
|
+
context <arquivo> Extrai assinaturas de um arquivo (funcoes, tipos)
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
MODOS:
|
|
25
|
+
--mcp Inicia servidor MCP para integracao com Claude Desktop
|
|
26
|
+
|
|
27
|
+
OPCOES:
|
|
28
|
+
--format=text|json Formato de saida (default: text)
|
|
29
|
+
--cwd=<path> Diretorio do projeto (default: cwd)
|
|
30
|
+
--no-cache Ignora cache e forca regeneracao
|
|
31
|
+
--limit=<n> Limite de sugestoes (default: 10, apenas suggest)
|
|
24
32
|
--help, -h Mostra esta ajuda
|
|
25
|
-
--version, -v Mostra
|
|
33
|
+
--version, -v Mostra versao
|
|
26
34
|
|
|
27
35
|
CACHE:
|
|
28
|
-
Resultados
|
|
29
|
-
O cache
|
|
30
|
-
Use --no-cache para
|
|
36
|
+
Resultados sao salvos em .analyze/ para acelerar execucoes futuras.
|
|
37
|
+
O cache e invalidado automaticamente quando arquivos mudam.
|
|
38
|
+
Use --no-cache para forcar regeneracao.
|
|
31
39
|
|
|
32
40
|
EXEMPLOS:
|
|
33
41
|
ai-tool map
|
|
@@ -38,10 +46,15 @@ EXEMPLOS:
|
|
|
38
46
|
ai-tool impact Button
|
|
39
47
|
ai-tool impact src/hooks/useAuth.ts
|
|
40
48
|
ai-tool impact src/components/Header.tsx --format=json
|
|
49
|
+
ai-tool suggest Button
|
|
50
|
+
ai-tool suggest src/hooks/useAuth.ts --limit=5
|
|
51
|
+
ai-tool context Button
|
|
52
|
+
ai-tool context src/hooks/useAuth.ts --format=json
|
|
53
|
+
ai-tool --mcp
|
|
41
54
|
|
|
42
55
|
SOBRE:
|
|
43
56
|
Criado por Koda AI Studio (kodaai.app)
|
|
44
|
-
Usa Skott para
|
|
57
|
+
Usa Skott para analise de dependencias e Knip para dead code detection.
|
|
45
58
|
`;
|
|
46
59
|
async function main() {
|
|
47
60
|
const args = process.argv.slice(2);
|
|
@@ -58,6 +71,11 @@ async function main() {
|
|
|
58
71
|
positional.push(arg);
|
|
59
72
|
}
|
|
60
73
|
}
|
|
74
|
+
if (flags.mcp) {
|
|
75
|
+
const { startMcpServer } = await import("./server-YV4BWISA.js");
|
|
76
|
+
await startMcpServer();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
61
79
|
if (flags.help || flags.h || positional.length === 0) {
|
|
62
80
|
console.log(HELP);
|
|
63
81
|
process.exit(0);
|
|
@@ -93,6 +111,29 @@ async function main() {
|
|
|
93
111
|
}
|
|
94
112
|
result = await impact(target, { format, cwd, cache });
|
|
95
113
|
break;
|
|
114
|
+
case "suggest":
|
|
115
|
+
if (!target) {
|
|
116
|
+
console.error("\u274C Erro: arquivo alvo \xE9 obrigat\xF3rio para o comando suggest");
|
|
117
|
+
console.error(" Exemplo: ai-tool suggest src/components/Button.tsx");
|
|
118
|
+
console.error(" Exemplo: ai-tool suggest Button");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
result = await suggest(target, {
|
|
122
|
+
format,
|
|
123
|
+
cwd,
|
|
124
|
+
cache,
|
|
125
|
+
limit: flags.limit ? Number(flags.limit) : void 0
|
|
126
|
+
});
|
|
127
|
+
break;
|
|
128
|
+
case "context":
|
|
129
|
+
if (!target) {
|
|
130
|
+
console.error("\u274C Erro: arquivo alvo \xE9 obrigat\xF3rio para o comando context");
|
|
131
|
+
console.error(" Exemplo: ai-tool context src/components/Button.tsx");
|
|
132
|
+
console.error(" Exemplo: ai-tool context Button");
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
result = await context(target, { format, cwd });
|
|
136
|
+
break;
|
|
96
137
|
default:
|
|
97
138
|
console.error(`\u274C Comando desconhecido: ${command}`);
|
|
98
139
|
console.error(" Use 'ai-tool --help' para ver comandos dispon\xEDveis.");
|
package/dist/index.d.ts
CHANGED
|
@@ -95,6 +95,61 @@ interface ImpactResult {
|
|
|
95
95
|
risks: RiskInfo[];
|
|
96
96
|
suggestions: string[];
|
|
97
97
|
}
|
|
98
|
+
interface SuggestOptions extends CommandOptions {
|
|
99
|
+
limit?: number;
|
|
100
|
+
}
|
|
101
|
+
type SuggestionPriority = "critical" | "high" | "medium" | "low";
|
|
102
|
+
interface Suggestion {
|
|
103
|
+
path: string;
|
|
104
|
+
category: FileCategory;
|
|
105
|
+
reason: string;
|
|
106
|
+
priority: SuggestionPriority;
|
|
107
|
+
}
|
|
108
|
+
interface SuggestResult {
|
|
109
|
+
version: string;
|
|
110
|
+
timestamp: string;
|
|
111
|
+
target: string;
|
|
112
|
+
category: FileCategory;
|
|
113
|
+
suggestions: Suggestion[];
|
|
114
|
+
}
|
|
115
|
+
interface ContextOptions extends CommandOptions {
|
|
116
|
+
depth?: number;
|
|
117
|
+
}
|
|
118
|
+
interface ImportInfo {
|
|
119
|
+
source: string;
|
|
120
|
+
specifiers: string[];
|
|
121
|
+
isTypeOnly: boolean;
|
|
122
|
+
}
|
|
123
|
+
type ParamInfo = {
|
|
124
|
+
name: string;
|
|
125
|
+
type: string;
|
|
126
|
+
};
|
|
127
|
+
interface FunctionInfo {
|
|
128
|
+
name: string;
|
|
129
|
+
params: ParamInfo[];
|
|
130
|
+
returnType: string;
|
|
131
|
+
isAsync: boolean;
|
|
132
|
+
isExported: boolean;
|
|
133
|
+
isArrowFunction: boolean;
|
|
134
|
+
jsdoc?: string;
|
|
135
|
+
}
|
|
136
|
+
type TypeKind = "interface" | "type" | "enum";
|
|
137
|
+
interface TypeInfo {
|
|
138
|
+
name: string;
|
|
139
|
+
kind: TypeKind;
|
|
140
|
+
definition: string;
|
|
141
|
+
isExported: boolean;
|
|
142
|
+
}
|
|
143
|
+
interface ContextResult {
|
|
144
|
+
version: string;
|
|
145
|
+
timestamp: string;
|
|
146
|
+
file: string;
|
|
147
|
+
category: FileCategory;
|
|
148
|
+
imports: ImportInfo[];
|
|
149
|
+
exports: string[];
|
|
150
|
+
functions: FunctionInfo[];
|
|
151
|
+
types: TypeInfo[];
|
|
152
|
+
}
|
|
98
153
|
|
|
99
154
|
/**
|
|
100
155
|
* Comando MAP - Mapa do projeto usando Skott
|
|
@@ -127,6 +182,24 @@ declare function deadFix(options?: DeadOptions): Promise<string>;
|
|
|
127
182
|
*/
|
|
128
183
|
declare function impact(target: string, options?: ImpactOptions): Promise<string>;
|
|
129
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Comando SUGGEST - Sugere arquivos para ler antes de modificar um arquivo
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Executa o comando SUGGEST
|
|
191
|
+
*/
|
|
192
|
+
declare function suggest(target: string, options?: SuggestOptions): Promise<string>;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Comando CONTEXT - Extrai assinaturas de funcoes e tipos de um arquivo
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Executa o comando CONTEXT
|
|
200
|
+
*/
|
|
201
|
+
declare function context(target: string, options?: ContextOptions): Promise<string>;
|
|
202
|
+
|
|
130
203
|
/**
|
|
131
204
|
* Utilitários para detecção e classificação de arquivos
|
|
132
205
|
*/
|
|
@@ -181,6 +254,6 @@ declare function invalidateCache(cwd: string): void;
|
|
|
181
254
|
* ```
|
|
182
255
|
*/
|
|
183
256
|
|
|
184
|
-
declare const VERSION = "0.
|
|
257
|
+
declare const VERSION = "0.3.1";
|
|
185
258
|
|
|
186
|
-
export { type CommandOptions, type DeadFile, type DeadOptions, type DeadResult, type FileCategory, type FileInfo, type FolderStats, type ImpactFile, type ImpactOptions, type ImpactResult, type MapOptions, type MapResult, type OutputFormat, type RiskInfo, VERSION, categoryIcons, dead, deadFix, detectCategory, getCacheDir, impact, invalidateCache, isCacheValid, isCodeFile, isEntryPoint, map };
|
|
259
|
+
export { type CommandOptions, type ContextOptions, type ContextResult, type DeadFile, type DeadOptions, type DeadResult, type FileCategory, type FileInfo, type FolderStats, type FunctionInfo, type ImpactFile, type ImpactOptions, type ImpactResult, type ImportInfo, type MapOptions, type MapResult, type OutputFormat, type ParamInfo, type RiskInfo, type SuggestOptions, type SuggestResult, type Suggestion, type SuggestionPriority, type TypeInfo, type TypeKind, VERSION, categoryIcons, context, dead, deadFix, detectCategory, getCacheDir, impact, invalidateCache, isCacheValid, isCodeFile, isEntryPoint, map, suggest };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VERSION,
|
|
3
3
|
categoryIcons,
|
|
4
|
+
context,
|
|
4
5
|
dead,
|
|
5
6
|
deadFix,
|
|
6
7
|
detectCategory,
|
|
@@ -10,11 +11,13 @@ import {
|
|
|
10
11
|
isCacheValid,
|
|
11
12
|
isCodeFile,
|
|
12
13
|
isEntryPoint,
|
|
13
|
-
map
|
|
14
|
-
|
|
14
|
+
map,
|
|
15
|
+
suggest
|
|
16
|
+
} from "./chunk-4HXWM7PK.js";
|
|
15
17
|
export {
|
|
16
18
|
VERSION,
|
|
17
19
|
categoryIcons,
|
|
20
|
+
context,
|
|
18
21
|
dead,
|
|
19
22
|
deadFix,
|
|
20
23
|
detectCategory,
|
|
@@ -24,5 +27,6 @@ export {
|
|
|
24
27
|
isCacheValid,
|
|
25
28
|
isCodeFile,
|
|
26
29
|
isEntryPoint,
|
|
27
|
-
map
|
|
30
|
+
map,
|
|
31
|
+
suggest
|
|
28
32
|
};
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VERSION,
|
|
3
|
+
context,
|
|
4
|
+
dead,
|
|
5
|
+
impact,
|
|
6
|
+
map,
|
|
7
|
+
suggest
|
|
8
|
+
} from "./chunk-4HXWM7PK.js";
|
|
9
|
+
|
|
10
|
+
// src/mcp/server.ts
|
|
11
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
var server = new McpServer({
|
|
15
|
+
name: "ai-tool-mcp-server",
|
|
16
|
+
version: VERSION
|
|
17
|
+
});
|
|
18
|
+
server.registerTool(
|
|
19
|
+
"aitool_project_map",
|
|
20
|
+
{
|
|
21
|
+
title: "Project Map",
|
|
22
|
+
description: `Gera um mapa completo do projeto com categorias de arquivos e estrutura de pastas.
|
|
23
|
+
|
|
24
|
+
FUNCIONALIDADES:
|
|
25
|
+
- Lista todos os arquivos TypeScript/JavaScript do projeto
|
|
26
|
+
- Categoriza automaticamente: page, layout, route, component, hook, service, store, util, type, config, test
|
|
27
|
+
- Agrupa estatisticas por pasta
|
|
28
|
+
- Detecta dependencias circulares
|
|
29
|
+
|
|
30
|
+
PARAMETROS:
|
|
31
|
+
- format: "text" (legivel) ou "json" (estruturado)
|
|
32
|
+
- cwd: Diretorio do projeto (default: diretorio atual)
|
|
33
|
+
|
|
34
|
+
RETORNA:
|
|
35
|
+
- Sumario com total de arquivos e pastas
|
|
36
|
+
- Distribuicao por categoria
|
|
37
|
+
- Lista de pastas com contagem
|
|
38
|
+
- Lista de arquivos com categoria
|
|
39
|
+
- Dependencias circulares detectadas
|
|
40
|
+
|
|
41
|
+
EXEMPLO DE USO:
|
|
42
|
+
Chamar para entender a estrutura de um projeto antes de modificar.`,
|
|
43
|
+
inputSchema: {
|
|
44
|
+
format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
|
|
45
|
+
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
46
|
+
},
|
|
47
|
+
annotations: {
|
|
48
|
+
title: "Project Map",
|
|
49
|
+
readOnlyHint: true,
|
|
50
|
+
destructiveHint: false,
|
|
51
|
+
idempotentHint: true,
|
|
52
|
+
openWorldHint: false
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
async (params) => {
|
|
56
|
+
try {
|
|
57
|
+
const result = await map({
|
|
58
|
+
format: params.format,
|
|
59
|
+
cwd: params.cwd
|
|
60
|
+
});
|
|
61
|
+
return { content: [{ type: "text", text: result }] };
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Erro ao executar map: ${error instanceof Error ? error.message : String(error)}`
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
isError: true
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
server.registerTool(
|
|
76
|
+
"aitool_dead_code",
|
|
77
|
+
{
|
|
78
|
+
title: "Dead Code Detector",
|
|
79
|
+
description: `Detecta codigo morto no projeto usando Knip.
|
|
80
|
+
|
|
81
|
+
DETECTA:
|
|
82
|
+
- Arquivos orfaos (nao importados por ninguem)
|
|
83
|
+
- Exports nao utilizados
|
|
84
|
+
- Dependencias npm nao usadas
|
|
85
|
+
|
|
86
|
+
PARAMETROS:
|
|
87
|
+
- format: "text" (legivel) ou "json" (estruturado)
|
|
88
|
+
- cwd: Diretorio do projeto (default: diretorio atual)
|
|
89
|
+
|
|
90
|
+
RETORNA:
|
|
91
|
+
- Sumario com total de codigo morto por tipo
|
|
92
|
+
- Lista de arquivos orfaos com categoria
|
|
93
|
+
- Lista de exports nao usados (arquivo + nome)
|
|
94
|
+
- Lista de dependencias npm nao usadas
|
|
95
|
+
|
|
96
|
+
EXEMPLO DE USO:
|
|
97
|
+
Chamar periodicamente para manter o projeto limpo.
|
|
98
|
+
Chamar antes de refatoracoes para identificar codigo removivel.
|
|
99
|
+
|
|
100
|
+
NOTA: Requer que o projeto tenha knip configurado ou use defaults.`,
|
|
101
|
+
inputSchema: {
|
|
102
|
+
format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
|
|
103
|
+
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
104
|
+
},
|
|
105
|
+
annotations: {
|
|
106
|
+
title: "Dead Code Detector",
|
|
107
|
+
readOnlyHint: true,
|
|
108
|
+
destructiveHint: false,
|
|
109
|
+
idempotentHint: true,
|
|
110
|
+
openWorldHint: false
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
async (params) => {
|
|
114
|
+
try {
|
|
115
|
+
const result = await dead({
|
|
116
|
+
format: params.format,
|
|
117
|
+
cwd: params.cwd
|
|
118
|
+
});
|
|
119
|
+
return { content: [{ type: "text", text: result }] };
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return {
|
|
122
|
+
content: [
|
|
123
|
+
{
|
|
124
|
+
type: "text",
|
|
125
|
+
text: `Erro ao executar dead: ${error instanceof Error ? error.message : String(error)}`
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
isError: true
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
server.registerTool(
|
|
134
|
+
"aitool_impact_analysis",
|
|
135
|
+
{
|
|
136
|
+
title: "Impact Analysis",
|
|
137
|
+
description: `Analisa o impacto de modificar um arquivo especifico.
|
|
138
|
+
|
|
139
|
+
ANALISA:
|
|
140
|
+
- UPSTREAM: Quem importa este arquivo (direto e indireto)
|
|
141
|
+
- DOWNSTREAM: O que este arquivo importa (direto e indireto)
|
|
142
|
+
- RISCOS: Arquivo critico, dependencias circulares, cadeia profunda
|
|
143
|
+
- SUGESTOES: O que verificar antes de modificar
|
|
144
|
+
|
|
145
|
+
PARAMETROS:
|
|
146
|
+
- target: Nome ou caminho do arquivo a analisar (obrigatorio)
|
|
147
|
+
- format: "text" (legivel) ou "json" (estruturado)
|
|
148
|
+
- cwd: Diretorio do projeto (default: diretorio atual)
|
|
149
|
+
|
|
150
|
+
O TARGET pode ser:
|
|
151
|
+
- Caminho completo: "src/components/Button.tsx"
|
|
152
|
+
- Caminho parcial: "components/Button"
|
|
153
|
+
- Nome do arquivo: "Button"
|
|
154
|
+
|
|
155
|
+
RETORNA:
|
|
156
|
+
- Categoria do arquivo target
|
|
157
|
+
- Lista de arquivos upstream (quem importa)
|
|
158
|
+
- Lista de arquivos downstream (o que importa)
|
|
159
|
+
- Alertas de risco com severidade
|
|
160
|
+
- Sugestoes de como proceder
|
|
161
|
+
|
|
162
|
+
EXEMPLO DE USO:
|
|
163
|
+
Chamar ANTES de modificar um arquivo para entender o impacto.
|
|
164
|
+
Usar para planejar refatoracoes seguras.`,
|
|
165
|
+
inputSchema: {
|
|
166
|
+
target: z.string().min(1).describe(
|
|
167
|
+
"Arquivo a analisar: caminho completo, parcial ou nome do arquivo"
|
|
168
|
+
),
|
|
169
|
+
format: z.enum(["text", "json"]).default("text").describe("Formato de saida: text (legivel) ou json (estruturado)"),
|
|
170
|
+
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
171
|
+
},
|
|
172
|
+
annotations: {
|
|
173
|
+
title: "Impact Analysis",
|
|
174
|
+
readOnlyHint: true,
|
|
175
|
+
destructiveHint: false,
|
|
176
|
+
idempotentHint: true,
|
|
177
|
+
openWorldHint: false
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
async (params) => {
|
|
181
|
+
try {
|
|
182
|
+
const result = await impact(params.target, {
|
|
183
|
+
format: params.format,
|
|
184
|
+
cwd: params.cwd
|
|
185
|
+
});
|
|
186
|
+
return { content: [{ type: "text", text: result }] };
|
|
187
|
+
} catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: "text",
|
|
192
|
+
text: `Erro ao executar impact: ${error instanceof Error ? error.message : String(error)}`
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
isError: true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
server.registerTool(
|
|
201
|
+
"aitool_suggest_reads",
|
|
202
|
+
{
|
|
203
|
+
title: "Suggest Files to Read",
|
|
204
|
+
description: `Sugere arquivos que devem ser lidos ANTES de modificar um arquivo especifico.
|
|
205
|
+
|
|
206
|
+
PRIORIZA (nesta ordem):
|
|
207
|
+
1. CRITICAL: Arquivos de tipos/interfaces usados pelo target
|
|
208
|
+
2. HIGH: Dependencias diretas (arquivos importados pelo target)
|
|
209
|
+
3. MEDIUM: Upstream (arquivos que importam o target)
|
|
210
|
+
4. LOW: Testes relacionados
|
|
211
|
+
|
|
212
|
+
PARAMETROS:
|
|
213
|
+
- target: Nome ou caminho do arquivo que sera modificado (obrigatorio)
|
|
214
|
+
- limit: Numero maximo de sugestoes (default: 10, max: 50)
|
|
215
|
+
- cwd: Diretorio do projeto (default: diretorio atual)
|
|
216
|
+
|
|
217
|
+
O TARGET pode ser:
|
|
218
|
+
- Caminho completo: "src/components/Button.tsx"
|
|
219
|
+
- Caminho parcial: "components/Button"
|
|
220
|
+
- Nome do arquivo: "Button"
|
|
221
|
+
|
|
222
|
+
RETORNA:
|
|
223
|
+
- Lista ordenada de arquivos para ler
|
|
224
|
+
- Cada sugestao tem: path, categoria, razao, prioridade
|
|
225
|
+
|
|
226
|
+
EXEMPLO DE USO:
|
|
227
|
+
Chamar ANTES de modificar um arquivo para saber o que ler primeiro.
|
|
228
|
+
Util para entender o contexto completo antes de fazer mudancas.`,
|
|
229
|
+
inputSchema: {
|
|
230
|
+
target: z.string().min(1).describe(
|
|
231
|
+
"Arquivo que sera modificado: caminho completo, parcial ou nome"
|
|
232
|
+
),
|
|
233
|
+
limit: z.number().int().min(1).max(50).default(10).describe("Numero maximo de sugestoes (default: 10)"),
|
|
234
|
+
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
235
|
+
},
|
|
236
|
+
annotations: {
|
|
237
|
+
title: "Suggest Files to Read",
|
|
238
|
+
readOnlyHint: true,
|
|
239
|
+
destructiveHint: false,
|
|
240
|
+
idempotentHint: true,
|
|
241
|
+
openWorldHint: false
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
async (params) => {
|
|
245
|
+
try {
|
|
246
|
+
const result = await suggest(params.target, {
|
|
247
|
+
limit: params.limit,
|
|
248
|
+
cwd: params.cwd,
|
|
249
|
+
format: "text"
|
|
250
|
+
});
|
|
251
|
+
return { content: [{ type: "text", text: result }] };
|
|
252
|
+
} catch (error) {
|
|
253
|
+
return {
|
|
254
|
+
content: [
|
|
255
|
+
{
|
|
256
|
+
type: "text",
|
|
257
|
+
text: `Erro ao executar suggest: ${error instanceof Error ? error.message : String(error)}`
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
isError: true
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
server.registerTool(
|
|
266
|
+
"aitool_file_context",
|
|
267
|
+
{
|
|
268
|
+
title: "Extract File Context",
|
|
269
|
+
description: `Extrai assinaturas de funcoes e tipos de um arquivo SEM a implementacao.
|
|
270
|
+
|
|
271
|
+
EXTRAI:
|
|
272
|
+
- IMPORTS: Todos os imports com specifiers e se sao type-only
|
|
273
|
+
- EXPORTS: Lista de tudo que e exportado
|
|
274
|
+
- FUNCOES: Nome, parametros (com tipos), retorno, async, arrow, JSDoc
|
|
275
|
+
- TIPOS: Interfaces, types e enums com suas definicoes completas
|
|
276
|
+
|
|
277
|
+
NAO INCLUI:
|
|
278
|
+
- Corpo das funcoes (implementacao)
|
|
279
|
+
- Logica interna
|
|
280
|
+
- Comentarios inline
|
|
281
|
+
|
|
282
|
+
PARAMETROS:
|
|
283
|
+
- target: Nome ou caminho do arquivo (obrigatorio)
|
|
284
|
+
- cwd: Diretorio do projeto (default: diretorio atual)
|
|
285
|
+
|
|
286
|
+
O TARGET pode ser:
|
|
287
|
+
- Caminho completo: "src/components/Button.tsx"
|
|
288
|
+
- Caminho parcial: "components/Button"
|
|
289
|
+
- Nome do arquivo: "Button"
|
|
290
|
+
|
|
291
|
+
RETORNA:
|
|
292
|
+
- Arquivo com categoria detectada
|
|
293
|
+
- Lista de imports estruturada
|
|
294
|
+
- Lista de exports
|
|
295
|
+
- Lista de funcoes com assinaturas completas
|
|
296
|
+
- Lista de tipos com definicoes
|
|
297
|
+
|
|
298
|
+
EXEMPLO DE USO:
|
|
299
|
+
Chamar para entender a API publica de um arquivo antes de usa-lo.
|
|
300
|
+
Util para saber quais funcoes/tipos um arquivo exporta.
|
|
301
|
+
Eficiente: retorna apenas assinaturas, nao o codigo completo.`,
|
|
302
|
+
inputSchema: {
|
|
303
|
+
target: z.string().min(1).describe(
|
|
304
|
+
"Arquivo para extrair contexto: caminho completo, parcial ou nome"
|
|
305
|
+
),
|
|
306
|
+
cwd: z.string().optional().describe("Diretorio do projeto a analisar")
|
|
307
|
+
},
|
|
308
|
+
annotations: {
|
|
309
|
+
title: "Extract File Context",
|
|
310
|
+
readOnlyHint: true,
|
|
311
|
+
destructiveHint: false,
|
|
312
|
+
idempotentHint: true,
|
|
313
|
+
openWorldHint: false
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
async (params) => {
|
|
317
|
+
try {
|
|
318
|
+
const result = await context(params.target, {
|
|
319
|
+
cwd: params.cwd,
|
|
320
|
+
format: "text"
|
|
321
|
+
});
|
|
322
|
+
return { content: [{ type: "text", text: result }] };
|
|
323
|
+
} catch (error) {
|
|
324
|
+
return {
|
|
325
|
+
content: [
|
|
326
|
+
{
|
|
327
|
+
type: "text",
|
|
328
|
+
text: `Erro ao executar context: ${error instanceof Error ? error.message : String(error)}`
|
|
329
|
+
}
|
|
330
|
+
],
|
|
331
|
+
isError: true
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
);
|
|
336
|
+
async function startMcpServer() {
|
|
337
|
+
const transport = new StdioServerTransport();
|
|
338
|
+
await server.connect(transport);
|
|
339
|
+
console.error(`[ai-tool] MCP server v${VERSION} running via stdio`);
|
|
340
|
+
}
|
|
341
|
+
export {
|
|
342
|
+
startMcpServer
|
|
343
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justmpm/ai-tool",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.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",
|
|
@@ -43,8 +43,11 @@
|
|
|
43
43
|
"typecheck": "tsc --noEmit"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
46
47
|
"knip": "^5.44.0",
|
|
47
|
-
"skott": "^0.35.2"
|
|
48
|
+
"skott": "^0.35.2",
|
|
49
|
+
"ts-morph": "^27.0.2",
|
|
50
|
+
"zod": "^3.25.76"
|
|
48
51
|
},
|
|
49
52
|
"devDependencies": {
|
|
50
53
|
"@types/node": "^22.15.21",
|