@justmpm/ai-tool 3.23.0 → 4.0.0
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/{chunk-WTRV35AO.js → chunk-BFOWLQIL.js} +23 -581
- package/dist/chunk-OQSQWBJV.js +387 -0
- package/dist/cli.js +4 -58
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{server-3HLEATUD.js → server-QFWWHDJY.js} +2 -157
- package/package.json +4 -2
- package/dist/chunk-4Z6PUAFR.js +0 -2185
|
@@ -201,18 +201,6 @@ var COMMAND_MAP = {
|
|
|
201
201
|
changes_staged: {
|
|
202
202
|
cli: "ai-tool changes --staged",
|
|
203
203
|
mcp: "analyze__aitool_changes { target: 'staged' }"
|
|
204
|
-
},
|
|
205
|
-
deps_info: {
|
|
206
|
-
cli: "ai-tool deps info <pacote>",
|
|
207
|
-
mcp: "analyze__aitool_deps_info { package: '<pacote>' }"
|
|
208
|
-
},
|
|
209
|
-
deps_api: {
|
|
210
|
-
cli: "ai-tool deps api <pacote>",
|
|
211
|
-
mcp: "analyze__aitool_deps_api { package: '<pacote>' }"
|
|
212
|
-
},
|
|
213
|
-
deps_search: {
|
|
214
|
-
cli: "ai-tool deps search <pacote> <termo>",
|
|
215
|
-
mcp: "analyze__aitool_deps_search { package: '<pacote>', query: '<termo>' }"
|
|
216
204
|
}
|
|
217
205
|
};
|
|
218
206
|
function hint(command, ctx, params) {
|
|
@@ -282,18 +270,6 @@ var NEXT_STEPS = {
|
|
|
282
270
|
{ command: "context", description: "ver assinaturas atuais de um arquivo modificado" },
|
|
283
271
|
{ command: "impact", description: "ver impacto das mudancas em outros arquivos" },
|
|
284
272
|
{ command: "suggest", description: "o que ler antes de editar um arquivo modificado" }
|
|
285
|
-
],
|
|
286
|
-
deps_info: [
|
|
287
|
-
{ command: "deps_api", description: "ver API publica do pacote" },
|
|
288
|
-
{ command: "deps_search", description: "buscar simbolo especifico no pacote" }
|
|
289
|
-
],
|
|
290
|
-
deps_api: [
|
|
291
|
-
{ command: "deps_search", description: "buscar simbolo especifico" },
|
|
292
|
-
{ command: "deps_info", description: "ver metadados do pacote" }
|
|
293
|
-
],
|
|
294
|
-
deps_search: [
|
|
295
|
-
{ command: "deps_api", description: "ver toda a API publica" },
|
|
296
|
-
{ command: "deps_info", description: "ver metadados do pacote" }
|
|
297
273
|
]
|
|
298
274
|
};
|
|
299
275
|
function nextSteps(command, ctx) {
|
|
@@ -340,8 +316,16 @@ function recoveryHint(errorType, ctx, _extra) {
|
|
|
340
316
|
return `
|
|
341
317
|
\u{1F4A1} Nenhuma area configurada neste projeto.
|
|
342
318
|
\u2192 ${hint("areas_init", ctx)} - gerar arquivo de configuracao
|
|
343
|
-
\u2192 Depois edite .analyze/areas.config.json com as areas do projeto
|
|
344
319
|
\u2192 ${hint("map", ctx)} - ver estrutura do projeto sem areas
|
|
320
|
+
|
|
321
|
+
Como configurar o areas.config.json:
|
|
322
|
+
- patterns: glob para pastas (ex: "app/dashboard/**", "hooks/usePets.*")
|
|
323
|
+
- keywords: substring no path, case-insensitive (ex: ["pet", "animal"])
|
|
324
|
+
- exclude: remove falsos positivos de uma area (ex: "components/pets/shared/**")
|
|
325
|
+
- descriptions: contexto manual para arquivos importantes (aparece no suggest, context, changes)
|
|
326
|
+
- settings.inferDescriptions: true para inferir descricoes automaticamente pelo nome do arquivo
|
|
327
|
+
- Um arquivo pode pertencer a multiplas areas
|
|
328
|
+
- Ideal: 5 a 15 areas (muitas = dificil de navegar)
|
|
345
329
|
`;
|
|
346
330
|
case "symbol_not_found":
|
|
347
331
|
return `
|
|
@@ -351,12 +335,6 @@ function recoveryHint(errorType, ctx, _extra) {
|
|
|
351
335
|
\u2192 ${hint("find", ctx)} - buscar com outro termo
|
|
352
336
|
\u2192 ${hint("describe", ctx)} - buscar areas por descricao
|
|
353
337
|
\u2192 ${hint("map", ctx)} - ver estrutura do projeto
|
|
354
|
-
`;
|
|
355
|
-
case "package_not_found":
|
|
356
|
-
return `
|
|
357
|
-
\u{1F4A1} Pacote nao encontrado no node_modules.
|
|
358
|
-
\u2192 Verifique se o pacote esta instalado no projeto
|
|
359
|
-
\u2192 ${hint("deps_info", ctx)} - use deps info para confirmar se esta instalado
|
|
360
338
|
`;
|
|
361
339
|
case "index_failed":
|
|
362
340
|
return `
|
|
@@ -374,77 +352,6 @@ function recoveryHint(errorType, ctx, _extra) {
|
|
|
374
352
|
}
|
|
375
353
|
}
|
|
376
354
|
|
|
377
|
-
// src/utils/semver.ts
|
|
378
|
-
function parseVersion(version) {
|
|
379
|
-
const trimmed = version.trim();
|
|
380
|
-
const clean = trimmed.startsWith("v") ? trimmed.slice(1) : trimmed;
|
|
381
|
-
const parts = clean.split(".");
|
|
382
|
-
if (parts.length < 2) return null;
|
|
383
|
-
const major = parseInt(parts[0], 10);
|
|
384
|
-
if (isNaN(major)) return null;
|
|
385
|
-
const minor = parseInt(parts[1], 10);
|
|
386
|
-
if (isNaN(minor)) return null;
|
|
387
|
-
const patch = parts.length >= 3 ? parseInt(parts[2], 10) : 0;
|
|
388
|
-
if (isNaN(patch)) return null;
|
|
389
|
-
return { major, minor, patch };
|
|
390
|
-
}
|
|
391
|
-
function compareSemver(a, b) {
|
|
392
|
-
if (a.major !== b.major) return a.major < b.major ? -1 : 1;
|
|
393
|
-
if (a.minor !== b.minor) return a.minor < b.minor ? -1 : 1;
|
|
394
|
-
if (a.patch !== b.patch) return a.patch < b.patch ? -1 : 1;
|
|
395
|
-
return 0;
|
|
396
|
-
}
|
|
397
|
-
function satisfiesComparator(installed, comparator) {
|
|
398
|
-
const trimmed = comparator.trim();
|
|
399
|
-
if (trimmed.startsWith("^")) {
|
|
400
|
-
const target = parseVersion(trimmed.slice(1));
|
|
401
|
-
if (!target) return true;
|
|
402
|
-
return installed.major === target.major && compareSemver(installed, target) >= 0;
|
|
403
|
-
}
|
|
404
|
-
if (trimmed.startsWith("~")) {
|
|
405
|
-
const target = parseVersion(trimmed.slice(1));
|
|
406
|
-
if (!target) return true;
|
|
407
|
-
return installed.major === target.major && installed.minor === target.minor && compareSemver(installed, target) >= 0;
|
|
408
|
-
}
|
|
409
|
-
if (trimmed.startsWith(">=")) {
|
|
410
|
-
const target = parseVersion(trimmed.slice(2));
|
|
411
|
-
if (!target) return true;
|
|
412
|
-
return compareSemver(installed, target) >= 0;
|
|
413
|
-
}
|
|
414
|
-
if (trimmed.startsWith("<=")) {
|
|
415
|
-
const target = parseVersion(trimmed.slice(2));
|
|
416
|
-
if (!target) return true;
|
|
417
|
-
return compareSemver(installed, target) <= 0;
|
|
418
|
-
}
|
|
419
|
-
if (trimmed.startsWith(">") && !trimmed.startsWith(">=")) {
|
|
420
|
-
const target = parseVersion(trimmed.slice(1));
|
|
421
|
-
if (!target) return true;
|
|
422
|
-
return compareSemver(installed, target) > 0;
|
|
423
|
-
}
|
|
424
|
-
if (trimmed.startsWith("<") && !trimmed.startsWith("<=")) {
|
|
425
|
-
const target = parseVersion(trimmed.slice(1));
|
|
426
|
-
if (!target) return true;
|
|
427
|
-
return compareSemver(installed, target) < 0;
|
|
428
|
-
}
|
|
429
|
-
const exact = parseVersion(trimmed);
|
|
430
|
-
if (!exact) return true;
|
|
431
|
-
return compareSemver(installed, exact) === 0;
|
|
432
|
-
}
|
|
433
|
-
function satisfiesSemver(installed, declared) {
|
|
434
|
-
const installedVersion = parseVersion(installed);
|
|
435
|
-
if (!installedVersion) return true;
|
|
436
|
-
const orParts = declared.split("||");
|
|
437
|
-
for (const orPart of orParts) {
|
|
438
|
-
const comparators = orPart.trim().split(/\s+/).filter((c) => c.length > 0);
|
|
439
|
-
if (comparators.length === 0) continue;
|
|
440
|
-
const allSatisfy = comparators.every(
|
|
441
|
-
(comp) => satisfiesComparator(installedVersion, comp)
|
|
442
|
-
);
|
|
443
|
-
if (allSatisfy) return true;
|
|
444
|
-
}
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
355
|
// src/utils/similarity.ts
|
|
449
356
|
function levenshteinDistance(a, b) {
|
|
450
357
|
const matrix = [];
|
|
@@ -626,6 +533,8 @@ function formatMapSummary(result, areasInfo, ctx = "cli") {
|
|
|
626
533
|
out += ` \u2192 ${hint("areas_missing", ctx)} para ver quais arquivos estao sem area
|
|
627
534
|
`;
|
|
628
535
|
out += ` \u2192 ${hint("areas_init", ctx)} para criar/editar areas.config
|
|
536
|
+
`;
|
|
537
|
+
out += ` Boas praticas: patterns (glob exato) para pastas, keywords (case-insensitive) para arquivos espalhados, exclude para falsos positivos
|
|
629
538
|
|
|
630
539
|
`;
|
|
631
540
|
}
|
|
@@ -1895,65 +1804,6 @@ AFFECTED AREAS:
|
|
|
1895
1804
|
const semanticFiles = result.files.filter((f) => f.changes.length > 0 && !f.newFile);
|
|
1896
1805
|
const newFiles = result.files.filter((f) => f.newFile);
|
|
1897
1806
|
const otherFiles = result.files.filter((f) => f.changes.length === 0 && !f.newFile);
|
|
1898
|
-
const COMPACT_THRESHOLD = 10;
|
|
1899
|
-
const filesExceedThreshold = semanticFiles.length + newFiles.length > COMPACT_THRESHOLD;
|
|
1900
|
-
if (filesExceedThreshold) {
|
|
1901
|
-
out += `
|
|
1902
|
-
COMPACT MODE: Too many files. Use --file=<path> for details.
|
|
1903
|
-
|
|
1904
|
-
`;
|
|
1905
|
-
const modifiedCompact = result.files.filter((f) => !f.newFile);
|
|
1906
|
-
const renamedCompact = modifiedCompact.filter((f) => f.renamed);
|
|
1907
|
-
const otherModifiedCompact = modifiedCompact.filter((f) => !f.renamed);
|
|
1908
|
-
if (otherModifiedCompact.length > 0) {
|
|
1909
|
-
out += `Modified files:
|
|
1910
|
-
`;
|
|
1911
|
-
for (const file of otherModifiedCompact) {
|
|
1912
|
-
const changeCount = file.changes.length;
|
|
1913
|
-
out += ` ${file.path} (+${file.stats.added} -${file.stats.removed})`;
|
|
1914
|
-
if (changeCount > 0) {
|
|
1915
|
-
out += ` - ${changeCount} changes`;
|
|
1916
|
-
} else {
|
|
1917
|
-
out += ` - (no semantic changes)`;
|
|
1918
|
-
}
|
|
1919
|
-
out += `
|
|
1920
|
-
`;
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
if (renamedCompact.length > 0) {
|
|
1924
|
-
out += `
|
|
1925
|
-
Renamed files:
|
|
1926
|
-
`;
|
|
1927
|
-
for (const file of renamedCompact) {
|
|
1928
|
-
out += ` ${file.renamedFrom} -> ${file.path} (+${file.stats.added} -${file.stats.removed})`;
|
|
1929
|
-
const changeCount = file.changes.length;
|
|
1930
|
-
if (changeCount > 0) {
|
|
1931
|
-
out += ` - ${changeCount} changes`;
|
|
1932
|
-
}
|
|
1933
|
-
out += `
|
|
1934
|
-
`;
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
if (newFiles.length > 0) {
|
|
1938
|
-
out += `
|
|
1939
|
-
New files (untracked):
|
|
1940
|
-
`;
|
|
1941
|
-
for (const file of newFiles) {
|
|
1942
|
-
const changeCount = file.changes.length;
|
|
1943
|
-
out += ` ${file.path} (+${file.stats.added} new)`;
|
|
1944
|
-
if (changeCount > 0) {
|
|
1945
|
-
out += ` - ${changeCount} symbols`;
|
|
1946
|
-
}
|
|
1947
|
-
out += `
|
|
1948
|
-
`;
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
out += `
|
|
1952
|
-
Use: ${hint("changes", ctx)} --file=<arquivo>
|
|
1953
|
-
`;
|
|
1954
|
-
out += nextSteps("changes", ctx);
|
|
1955
|
-
return out;
|
|
1956
|
-
}
|
|
1957
1807
|
for (const file of semanticFiles) {
|
|
1958
1808
|
out += `
|
|
1959
1809
|
--- ${file.path} (+${file.stats.added} -${file.stats.removed}) ---
|
|
@@ -2147,410 +1997,6 @@ function formatUsageExamples(examples, indent = 2) {
|
|
|
2147
1997
|
}
|
|
2148
1998
|
return out;
|
|
2149
1999
|
}
|
|
2150
|
-
function formatDepsInfoText(result, ctx = "cli") {
|
|
2151
|
-
let out = "";
|
|
2152
|
-
const info = result.info;
|
|
2153
|
-
const name = info.name || result.package;
|
|
2154
|
-
out += `${name} v${info.version}`;
|
|
2155
|
-
out += `
|
|
2156
|
-
`;
|
|
2157
|
-
if (result.declaredVersion) {
|
|
2158
|
-
if (satisfiesSemver(info.version, result.declaredVersion)) {
|
|
2159
|
-
out += ` Status: OK
|
|
2160
|
-
`;
|
|
2161
|
-
} else {
|
|
2162
|
-
out += ` Status: desatualizada (declarada: ${result.declaredVersion})
|
|
2163
|
-
`;
|
|
2164
|
-
}
|
|
2165
|
-
}
|
|
2166
|
-
if (info.description) {
|
|
2167
|
-
out += ` Descricao: ${info.description}
|
|
2168
|
-
`;
|
|
2169
|
-
}
|
|
2170
|
-
if (info.hasTypes) {
|
|
2171
|
-
if (info.typesSource === "@types" && info.typesPackage) {
|
|
2172
|
-
out += ` Tipos: ${info.typesPackage} (pacote separado)
|
|
2173
|
-
`;
|
|
2174
|
-
} else if (info.types) {
|
|
2175
|
-
out += ` Tipos: ${info.types}
|
|
2176
|
-
`;
|
|
2177
|
-
} else if (info.typings) {
|
|
2178
|
-
out += ` Tipos: ${info.typings}
|
|
2179
|
-
`;
|
|
2180
|
-
} else {
|
|
2181
|
-
out += ` Tipos: embutidos (via exports)
|
|
2182
|
-
`;
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
const mainEntries = result.entryPoints.filter(
|
|
2186
|
-
(ep) => ep.type === "main" || ep.type === "types" || ep.type === "module"
|
|
2187
|
-
);
|
|
2188
|
-
const otherCount = result.entryPoints.length - mainEntries.length;
|
|
2189
|
-
out += ` Entry points: (${result.entryPoints.length})
|
|
2190
|
-
`;
|
|
2191
|
-
const topLevel = mainEntries.filter((ep) => {
|
|
2192
|
-
const conditions = ep.condition.split(", ");
|
|
2193
|
-
return conditions.every((c) => !c.startsWith("./"));
|
|
2194
|
-
});
|
|
2195
|
-
const subExports = mainEntries.filter((ep) => {
|
|
2196
|
-
const conditions = ep.condition.split(", ");
|
|
2197
|
-
return conditions.some((c) => c.startsWith("./"));
|
|
2198
|
-
});
|
|
2199
|
-
for (const ep of topLevel) {
|
|
2200
|
-
const fileName = ep.path.split(/[\\/]/).pop() || ep.path;
|
|
2201
|
-
const conditions = ep.condition.split(", ");
|
|
2202
|
-
if (conditions.length > 1) {
|
|
2203
|
-
out += ` ${ep.type}: ${fileName} [${conditions.length} conditions]
|
|
2204
|
-
`;
|
|
2205
|
-
} else {
|
|
2206
|
-
out += ` ${ep.type}: ${fileName}
|
|
2207
|
-
`;
|
|
2208
|
-
}
|
|
2209
|
-
}
|
|
2210
|
-
if (subExports.length > 0) {
|
|
2211
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
2212
|
-
for (const ep of subExports) {
|
|
2213
|
-
const conditions = ep.condition.split(", ");
|
|
2214
|
-
const subExportCondition = conditions.find((c) => c.startsWith("./"));
|
|
2215
|
-
if (!subExportCondition) continue;
|
|
2216
|
-
const exportKeyMatch = subExportCondition.match(/^(\.\/[^/]+)/);
|
|
2217
|
-
const exportKey = exportKeyMatch ? exportKeyMatch[1] : subExportCondition;
|
|
2218
|
-
const existing = grouped.get(exportKey);
|
|
2219
|
-
if (existing) {
|
|
2220
|
-
existing.push({ condition: subExportCondition, path: ep.path, type: ep.type });
|
|
2221
|
-
} else {
|
|
2222
|
-
grouped.set(exportKey, [{ condition: subExportCondition, path: ep.path, type: ep.type }]);
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
out += ` Sub-exports (${grouped.size}):
|
|
2226
|
-
`;
|
|
2227
|
-
for (const [exportKey, entries] of grouped) {
|
|
2228
|
-
const moduleName = exportKey.replace(/^\.\//, "");
|
|
2229
|
-
const normalizedPath = entries[0].path.replace(/\\/g, "/");
|
|
2230
|
-
const pkgMatch = normalizedPath.match(/node_modules\/[^/]+\/(.+)/);
|
|
2231
|
-
const relativePath = pkgMatch ? pkgMatch[1] : normalizedPath.split(/[\\/]/).pop() || entries[0].path;
|
|
2232
|
-
if (entries.length === 1) {
|
|
2233
|
-
out += ` ${moduleName}: ${relativePath}
|
|
2234
|
-
`;
|
|
2235
|
-
} else {
|
|
2236
|
-
const variantNames = entries.map((e) => {
|
|
2237
|
-
const cond = e.condition.split(", ").find((c) => c.startsWith("./"));
|
|
2238
|
-
return cond?.replace(/^\.\/[^/]+\//, "") || "";
|
|
2239
|
-
}).filter(Boolean);
|
|
2240
|
-
out += ` ${moduleName}: ${relativePath} [${variantNames.join(", ")}]
|
|
2241
|
-
`;
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
if (otherCount > 0) {
|
|
2246
|
-
out += ` + ${otherCount} condicional(is) via exports
|
|
2247
|
-
`;
|
|
2248
|
-
}
|
|
2249
|
-
if (info.repository) {
|
|
2250
|
-
out += ` Repository: ${info.repository}
|
|
2251
|
-
`;
|
|
2252
|
-
}
|
|
2253
|
-
if (info.homepage) {
|
|
2254
|
-
out += ` Homepage: ${info.homepage}
|
|
2255
|
-
`;
|
|
2256
|
-
}
|
|
2257
|
-
if (info.license) {
|
|
2258
|
-
out += ` License: ${info.license}
|
|
2259
|
-
`;
|
|
2260
|
-
}
|
|
2261
|
-
const peerDeps = Object.entries(info.peerDependencies);
|
|
2262
|
-
if (peerDeps.length > 0) {
|
|
2263
|
-
out += `
|
|
2264
|
-
Peer dependencies (${peerDeps.length}):
|
|
2265
|
-
`;
|
|
2266
|
-
for (const [depName, depVer] of peerDeps.slice(0, 5)) {
|
|
2267
|
-
out += ` ${depName}: ${depVer}
|
|
2268
|
-
`;
|
|
2269
|
-
}
|
|
2270
|
-
if (peerDeps.length > 5) {
|
|
2271
|
-
out += ` + ${peerDeps.length - 5} outras
|
|
2272
|
-
`;
|
|
2273
|
-
}
|
|
2274
|
-
}
|
|
2275
|
-
const directDeps = Object.entries(info.dependencies);
|
|
2276
|
-
if (directDeps.length > 0) {
|
|
2277
|
-
const depCount = directDeps.length;
|
|
2278
|
-
out += ` Dependencias diretas: ${depCount}`;
|
|
2279
|
-
if (depCount > 0) {
|
|
2280
|
-
out += ` (top 5):
|
|
2281
|
-
`;
|
|
2282
|
-
for (const [depName, depVer] of directDeps.slice(0, 5)) {
|
|
2283
|
-
out += ` ${depName}: ${depVer}
|
|
2284
|
-
`;
|
|
2285
|
-
}
|
|
2286
|
-
if (depCount > 5) {
|
|
2287
|
-
out += ` + ${depCount - 5} outras
|
|
2288
|
-
`;
|
|
2289
|
-
}
|
|
2290
|
-
} else {
|
|
2291
|
-
out += `
|
|
2292
|
-
`;
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
out += nextSteps("deps_info", ctx);
|
|
2296
|
-
return out;
|
|
2297
|
-
}
|
|
2298
|
-
function formatDepsApiText(result, ctx = "cli") {
|
|
2299
|
-
let out = "";
|
|
2300
|
-
const typeFileLabel = result.typeFilesSummary ? result.typeFilesSummary : result.typeFiles.length === 1 ? "1 type file" : `${result.typeFiles.length} type files`;
|
|
2301
|
-
if (result.typesSource === "@types") {
|
|
2302
|
-
out += `${result.package} - API Publica (via ${result.typesPackage})
|
|
2303
|
-
|
|
2304
|
-
`;
|
|
2305
|
-
} else if (result.typesSource === "js-fallback" || result.jsFallback) {
|
|
2306
|
-
out += `${result.package} - API Publica (tipos aproximados de JS)
|
|
2307
|
-
|
|
2308
|
-
`;
|
|
2309
|
-
} else if (result.typesSource === "builtin") {
|
|
2310
|
-
out += `${result.package} - API Publica (${typeFileLabel} - tipos embutidos)
|
|
2311
|
-
|
|
2312
|
-
`;
|
|
2313
|
-
} else {
|
|
2314
|
-
out += `${result.package} - API Publica (${typeFileLabel})
|
|
2315
|
-
|
|
2316
|
-
`;
|
|
2317
|
-
}
|
|
2318
|
-
if (result.typeFilesPreview && result.typeFilesPreview.length > 0) {
|
|
2319
|
-
out += `TYPE FILES (top ${result.typeFilesPreview.length})
|
|
2320
|
-
`;
|
|
2321
|
-
for (const tf of result.typeFilesPreview) {
|
|
2322
|
-
out += ` ${tf}
|
|
2323
|
-
`;
|
|
2324
|
-
}
|
|
2325
|
-
out += `
|
|
2326
|
-
`;
|
|
2327
|
-
}
|
|
2328
|
-
const components = result.functions.filter((f) => f.kind === "component");
|
|
2329
|
-
const hooks = result.functions.filter((f) => f.kind === "hook");
|
|
2330
|
-
const plainFunctions = result.functions.filter((f) => f.kind !== "component" && f.kind !== "hook");
|
|
2331
|
-
if (components.length > 0) {
|
|
2332
|
-
out += `COMPONENTS (${components.length})
|
|
2333
|
-
`;
|
|
2334
|
-
for (const fn of components) {
|
|
2335
|
-
const params = fn.params.map((p) => `${p.name}: ${p.type}`).join(", ");
|
|
2336
|
-
out += ` ${fn.name}(${params}): ${fn.returnType}
|
|
2337
|
-
`;
|
|
2338
|
-
}
|
|
2339
|
-
out += `
|
|
2340
|
-
`;
|
|
2341
|
-
}
|
|
2342
|
-
if (hooks.length > 0) {
|
|
2343
|
-
out += `HOOKS (${hooks.length})
|
|
2344
|
-
`;
|
|
2345
|
-
for (const fn of hooks) {
|
|
2346
|
-
const asyncLabel = fn.isAsync ? "async " : "";
|
|
2347
|
-
const params = fn.params.map((p) => `${p.name}: ${p.type}`).join(", ");
|
|
2348
|
-
out += ` ${asyncLabel}${fn.name}(${params}): ${fn.returnType}
|
|
2349
|
-
`;
|
|
2350
|
-
}
|
|
2351
|
-
out += `
|
|
2352
|
-
`;
|
|
2353
|
-
}
|
|
2354
|
-
if (plainFunctions.length > 0) {
|
|
2355
|
-
out += `FUNCTIONS (${plainFunctions.length})
|
|
2356
|
-
`;
|
|
2357
|
-
for (const fn of plainFunctions) {
|
|
2358
|
-
const asyncLabel = fn.isAsync ? "async " : "";
|
|
2359
|
-
const params = fn.params.map((p) => `${p.name}: ${p.type}`).join(", ");
|
|
2360
|
-
out += ` ${asyncLabel}${fn.name}(${params}): ${fn.returnType}
|
|
2361
|
-
`;
|
|
2362
|
-
}
|
|
2363
|
-
out += `
|
|
2364
|
-
`;
|
|
2365
|
-
}
|
|
2366
|
-
const interfaces = result.types.filter((t) => t.kind === "interface");
|
|
2367
|
-
const typeAliases = result.types.filter((t) => t.kind === "type");
|
|
2368
|
-
const enums = result.types.filter((t) => t.kind === "enum");
|
|
2369
|
-
if (interfaces.length > 0) {
|
|
2370
|
-
out += `INTERFACES (${interfaces.length})
|
|
2371
|
-
`;
|
|
2372
|
-
for (const t of interfaces) {
|
|
2373
|
-
const def = truncateText(t.definition, 100);
|
|
2374
|
-
out += ` ${t.name}
|
|
2375
|
-
`;
|
|
2376
|
-
out += ` ${def}
|
|
2377
|
-
`;
|
|
2378
|
-
}
|
|
2379
|
-
out += `
|
|
2380
|
-
`;
|
|
2381
|
-
}
|
|
2382
|
-
if (typeAliases.length > 0) {
|
|
2383
|
-
out += `TYPE ALIASES (${typeAliases.length})
|
|
2384
|
-
`;
|
|
2385
|
-
for (const t of typeAliases) {
|
|
2386
|
-
const def = truncateText(t.definition, 100);
|
|
2387
|
-
out += ` ${def}
|
|
2388
|
-
`;
|
|
2389
|
-
}
|
|
2390
|
-
out += `
|
|
2391
|
-
`;
|
|
2392
|
-
}
|
|
2393
|
-
if (enums.length > 0) {
|
|
2394
|
-
out += `ENUMS (${enums.length})
|
|
2395
|
-
`;
|
|
2396
|
-
for (const t of enums) {
|
|
2397
|
-
const def = truncateText(t.definition, 100);
|
|
2398
|
-
out += ` ${def}
|
|
2399
|
-
`;
|
|
2400
|
-
}
|
|
2401
|
-
out += `
|
|
2402
|
-
`;
|
|
2403
|
-
}
|
|
2404
|
-
if (result.constants && result.constants.length > 0) {
|
|
2405
|
-
out += `CONSTANTS (${result.constants.length})
|
|
2406
|
-
`;
|
|
2407
|
-
for (const c of result.constants) {
|
|
2408
|
-
out += ` ${c.name}: ${c.type}
|
|
2409
|
-
`;
|
|
2410
|
-
}
|
|
2411
|
-
out += `
|
|
2412
|
-
`;
|
|
2413
|
-
}
|
|
2414
|
-
if (result.truncated.functions || result.truncated.types) {
|
|
2415
|
-
if (result.truncated.functions) {
|
|
2416
|
-
const total = result.truncated.totalFunctions ?? 50;
|
|
2417
|
-
out += `[truncated: functions ${result.functions.length}/${total}]
|
|
2418
|
-
`;
|
|
2419
|
-
}
|
|
2420
|
-
if (result.truncated.types) {
|
|
2421
|
-
const total = result.truncated.totalTypes ?? 50;
|
|
2422
|
-
out += `[truncated: types ${result.types.length}/${total}]
|
|
2423
|
-
`;
|
|
2424
|
-
}
|
|
2425
|
-
out += `Use ${hint("deps_search", ctx, { "<pacote>": result.package, "<termo>": "*Symbol*" })} para buscar simbolos especificos
|
|
2426
|
-
`;
|
|
2427
|
-
}
|
|
2428
|
-
if (result.availableKindsWhenFilteredEmpty && result.availableKindsWhenFilteredEmpty.length > 0) {
|
|
2429
|
-
const kinds = result.availableKindsWhenFilteredEmpty.map((k) => `${k.kind} (${k.count})`).join(", ");
|
|
2430
|
-
out += `
|
|
2431
|
-
Filtro --kind nao encontrou simbolos, mas ha outros tipos disponiveis:
|
|
2432
|
-
`;
|
|
2433
|
-
out += ` ${kinds}
|
|
2434
|
-
`;
|
|
2435
|
-
out += ` Use ${hint("deps_api", ctx, { "<pacote>": result.package })} sem filtro --kind para ver tudo
|
|
2436
|
-
`;
|
|
2437
|
-
}
|
|
2438
|
-
out += nextSteps("deps_api", ctx);
|
|
2439
|
-
return out;
|
|
2440
|
-
}
|
|
2441
|
-
function formatDepsSearchText(result, ctx = "cli") {
|
|
2442
|
-
let out = "";
|
|
2443
|
-
if (result.typesSource === "@types") {
|
|
2444
|
-
out += `${result.package} - Busca: "${result.query}" (via ${result.typesPackage})
|
|
2445
|
-
|
|
2446
|
-
`;
|
|
2447
|
-
} else if (result.typesSource === "js-fallback" || result.jsFallback) {
|
|
2448
|
-
out += `${result.package} - Busca: "${result.query}" (tipos aproximados)
|
|
2449
|
-
|
|
2450
|
-
`;
|
|
2451
|
-
} else if (result.typesSource === "builtin") {
|
|
2452
|
-
out += `${result.package} - Busca: "${result.query}" (tipos embutidos)
|
|
2453
|
-
|
|
2454
|
-
`;
|
|
2455
|
-
} else {
|
|
2456
|
-
out += `${result.package} - Busca: "${result.query}"
|
|
2457
|
-
|
|
2458
|
-
`;
|
|
2459
|
-
}
|
|
2460
|
-
if (result.matches.length === 0) {
|
|
2461
|
-
out += `Nenhum simbolo encontrado para "${result.query}".
|
|
2462
|
-
`;
|
|
2463
|
-
if (result.availableKindsWhenEmpty && result.availableKindsWhenEmpty.length > 0) {
|
|
2464
|
-
const kinds = result.availableKindsWhenEmpty.map((k) => `"${k}"`).join(", ");
|
|
2465
|
-
out += `
|
|
2466
|
-
Simbolos encontrados, mas como tipo diferente:
|
|
2467
|
-
`;
|
|
2468
|
-
out += ` Kinds disponiveis: ${kinds}
|
|
2469
|
-
`;
|
|
2470
|
-
out += ` Tente: ${hint("deps_search", ctx, { "<pacote>": result.package, "<termo>": result.query })} sem filtro --kind
|
|
2471
|
-
`;
|
|
2472
|
-
}
|
|
2473
|
-
if (result.typesSource === void 0 && !result.jsFallback) {
|
|
2474
|
-
out += `
|
|
2475
|
-
Pacote "${result.package}" nao possui TypeScript declarations.
|
|
2476
|
-
`;
|
|
2477
|
-
out += ` Instale com: npm install -D @types/${result.package}
|
|
2478
|
-
`;
|
|
2479
|
-
}
|
|
2480
|
-
out += `
|
|
2481
|
-
Dicas:
|
|
2482
|
-
`;
|
|
2483
|
-
out += ` -> Verifique a ortografia
|
|
2484
|
-
`;
|
|
2485
|
-
out += ` -> Tente buscar parte do nome (ex: "Btn" em vez de "Button")
|
|
2486
|
-
`;
|
|
2487
|
-
out += ` -> ${hint("deps_api", ctx, { "<pacote>": result.package })} - ver toda a API
|
|
2488
|
-
`;
|
|
2489
|
-
return out;
|
|
2490
|
-
}
|
|
2491
|
-
for (let i = 0; i < result.matches.length; i++) {
|
|
2492
|
-
const match = result.matches[i];
|
|
2493
|
-
out += `${i + 1}. ${match.name} (${match.kind})`;
|
|
2494
|
-
if (match.fromConcept) {
|
|
2495
|
-
out += ` [conceito: "${match.fromConcept}"]`;
|
|
2496
|
-
}
|
|
2497
|
-
out += `
|
|
2498
|
-
`;
|
|
2499
|
-
out += ` ${match.file}
|
|
2500
|
-
`;
|
|
2501
|
-
const sig = truncateText(match.signature, 100);
|
|
2502
|
-
out += ` ${sig}
|
|
2503
|
-
`;
|
|
2504
|
-
out += `
|
|
2505
|
-
`;
|
|
2506
|
-
}
|
|
2507
|
-
if (result.summary.byKind && result.summary.byKind.length > 1) {
|
|
2508
|
-
out += `POR KIND:
|
|
2509
|
-
`;
|
|
2510
|
-
for (const k of result.summary.byKind) {
|
|
2511
|
-
if (k.total > 0) {
|
|
2512
|
-
const truncInfo = k.shown < k.total ? ` (${k.shown}/${k.total})` : "";
|
|
2513
|
-
out += ` ${k.kind}: ${k.total}${truncInfo}
|
|
2514
|
-
`;
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
if (result.summary.byFile && result.summary.byFile.length > 1) {
|
|
2519
|
-
out += `POR ARQUIVO:
|
|
2520
|
-
`;
|
|
2521
|
-
for (const f of result.summary.byFile) {
|
|
2522
|
-
if (f.count > 1) {
|
|
2523
|
-
out += ` ${f.file}: ${f.count} matches
|
|
2524
|
-
`;
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
const shown = result.summary.shown;
|
|
2529
|
-
const total = result.summary.total;
|
|
2530
|
-
const hidden = result.summary.hidden;
|
|
2531
|
-
const pluralTotal = total !== 1 ? "s" : "";
|
|
2532
|
-
const pluralFiles = result.summary.files !== 1 ? "s" : "";
|
|
2533
|
-
if (hidden > 0) {
|
|
2534
|
-
out += `${shown} de ${total} resultado${pluralTotal} (${hidden} hidden)
|
|
2535
|
-
`;
|
|
2536
|
-
out += ` em ${result.summary.files} arquivo${pluralFiles}
|
|
2537
|
-
`;
|
|
2538
|
-
} else {
|
|
2539
|
-
out += `${total} resultado${pluralTotal} em ${result.summary.files} arquivo${pluralFiles}
|
|
2540
|
-
`;
|
|
2541
|
-
}
|
|
2542
|
-
if (total > 50) {
|
|
2543
|
-
out += `
|
|
2544
|
-
Muitos resultados encontrados. Refine a busca com termos mais especificos.
|
|
2545
|
-
`;
|
|
2546
|
-
}
|
|
2547
|
-
out += nextSteps("deps_search", ctx);
|
|
2548
|
-
return out;
|
|
2549
|
-
}
|
|
2550
|
-
function truncateText(text, maxLen) {
|
|
2551
|
-
if (text.length <= maxLen) return text;
|
|
2552
|
-
return text.substring(0, maxLen - 3) + "...";
|
|
2553
|
-
}
|
|
2554
2000
|
|
|
2555
2001
|
// src/cache/index.ts
|
|
2556
2002
|
import {
|
|
@@ -7005,14 +6451,20 @@ Ou edite manualmente o arquivo existente.
|
|
|
7005
6451
|
ai-tool area auth # Ver arquivos de uma \xE1rea
|
|
7006
6452
|
ai-tool map # Ver resumo do projeto
|
|
7007
6453
|
|
|
7008
|
-
\u{1F4A1} Dicas:
|
|
6454
|
+
\u{1F4A1} Dicas:
|
|
7009
6455
|
|
|
7010
|
-
\u2022
|
|
7011
|
-
\u2022
|
|
7012
|
-
\u2022 Um arquivo pode pertencer a m\xFAltiplas \xE1reas
|
|
7013
|
-
\u2022
|
|
6456
|
+
\u2022 patterns: glob para pastas (ex: "app/dashboard/**", "hooks/usePets.*")
|
|
6457
|
+
\u2022 keywords: substring no path inteiro, case-insensitive (ex: ["pet", "animal"])
|
|
6458
|
+
\u2022 Um arquivo pode pertencer a m\xFAltiplas \xE1reas
|
|
6459
|
+
\u2022 exclude: remove falsos positivos de uma \xE1rea (glob patterns)
|
|
6460
|
+
\u2022 descriptions (campo raiz): contexto manual para arquivos importantes
|
|
6461
|
+
Aparece nos comandos suggest, context e changes
|
|
6462
|
+
Ex: "src/hooks/useAuth.ts": "Hook principal de autentica\xE7\xE3o"
|
|
6463
|
+
\u2022 settings.inferDescriptions: true j\xE1 infere descri\xE7\xF5es automaticamente
|
|
6464
|
+
pelo nome do arquivo (ex: useAuth.ts \u2192 "Hook de auth", petService.ts \u2192 "Service de pet")
|
|
6465
|
+
Ativado por padr\xE3o no template gerado
|
|
7014
6466
|
|
|
7015
|
-
\u{1F4D6} Exemplo completo:
|
|
6467
|
+
\u{1F4D6} Exemplo completo:
|
|
7016
6468
|
|
|
7017
6469
|
{
|
|
7018
6470
|
"areas": {
|
|
@@ -8771,13 +8223,7 @@ export {
|
|
|
8771
8223
|
findSimilar,
|
|
8772
8224
|
findBestMatch,
|
|
8773
8225
|
extractFileName,
|
|
8774
|
-
formatDepsInfoText,
|
|
8775
|
-
formatDepsApiText,
|
|
8776
|
-
formatDepsSearchText,
|
|
8777
|
-
logger,
|
|
8778
8226
|
getWorkspaceFiles,
|
|
8779
|
-
simplifyType,
|
|
8780
|
-
expandMuiOverrideType,
|
|
8781
8227
|
getProjectIndexArtifact,
|
|
8782
8228
|
isFirebaseProject,
|
|
8783
8229
|
hasFirebaseFunctions,
|
|
@@ -8810,10 +8256,6 @@ export {
|
|
|
8810
8256
|
formatInvalidCommand,
|
|
8811
8257
|
impact,
|
|
8812
8258
|
suggest,
|
|
8813
|
-
addSourceFile,
|
|
8814
|
-
extractFunctions,
|
|
8815
|
-
extractTypes,
|
|
8816
|
-
extractExports,
|
|
8817
8259
|
context,
|
|
8818
8260
|
areaContext,
|
|
8819
8261
|
areas,
|