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 ā¤ļø.

80 lines (79 loc) • 2.77 kB
import fs from 'fs'; import readline from 'readline'; import chalk from 'chalk'; import { searchFiles } from '../db/fileIndex.js'; import { sanitizeQueryForFts } from '../utils/sanitizeQuery.js'; import { NUM_TOPFILES, RELATED_FILES_LIMIT, getIndexDir } from '../constants.js'; import { MainAgent } from '../agents/MainAgent.js'; import { buildLightContext } from '../utils/buildContextualPrompt.js'; export async function runAskCommand(query) { // STEP 0: Get user query if (!query) query = await promptOnce('šŸ’¬ Ask your question:\n'); query = query.trim(); if (!query) { console.error('āŒ No question provided.\nšŸ‘‰ Usage: scai ask "your question"'); return; } console.log(`šŸ“ Using index root: ${getIndexDir()}`); // STEP 1: FTS Search const safeQuery = sanitizeQueryForFts(query); const start = Date.now(); const results = await searchFiles(safeQuery, RELATED_FILES_LIMIT); console.log(`ā±ļø searchFiles took ${Date.now() - start}ms and returned ${results.length} result(s)`); if (results.length === 0) { console.log(chalk.redBright('āŒ No results found.')); return; } // STEP 2: Build topFiles (with code) const topResults = results.slice(0, NUM_TOPFILES); const topFiles = topResults.map(r => { let code = ''; try { code = fs.readFileSync(r.path, 'utf-8'); } catch (err) { console.warn(`āš ļø Failed to read file: ${r.path}`); } return { path: r.path, summary: r.summary ?? undefined, code, }; }); console.log(chalk.greenBright(`šŸŽÆ Selected top ${topFiles.length} file(s):`)); topFiles.forEach(f => console.log(` → ${f.path}`)); // STEP 3: Related files (all results except topFiles) const relatedFiles = results.slice(NUM_TOPFILES).map(f => ({ id: f.id, path: f.path, summary: f.summary ?? undefined, })); // STEP 4: Build context prompt const promptArgs = { topFiles, relatedFiles, query, }; const context = await buildLightContext(promptArgs); // STEP 5: Run agent try { console.log('\nšŸ¤– Launching autonomous agent...'); const agent = new MainAgent(context); await agent.run(); } catch (err) { console.error('āŒ Autonomous agent run failed:', err); } } // helper function promptOnce(promptText) { return new Promise(resolve => { console.log(promptText); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('> ', answer => { rl.close(); resolve(answer.trim()); }); }); }