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**

75 lines (74 loc) 2.73 kB
// File: src/modules/selectRelevantSourcesStep.ts import fs from "fs"; import { logInputOutput } from "../utils/promptLogHelper.js"; /** * Purpose: * Mirrors previously selected files into workingFiles. * - Does NOT promote files based on evidence. * - Candidate files are left untouched. * - Rationale is preserved from preFileSearchCheckStep. */ export const selectRelevantSourcesStep = { name: "selectRelevantSources", description: "Mirrors focus.selectedFiles into workingFiles without reasoning over evidence.", groups: ["analysis"], run: async (input) => { const query = input.query ?? ""; const context = input.context; if (!context?.analysis?.focus) { throw new Error("[selectRelevantSources] context.analysis.focus is required."); } const selectedFiles = context.analysis.focus.selectedFiles ?? []; const candidateFiles = context.analysis.focus.candidateFiles ?? []; const discardedFiles = []; // no reasoning done here // --------------------------- // 1️⃣ Populate workingFiles from selectedFiles only // --------------------------- const workingFiles = []; for (const path of selectedFiles) { let code; try { code = fs.readFileSync(path, "utf-8"); } catch { code = undefined; } workingFiles.push({ path, code, selectionReason: "Selected by preFileSearchCheckStep", }); } // Deduplicate if anything preexists const seen = new Set(); context.workingFiles = [ ...(context.workingFiles ?? []), ...workingFiles.filter(f => { if (!f.path || seen.has(f.path)) return false; seen.add(f.path); return true; }), ]; // --------------------------- // 2️⃣ Preserve focus but update rationale // --------------------------- context.analysis.focus = { selectedFiles, candidateFiles, discardedFiles, rationale: (context.analysis.focus.rationale ?? "") + "\n[selectRelevantSources] Working files mirrored mechanically from previous selections.", }; const output = { query, data: { workingFiles: context.workingFiles.map(f => ({ path: f.path })), selectedFiles, candidateFiles }, }; logInputOutput("selectRelevantSources", "output", output.data); return output; }, };