UNPKG

scai

Version:

> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** > **100% local • No token cost • Private by design • GDPR-friendly** — made in Denmark/EU with ❤️.

89 lines (88 loc) 3.34 kB
import fs from 'fs/promises'; import path from 'path'; import readline from 'readline'; import { queryFiles } from '../db/fileIndex.js'; import { summaryModule } from '../pipeline/modules/summaryModule.js'; import { detectFileType } from '../fileRules/detectFileType.js'; import { sanitizeQueryForFts } from '../utils/sanitizeQuery.js'; import { styleText } from '../utils/outputFormatter.js'; import { indexFile } from '../daemon/runIndexingBatch.js'; export async function summarizeFile(filepath) { let content = ''; let filePathResolved; // 📁 Resolve file path from index or local disk if (filepath) { const sanitizedQuery = sanitizeQueryForFts(filepath); const matches = queryFiles(sanitizedQuery); if (matches.length > 0) { const topMatch = matches[0]; filePathResolved = path.resolve(process.cwd(), topMatch.path); console.log(`🔗 Matched file from index: ${path.relative(process.cwd(), filePathResolved)}`); } else { const localPath = path.resolve(process.cwd(), filepath); try { await fs.access(localPath); filePathResolved = localPath; console.log(`📁 Using local file: ${path.relative(process.cwd(), localPath)}`); } catch { console.error(`❌ Could not find or resolve file: "${filepath}"`); return; } } } // 📄 Load file content (from path or stdin) if (filePathResolved) { const matches = queryFiles(`"${filePathResolved}"`); const match = matches.find(row => path.resolve(row.path) === filePathResolved); if (match?.summary) { console.log(`🧠 Cached summary for ${filepath}:\n`); console.log(styleText(match.summary)); return; } try { content = await fs.readFile(filePathResolved, 'utf-8'); } catch (err) { console.error(`❌ Could not read file: ${filePathResolved}\n${err.message}`); return; } } else if (!process.stdin.isTTY) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false, }); for await (const line of rl) { content += line + '\n'; } } else { console.error('❌ No file provided and no piped input.\n👉 Usage: scai summ <file> or cat file | scai summ'); return; } // 🧠 Generate summary and save if (content.trim()) { console.log('🧪 Generating summary...\n'); const response = await summaryModule.run({ query: `Summarize file: ${filepath ?? 'stdin'}`, content, }); const summary = response.data?.summary; if (!summary) { console.warn('⚠️ No summary generated.'); return; } console.log(styleText(summary)); if (filePathResolved) { const fileType = detectFileType(filePathResolved); indexFile(filePathResolved, summary, fileType); console.log('💾 Summary saved to local database.'); } } else { console.error('❌ No content provided to summarize.'); } }