UNPKG

scai

Version:

> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** 100% local, private, 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.'); } }