env-ai
Version:
AI Assistant for Your Local Environment
236 lines (170 loc) • 33.9 kB
JavaScript
;const o=require("ollama"),ollama=require("@llamaindex/ollama"),json=require("@llamaindex/readers/json"),llamaindex=require("llamaindex"),globby=require("globby"),promises=require("node:fs/promises"),node_path=require("node:path"),node_url=require("node:url"),smolToml=require("smol-toml"),y=require("yaml"),e$1=require("node:process"),zod=require("zod"),t=require("picocolors"),prompts=require("@clack/prompts"),core=require("@clack/core"),_$1=require("is-unicode-supported"),sisteransi=require("sisteransi");function _interopDefaultCompat(g){return g&&typeof g=="object"&&"default"in g?g.default:g}function _interopNamespaceCompat(g){if(g&&typeof g=="object"&&"default"in g)return g;const s=Object.create(null);if(g)for(const h in g)s[h]=g[h];return s.default=g,s}function _mergeNamespaces(g,s){for(var h=0;h<s.length;h++){const p=s[h];if(typeof p!="string"&&!Array.isArray(p))for(const d in p)d!=="default"&&!(d in g)&&(g[d]=p[d])}return g}const o__default=_interopDefaultCompat(o),y__default=_interopDefaultCompat(y),e__default=_interopDefaultCompat(e$1),t__default=_interopDefaultCompat(t),prompts__namespace=_interopNamespaceCompat(prompts),___default=_interopDefaultCompat(_$1),name="env-ai",version="0.4.2",description="AI Assistant for Your Local Environment",bugs={url:"https://github.com/pigeonposse/env-ai/issues"},projectDesc=description,bugsUrl=bugs.url,projectName=name,overwrite={always:"always",ask:"ask",last:"last"},theme={custom:"custom",explain:"explain",docs:"docs",fix:"fix",performance:"performance",refactor:"refactor",test:"tests"},themeDesc={custom:"Adapt the system to your needs.",explain:"Provide clear explanations of code and functionality.",docs:"Generate user guides and technical documentation.",fix:"Identify and resolve bugs for accurate output.",performance:"Improve the efficiency of your code and reduce response times.",refactor:"Improve code structure for better readability and maintainability.",test:"Create tests and ensure quality."},PROMPT_VARS={CONTENT:"content"},i$1={__proto__:null,PROMPT_VARS,bugsUrl,overwrite,projectDesc,projectName,theme,themeDesc,version},isPath=g=>{if((node_path.isAbsolute(g)||/^(\.\/|\.\.\/|[A-Za-z]:\\|\/)/.test(g))&&(node_path.isAbsolute(g)||/^(\.\/|\.\.\/|[A-Za-z]:\\|\/)/.test(g))){if(/\s(?!\\)/.test(g)&&!/\\\s/.test(g))return!1;try{return node_path.join(g)!==""}catch{return!1}}return!1};class F{path={resolve:node_path.resolve,extname:node_path.extname,basename:node_path.basename,isAbsolute:node_path.isAbsolute,join:node_path.join};readFile=promises.readFile;writeFile=promises.writeFile;isAbsolute=node_path.isAbsolute;join=node_path.join;isPath=isPath;getPaths=globby.globby;extname=node_path.extname;async existsFile(s){try{return(await promises.stat(s)).isFile()}catch{return!1}}async readConfigFile(s){const h=this.extname(s),p=await this.readFile(s,"utf8");let d;if(h===".json")d=JSON.parse(p);else if(h===".yml"||h===".yaml")d=y__default.parse(p);else if(h===".toml"||h===".tml")d=smolToml.parse(p);else if(h===".js"||h===".mjs")d=(await import(node_url.pathToFileURL(s).href)).default;else throw new Error(`Unsupported file extension: ${h}`);return d}}const replacePlaceholders=async(g,s,h)=>{const p=/{{\s*([\w:/.-]+)\s*(?:\(\s*['"]([^'"]+)['"]\s*\))?\s*}}/g,d=[];let w;for(;(w=p.exec(g))!==null;){const[f,v,R]=w;d.push({placeholder:f,key:v,arg:R})}for(const{placeholder:f,key:v,arg:R}of d){const x=s[v];let D="";typeof x=="function"?D=await x(R||""):x!==void 0?D=x:h?D=await h(v):D=f,g=g.replace(f,D)}return g},setErrorString=g=>{const s={code:g?.code,name:g?.name,message:g?.message,stack:g?.stack?g.stack.split(`
`):[],...g instanceof Object?g:{}};return Array.isArray(s.stack)&&s.stack.length>0?s.stack.map(h=>` ${h}`).join(`
`):JSON.stringify(s,null," ")},sanitizeContent=g=>g,getTextPlainFromURL=async g=>{try{const s=await fetch(g);if(!s.ok)throw new Error(`HTTP error! Status: ${s.status}`);return await s.text()}catch(s){throw new Error(`Failed to fetch URL [${g}]: ${s?.message||"Unexpected error"}`)}},getStringType=g=>u$2(g)?"url":isPath(g)?"path":"text",u$2=g=>{try{return new URL(g),!0}catch{return!1}},l={__proto__:null,getStringType,getTextPlainFromURL,replacePlaceholders,sanitizeContent,setErrorString};class S{#e;#s;#i;#r;#t;constructor(s){this.#e=new ollama.OllamaEmbedding({model:"nomic-embed-text"}),this.#i=new F,this.#r=s.system,this.#s=new ollama.Ollama({model:s.model,options:{temperature:.5}}),this.#t=void 0,llamaindex.Settings.embedModel=this.#e,llamaindex.Settings.llm=this.#s,llamaindex.Settings.chunkSize=300,llamaindex.Settings.chunkOverlap=20}async#o(s){const h=new TextEncoder().encode(s);return await new json.JSONReader({levelsBack:0}).loadDataAsContent(h)}async generateChat(s){if(s.length==0){const f=new llamaindex.Document({id_:"default_doc",text:"There are no documents loaded.Starting chat without documentation.",metadata:{file_path:"default",file_name:"default"}});s.push({content:f.text,path:f.id_})}const h=f=>{try{const v=JSON.parse(f);return typeof v=="object"&&v!==null}catch{return!1}},p=s.map(async f=>{const v=getStringType(f.path)==="url",R=v&&h(f.content),x=f.path.endsWith(".json")||R,D={id_:f.path,metadata:{is_url:v,is_JSON_content:x,is_local_path:!v,file_path:v?f.path:this.#i.path.resolve(f.path),file_name:v?f.path:this.#i.path.basename(f.path)}};if(x){const T={...(await this.#o(f.content))[0],...D};return new llamaindex.Document(T)}return new llamaindex.Document({text:f.content,id_:f.path,...D})}),d=await Promise.all(p),w=(await llamaindex.VectorStoreIndex.fromDocuments(d)).asRetriever({similarityTopK:3});this.#t&&this.#t.reset(),this.#t=new llamaindex.ContextChatEngine({retriever:w,chatModel:this.#s,systemPrompt:this.#r})}async chat(s){return this.#t?await this.#t.chat({message:s,stream:!0}):void 0}async resetChatEngine(){this.#t&&this.#t.reset()}}class a{#e;error={NO_MODELS:"no-models"};constructor(){this.#e=o__default}async getModels(){const s=await this.#e.list();if(!s.models||s.models.length===0)throw new Error(this.error.NO_MODELS);return s.models.map(h=>h.name)}async installModel(s){return await o__default.pull({model:s,stream:!0})}async chatVectored(s){const h=new S({model:s.model,system:s.system});return await h.generateChat(s.docs),{send:h.chat.bind(h),reset:h.resetChatEngine.bind(h)}}async chat(s){const h=this.#e,p=[{role:"system",content:s.system}];return{send:async d=>(p.push({role:"user",content:d}),await h.chat({stream:!0,model:s.model,messages:p,options:{temperature:0}})),addAssistantMessage:d=>p.push({role:"assistant",content:d})}}}const catchError=async g=>g.then(s=>[void 0,s]).catch(s=>[s]);class TypedError extends Error{data;constructor(s,h){super(s),this.data=h,Error.captureStackTrace(this,this.constructor)}}const c=g=>e__default.on("SIGINT",g),exit=g=>e__default.exit(g),rmDeprecationAlerts=()=>{e__default.noDeprecation=!0},onOutputWrite=async({fn:g,on:s})=>{const h=e$1.stdout.write;e$1.stdout.write=async(p,...d)=>{const w=p.toString();await s(w)&&h.call(e$1.stdout,p,...d)};try{return await g()}finally{e$1.stdout.write=h}},_={__proto__:null,argv:e$1.argv,cwd:e$1.cwd,exit,onOutputWrite,onSIGNIT:c,rmDeprecationAlerts,stdout:e$1.stdout},validate=zod.z,createLiteralUnion=g=>zod.z.union(g.map(s=>zod.z.literal(s))),n=createLiteralUnion(Object.values(overwrite)),r=createLiteralUnion(Object.values(theme)),argvSchema=validate.object({output:validate.string().optional(),input:validate.array(validate.string()).optional(),overwrite:n.optional(),model:validate.string().optional(),prompt:validate.string().optional(),system:validate.string().optional(),theme:r.optional(),single:validate.boolean().optional(),debug:validate.boolean().optional(),config:validate.string().optional()}),u$1=class extends TypedError{};class CoreSuper{_c;_p;_argv;_sys=new F;_ai=new a;_string=l;_const=i$1;_process=_;_catchError=catchError;Error=u$1;ERROR_ID={CANCELLED:"CANCELLED",RESPONSE_CANCELLED:"RESPONSE_CANCELLED"};title="core";description;argvSceham=argvSchema;constructor({argv:s,c:h,p}){this._c=h,this._p=p,this._argv=s}_successRes(s,h,p=!1){const d=s+(h!==""?`
`+this._c.gray(h):"");if(p)return d;this._p.log.success(s+`
`+this._c.gray(h))}_errorRes(s,h,p=!1){const d=s+(h!==""?`
`+this._c.gray(h):"");if(p)return d;this._p.log.error(d)}_setDebug(s){this._p.log.debug(this._c.section(this.title.toUpperCase()),s)}_setTitle(){const s=this.description?`
`+this._c.gray(this.description):"";this._p.log.info(this._c.section(this.title.toUpperCase())+s)}_setErrorMessage(s,h="Unexpected error"){return s instanceof Error?s.message:h}cancel(s){this._p.log.warn(this._c.warn(s)),this.exit()}exit(s=0){console.log(""),s==="error"?this._process.exit(1):this._process.exit(s)}async _textPrompt(s){const h=await this._p.text({message:s.message,placeholder:s.placeholder,validate(p){if(!p||p.trim()==="")return"No empty value is allowed."}});if(this._p.isCancel(h))throw new this.Error(this.ERROR_ID.CANCELLED);return h}async _confirmPrompt(s){const h=await this._p.confirm({message:s.message});if(this._p.isCancel(h))throw new this.Error(this.ERROR_ID.CANCELLED);return h}async _selectPrompt(s){const h=await this._p.select({message:s.message,options:s.opts.map(p=>({value:p.value,label:p.title,hint:p.desc}))});if(this._p.isCancel(h))throw new this.Error(this.ERROR_ID.CANCELLED);return h}_setProcessPath(s){return this._sys.path.resolve(this._process.cwd(),s)}async _validateContent(s){const h=async f=>{const v=this._setProcessPath(f);if(!await this._sys.existsFile(v))throw new this.Error(`Path "${f}" doesn't exist or is not found.`);const R=await this._sys.readFile(v,"utf-8");if(R&&typeof R=="string")return R;throw new this.Error(`Path "${f}" has unexpected content type: ${typeof R}`)},p=async f=>{const v=await this._string.getTextPlainFromURL(f);if(v&&typeof v=="string")return v;throw new this.Error(`URL "${f}" has unexpected content type: ${typeof v}`)},d=async f=>{const v=this._string.getStringType(f);return v==="path"?await h(f):v==="url"?await p(f):f},w=await d(s);return await this._string.replacePlaceholders(w,{url:async f=>await p(f),path:async f=>await h(f)},async f=>await d(f))}}class CoreConfig extends CoreSuper{validateProperties(s){return this.argvSceham.parse(s)}async set(){const s=this._argv,h=s.config;if(h)try{const p=await this._sys.readConfigFile(h),d=await this.validateProperties(p);for(const w in d)s[w]||(s[w]=d[w])}catch(p){this._p.log.warn("Error setting config properties: "+this._setErrorMessage(p))}}}class CoreInputs extends CoreSuper{title="Input";description="Inputs to add context to your chat. This in not required.";errorTitle=this._c.error(this.title);async _getDataContent(s,h){h=h??"path";const p=this._p.spinner();p.start("Preparing inputs...");let d=[];if(h==="url"){p.message("Reading and sanitizing url...");const w={};for(const f of s){const[v,R]=await this._catchError((async()=>{p.message("Reading "+f);const x=await this._string.getTextPlainFromURL(f.toString());return this._string.sanitizeContent(x)})());if(v)throw p.stop("Error reading url: "+this._c.gray(f.toString()),1),v;w[f.toString()]=R}p.message("Getting source for all urls..."),d=[...d,...Object.entries(w).map(([f,v])=>({content:v,path:f}))],p.stop("Source urls obtained!")}if(h==="path"){p.message("Reading and sanitizing files...");const w={};for(const f of s){p.message("Reading "+f);const v=await this._sys.readFile(f,"utf-8");w[f.toString()]=this._string.sanitizeContent(v)}p.message("Getting source for all files..."),d=[...d,...Object.entries(w).map(([f,v])=>({content:v,path:f}))],p.stop("Source files obtained!")}return d}async getContent(s){const h=()=>this._errorRes(this.errorTitle,"Unexpected error! Missing required arguments. Please provide all required arguments.");if(!s)return h(),s=await this.getInputs(void 0,void 0),await this.getContent(s);try{const p=!s.urls||!s.urls.length?void 0:await this._getDataContent(s.urls,"url"),d=!s.paths||!s.paths.length?void 0:await this._getDataContent(s.paths,"path");return p&&d?[...p,...d]:p||d||[]}catch{return s=await this.getInputs(void 0,void 0),await this.getContent(s)}}#e(s){const h=[],p=[];for(const d of s)this._string.getStringType(d)==="url"?h.push(new URL(d)):p.push(d);if(!(!p.length&&!h.length))return{urls:h,paths:p}}async#s(s){return(await this._textPrompt({message:"Enter path patterns or URLs to be processed (comma-separated):",placeholder:s})).split(",").map(h=>h.trim())}async getInputs(s,h){const p=s?(this._successRes("Inputs selected:",s.length?s.join(", "):"none"),s):await this.#s(h);let d=this.#e(p);const w=()=>this._errorRes("No files or urls were found matching the inclusion patterns in:",p.join(", "));return d?(d.paths=await this._sys.getPaths(d.paths),(!d||!d.paths.length&&!d.urls.length)&&(w(),d=await this.getInputs(void 0,p.join(", ")))):d={urls:[],paths:[]},d}async get(){this._setTitle();const s=await this.getInputs(this._argv.input||[]),h=await this.getContent(s);return this._setDebug(JSON.stringify(h,null,2)),h}}class CoreModel extends CoreSuper{title="Model";description="LLM model to use for your chat.";async installModel(s){const h=this._p.spinner(),p=d=>`[${s}] Installation: `+d;try{h.start(p("Initializing..."));const d=await this._ai.installModel(s);if(d[Symbol.asyncIterator]){this._process.onSIGNIT(()=>{this._process.stdout.write(`
`),this.cancel("Exit from installation")});for await(const w of d)h.message(p(w.status));h.stop(p("Model installed successfully! \u2728"))}else throw new this.Error("Response is not iterable")}catch(d){throw h.stop(p("Error installing model"),1),new Error(`Error installing [${s}] model: ${this._setErrorMessage(d)}`)}}async get(){const s=this._argv.model,{gray:h}=this._c;this._setTitle();const p=async()=>{const[R,x]=await this._catchError(this._ai.getModels());if(R){const D=`
For more information about Ollama please visit ${this._c.gray("https://ollama.com/")}`;throw this._errorRes("Error retrieving model from Ollama.",""),R instanceof Error&&R.message===this._ai.error.NO_MODELS?new this.Error(`No Ollama models found.
Please download at least one model.`+D):new this.Error(`Ollama is not installed or is not running.
Please install/start Ollama to use this tool.`+D)}else return x},d="Select a LLM model:",w=await p();if(s&&w.includes(s))return this._p.log.success(`${d}
${h(s)}`),s;s&&!w.includes(s)&&this._p.log.error(`Model [${s}] not exists or is not installed.`);const f="nomic-embed-text";if(!w.some(R=>R.startsWith(f))){if(this._p.log.warn(`Model [${f}] must be installed for create embeddings`),await this._confirmPrompt({message:`Do you want to install [${f}] model now?`})===!1)throw new this.Error(`Model [${f}] must be installed.
Read more about it at https://ollama.com/library/nomic-embed-text`);if(await this.installModel(f),!(await p()).some(R=>R.startsWith(f)))throw new this.Error(`Model [${f}] failed to install unexpectedly`)}const v=await this._selectPrompt({message:d,opts:w.filter(R=>!R.startsWith(f)).map(R=>({value:R,title:R}))});return this._setDebug(v),v}}class CoreOutput extends CoreSuper{title="Output";description="Output configuration for save the generated content.";async getOverwrite(){const s=this._argv.overwrite,{ask:h,...p}=this._const.overwrite,d="Select overwrite type:";if(s&&s!==h){if(s==="always"||s==="last")return this._successRes(d,s),s;this._errorRes("Invalid overwrite type: ",s)}return await this._selectPrompt({message:d,opts:Object.values(p).map(w=>({value:w,title:w}))})}async getSingle(){const s=this._argv.single;return!s||s!==!0?!1:(this._successRes("Response type:","Single"),s)}async getPath(){const s=async(p,d)=>{const w=p?(this._successRes("Output path:",p),p):await this._textPrompt({message:"Enter output path:",placeholder:d});return this._setProcessPath(w)},h=this._argv.output;return h?await s(h):void 0}async get(){this._setTitle();const s=await this.getPath(),h=await this.getSingle(),p=s?await this.getOverwrite():void 0,d={path:s,overwrite:p,single:h};return!s&&!h&&this._p.log.success("No output path provided"),this._setDebug(JSON.stringify(d,null,2)),d}}const i={[theme.docs]:{system:`You are a helpful assistant explaining how to use the provided code library and provide detailed documentation.
Generate a complete and user-oriented README in Markdown format for the provided code library.
Assume the documentation will be viewed by end-users who seek a clear understanding of how to install, configure, and use the library effectively.
If a package.json file is provided, extract relevant information such as project name, description, installation steps, available binaries, author(s), contributor(s), license, exports, and dependencies, integrating these details seamlessly into the documentation.
Include examples and details for each aspect of the library, aiming to cover both beginners and advanced users.
structure:
# Project Title
> A concise project description explaining the library's purpose and main features.
## Table of Contents
- Overview
- Installation
- Usage
- Setup & Configuration
- API Reference
- Code Examples
- Additional Information
- Author & Contributors
- Contributing
- License
## Overview
Provide a high-level explanation of the library's functionality, its key advantages, and core use cases.
## Installation
Explain installation in detail:
1. List prerequisites, if any.
2. Provide step-by-step installation instructions using npm/yarn or other methods, based on package.json information.
## Usage
### Setup & Configuration
Outline any configuration steps required post-installation, using examples if needed.
### API Reference
Document all exposed functions, classes, or modules:
- **Function/Class Name**: Describe its purpose and main use.
- **Parameters**: Detail expected parameters with types and optional/default values.
- **Return Value**: Describe the return type and any specific details.
- **Examples**: Provide clear, context-rich examples.
### Code Examples
Include multiple examples showcasing the library in action, covering different scenarios.
## Additional Information
### Author
List the main author as found in package.json.
### Contributors
Provide a contributors list, if available.
### Contributing
Explain how to contribute, with links to contributing guidelines if they exist.
### License
Detail the license information as specified in package.json.
---
The output should be written in strict Markdown format and provide a comprehensive, user-friendly guide.
`},[theme.fix]:{system:`You are a helpful assistant explaining how to identify and fix issues in the provided code library.
Analyze the provided code library and generate a detailed report in Markdown format on common issues and their solutions.
If a package.json file is provided, extract relevant information such as project name, description, and installation steps, integrating these details seamlessly into the report.
Include examples and details for each aspect of the library, aiming to cover both simple and complex issues.
structure:
# Project Title
> A concise project description explaining the library's purpose and main features.
## Table of Contents
- Overview of Common Issues
- Solutions
- Additional Information
## Overview of Common Issues
Provide a summary of typical problems encountered when using the library.
## Solutions
Outline solutions to each identified issue, with step-by-step instructions and code examples.
## Additional Information
### Author
List the main author as found in package.json.
### Contributors
Provide a contributors list, if available.
### License
Detail the license information as specified in package.json.
---
The output should be written in strict Markdown format and provide a comprehensive guide to troubleshooting the library.`},[theme.performance]:{system:"You are a helpful assistant explaining how to optimize the performance of the provided code library."},[theme.refactor]:{system:`You are a helpful assistant explaining how to refactor code for the provided code library.
Generate a detailed guide in Markdown format on how to refactor the provided code library.
Include best practices and principles for writing clean, maintainable code.
structure:
# Project Title
> A concise project description explaining the library's purpose and main features.
## Table of Contents
- Overview of Refactoring
- Refactoring Techniques
- Example Refactorings
- Additional Information
## Overview of Refactoring
Discuss what refactoring is and its importance in software development.
## Refactoring Techniques
Describe common refactoring techniques, providing examples for each.
## Example Refactorings
Provide concrete examples of code refactorings applied to the library, with before and after comparisons.
## Additional Information
### Author
List the main author as found in package.json.
### Contributors
Provide a contributors list, if available.
### License
Detail the license information as specified in package.json.
---
The output should be written in strict Markdown format and provide a comprehensive guide to code refactoring.`},[theme.explain]:{system:`You are a helpful assistant providing explanations for the provided code library.
Create a detailed explanation in Markdown format for the provided code library, focusing on its design, structure, and functionality.
Include examples to illustrate key concepts and usage.
structure:
# Project Title
> A concise project description explaining the library's purpose and main features.
## Table of Contents
- Overview of the Code Library
- Key Components
- Detailed Explanations
- Additional Information
## Overview of the Code Library
Provide an overview of the library, including its main features and intended use cases.
## Key Components
Describe the key components of the library, explaining their roles and how they interact.
## Detailed Explanations
Provide detailed explanations of important concepts, including code snippets to clarify usage.
## Additional Information
### Author
List the main author as found in package.json.
### Contributors
Provide a contributors list, if available.
### License
Detail the license information as specified in package.json.
---
The output should be written in strict Markdown format and provide a comprehensive guide to understanding the library.`},[theme.test]:{system:`You are a helpful assistant guiding users on testing the provided code library.
Develop a detailed guide in Markdown format on testing the provided code library.
Assume the audience consists of developers who want to ensure their code is well-tested.
structure:
# Project Title
> A concise project description explaining the library's purpose and main features.
## Table of Contents
- Overview of Testing
- Testing Frameworks and Tools
- Test Cases and Examples
- Additional Information
## Overview of Testing
Discuss the importance of testing in software development and provide an overview of the library's testing approach.
## Testing Frameworks and Tools
Describe the testing frameworks and tools available for use with the library, providing examples of how to set them up.
## Test Cases and Examples
Provide examples of test cases, including unit tests and integration tests, demonstrating how to write and run tests.
## Additional Information
### Author
List the main author as found in package.json.
### Contributors
Provide a contributors list, if available.
### License
Detail the license information as specified in package.json.
---
The output should be written in strict Markdown format and provide a comprehensive guide to testing the library.`}};class CorePrompt extends CoreSuper{title="Prompt";description="The prompt configuration for your chat.";defaults=i;async#e(s){const h=`System prompt ${this._c.italic("(Enter text path or url)")}:`,p=async(w,f)=>{let v,R;try{if(w?v=await this._validateContent(w):(R=await this._textPrompt({message:h,placeholder:f||"You are an expert code programmer with extensive knowledge of the content of this library"}),v=await this._validateContent(R)),!v)throw new Error}catch(x){if(x instanceof this.Error&&x.message===this.ERROR_ID.CANCELLED)throw new this.Error(this.ERROR_ID.CANCELLED);this._errorRes("System prompt error:",this._setErrorMessage(x)),v=await p(void 0,v||R)}return v},d=this._argv.system;return d?(this._successRes(h,d),await p(d)):s||await p(void 0)}async getTheme(){const s=this._argv.theme,h="Select theme:";return s?(this._successRes(h,s),s):await this._selectPrompt({message:h,opts:Object.entries(this._const.theme).map(([p,d])=>({value:d,title:d,desc:this._const.themeDesc[p]||void 0}))})}async get(){this._setTitle();const s=await this.getTheme(),h=await this.#e(s!=="custom"?this.defaults[s].system:void 0),p={theme:s,system:h};return this._setDebug(JSON.stringify(p,null,2)),p}}class CoreResponse extends CoreSuper{title="Chat";#e;#s="\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";async#i(s){this._setDebug(s);const h=this.#s,p="Assistant:",d=()=>(console.log(`
`),this._p.intro(h)),w=()=>(this._p.outro(h),console.log(`
`)),f=this._p.spinnerCustom();let v="",R=!1;if(!this.#e)throw new this.Error("Chat not initialized");f.start(p+" Thinking...");const x=await this.#e.send(s);if(f.message(p+" Thinking..."),x&&x[Symbol.asyncIterator]){f.stop(p),w(),this._process.onSIGNIT(async()=>R=!0);for await(const D of x){if(R)throw this._process.stdout.write(`
`),d(),new this.Error(this.ERROR_ID.RESPONSE_CANCELLED);this._process.stdout.write(D.message.content.toString()),v+=D.message.content}d()}else throw f.stop(p+"There has been an error in the chat process"),new this.Error("Chat unexpeted error");return v}async#r({system:s,model:h,docs:p}){const d=this._p.spinner();d.start("starting...");try{const w="Generating chat";d.message(w);const f=[];this.#e=await this._process.onOutputWrite({fn:async()=>await this._ai.chatVectored({system:s,model:h,docs:p}),on:async v=>{if(!v.includes(w)&&!v.includes("\x1B[999D")&&!v.includes("\x1B[J"))f.push(v);else return v}}),d.stop("Chat successfully generated! \u2728"),f.length||f.join(`
`).trim()!==""?this._p.note(f.join(`
`),"Notifications"):this._p.log.message(this.#s)}catch(w){throw this._p.log.error("Error generating repsonse: "+this._setErrorMessage(w)),w}}async#t(s=void 0){const h=s?.first;let p="";try{const d=s?.prompt&&h?(this._successRes("You:",s.prompt),s.prompt):await this._textPrompt({message:"You:",placeholder:h?"Write your first prompt here":"Write your next prompt here"});p=await this._validateContent(d),p=await this.#i(p)}catch(d){if(d instanceof this.Error&&d.message===this.ERROR_ID.CANCELLED)throw new this.Error(this.ERROR_ID.CANCELLED);d instanceof this.Error&&d.message===this.ERROR_ID.RESPONSE_CANCELLED&&await this.#t(),this._errorRes(this.title,this._setErrorMessage(d)),p=await this.#t()}return p}async#o(s,h,p){if(p==="last"&&await this._sys.existsFile(s)){const d=await this._sys.readFile(s,"utf-8");h=`${d===""?"":d+`
---
`}${h}`}await this._sys.writeFile(s,h),this._successRes("Response saved in:",s)}async#a(s,h){const p=await this.#t();s&&await this.#o(s,p,h||"last"),await this.#a(s,h)}async get({system:s,model:h,docs:p,output:d}){this._setTitle(),await this.#r({system:s,model:h,docs:p});const w=this._argv.prompt,f=await this.#t({first:!0,prompt:w});d.path&&d.overwrite&&await this.#o(d.path,f,d.overwrite),d.single||await this.#a(d?.path,d?.overwrite)}}const coreMessages={};class Core{prompt;model;config;input;response;output;Error;ERROR_ID;exit;cancel;constructor(s){this.config=new CoreConfig(s),this.prompt=new CorePrompt(s),this.model=new CoreModel(s),this.input=new CoreInputs(s),this.output=new CoreOutput(s),this.response=new CoreResponse(s),this.Error=this.input.Error,this.ERROR_ID=this.input.ERROR_ID,this.exit=this.input.exit.bind(this.input),this.cancel=this.input.cancel.bind(this.input)}}const setLine=async(g,s)=>{const{group:h}=g.p,{onCancel:p,onError:d}=s;return{list:async w=>{try{await h(w,{onCancel:async()=>await p()})}catch(f){await d(f)}}}},green=t__default.green,italic=t__default.italic,yellow=t__default.yellow,red=t__default.red,magenta=t__default.magenta,blue=t__default.cyan,underline=t__default.underline,grayBright=t__default.gray,black=t__default.black,gray=g=>t__default.gray(t__default.dim(g)),blackBold=g=>t__default.black(t__default.bold(g)),introColor=g=>t__default.bgCyan(blackBold(` ${g} `)),error=g=>t__default.bgRed(` ${g} `),warn=g=>t__default.bgYellow(blackBold(` ${g} `)),success=g=>t__default.bgGreen(blackBold(` ${g} `)),debug=g=>t__default.bgWhite(t__default.black(` ${g} `)),section=g=>t__default.bgBlue(t__default.white(` ${g} `)),link=g=>underline(italic(g)),E={__proto__:null,black,blackBold,blue,debug,error,gray,grayBright,green,introColor,italic,link,magenta,red,section,success,underline,warn,yellow},u=___default(),m=(g,s)=>u?g:s,b=m("\u25A0","x"),k=m("\u25B2","x"),C=m("\u25C7","o"),G=m("\u2502","|"),spinnerCustom=()=>{const g=u?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],s=u?80:120;let h,p,d=!1,w="";const f=I=>{const O=I>1?"Something went wrong":"Canceled";d&&j(O,I)},v=()=>f(2),R=()=>f(1),x=()=>{e__default.on("uncaughtExceptionMonitor",v),e__default.on("unhandledRejection",v),e__default.on("SIGINT",R),e__default.on("SIGTERM",R),e__default.on("exit",f)},D=()=>{e__default.removeListener("uncaughtExceptionMonitor",v),e__default.removeListener("unhandledRejection",v),e__default.removeListener("SIGINT",R),e__default.removeListener("SIGTERM",R),e__default.removeListener("exit",f)},T=(I="")=>{d=!0,h=core.block(),w=I.replace(/\.+$/,""),e__default.stdout.write(`${grayBright(G)}
`);let O=0,L=0;x(),p=setInterval(()=>{const A=magenta(g[O]),$=".".repeat(Math.floor(L)).slice(0,3);e__default.stdout.write(sisteransi.cursor.move(-999,0)),e__default.stdout.write(sisteransi.erase.down(1)),e__default.stdout.write(`${A} ${w}${$}`),O=O+1<g.length?O+1:0,L=L<g.length?L+.125:0},s)},j=(I="",O=0)=>{w=I??w,d=!1,clearInterval(p);const L=O===0?blue(C):red(O===1?b:k);e__default.stdout.write(sisteransi.cursor.move(-999,0)),e__default.stdout.write(sisteransi.erase.down(1)),e__default.stdout.write(`${L} ${w}
`),D(),h()};return{start:T,stop:j,message:(I="")=>{w=I??w}}},P=_mergeNamespaces({__proto__:null,spinnerCustom},[prompts__namespace]);class CLI{#e;c=E;p=P;_const=i$1;name="";desc="";options={input:{alias:"i",describe:"Path patterns or URLs to be processed",type:"array"},model:{alias:"m",describe:"Ollama LLM model name",type:"string"},system:{alias:"s",describe:"System message (text, path or url)",type:"string"},prompt:{alias:"p",describe:"Fist prompt to generate a response (text, path or url)",type:"string"},theme:{alias:"t",describe:"Set a theme for your chat.",choices:Object.values(theme)},output:{alias:"o",describe:"Output path for the generated response",type:"string"},overwrite:{describe:"Behavior when output file exists",choices:Object.values(overwrite)},single:{describe:"Only one response",type:"boolean"},config:{alias:"c",describe:"Path to config file. Files supported: [.mjs|.js|.json|.yml|.yaml|.toml|.tml]",type:"string"},debug:{describe:"Debug mode",type:"boolean"}};message={intro:"Line execution",outro:"Operation completed!",cancel:"Operation cancelled",error:{general:"Error",debug:"Debug Error",debugFlag:s=>`You can debug the error with flag: ${s}`,debugContact:s=>`Or contact developers at: ${s}`,unexpected:"Unexpected error"},...coreMessages};constructor(s){this.#e=s}async fn(s){return await this.#s(s)}async#s(s){const h=this.p,p=this.c;this.#e;const d={...h,log:{...h.log,debug:(x,D)=>{s.debug&&h.log.info(p.debug("DEBUG")+" "+p.gray(x)+`
`+D)}}},w=new Core({argv:s,c:p,p:d}),f=()=>w.cancel(this.message.cancel),{list:v}=await setLine({p:d},{onCancel:async()=>f(),onError:async x=>{const D=typeof x=="string"?x:setErrorString(x),T=x instanceof w.Error,j=x instanceof Error?x.message:typeof x=="string"?x:this.message.error.unexpected,I=s.debug,O=(L,A)=>(h.log.step(""),h.log.error(p.error(L.toUpperCase())),h.log.step(""),h.cancel(A));T?x.message===w.ERROR_ID.CANCELLED?f():O(this.message.error.general,j):I?O(this.message.error.debug,D.trim()):O(this.message.error.general,`${j}
${this.message.error.debugFlag(p.italic("--debug"))}
${this.message.error.debugContact(p.link(this._const.bugsUrl))}`),w.exit("error")}}),R=new Error(this.message.error.unexpected);await v({intro:async()=>h.intro(p.introColor(this.message.intro.toUpperCase())),config:async()=>await w.config.set(),model:async()=>await w.model.get(),content:async()=>await w.input.get(),ai:async()=>await w.prompt.get(),output:async()=>await w.output.get(),response:async({results:x})=>{if(!x.ai||!x.output||!x.model||!x.content)throw R;return await w.response.get({system:x.ai.system,model:x.model,docs:x.content,output:x.output})},outro:async()=>(h.log.step(""),h.outro(p.success(this.message.outro.toUpperCase())))})}run(){return{command:this.name,describe:this.desc,builder:s=>s.options(this.options),handler:this.#s.bind(this)}}}class e extends CLI{constructor(s){super(s);const h=this._const.projectName;this.name="chat",this.desc=`Chat with the ${h} assistant`,this.message.intro=`${h} assistant`,this.message.cancel=`${h} assistant cancelled!`,this.message.outro=`${h} assistant completed!`}}exports.e=e,exports.rmDeprecationAlerts=rmDeprecationAlerts;