UNPKG

pi-lens

Version:

Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo

146 lines (144 loc) • 5.24 kB
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url); import { parseSymbolKey } from "./chunk-NKOUFPQF.js"; import "./chunk-3MED75HT.js"; import { isBuildArtifact } from "./chunk-6QIUX4EP.js"; import "./chunk-VHQLPIRJ.js"; import { getProjectDataDir } from "./chunk-VN2AXLEX.js"; import "./chunk-QYF5S6P6.js"; import "./chunk-5ZEJHV35.js"; import { detectFileRole } from "./chunk-DQ2NZ7C4.js"; import "./chunk-VNMT7C64.js"; import { writeFileAtomic } from "./chunk-2EECBNC5.js"; import "./chunk-N3YQJI6O.js"; import "./chunk-O6TQT6RI.js"; import "./chunk-5THXD6X5.js"; import "./chunk-UK3CMEAL.js"; import "./chunk-LJDODBBZ.js"; import "./chunk-ABBOA7UD.js"; import { isExternalOrVendorFile } from "./chunk-Q5U6FMDI.js"; import "./chunk-NXL4FFQQ.js"; // dist/clients/codebase-model.js import * as fs from "node:fs"; import * as path from "node:path"; var DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET = 1500; var MAX_CALLS_PER_SYMBOL = 10; var MIN_IN_DEGREE = 0.5; var CODEBASE_MODEL_VERSION = 1; function inferKind(symbolKey) { const parsed = parseSymbolKey(symbolKey); if (parsed.kind === "class") return "class"; if (parsed.kind === "method" || parsed.symbolName?.includes(".")) return "method"; return /^[A-Z]/.test(parsed.symbolName ?? "") ? "class" : "function"; } function estimateTokens(entry) { const text = [ entry.name, entry.file, entry.calls.join(","), entry.calledBy.join(",") ].join(" "); return Math.ceil(text.length / 4) + 5; } function buildCodebaseModel(graph, cwd, budget = DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET, identity) { const modelIdentity = identity ?? { reviewGraphVersion: graph.builtAt || "call-graph-unknown", reviewGraphSignature: graph.builtAt || "call-graph-unknown" }; const ranked = [...graph.inDegree.entries()].filter(([, score]) => score >= MIN_IN_DEGREE).sort(([, a], [, b]) => b - a); const entries = []; let totalTokens = 0; const seenNames = /* @__PURE__ */ new Set(); for (const [calleeKey, inDegree] of ranked) { if (totalTokens >= budget) break; const parsedCallee = parseSymbolKey(calleeKey); const name = parsedCallee.symbolName ?? calleeKey; const filePath = parsedCallee.filePath; const fileRole = detectFileRole(filePath); if (fileRole === "test" || fileRole === "generated" || isExternalOrVendorFile(filePath, cwd) || isBuildArtifact(filePath)) { continue; } if (seenNames.has(name)) continue; seenNames.add(name); const calls = [...graph.callees.get(calleeKey) ?? /* @__PURE__ */ new Set()].map((k) => parseSymbolKey(k).symbolName ?? k).filter(Boolean).slice(0, MAX_CALLS_PER_SYMBOL); const calledBy = [...graph.callers.get(calleeKey) ?? /* @__PURE__ */ new Set()].map((k) => parseSymbolKey(k).symbolName ?? k).filter((n) => !n.startsWith("file:")).slice(0, MAX_CALLS_PER_SYMBOL); const file = filePath ? path.relative(cwd, filePath).replace(/\\/g, "/") : "unknown"; const draft = { file, name, kind: inferKind(calleeKey), calls, calledBy, inDegree }; const tokens = estimateTokens(draft); if (totalTokens + tokens > budget) continue; entries.push({ ...draft, tokens }); totalTokens += tokens; } const allFiles = new Set([...graph.callers.keys(), ...graph.callees.keys()].map((k) => parseSymbolKey(k).filePath).filter(Boolean)); return { version: CODEBASE_MODEL_VERSION, reviewGraphVersion: modelIdentity.reviewGraphVersion, reviewGraphSignature: modelIdentity.reviewGraphSignature, generatedAt: (/* @__PURE__ */ new Date()).toISOString(), totalSymbols: graph.inDegree.size, totalFiles: allFiles.size, entries, totalTokens }; } function cacheFilePath(cwd) { return path.join(getProjectDataDir(cwd), "cache", "codebase-model.json"); } function metaFilePath(cwd) { return path.join(getProjectDataDir(cwd), "cache", "codebase-model.meta.json"); } function saveCodebaseModel(cwd, model) { const cacheFile = cacheFilePath(cwd); try { fs.mkdirSync(path.dirname(cacheFile), { recursive: true }); writeFileAtomic(cacheFile, JSON.stringify(model)); writeFileAtomic(metaFilePath(cwd), JSON.stringify({ savedAt: (/* @__PURE__ */ new Date()).toISOString(), entryCount: model.entries.length, totalTokens: model.totalTokens })); } catch { } } function loadCodebaseModel(cwd, expectedIdentity) { try { const raw = JSON.parse(fs.readFileSync(cacheFilePath(cwd), "utf-8")); if (raw.version !== CODEBASE_MODEL_VERSION || typeof raw.reviewGraphVersion !== "string" || raw.reviewGraphVersion.length === 0 || typeof raw.reviewGraphSignature !== "string" || raw.reviewGraphSignature.length === 0 || typeof raw.generatedAt !== "string" || !Array.isArray(raw.entries)) return void 0; if (raw.reviewGraphVersion !== expectedIdentity.reviewGraphVersion || raw.reviewGraphSignature !== expectedIdentity.reviewGraphSignature) return void 0; return raw; } catch { return void 0; } } export { CODEBASE_MODEL_VERSION, DEFAULT_CODEBASE_MODEL_TOKEN_BUDGET, buildCodebaseModel, loadCodebaseModel, saveCodebaseModel };