@kinkai.cloud/vibecheck 0.1.3 → 0.1.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.
Files changed (2) hide show
  1. package/dist/cli.js +322 -32
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -14543,6 +14543,7 @@ var MAX_BYTES = 256e3;
14543
14543
  var MAX_ROTULO = 80;
14544
14544
  var MAX_ID = 64;
14545
14545
  var MAX_CAMINHO = 180;
14546
+ var MAX_PACOTES = 32;
14546
14547
  var caminho = external_exports.string().min(1).max(MAX_CAMINHO);
14547
14548
  var noSchema = external_exports.object({
14548
14549
  id: external_exports.string().min(1).max(MAX_ID),
@@ -14565,10 +14566,39 @@ var grafoScanSchema = external_exports.object({
14565
14566
  avancado: external_exports.boolean(),
14566
14567
  nos: external_exports.array(noSchema).max(MAX_NOS),
14567
14568
  arestas: external_exports.array(arestaSchema).max(MAX_ARESTAS),
14568
- comunidades: external_exports.array(comunidadeSchema).max(MAX_COMUNIDADES)
14569
+ comunidades: external_exports.array(comunidadeSchema).max(MAX_COMUNIDADES),
14570
+ pacotes: external_exports.array(external_exports.string().min(1).max(MAX_ROTULO)).max(MAX_PACOTES)
14569
14571
  });
14570
14572
 
14573
+ // ../../packages/graph/src/dicas.ts
14574
+ function rotaDeArquivo(caminho2) {
14575
+ const normal = caminho2.replaceAll("\\", "/");
14576
+ const app = /(?:^|\/)app\/(.+)\/route\.(t|j)sx?$/i.exec(normal);
14577
+ if (app?.[1] !== void 0) {
14578
+ const segmentos = app[1].split("/").filter((s) => s.length > 0 && !s.startsWith("(") && !s.startsWith("@")).map((s) => s.replace(/^\[+\.\.\.(.+)\]+$/, "*").replace(/^\[+(.+)\]+$/, ":$1"));
14579
+ if (segmentos.length === 0) return "/api";
14580
+ return `/${segmentos.join("/")}`;
14581
+ }
14582
+ const pages = /(?:^|\/)pages\/api\/(.+)\.(t|j)sx?$/i.exec(normal);
14583
+ if (pages?.[1] !== void 0) {
14584
+ const semIndex = pages[1].replace(/\/index$/i, "");
14585
+ return `/api/${semIndex}`;
14586
+ }
14587
+ return null;
14588
+ }
14589
+
14571
14590
  // ../../packages/graph/src/mapear.ts
14591
+ var ROTULO_KIND = {
14592
+ browser: "navegador",
14593
+ app: "aplica\xE7\xE3o",
14594
+ api: "API",
14595
+ db: "banco",
14596
+ storage: "arquivos",
14597
+ auth: "autentica\xE7\xE3o",
14598
+ ai: "IA",
14599
+ payments: "pagamentos",
14600
+ secrets: "segredos"
14601
+ };
14572
14602
  var REGRAS = [
14573
14603
  {
14574
14604
  kind: "api",
@@ -14593,13 +14623,78 @@ function mapearKind(sinal) {
14593
14623
  return "app";
14594
14624
  }
14595
14625
 
14626
+ // ../../packages/graph/src/pacotes.ts
14627
+ var CARA_DE_CHAVE = /(sk_live_|sk_test_|rk_live_|pk_live_|pk_test_|sb_secret_|eyJ[A-Za-z0-9_-]{20,}|gsk_[A-Za-z0-9]|sk-ant-|sk-proj-|sk-or-v1-)/i;
14628
+ var REGRAS2 = [
14629
+ { id: "next", teste: /^next(?:\/|$)/ },
14630
+ { id: "react", teste: /^react(?:-dom)?(?:\/|$)/ },
14631
+ { id: "vue", teste: /^vue(?:\/|$)/ },
14632
+ { id: "svelte", teste: /^svelte(?:\/|$)/ },
14633
+ { id: "angular", teste: /^@angular\// },
14634
+ { id: "vite", teste: /^vite(?:\/|$)/ },
14635
+ { id: "astro", teste: /^astro(?:\/|$)/ },
14636
+ { id: "stripe", teste: /^(?:stripe|@stripe\/)/ },
14637
+ { id: "supabase", teste: /^(?:@supabase\/|@supabase$)/ },
14638
+ { id: "firebase", teste: /^(?:firebase|@firebase\/)/ },
14639
+ { id: "clerk", teste: /^@clerk\// },
14640
+ { id: "next-auth", teste: /^(?:next-auth|@auth\/)/ },
14641
+ { id: "prisma", teste: /^(?:@prisma\/client|prisma)(?:\/|$)/ },
14642
+ { id: "drizzle", teste: /^drizzle-orm(?:\/|$)/ },
14643
+ { id: "kysely", teste: /^kysely(?:\/|$)/ },
14644
+ { id: "postgres", teste: /^(?:postgres|pg|@neondatabase\/)/ },
14645
+ { id: "mongodb", teste: /^(?:mongodb|mongoose)(?:\/|$)/ },
14646
+ { id: "styled-components", teste: /^styled-components(?:\/|$)/ },
14647
+ { id: "emotion", teste: /^@emotion\// },
14648
+ { id: "tailwind", teste: /^tailwindcss(?:\/|$)/ },
14649
+ { id: "openai", teste: /^openai(?:\/|$)/ },
14650
+ { id: "anthropic", teste: /^@anthropic-ai\// },
14651
+ { id: "langchain", teste: /^langchain(?:\/|$)/ },
14652
+ { id: "trpc", teste: /^@trpc\// },
14653
+ { id: "hono", teste: /^hono(?:\/|$)/ },
14654
+ { id: "express", teste: /^express(?:\/|$)/ },
14655
+ { id: "fastify", teste: /^fastify(?:\/|$)/ },
14656
+ { id: "graphql", teste: /^(?:graphql|@apollo\/)/ },
14657
+ { id: "redis", teste: /^(?:redis|ioredis)(?:\/|$)/ },
14658
+ { id: "resend", teste: /^resend(?:\/|$)/ },
14659
+ { id: "auth0", teste: /^(?:auth0|@auth0\/)/ },
14660
+ { id: "lucia", teste: /^lucia(?:\/|$)/ },
14661
+ { id: "kinde", teste: /^@kinde-oss\// }
14662
+ ];
14663
+ function idDePacote(spec) {
14664
+ const limpo = spec.trim().replace(/^npm:/, "");
14665
+ if (limpo.length === 0 || limpo.startsWith(".") || limpo.startsWith("/")) return null;
14666
+ if (limpo.startsWith("node:") || limpo.startsWith("#")) return null;
14667
+ for (const regra of REGRAS2) {
14668
+ if (regra.teste.test(limpo)) return regra.id;
14669
+ }
14670
+ return null;
14671
+ }
14672
+ function sanitizarPacote(bruto) {
14673
+ const limpo = bruto.trim().slice(0, MAX_ROTULO);
14674
+ if (limpo.length === 0) return null;
14675
+ if (CARA_DE_CHAVE.test(limpo)) return null;
14676
+ if (!/^[@a-z0-9][a-z0-9._+/-]{0,60}$/i.test(limpo)) return null;
14677
+ return limpo;
14678
+ }
14679
+ function uniquePacotes(values) {
14680
+ const seen = /* @__PURE__ */ new Set();
14681
+ const out = [];
14682
+ for (const value of values) {
14683
+ if (out.length >= MAX_PACOTES) break;
14684
+ const limpo = sanitizarPacote(value);
14685
+ if (limpo === null || seen.has(limpo)) continue;
14686
+ seen.add(limpo);
14687
+ out.push(limpo);
14688
+ }
14689
+ return out;
14690
+ }
14691
+
14596
14692
  // ../../packages/graph/src/sanitize.ts
14597
14693
  var CAMPOS_CORPO = /* @__PURE__ */ new Set([
14598
14694
  "content",
14599
14695
  "snippet",
14600
14696
  "code",
14601
14697
  "rationale",
14602
- "source",
14603
14698
  "body",
14604
14699
  "text",
14605
14700
  "source_location",
@@ -14609,7 +14704,7 @@ var CAMPOS_CORPO = /* @__PURE__ */ new Set([
14609
14704
  ]);
14610
14705
  var EXTENSOES_SEGREDO = /\.(env|pem|key|p12|pfx|crt|cer|p8|keystore)(?:\.|$)/i;
14611
14706
  var SEGMENTO_PROIBIDO = /(?:^|\/)(?:\.env(?:\..+)?|id_rsa|id_ed25519|credentials|secrets?)(?:\/|$)/i;
14612
- var CARA_DE_CHAVE = /(sk_live_|sk_test_|rk_live_|sb_secret_|eyJ[A-Za-z0-9_-]{8,}|gsk_|sk-ant-|sk-proj-|api[_-]?key|secret|password|token|bearer)/i;
14707
+ var CARA_DE_CHAVE2 = /(sk_live_|sk_test_|rk_live_|pk_live_|pk_test_|sb_secret_|sb_publishable_|eyJ[A-Za-z0-9_-]{20,}|gsk_[A-Za-z0-9]|sk-ant-|sk-proj-|sk-or-v1-)/i;
14613
14708
  var MAX_ROTULO_ARQUIVO = MAX_CAMINHO;
14614
14709
  function eRecord(value) {
14615
14710
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -14631,7 +14726,7 @@ function sanitizarCaminho(bruto) {
14631
14726
  function redigirRotulo(bruto) {
14632
14727
  const limpo = bruto.trim().slice(0, MAX_ROTULO);
14633
14728
  if (limpo.length === 0) return "n\xF3";
14634
- if (CARA_DE_CHAVE.test(limpo)) return "[redigido]";
14729
+ if (CARA_DE_CHAVE2.test(limpo)) return "[redigido]";
14635
14730
  return limpo;
14636
14731
  }
14637
14732
  function uniqueCapped(values, cap) {
@@ -14676,10 +14771,28 @@ function stripCorpo(value) {
14676
14771
  const out = {};
14677
14772
  for (const [chave, item] of Object.entries(value)) {
14678
14773
  if (CAMPOS_CORPO.has(chave)) continue;
14774
+ if (chave === "source" && typeof item === "string" && (item.includes("\n") || item.length > MAX_ID)) {
14775
+ continue;
14776
+ }
14679
14777
  out[chave] = stripCorpo(item);
14680
14778
  }
14681
14779
  return out;
14682
14780
  }
14781
+ function primeiroExport(value) {
14782
+ if (typeof value === "string" && value.length > 0) {
14783
+ const primeiro = value.split(/[\s,]+/)[0];
14784
+ return primeiro !== void 0 && primeiro.length > 0 ? primeiro : null;
14785
+ }
14786
+ if (!Array.isArray(value)) return null;
14787
+ for (const item of value) {
14788
+ if (typeof item === "string" && item.length > 0) return item;
14789
+ if (eRecord(item)) {
14790
+ const nome = comoString(item["name"]) ?? comoString(item["identifier"]);
14791
+ if (nome !== null) return nome;
14792
+ }
14793
+ }
14794
+ return null;
14795
+ }
14683
14796
  function nosDoDump(dump) {
14684
14797
  const bruto = dump["nodes"] ?? dump["nos"];
14685
14798
  const lista = Array.isArray(bruto) ? bruto : eRecord(bruto) ? Object.entries(bruto).map(
@@ -14692,7 +14805,7 @@ function nosDoDump(dump) {
14692
14805
  item["arquivos"] ?? item["files"] ?? item["source_file"] ?? item["sourceFile"] ?? item["file"] ?? item["path"]
14693
14806
  );
14694
14807
  const rotulo = redigirRotulo(
14695
- comoString(item["rotulo"]) ?? comoString(item["label"]) ?? comoString(item["name"]) ?? arquivos[0] ?? `n\xF3-${String(i)}`
14808
+ comoString(item["rotulo"]) ?? comoString(item["label"]) ?? comoString(item["name"]) ?? comoString(item["identifier"]) ?? comoString(item["symbol"]) ?? primeiroExport(item["exports"] ?? item["identificadores"]) ?? arquivos[0] ?? `n\xF3-${String(i)}`
14696
14809
  );
14697
14810
  const kindBruto = comoString(item["kind"]) ?? comoString(item["nodeKind"]);
14698
14811
  const kind = kindBruto !== null && NODE_KINDS.includes(kindBruto) ? kindBruto : mapearKind({ rotulo, arquivos });
@@ -14753,7 +14866,7 @@ function comunidadesDoDump(dump, nos) {
14753
14866
  seen.add(nodeKind);
14754
14867
  out2.push({
14755
14868
  nodeKind,
14756
- rotulo: redigirRotulo(comoString(item["rotulo"]) ?? comoString(item["label"]) ?? nodeKind),
14869
+ rotulo: ROTULO_KIND[nodeKind],
14757
14870
  arquivos: uniqueCapped(
14758
14871
  arquivosDe(item["arquivos"] ?? item["files"]),
14759
14872
  MAX_ARQUIVOS_COMUNIDADE
@@ -14775,7 +14888,7 @@ function comunidadesDoDump(dump, nos) {
14775
14888
  if (grupo === void 0) continue;
14776
14889
  const arquivos = uniqueCapped(grupo.arquivos, MAX_ARQUIVOS_COMUNIDADE);
14777
14890
  if (arquivos.length === 0 && grupo.rotulo.length === 0) continue;
14778
- out.push({ nodeKind: kind, rotulo: redigirRotulo(grupo.rotulo), arquivos });
14891
+ out.push({ nodeKind: kind, rotulo: ROTULO_KIND[kind], arquivos });
14779
14892
  if (out.length >= MAX_COMUNIDADES) break;
14780
14893
  }
14781
14894
  return out;
@@ -14795,6 +14908,7 @@ function sanitizarGrafo(entrada) {
14795
14908
  const ids = new Set(nos.map((n) => n.id));
14796
14909
  const arestas = arestasDoDump(limpo, ids);
14797
14910
  const comunidades = comunidadesDoDump(limpo, nos);
14911
+ const pacotes = uniquePacotes(pacotesDoDump(limpo, nos));
14798
14912
  const temArquivo = comunidades.some((c) => c.arquivos.length > 0) || nos.some((n) => n.arquivos.length > 0);
14799
14913
  if (!temArquivo) return { ok: false, motivo: "vazio" };
14800
14914
  const avancado = comunidades.length > 0;
@@ -14805,10 +14919,24 @@ function sanitizarGrafo(entrada) {
14805
14919
  avancado,
14806
14920
  nos,
14807
14921
  arestas,
14808
- comunidades
14922
+ comunidades,
14923
+ pacotes
14809
14924
  }
14810
14925
  };
14811
14926
  }
14927
+ function pacotesDoDump(dump, nos) {
14928
+ const brutos = [];
14929
+ const campo = dump["pacotes"] ?? dump["packages"];
14930
+ if (Array.isArray(campo)) {
14931
+ for (const item of campo) {
14932
+ if (typeof item === "string") brutos.push(item);
14933
+ }
14934
+ }
14935
+ for (const no of nos) {
14936
+ if (no.id.startsWith("pkg:")) brutos.push(no.rotulo);
14937
+ }
14938
+ return brutos;
14939
+ }
14812
14940
 
14813
14941
  // src/graphify.ts
14814
14942
  import { spawn } from "child_process";
@@ -14981,16 +15109,13 @@ var IGNORAR = /* @__PURE__ */ new Set([
14981
15109
  "build"
14982
15110
  ]);
14983
15111
  var CODIGO = /\.(m?[jt]sx?)$/;
14984
- var SINAIS = [
14985
- { re: /(?:^|\/)app\/.*\/route\.(t|j)sx?$/i, rotulo: "rota App Router" },
14986
- { re: /(?:^|\/)pages\/api\//i, rotulo: "pages/api" },
14987
- { re: /\bstripe\b/i, rotulo: "stripe" },
14988
- { re: /\bsupabase\b/i, rotulo: "supabase" },
14989
- { re: /\bfirebase\b/i, rotulo: "firebase" },
14990
- { re: /\bopenai\b|\banthropic\b/i, rotulo: "openai" },
14991
- { re: /\bclerk\b|next-auth/i, rotulo: "clerk" }
14992
- ];
14993
- var IMPORT_SINAL = /from\s+['"](@supabase\/|@clerk\/|stripe|firebase|openai|@anthropic|next-auth)/i;
15112
+ var MAX_ARQUIVOS = 800;
15113
+ var MAX_NOS_WALKER = 120;
15114
+ var EXT = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
15115
+ var EXPORT_RE = /export\s+(?:default\s+)?(?:async\s+)?(?:function\*?|class|const|let|var|enum)\s+([A-Za-z_$][\w$]*)/g;
15116
+ var EXPORT_LISTA_RE = /export\s+\{([^}]+)\}/g;
15117
+ var FROM_RE = /(?:from\s+|import\s*\(\s*|require\s*\(\s*)['"]([^'"]+)['"]/g;
15118
+ var HANDLERS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
14994
15119
  function listar(raiz, dir, acc) {
14995
15120
  let nomes;
14996
15121
  try {
@@ -15013,31 +15138,196 @@ function listar(raiz, dir, acc) {
15013
15138
  }
15014
15139
  if (!stat.isFile() || !CODIGO.test(nome)) continue;
15015
15140
  acc.push(cheio);
15016
- if (acc.length >= 800) return;
15141
+ if (acc.length >= MAX_ARQUIVOS) return;
15142
+ }
15143
+ }
15144
+ function posixRel(raiz, cheio) {
15145
+ return relative(raiz, cheio).replaceAll("\\", "/");
15146
+ }
15147
+ function dirnamePosix(caminho2) {
15148
+ const i = caminho2.lastIndexOf("/");
15149
+ return i <= 0 ? "" : caminho2.slice(0, i);
15150
+ }
15151
+ function normalizarPosix(caminho2) {
15152
+ const partes = [];
15153
+ for (const p of caminho2.replaceAll("\\", "/").split("/")) {
15154
+ if (p === "" || p === ".") continue;
15155
+ if (p === "..") {
15156
+ partes.pop();
15157
+ continue;
15158
+ }
15159
+ partes.push(p);
15160
+ }
15161
+ return partes.join("/");
15162
+ }
15163
+ function exportsDe(conteudo) {
15164
+ const out = [];
15165
+ const seen = /* @__PURE__ */ new Set();
15166
+ const push = (nome) => {
15167
+ if (nome.length === 0 || seen.has(nome)) return;
15168
+ seen.add(nome);
15169
+ out.push(nome);
15170
+ };
15171
+ EXPORT_RE.lastIndex = 0;
15172
+ let m;
15173
+ while ((m = EXPORT_RE.exec(conteudo)) !== null) {
15174
+ if (m[1] !== void 0) push(m[1]);
15175
+ }
15176
+ EXPORT_LISTA_RE.lastIndex = 0;
15177
+ while ((m = EXPORT_LISTA_RE.exec(conteudo)) !== null) {
15178
+ const lista = m[1];
15179
+ if (lista === void 0) continue;
15180
+ for (const parte of lista.split(",")) {
15181
+ const nome = parte.trim().split(/\s+as\s+/).at(-1)?.trim();
15182
+ if (nome !== void 0 && /^[A-Za-z_$][\w$]*$/.test(nome)) push(nome);
15183
+ }
15017
15184
  }
15185
+ return out;
15018
15186
  }
15019
- function noDeArquivo(raiz, cheio, i) {
15020
- const rel = relative(raiz, cheio).replaceAll("\\", "/");
15187
+ function specsDe(conteudo) {
15188
+ const out = [];
15189
+ FROM_RE.lastIndex = 0;
15190
+ let m;
15191
+ while ((m = FROM_RE.exec(conteudo)) !== null) {
15192
+ if (m[1] !== void 0) out.push(m[1]);
15193
+ }
15194
+ return out;
15195
+ }
15196
+ function acharNoIndice(specPath, indice) {
15197
+ const n = specPath.replaceAll("\\", "/").replace(/^\.\//, "");
15198
+ for (const ext of EXT) {
15199
+ const hit = indice.get(n + ext);
15200
+ if (hit !== void 0) return hit;
15201
+ }
15202
+ return null;
15203
+ }
15204
+ function resolverSpec(de, spec, indice) {
15205
+ if (spec.startsWith(".")) {
15206
+ const base = normalizarPosix(`${dirnamePosix(de)}/${spec}`);
15207
+ return acharNoIndice(base, indice);
15208
+ }
15209
+ const alias = spec.startsWith("@/") ? spec.slice(2) : spec.startsWith("~/") ? spec.slice(2) : null;
15210
+ if (alias === null) return null;
15211
+ for (const prefixo of ["", "src/", "app/"]) {
15212
+ const hit = acharNoIndice(`${prefixo}${alias}`, indice);
15213
+ if (hit !== null) return hit;
15214
+ }
15215
+ return null;
15216
+ }
15217
+ function rotuloDe(rel, exports) {
15218
+ const rota = rotaDeArquivo(rel);
15219
+ const handlers = exports.filter((e) => HANDLERS.has(e));
15220
+ if (rota !== null && handlers.length > 0) return `${handlers[0]} ${rota}`;
15221
+ if (rota !== null) return rota;
15222
+ const simbolo = exports.find((e) => !HANDLERS.has(e));
15223
+ if (simbolo !== void 0) return simbolo;
15224
+ const base = rel.split("/").at(-1)?.replace(/\.(m?[jt]sx?)$/i, "");
15225
+ return base !== void 0 && base.length > 0 && base !== "index" ? base : rel;
15226
+ }
15227
+ function lerArquivo(raiz, cheio) {
15228
+ const rel = posixRel(raiz, cheio);
15021
15229
  let conteudo = "";
15022
15230
  try {
15023
- conteudo = readFileSync2(cheio, "utf8").slice(0, 8e3);
15231
+ conteudo = readFileSync2(cheio, "utf8").slice(0, 12e3);
15024
15232
  } catch {
15025
15233
  return null;
15026
15234
  }
15027
- const rotulo = SINAIS.find((s) => s.re.test(rel) || s.re.test(conteudo) || IMPORT_SINAL.test(conteudo))?.rotulo ?? rel.split("/").at(-1) ?? `arquivo-${String(i)}`;
15028
- return { id: `f${String(i)}`, label: rotulo, source_file: rel };
15235
+ const exports = exportsDe(conteudo);
15236
+ const specs = specsDe(conteudo);
15237
+ return {
15238
+ rel,
15239
+ rotulo: rotuloDe(rel, exports),
15240
+ exports,
15241
+ importsRel: specs.filter((s) => s.startsWith(".") || s.startsWith("@/") || s.startsWith("~/")),
15242
+ importsPkg: specs
15243
+ };
15244
+ }
15245
+ function prioridade(info) {
15246
+ const kind = mapearKind({ rotulo: info.rotulo, arquivos: [info.rel] });
15247
+ if (kind === "api") return 0;
15248
+ if (kind === "payments" || kind === "auth" || kind === "db") return 1;
15249
+ if (kind === "storage" || kind === "secrets" || kind === "browser" || kind === "ai") return 2;
15250
+ if (info.importsPkg.some((s) => idDePacote(s) !== null)) return 3;
15251
+ return 8;
15029
15252
  }
15030
15253
  function extrairDoRepo(raiz) {
15031
- const arquivos = [];
15032
- listar(raiz, raiz, arquivos);
15033
- if (arquivos.length === 0) return null;
15254
+ const caminhos = [];
15255
+ listar(raiz, raiz, caminhos);
15256
+ if (caminhos.length === 0) return null;
15257
+ const infos = [];
15258
+ const indice = /* @__PURE__ */ new Map();
15259
+ for (const cheio of caminhos) {
15260
+ const info = lerArquivo(raiz, cheio);
15261
+ if (info === null) continue;
15262
+ infos.push(info);
15263
+ indice.set(info.rel, info.rel);
15264
+ }
15265
+ if (infos.length === 0) return null;
15266
+ const porRel = new Map(infos.map((i) => [i.rel, i]));
15267
+ const escolhidos = /* @__PURE__ */ new Set();
15268
+ const ordenados = [...infos].sort((a, b) => prioridade(a) - prioridade(b) || a.rel.localeCompare(b.rel));
15269
+ for (const info of ordenados) {
15270
+ if (prioridade(info) <= 3) escolhidos.add(info.rel);
15271
+ }
15272
+ const expandir = (saltos) => {
15273
+ let fronteira = [...escolhidos];
15274
+ for (let s = 0; s < saltos; s += 1) {
15275
+ const proxima = [];
15276
+ for (const rel of fronteira) {
15277
+ const info = porRel.get(rel);
15278
+ if (info === void 0) continue;
15279
+ for (const spec of info.importsRel) {
15280
+ const alvo = resolverSpec(rel, spec, indice);
15281
+ if (alvo === null || escolhidos.has(alvo)) continue;
15282
+ escolhidos.add(alvo);
15283
+ proxima.push(alvo);
15284
+ }
15285
+ }
15286
+ fronteira = proxima;
15287
+ }
15288
+ };
15289
+ expandir(2);
15290
+ if (escolhidos.size === 0) {
15291
+ for (const info of ordenados.slice(0, Math.min(24, ordenados.length))) {
15292
+ escolhidos.add(info.rel);
15293
+ }
15294
+ }
15295
+ const files = [...escolhidos].map((rel) => porRel.get(rel)).filter((i) => i !== void 0).sort((a, b) => prioridade(a) - prioridade(b) || a.rel.localeCompare(b.rel)).slice(0, MAX_NOS_WALKER);
15034
15296
  const nodes = [];
15035
- for (const [i, cheio] of arquivos.entries()) {
15036
- const no = noDeArquivo(raiz, cheio, i);
15037
- if (no !== null) nodes.push(no);
15297
+ const edges = [];
15298
+ const pacotes = /* @__PURE__ */ new Set();
15299
+ const idDe2 = /* @__PURE__ */ new Map();
15300
+ for (const [i, info] of files.entries()) {
15301
+ const id = `f${String(i)}`;
15302
+ idDe2.set(info.rel, id);
15303
+ nodes.push({
15304
+ id,
15305
+ label: info.rotulo,
15306
+ identifier: info.exports[0] ?? info.rotulo,
15307
+ source_file: info.rel
15308
+ });
15309
+ }
15310
+ for (const info of files) {
15311
+ const de = idDe2.get(info.rel);
15312
+ if (de === void 0) continue;
15313
+ for (const spec of info.importsRel) {
15314
+ const alvo = resolverSpec(info.rel, spec, indice);
15315
+ const para = alvo === null ? void 0 : idDe2.get(alvo);
15316
+ if (para === void 0) continue;
15317
+ edges.push({ source: de, target: para, relation: "imports" });
15318
+ }
15319
+ for (const spec of info.importsPkg) {
15320
+ const pkg = idDePacote(spec);
15321
+ if (pkg === null) continue;
15322
+ pacotes.add(pkg);
15323
+ const pkgId = `pkg:${pkg}`;
15324
+ if (!nodes.some((n) => n["id"] === pkgId)) {
15325
+ nodes.push({ id: pkgId, label: pkg });
15326
+ }
15327
+ edges.push({ source: de, target: pkgId, relation: "imports" });
15328
+ }
15038
15329
  }
15039
- if (nodes.length === 0) return null;
15040
- const sanitizado = sanitizarGrafo({ nodes, edges: [] });
15330
+ const sanitizado = sanitizarGrafo({ nodes, edges, pacotes: [...pacotes] });
15041
15331
  if (!sanitizado.ok || !sanitizado.grafo.avancado) return null;
15042
15332
  return sanitizado.grafo;
15043
15333
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kinkai.cloud/vibecheck",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {