UNPKG

scai

Version:

> **A local-first AI CLI for understanding, querying, and iterating on large codebases.** > **100% local • No token costs • No cloud • No prompt injection • Private by design**

62 lines (61 loc) 2.73 kB
// File: src/modules/structuralPreloadStep.ts import { buildInDepthContext } from "../utils/buildContextualPrompt.js"; import { logInputOutput } from "../utils/promptLogHelper.js"; /** * Structural preload: * - Calls buildInDepthContext for candidate files. * - Extracts structural facts only. * - Populates analysis.fileAnalysis[path].structural. * - Does NOT reason or assign relevance. */ export const structuralPreloadStep = { name: "structuralPreload", description: "Preloads structural KG and code metadata into fileAnalysis without performing reasoning.", groups: ["analysis"], run: async (input) => { const query = input.query ?? ""; const context = input.context; if (!context?.analysis) { throw new Error("[structuralPreload] context.analysis is required."); } // ---- Ensure fileAnalysis exists (type-safe) ---- if (!context.analysis.fileAnalysis) { context.analysis.fileAnalysis = {}; } const fileAnalysis = context.analysis.fileAnalysis; // ---- Candidate files ---- const candidatePaths = [ ...(context.initContext?.relatedFiles ?? []), ]; const uniquePaths = Array.from(new Set(candidatePaths)); if (!uniquePaths.length) { console.warn("[structuralPreload] No candidate files to preload."); return { query, data: {} }; } // ---- Only preload missing structural data ---- const pathsNeedingStructure = uniquePaths.filter((p) => !fileAnalysis[p]?.structural); if (!pathsNeedingStructure.length) return { query, data: {} }; // ---- Get structural data (path → structural object) ---- const structuralMap = await buildInDepthContext({ filenames: pathsNeedingStructure, relatedFiles: context.initContext?.relatedFiles ?? [], query, }); // ---- Merge into fileAnalysis ---- for (const [path, structural] of Object.entries(structuralMap)) { fileAnalysis[path] ?? (fileAnalysis[path] = { semanticAnalyzed: false }); fileAnalysis[path].structural = structural; } // ---- Minimal structured log ---- const logSummary = Object.entries(fileAnalysis).map(([path, analysis]) => ({ file: path, hasStructural: !!analysis.structural, functions: analysis.structural?.functions?.length ?? 0, classes: analysis.structural?.classes?.length ?? 0, imports: analysis.structural?.imports?.length ?? 0, })); logInputOutput("structuralPreload", "output", logSummary); return { query, data: {} }; }, };