rawi
Version:
Rawi (راوي) is the developer-friendly AI CLI that brings the power of 11 major AI providers directly to your terminal. With seamless shell integration, persistent conversations, and 200+ specialized prompt templates, Rawi transforms your command line into
34 lines (25 loc) • 10.1 kB
JavaScript
/* Rawi (راوي) is the developer-friendly AI CLI that brings the power of 11 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 d,b as g,c as l}from"./chunk-VSPMROUG.js";import{writeFileSync as m}from"fs";import{confirm as u,select as h}from"@inquirer/prompts";import o from"chalk";var f=class{dbManager;constructor(t){this.dbManager=t}async handleSessionStart(t){try{let s=t.profile||"default";if(t.newSession)return await this.createNewSession(s);if(t.session)return(await this.continueSession(t.session,s)).sessionId;let e=await this.getRecentSessions(s,5);if(e.length===0)return console.log(o.dim("No recent sessions found. Creating a new session...")),await this.createNewSession(s);let n=await this.displaySessionSelection(e);return n===null?await this.createNewSession(s):(await this.continueSession(n,s),n)}catch(s){if(s instanceof d||s instanceof g)return console.error(o.red(`\u274C ${s.message}`)),console.log(o.dim("Falling back to creating a new session...")),await this.createNewSession(t.profile||"default");if(s instanceof l)return console.error(o.red(`\u274C Database error: ${s.message}`)),console.log(o.dim("Creating temporary session...")),await this.dbManager.createEmergencySession(t.profile||"default","chat");throw s}}async createNewSession(t,s){try{let e=await this.dbManager.createSession(t,s,"chat");return console.log(o.green(`\u2705 Created new session: ${e}`)),e}catch(e){throw console.error(o.red(`\u274C Failed to create session: ${e}`)),new l("Failed to create new session",e instanceof Error?e:new Error(String(e)))}}async continueSession(t,s){try{let e=await this.dbManager.getSession(t);if(!e)throw new d(t,s);if(e.profile!==s)throw new g(t,s,e.profile);let n=await this.dbManager.getMessages(t);return console.log(o.green(`\u2705 Continuing session: ${t}`)),e.title&&console.log(o.dim(`\u{1F4DD} Title: ${e.title}`)),console.log(o.dim(`\u{1F4AC} Messages: ${n.length}`)),{sessionId:e.id,profile:e.profile,title:e.title,messages:n,displaySessionInfo:()=>this.displaySessionInfo(e),displayConversationHistory:r=>this.displayConversationHistory(n,r),addUserMessage:async r=>{await this.dbManager.addMessage(t,"user",r,"unknown","unknown")},addAssistantMessage:async(r,i)=>{await this.dbManager.addMessage(t,"assistant",r,i.provider||"unknown",i.model||"unknown",i.temperature,i.maxTokens,i)},updateSessionTitle:async r=>{await this.dbManager.updateSessionTitle(t,r)},getSessionStats:()=>({messageCount:n.length,createdAt:e.createdAt,updatedAt:e.updatedAt,duration:this.calculateDuration(e.createdAt,e.updatedAt),providers:Array.from(new Set(n.map(r=>r.provider))),models:Array.from(new Set(n.map(r=>r.model)))})}}catch(e){throw e instanceof d||e instanceof g?e:(console.error(o.red(`\u274C Failed to continue session: ${e}`)),new l("Failed to continue session",e instanceof Error?e:new Error(String(e))))}}async getRecentSessions(t,s=10){try{return await this.dbManager.getSessions({profile:t,limit:s})}catch(e){throw console.error(o.red(`\u274C Failed to get recent sessions: ${e}`)),new l("Failed to retrieve recent sessions",e instanceof Error?e:new Error(String(e)))}}async displaySessionSelection(t){console.log(o.bold.blue(`
\u{1F50D} Recent Sessions:`));let s=[{name:o.green("\u2795 Create new session"),value:"new"},...t.map(e=>({name:this.formatSessionChoice(e),value:e.id}))];try{let e=await h({message:"Choose a session to continue or create a new one:",choices:s});return e==="new"?null:e}catch(e){throw e instanceof Error&&e.name==="ExitPromptError"&&(console.log(o.yellow(`
\u{1F44B} Session selection cancelled`)),process.exit(0)),e}}async listSessions(t){try{let s=await this.dbManager.getSessions({profile:t.profile,limit:t.limit||20,fromDate:t.fromDate,toDate:t.toDate});if(s.length===0){console.log(o.dim("No sessions found."));return}switch(t.format||"table"){case"json":console.log(JSON.stringify(s,null,2));break;case"summary":this.displaySessionsSummary(s);break;default:this.displaySessionsTable(s);break}}catch(s){throw console.error(o.red(`\u274C Failed to list sessions: ${s}`)),new l("Failed to list sessions",s instanceof Error?s:new Error(String(s)))}}async deleteSession(t,s){try{let e=await this.dbManager.getSession(t);if(!e)return console.error(o.red(`\u274C Session '${t}' not found`)),!1;if(!s.force&&s.confirm!==!1&&!await u({message:`Are you sure you want to delete session '${t}'${e.title?` (${e.title})`:""}? This will delete all ${e.messageCount} messages.`,default:!1}))return console.log(o.dim("Session deletion cancelled.")),!1;let n=await this.dbManager.deleteSession(t);return n?console.log(o.green(`\u2705 Session '${t}' deleted successfully`)):console.error(o.red(`\u274C Failed to delete session '${t}'`)),n}catch(e){if(e instanceof Error&&e.name==="ExitPromptError")return console.log(o.yellow(`
\u{1F44B} Session deletion cancelled`)),!1;throw console.error(o.red(`\u274C Failed to delete session: ${e}`)),new l("Failed to delete session",e instanceof Error?e:new Error(String(e)))}}async renameSession(t,s){try{if(!await this.dbManager.getSession(t))return console.error(o.red(`\u274C Session '${t}' not found`)),!1;if(!s||s.trim().length===0)return console.error(o.red("\u274C Session title cannot be empty")),!1;let n=s.trim();if(n.length>200)return console.error(o.red("\u274C Session title cannot exceed 200 characters")),!1;let r=await this.dbManager.updateSessionTitle(t,n);return r?console.log(o.green(`\u2705 Session '${t}' renamed to: ${n}`)):console.error(o.red(`\u274C Failed to rename session '${t}'`)),r}catch(e){throw console.error(o.red(`\u274C Failed to rename session: ${e}`)),new l("Failed to rename session",e instanceof Error?e:new Error(String(e)))}}async exportSessions(t){try{let s=await this.dbManager.exportChatHistory({profile:t.profile,fromDate:t.fromDate,toDate:t.toDate}),e=s.sessions,n=s.messages;if(t.sessions&&t.sessions.length>0&&(e=s.sessions.filter(c=>t.sessions.includes(c.id)),n=Object.fromEntries(Object.entries(s.messages).filter(([c])=>t.sessions.includes(c)))),e.length===0)return console.log(o.dim("No sessions found to export.")),"";let r=new Date().toISOString().replace(/[:.]/g,"-"),i=t.output||`rawi-sessions-${r}.${t.format}`,a;switch(t.format){case"json":a=JSON.stringify({exportedAt:new Date().toISOString(),sessions:e,messages:n,stats:s.stats},null,2);break;case"markdown":a=this.formatSessionsAsMarkdown(e,n);break;default:throw new Error(`Unsupported export format: ${t.format}`)}return m(i,a,"utf8"),console.log(o.green(`\u2705 Exported ${e.length} sessions to: ${i}`)),i}catch(s){throw console.error(o.red(`\u274C Failed to export sessions: ${s}`)),new l("Failed to export sessions",s instanceof Error?s:new Error(String(s)))}}formatSessionChoice(t){let s=this.formatAge(t.updatedAt),e=t.title||"Untitled",n=t.messageCount;return`${o.cyan(t.id.slice(0,8))} - ${o.white(e)} ${o.dim(`(${n} messages, ${s})`)}`}formatAge(t){let s=new Date(t),n=new Date().getTime()-s.getTime(),r=Math.floor(n/(1e3*60)),i=Math.floor(n/(1e3*60*60)),a=Math.floor(n/(1e3*60*60*24));return r<60?`${r}m ago`:i<24?`${i}h ago`:`${a}d ago`}calculateDuration(t,s){let e=new Date(t),r=new Date(s).getTime()-e.getTime(),i=Math.floor(r/(1e3*60)),a=Math.floor(r/(1e3*60*60)),c=Math.floor(r/(1e3*60*60*24));return i<60?`${i} minutes`:a<24?`${a} hours`:`${c} days`}displaySessionInfo(t){console.log(o.dim(`ID: ${t.id}`)),console.log(o.dim(`Profile: ${t.profile}`)),t.title&&console.log(o.dim(`Title: ${t.title}`)),console.log(o.dim(`Created: ${new Date(t.createdAt).toLocaleString()}`)),console.log(o.dim(`Updated: ${new Date(t.updatedAt).toLocaleString()}`)),console.log(o.dim(`Messages: ${t.messageCount}`))}displayConversationHistory(t,s){let e=s?t.slice(-s):t;if(e.length===0){console.log(o.dim("No previous messages in this session."));return}console.log(o.bold.blue(`
\u{1F4AC} Conversation History:`)),e.forEach(n=>{let r=n.role==="user"?o.blue("You"):o.green("Assistant"),i=n.content.length>100?`${n.content.substring(0,100)}...`:n.content;console.log(`${r}: ${o.dim(i)}`)}),console.log("")}displaySessionsTable(t){console.log(o.bold.blue(`
\u{1F4CB} Sessions:`)),console.log(o.dim("ID".padEnd(10)+"Title".padEnd(30)+"Messages".padEnd(10)+"Updated".padEnd(20))),console.log(o.dim("-".repeat(70))),t.forEach(s=>{let e=s.id.slice(0,8),n=(s.title||"Untitled").slice(0,28),r=s.messageCount.toString(),i=this.formatAge(s.updatedAt);console.log(o.cyan(e.padEnd(10))+o.white(n.padEnd(30))+o.dim(r.padEnd(10))+o.dim(i.padEnd(20)))}),console.log("")}displaySessionsSummary(t){console.log(o.bold.blue(`
\u{1F4CB} Sessions Summary:`)),t.forEach(s=>{console.log(o.cyan(`
\u{1F539} ${s.id.slice(0,8)}`)),console.log(o.white(` Title: ${s.title||"Untitled"}`)),console.log(o.dim(` Messages: ${s.messageCount}`)),console.log(o.dim(` Created: ${new Date(s.createdAt).toLocaleString()}`)),console.log(o.dim(` Updated: ${new Date(s.updatedAt).toLocaleString()}`))}),console.log("")}formatSessionsAsMarkdown(t,s){let e=`# Rawi Chat Sessions Export
`;return e+=`Exported on: ${new Date().toLocaleString()}
`,e+=`Total sessions: ${t.length}
`,t.forEach(n=>{e+=`## Session: ${n.title||"Untitled"}
`,e+=`- **ID**: ${n.id}
`,e+=`- **Profile**: ${n.profile}
`,e+=`- **Created**: ${new Date(n.createdAt).toLocaleString()}
`,e+=`- **Updated**: ${new Date(n.updatedAt).toLocaleString()}
`,e+=`- **Messages**: ${n.messageCount}
`;let r=s[n.id]||[];r.length>0&&(e+=`### Conversation
`,r.forEach(i=>{let a=i.role==="user"?"**You**":"**Assistant**",c=new Date(i.timestamp).toLocaleString();e+=`${a} _(${c})_:
${i.content}
---
`})),e+=`
`}),e}};export{f as a};
/* Rawi (راوي) is the developer-friendly AI CLI that brings the power of 11 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-ORMDPPOJ.js.map