rawi
Version:
Rawi (راوي) is the developer-friendly AI CLI that brings the power of 12 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into
13 lines (12 loc) • 8.74 kB
JavaScript
/* Rawi (راوي) is the developer-friendly AI CLI that brings the power of 12 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into an intelligent development workspace. */
import{a as M}from"./chunk-MPDXSLZB.js";import{a as S}from"./chunk-LSO6QN77.js";import{a as F,b as E}from"./chunk-AZFH5WY6.js";import{d as U}from"./chunk-D5ICEXBJ.js";import{b as P}from"./chunk-LDSHVY7O.js";import{a as j}from"./chunk-ABWXKSWH.js";import{b as c}from"./chunk-U7K37PAJ.js";import{d as $}from"./chunk-3JCRW7ET.js";import e from"chalk";import{Command as A}from"commander";var R=()=>new Promise(p=>{let y="";if(process.stdin.isTTY){p("");return}process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>{y+=r}),process.stdin.on("end",()=>{p(y.trim())})}),G=()=>{let p=new A("ask");return p.description([e.bold("Ask AI a question and get a response."),"",e.gray("Supports piped input from stdin and file processing."),e.gray("Use --act <template> for expert prompt templates."),e.gray('See all templates with "rawi act --list".')].join(`
`)).argument("[query]",e.white("The question or prompt to send to the AI (can be combined with piped input or file content)")).option("-p, --profile <profile>",e.white("Profile to use for AI configuration"),$).option("-s, --session <sessionId>",e.white("Continue an existing chat session")).option("-n, --new-session",e.white("Start a new chat session")).option("--act <template>",e.white("Use an act template (e.g., ethereum-developer)")).option("-f, --file <path>",e.white("Process content from a file (PDF, DOCX, PPTX, XLSX, ODT, ODP, ODS, TXT, etc.)")).option("-F, --files <paths...>",e.white("Process content from multiple files")).option("-b, --batch <patterns...>",e.white('Process files matching glob patterns (e.g., "src/**/*.js" "docs/*.md")')).option("--parallel",e.white("Process multiple files in parallel (faster for many files)")).option("--max-concurrency <number>",e.white("Maximum number of files to process concurrently (default: 5)"),"5").option("--continue-on-error",e.white("Continue processing other files if one fails")).option("--file-type <type>",e.white("Override automatic file type detection (pdf, docx, pptx, xlsx, odt, odp, ods, txt, etc.)")).option("--verbose",e.white("Show detailed status and debug information")).addHelpText("after",[e.bold.cyan(`
Examples:`),e.gray(' rawi ask "What is this document about?" --file report.pdf'),e.gray(' rawi ask "Analyze this data" --file data.xlsx'),e.gray(' rawi ask "Review this code" --file src/app.js'),e.gray(' rawi ask "Summarize" --file document.docx --act technical-writer'),e.gray(' echo "Additional context" | rawi ask "Analyze" --file data.json'),"",e.bold.cyan("Batch Processing:"),e.gray(' rawi ask "Review these files" --files file1.js file2.py file3.md'),e.gray(' rawi ask "Analyze source code" --batch "src/**/*.{js,ts}"'),e.gray(' rawi ask "Review docs" --batch "docs/**/*.md" --parallel'),e.gray(' rawi ask "Check configs" --batch "**/*.{json,yml,yaml}" --continue-on-error'),"",e.bold.cyan("See also:"),e.gray(" rawi act --list"),e.gray(" rawi provider --list"),e.gray(" rawi configure --show"),e.gray(" rawi ask --help")].join(`
`)).action(async(y,r)=>{let i=null;try{let v=await R(),g="";if(r.file||r.files||r.batch){r.verbose&&console.log(e.dim("\u{1F4C4} Processing files..."));try{let s;if(r.fileType){let w=r.fileType.toUpperCase();w in S?s=S[w]:(console.error(e.red(`\u274C Unsupported file type: ${r.fileType}`)),console.log(e.yellow("Supported types: pdf, docx, pptx, xlsx, odt, odp, ods, txt, js, jsx, ts, tsx, py, java, cpp, c, go, rs, rb, kt, swift, dart, scala, php, json, md, yml, yaml, xml, html, css, sql, sh, bash, env, ini, conf, toml, log, and more")),process.exit(1))}let d=new M({verbose:r.verbose,forceFileType:s}),m,x=0;if(r.file)m=await d.readFile(r.file),m.success&&m.content?(g=m.content.text,x=1):(console.error(e.red(`\u274C Failed to process file: ${m.error}`)),process.exit(1));else{let w=Number.parseInt(r.maxConcurrency)||5,C={parallel:r.parallel,maxConcurrency:w,continueOnError:r.continueOnError,fileType:r.fileType,onProgress:r.verbose?(b,u,l)=>{console.log(e.dim(`\u{1F4DD} [${b}/${u}] Processing: ${l}`))}:void 0},a;if(r.files?a=await d.processMultipleFiles(r.files,C):r.batch&&(a=await d.processGlobPatterns(r.batch,C)),a){let b=[],u=0;for(let l of a.results)l.result.success&&l.result.content&&(b.push(`=== ${l.filePath} ===
${l.result.content.text}
`),u++);if(g=b.join(`
`),x=a.totalFiles,r.verbose&&(console.log(e.dim(`\u2705 Successfully processed ${u}/${a.totalFiles} files`)),console.log(e.dim(`\u23F1\uFE0F Total time: ${(a.totalProcessingTime/1e3).toFixed(2)}s`)),console.log(e.dim(`\u{1F4CA} Total content length: ${g.length} characters`)),a.failedFiles>0)){console.log(e.yellow(`\u26A0\uFE0F ${a.failedFiles} files failed to process:`));for(let l of a.errors)console.log(e.yellow(` \u2022 ${l.filePath}: ${l.error}`))}u===0&&(console.error(e.red("\u274C No files were processed successfully")),process.exit(1))}}r.verbose&&x===1&&(console.log(e.dim("\u2705 Successfully processed file")),console.log(e.dim(`\u{1F4CA} Content length: ${g.length} characters`)))}catch(s){let d=s instanceof Error?s.message:"Unknown error occurred";console.error(e.red(`\u274C Error processing file: ${d}`)),process.exit(1)}}let f,T=[y,v,g].filter(Boolean);if(T.length===0){p.help();return}if(f=T.join(`
`),r.act)try{f=U(r.act,f),r.verbose&&console.log(e.dim(`\u{1F3AD} Using act template: ${r.act}`))}catch(s){let d=s instanceof Error?s.message:"Unknown error occurred";r.verbose&&(console.error(e.red(`\u274C ${d}`)),console.log(e.yellow('\u{1F4A1} Use "rawi act --list" to see available templates.')));return}let n=r.profile||$;E(n)||(r.verbose&&(console.error(e.red(`\u274C Profile '${n}' does not exist or is not properly configured.`)),console.error(e.yellow(`Run 'rawi configure -p ${n}' to set up this profile.`))),process.exit(1)),i=new j;let t;if(r.newSession)t=await i.createSession(n),r.verbose&&console.log(e.dim(`\u{1F195} Started new session: ${t}`));else if(r.session){t=r.session;let s=await i.getSession(t);s||(r.verbose&&console.error(e.red(`\u274C Session '${t}' not found.`)),process.exit(1)),s.profile!==n&&(r.verbose&&console.error(e.red(`\u274C Session '${t}' belongs to profile '${s.profile}', not '${n}'.`)),process.exit(1)),r.verbose&&console.log(e.dim(`\u{1F504} Continuing session: ${t}`))}else t=await i.getCurrentSession(n),r.verbose&&console.log(e.dim(`\u{1F4DD} Using current session: ${t}`));r.verbose&&(console.log(`Using profile: ${n}`),console.log(`Processing query: ${f.length>100?`${f.substring(0,100)}...`:f}`)),r.verbose&&c.start("validation","Validating configuration...");let o=F(n);o||(r.verbose&&(c.fail("validation","Configuration validation failed"),console.error(e.red(`\u274C Unable to load credentials for profile '${n}'.`))),process.exit(1)),r.verbose&&c.succeed("validation","Configuration validated successfully"),await i.addMessage(t,"user",f,o.provider,o.model,o.temperature,o.maxTokens),r.verbose&&c.start("generation",`Streaming response using ${o.provider} (${o.model})...`,{color:"cyan"}),console.log(`${e.cyan("Result:")}`);let h,k=!1;try{h=await P(o,f,{streaming:!0,onChunk:s=>{k||(r.verbose&&c.succeed("generation","Starting to stream response..."),k=!0),process.stdout.write(s)},onComplete:()=>{console.log(),r.verbose&&console.log(e.dim("\u2705 Streaming completed"))},onError:s=>{r.verbose&&(c.fail("generation","Failed to generate response"),console.error(e.red(`\u274C ${s.message}`)))}}),await i.addMessage(t,"assistant",h,o.provider,o.model,o.temperature,o.maxTokens),r.verbose&&c.succeed("generation","Response streamed successfully!")}catch(s){r.verbose&&(c.fail("generation","Failed to generate response"),console.error(e.red(`\u274C ${s instanceof Error?s.message:String(s)}`))),h=`Unable to generate response using ${o.provider} (${o.model}). Error: ${s instanceof Error?s.message:String(s)}`,await i.addMessage(t,"assistant",h,o.provider,o.model,o.temperature,o.maxTokens,{error:!0})}if(r.verbose){let s=await i.getSession(t);s&&console.log(e.dim(`
\u{1F4AC} Session: ${t} (${s.messageCount} messages)`))}}catch(v){r.verbose&&console.error("Error processing query:",v),process.exit(1)}finally{i&&i.close()}}),p};export{G as a};
/* Rawi (راوي) is the developer-friendly AI CLI that brings the power of 12 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into an intelligent development workspace. */
//# sourceMappingURL=chunk-Y3NLNGEE.js.map