aicommit2 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/cli.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ The core functionalities and architecture of this project are inspired by [AI Co
|
|
|
36
36
|
npm install -g aicommit2
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
2. Retrieve
|
|
39
|
+
2. Retrieve the API key or Cookie you intend to use
|
|
40
40
|
|
|
41
41
|
- [OpenAI](https://platform.openai.com/account/api-keys)
|
|
42
42
|
- [Anthropic Claude](https://console.anthropic.com/)
|
|
@@ -274,10 +274,11 @@ Default: `claude-2.1`
|
|
|
274
274
|
|
|
275
275
|
Supported:
|
|
276
276
|
- `claude-2.1`
|
|
277
|
+
- `claude-2.0`
|
|
277
278
|
- `claude-instant-1.2`
|
|
278
279
|
|
|
279
280
|
```sh
|
|
280
|
-
aicommit2 config set ANTHROPIC_MODEL=claude-2
|
|
281
|
+
aicommit2 config set ANTHROPIC_MODEL=claude-instant-1.2
|
|
281
282
|
```
|
|
282
283
|
|
|
283
284
|
#### GEMINI_KEY
|
package/dist/cli.mjs
CHANGED
|
@@ -30,7 +30,7 @@ ${JSON.stringify({docs:"Documentation only changes",style:"Changes that do not a
|
|
|
30
30
|
`),Js=e=>/^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\([\s\w\.\-\p{Extended_Pictographic}]+\))?(!)?: ([\s\w \p{Extended_Pictographic}])+([\s\S]*)/.test(e),Zs=e=>/^\:\w+\: (.*)$/.test(e),V={OPEN_AI:"OPENAI_KEY",GEMINI:"GEMINI_KEY",ANTHROPIC:"ANTHROPIC_KEY",HUGGING:"HUGGING_COOKIE",CLOVA_X:"CLOVAX_COOKIE"},_n=Object.values(V).map(e=>e);class ae{constructor(t){this.handleError$=n=>{let r="An error occurred";return n.message&&(r=n.message),Z({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.serviceName="AI",this.errorPrefix="ERROR",this.colors={primary:""}}buildPrompt(t,n,r,u,o){return`${Mn(t,u,o)}
|
|
31
31
|
Please just generate ${r} messages in numbered list format.
|
|
32
32
|
Here are git diff:
|
|
33
|
-
${n}`}extractCommitMessageFromRawText(t,n){switch(t){case"conventional":const r=new RegExp(/(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.*\))?: .*$/),u=n.match(r);return u?u[0].replace(/: (\w)/,(a,i)=>`: ${i.toLowerCase()}`):"";case"gitmoji":const o=new RegExp(/\:\w+\: (.*)$/),s=n.match(o);return s?s[0]:"";default:return n}}}var Tn="1.
|
|
33
|
+
${n}`}extractCommitMessageFromRawText(t,n){switch(t){case"conventional":const r=new RegExp(/(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.*\))?: .*$/),u=n.match(r);return u?u[0].replace(/: (\w)/,(a,i)=>`: ${i.toLowerCase()}`):"";case"gitmoji":const o=new RegExp(/\:\w+\: (.*)$/),s=n.match(o);return s?s[0]:"";default:return n}}}var Tn="1.4.0",Qs="A Reactive CLI that generates git commit messages with various AI";class w extends Error{}const ct=" ",ve=e=>{e instanceof Error&&(e instanceof w||(e.stack&&console.error(g.dim(e.stack.split(`
|
|
34
34
|
`).slice(1).join(`
|
|
35
35
|
`))),console.error(`
|
|
36
36
|
${ct}${g.dim(`aicommit2 v${Tn}`)}`),console.error(`
|
|
@@ -52,7 +52,7 @@ ${o}`),u.statusCode===500&&(s+=`
|
|
|
52
52
|
Check the API status: https://status.openai.com`),new w(s)}return JSON.parse(o)},Ii=e=>e.trim().replace(/[\n\r]/g,"").replace(/(\w)\.$/,"$1"),pe=e=>Array.from(new Set(e)),Si=async(e,t,n,r,u,o,s,a,i,f,l)=>{try{const D=await Oi(e,{model:t,messages:[{role:"system",content:Mn(n,o,s)},{role:"user",content:r}],temperature:f,top_p:1,frequency_penalty:0,presence_penalty:0,max_tokens:i,stream:!1,n:u},a,l);return pe(D.choices.filter(c=>c.message?.content).map(c=>Ii(c.message.content)).map(c=>{if(s==="conventional"){const d=/: (\w)/;return c.replace(d,(p,m)=>`: ${m.toLowerCase()}`)}return c}).filter(c=>{switch(s){case"gitmoji":return Zs(c);case"conventional":return Js(c);case"":default:return!0}}))}catch(D){const c=D;throw c.code==="ENOTFOUND"?new w(`Error connecting to ${c.hostname} (${c.syscall})`):c}};class Pi extends ae{constructor(t){super(t),this.params=t,this.handleError$=n=>{const r=n.error?.error?.message?.replace(/(\r\n|\n|\r)/gm,"")||"An error occurred";return Z({name:`${this.errorPrefix} ${r}`,value:r,isError:!0})},this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=g.red.bold("[Anthropic]"),this.anthropic=new Re({apiKey:this.params.config.ANTHROPIC_KEY})}generateCommitMessage$(){return te(this.generateMessage()).pipe(Q(t=>G(t)),H(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),ee(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:u}=this.params.config,o=this.params.config["max-length"],s=this.buildPrompt(n,t,r,o,u),i=(await this.anthropic.completions.create({model:this.params.config.ANTHROPIC_MODEL,max_tokens_to_sample:this.params.config["max-tokens"],temperature:this.params.config.temperature,prompt:`${Re.HUMAN_PROMPT} ${s}${Re.AI_PROMPT}`})).completion;return pe(this.sanitizeMessage(i))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new w(`Error connecting to ${n.hostname} (${n.syscall})`):n}}sanitizeMessage(t){return t.split(`
|
|
53
53
|
`).map(n=>n.trim().replace(/^\d+\.\s/,"")).map(n=>n.replace(/`/g,"")).map(n=>this.extractCommitMessageFromRawText(this.params.config.type,n)).filter(n=>!!n)}}const{hasOwnProperty:bt}=Object.prototype,$e=typeof process<"u"&&process.platform==="win32"?`\r
|
|
54
54
|
`:`
|
|
55
|
-
`,At=(e,t)=>{const n=[];let r="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const u=t.whitespace?" = ":"=";for(const o of Object.keys(e)){const s=e[o];if(s&&Array.isArray(s))for(const a of s)r+=J(o+"[]")+u+J(a)+$e;else s&&typeof s=="object"?n.push(o):r+=J(o)+u+J(s)+$e}t.section&&r.length&&(r="["+J(t.section)+"]"+$e+r);for(const o of n){const s=zn(o).join("\\."),a=(t.section?t.section+".":"")+s,{whitespace:i}=t,f=At(e[o],{section:a,whitespace:i});r.length&&f.length&&(r+=$e),r+=f}return r},zn=e=>e.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(t=>t.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),Wn=e=>{const t=Object.create(null);let n=t,r=null;const u=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,o=e.split(/[\r\n]+/g);for(const a of o){if(!a||a.match(/^\s*[;#]/))continue;const i=a.match(u);if(!i)continue;if(i[1]!==void 0){if(r=xe(i[1]),r==="__proto__"){n=Object.create(null);continue}n=t[r]=t[r]||Object.create(null);continue}const f=xe(i[2]),l=f.length>2&&f.slice(-2)==="[]",D=l?f.slice(0,-2):f;if(D==="__proto__")continue;const c=i[3]?xe(i[4]):!0,d=c==="true"||c==="false"||c==="null"?JSON.parse(c):c;l&&(bt.call(n,D)?Array.isArray(n[D])||(n[D]=[n[D]]):n[D]=[]),Array.isArray(n[D])?n[D].push(d):n[D]=d}const s=[];for(const a of Object.keys(t)){if(!bt.call(t,a)||typeof t[a]!="object"||Array.isArray(t[a]))continue;const i=zn(a);n=t;const f=i.pop(),l=f.replace(/\\\./g,".");for(const D of i)D!=="__proto__"&&((!bt.call(n,D)||typeof n[D]!="object")&&(n[D]=Object.create(null)),n=n[D]);n===t&&l===f||(n[l]=t[a],s.push(a))}for(const a of s)delete t[a];return t},Yn=e=>e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"),J=e=>typeof e!="string"||e.match(/[=\r\n]/)||e.match(/^\[/)||e.length>1&&Yn(e)||e!==e.trim()?JSON.stringify(e):e.split(";").join("\\;").split("#").join("\\#"),xe=(e,t)=>{if(e=(e||"").trim(),Yn(e)){e.charAt(0)==="'"&&(e=e.slice(1,-1));try{e=JSON.parse(e)}catch{}}else{let n=!1,r="";for(let u=0,o=e.length;u<o;u++){const s=e.charAt(u);if(n)"\\;#".indexOf(s)!==-1?r+=s:r+="\\"+s,n=!1;else{if(";#".indexOf(s)!==-1)break;s==="\\"?n=!0:r+=s}}return n&&(r+="\\"),r.trim()}return e};var Mi={parse:Wn,decode:Wn,stringify:At,encode:At,safe:J,unsafe:xe},Vn=U(Mi);const Xn=e=>x.lstat(e).then(()=>!0,()=>!1),_i=["","conventional","gitmoji"],{hasOwnProperty:Ti}=Object.prototype,R=(e,t)=>Ti.call(e,t),E=(e,t,n)=>{if(!t)throw new w(`Invalid config property ${e}: ${n}`)},Oe={OPENAI_KEY(e){return e?(E("OPENAI_KEY",e.startsWith("sk-"),'Must start with "sk-"'),e):""},OPENAI_MODEL(e){return!e||e.length===0?"gpt-3.5-turbo":e},HUGGING_COOKIE(e){return e||""},HUGGING_MODEL(e){return!e||e.length===0?"mistralai/Mixtral-8x7B-Instruct-v0.1":(E("HUGGING_MODEL",["mistralai/Mixtral-8x7B-Instruct-v0.1","meta-llama/Llama-2-70b-chat-hf","NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO","codellama/CodeLlama-70b-Instruct-hf","mistralai/Mistral-7B-Instruct-v0.2","openchat/openchat-3.5-0106"].includes(e),"Invalid model type of hugging"),e)},CLOVAX_COOKIE(e){return e||""},GEMINI_KEY(e){return e||""},GEMINI_MODEL(e){return!e||e.length===0?"gemini-pro":(E("GEMINI_MODEL",["gemini-pro"].includes(e),"Invalid model type of Gemini"),e)},ANTHROPIC_MODEL(e){return!e||e.length===0?"claude-2.1":(E("ANTHROPIC_MODEL",["claude-2.1","claude-instant-1.2"].includes(e),"Invalid model type of Anthropic"),e)},ANTHROPIC_KEY(e){return e||""},confirm(e){return e?typeof e=="boolean"?e:(E("confirm",/^(?:true|false)$/.test(e),"Must be a boolean"),e==="true"):!1},locale(e){return e?(E("locale",e,"Cannot be empty"),E("locale",/^[a-z-]+$/i.test(e),"Must be a valid locale (letters and dashes/underscores). You can consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes"),e):"en"},generate(e){if(!e)return 1;E("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("generate",t>0,"Must be greater than 0"),E("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(E("type",_i.includes(e),"Invalid commit type"),e):"conventional"},proxy(e){if(!(!e||e.length===0))return E("proxy",/^https?:\/\//.test(e),"Must be a valid URL"),e},timeout(e){if(!e)return 1e4;E("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;E("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return E("temperature",t>0,"Must be greater than 0"),E("temperature",t<=2,"Must be less than or equal to 2"),t},"max-length"(e){if(!e)return 50;E("max-length",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("max-length",t>=20,"Must be greater than 20 characters"),t},"max-tokens"(e){return e?(E("max-tokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):200}},vt=j.join(Nt.homedir(),".aicommit2"),Jn=async()=>{if(!await Xn(vt))return Object.create(null);const t=await x.readFile(vt,"utf8");return Vn.parse(t)},Bt=async(e,t)=>{const n=await Jn(),r={};for(const u of Object.keys(Oe)){const o=Oe[u],s=e?.[u]??n[u];if(t)try{r[u]=o(s)}catch{}else r[u]=o(s)}return r},Ni=async e=>{const t=await Jn();for(const[n,r]of e){if(!R(Oe,n))throw new w(`Invalid config property: ${n}`);const u=Oe[n](r);t[n]=u}await x.writeFile(vt,Vn.stringify(t),"utf8")};class I{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=xr.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}class Ri extends ae{constructor(t){super(t),this.params=t,this.host="https://clova-x.naver.com",this.cookie="",this.colors={primary:"#00db9b",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[CLOVA X]"),this.errorPrefix=g.red.bold("[CLOVA X]"),this.cookie=this.params.config.CLOVAX_COOKIE}generateCommitMessage$(){return te(this.generateMessage()).pipe(Q(t=>G(t)),H(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),ee(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r}=this.params.config,u=this.params.config["max-length"],o=this.params.stagedDiff.diff,s=this.buildPrompt(t,o,n,u,r);await this.getAllConversationIds();const a=await this.sendMessage(s),{conversationId:i,allText:f}=this.parseSendMessageResult(a);return await this.deleteConversation(i),pe(this.sanitizeMessage(f))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new w(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async getAllConversationIds(){const n=(await new I({method:"GET",baseURL:`${this.host}/api/v1/conversations`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).setParams({page:0,size:50,sort:"turnUpdatedTime,DESC"}).execute()).data;if(!n||!n.content)throw new Error("No content on conversations ClovaX");return n.content.length===0?[]:n.content.map(u=>u.conversationId||"").filter(u=>!!u)}async sendMessage(t){const n={text:t,action:"new"},r=new Br;return r.set("form",new $r([JSON.stringify(n)],{type:"application/json"})),(await new I({method:"POST",baseURL:`${this.host}/api/v1/generate`,timeout:this.params.config.timeout}).setHeaders({"Content-Type":"multipart/form-data","Content-Length":this.getContentLength(r),Cookie:this.cookie}).setBody(r).execute()).data}parseSendMessageResult(t){const n=/data:{(.*)}/g,r=t.match(n);if(!r)throw new Error("Failed to extract object from generated text");const u=r.map(i=>i.trim().replace(/data:/g,""));if(!u||u.length===0)throw new Error("Cannot extract message");let o="",s="",a="";if(u.map(i=>{try{return JSON.parse(i)}catch{return null}}).filter(i=>!!i).forEach(i=>{if(R(i,"conversationId")){o=i.conversationId;return}if(R(i,"text")){s+=i.text;return}if(R(i,"error")){a=`${i.error}: ${i.type||i.message||""}`;return}}),a)throw new Error(a);if(!o)throw new Error("No conversationId!");if(!s)throw new Error("No allText!");return{conversationId:o,allText:s}}sanitizeMessage(t){return t.split(`
|
|
55
|
+
`,At=(e,t)=>{const n=[];let r="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const u=t.whitespace?" = ":"=";for(const o of Object.keys(e)){const s=e[o];if(s&&Array.isArray(s))for(const a of s)r+=J(o+"[]")+u+J(a)+$e;else s&&typeof s=="object"?n.push(o):r+=J(o)+u+J(s)+$e}t.section&&r.length&&(r="["+J(t.section)+"]"+$e+r);for(const o of n){const s=zn(o).join("\\."),a=(t.section?t.section+".":"")+s,{whitespace:i}=t,f=At(e[o],{section:a,whitespace:i});r.length&&f.length&&(r+=$e),r+=f}return r},zn=e=>e.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(t=>t.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),Wn=e=>{const t=Object.create(null);let n=t,r=null;const u=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,o=e.split(/[\r\n]+/g);for(const a of o){if(!a||a.match(/^\s*[;#]/))continue;const i=a.match(u);if(!i)continue;if(i[1]!==void 0){if(r=xe(i[1]),r==="__proto__"){n=Object.create(null);continue}n=t[r]=t[r]||Object.create(null);continue}const f=xe(i[2]),l=f.length>2&&f.slice(-2)==="[]",D=l?f.slice(0,-2):f;if(D==="__proto__")continue;const c=i[3]?xe(i[4]):!0,d=c==="true"||c==="false"||c==="null"?JSON.parse(c):c;l&&(bt.call(n,D)?Array.isArray(n[D])||(n[D]=[n[D]]):n[D]=[]),Array.isArray(n[D])?n[D].push(d):n[D]=d}const s=[];for(const a of Object.keys(t)){if(!bt.call(t,a)||typeof t[a]!="object"||Array.isArray(t[a]))continue;const i=zn(a);n=t;const f=i.pop(),l=f.replace(/\\\./g,".");for(const D of i)D!=="__proto__"&&((!bt.call(n,D)||typeof n[D]!="object")&&(n[D]=Object.create(null)),n=n[D]);n===t&&l===f||(n[l]=t[a],s.push(a))}for(const a of s)delete t[a];return t},Yn=e=>e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"),J=e=>typeof e!="string"||e.match(/[=\r\n]/)||e.match(/^\[/)||e.length>1&&Yn(e)||e!==e.trim()?JSON.stringify(e):e.split(";").join("\\;").split("#").join("\\#"),xe=(e,t)=>{if(e=(e||"").trim(),Yn(e)){e.charAt(0)==="'"&&(e=e.slice(1,-1));try{e=JSON.parse(e)}catch{}}else{let n=!1,r="";for(let u=0,o=e.length;u<o;u++){const s=e.charAt(u);if(n)"\\;#".indexOf(s)!==-1?r+=s:r+="\\"+s,n=!1;else{if(";#".indexOf(s)!==-1)break;s==="\\"?n=!0:r+=s}}return n&&(r+="\\"),r.trim()}return e};var Mi={parse:Wn,decode:Wn,stringify:At,encode:At,safe:J,unsafe:xe},Vn=U(Mi);const Xn=e=>x.lstat(e).then(()=>!0,()=>!1),_i=["","conventional","gitmoji"],{hasOwnProperty:Ti}=Object.prototype,R=(e,t)=>Ti.call(e,t),E=(e,t,n)=>{if(!t)throw new w(`Invalid config property ${e}: ${n}`)},Oe={OPENAI_KEY(e){return e?(E("OPENAI_KEY",e.startsWith("sk-"),'Must start with "sk-"'),e):""},OPENAI_MODEL(e){return!e||e.length===0?"gpt-3.5-turbo":e},HUGGING_COOKIE(e){return e||""},HUGGING_MODEL(e){return!e||e.length===0?"mistralai/Mixtral-8x7B-Instruct-v0.1":(E("HUGGING_MODEL",["mistralai/Mixtral-8x7B-Instruct-v0.1","meta-llama/Llama-2-70b-chat-hf","NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO","codellama/CodeLlama-70b-Instruct-hf","mistralai/Mistral-7B-Instruct-v0.2","openchat/openchat-3.5-0106"].includes(e),"Invalid model type of hugging"),e)},CLOVAX_COOKIE(e){return e||""},GEMINI_KEY(e){return e||""},GEMINI_MODEL(e){return!e||e.length===0?"gemini-pro":(E("GEMINI_MODEL",["gemini-pro"].includes(e),"Invalid model type of Gemini"),e)},ANTHROPIC_MODEL(e){return!e||e.length===0?"claude-2.1":(E("ANTHROPIC_MODEL",["claude-2.1","claude-2.0","claude-instant-1.2"].includes(e),"Invalid model type of Anthropic"),e)},ANTHROPIC_KEY(e){return e||""},confirm(e){return e?typeof e=="boolean"?e:(E("confirm",/^(?:true|false)$/.test(e),"Must be a boolean"),e==="true"):!1},locale(e){return e?(E("locale",e,"Cannot be empty"),E("locale",/^[a-z-]+$/i.test(e),"Must be a valid locale (letters and dashes/underscores). You can consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes"),e):"en"},generate(e){if(!e)return 1;E("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("generate",t>0,"Must be greater than 0"),E("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(E("type",_i.includes(e),"Invalid commit type"),e):"conventional"},proxy(e){if(!(!e||e.length===0))return E("proxy",/^https?:\/\//.test(e),"Must be a valid URL"),e},timeout(e){if(!e)return 1e4;E("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;E("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return E("temperature",t>0,"Must be greater than 0"),E("temperature",t<=2,"Must be less than or equal to 2"),t},"max-length"(e){if(!e)return 50;E("max-length",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return E("max-length",t>=20,"Must be greater than 20 characters"),t},"max-tokens"(e){return e?(E("max-tokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):200}},vt=j.join(Nt.homedir(),".aicommit2"),Jn=async()=>{if(!await Xn(vt))return Object.create(null);const t=await x.readFile(vt,"utf8");return Vn.parse(t)},Bt=async(e,t)=>{const n=await Jn(),r={};for(const u of Object.keys(Oe)){const o=Oe[u],s=e?.[u]??n[u];if(t)try{r[u]=o(s)}catch{}else r[u]=o(s)}return r},Ni=async e=>{const t=await Jn();for(const[n,r]of e){if(!R(Oe,n))throw new w(`Invalid config property: ${n}`);const u=Oe[n](r);t[n]=u}await x.writeFile(vt,Vn.stringify(t),"utf8")};class I{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=xr.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}class Ri extends ae{constructor(t){super(t),this.params=t,this.host="https://clova-x.naver.com",this.cookie="",this.colors={primary:"#00db9b",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[CLOVA X]"),this.errorPrefix=g.red.bold("[CLOVA X]"),this.cookie=this.params.config.CLOVAX_COOKIE}generateCommitMessage$(){return te(this.generateMessage()).pipe(Q(t=>G(t)),H(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),ee(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r}=this.params.config,u=this.params.config["max-length"],o=this.params.stagedDiff.diff,s=this.buildPrompt(t,o,n,u,r);await this.getAllConversationIds();const a=await this.sendMessage(s),{conversationId:i,allText:f}=this.parseSendMessageResult(a);return await this.deleteConversation(i),pe(this.sanitizeMessage(f))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new w(`Error connecting to ${n.hostname} (${n.syscall})`):n}}async getAllConversationIds(){const n=(await new I({method:"GET",baseURL:`${this.host}/api/v1/conversations`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).setParams({page:0,size:50,sort:"turnUpdatedTime,DESC"}).execute()).data;if(!n||!n.content)throw new Error("No content on conversations ClovaX");return n.content.length===0?[]:n.content.map(u=>u.conversationId||"").filter(u=>!!u)}async sendMessage(t){const n={text:t,action:"new"},r=new Br;return r.set("form",new $r([JSON.stringify(n)],{type:"application/json"})),(await new I({method:"POST",baseURL:`${this.host}/api/v1/generate`,timeout:this.params.config.timeout}).setHeaders({"Content-Type":"multipart/form-data","Content-Length":this.getContentLength(r),Cookie:this.cookie}).setBody(r).execute()).data}parseSendMessageResult(t){const n=/data:{(.*)}/g,r=t.match(n);if(!r)throw new Error("Failed to extract object from generated text");const u=r.map(i=>i.trim().replace(/data:/g,""));if(!u||u.length===0)throw new Error("Cannot extract message");let o="",s="",a="";if(u.map(i=>{try{return JSON.parse(i)}catch{return null}}).filter(i=>!!i).forEach(i=>{if(R(i,"conversationId")){o=i.conversationId;return}if(R(i,"text")){s+=i.text;return}if(R(i,"error")){a=`${i.error}: ${i.type||i.message||""}`;return}}),a)throw new Error(a);if(!o)throw new Error("No conversationId!");if(!s)throw new Error("No allText!");return{conversationId:o,allText:s}}sanitizeMessage(t){return t.split(`
|
|
56
56
|
`).map(n=>n.trim().replace(/^\d+\.\s/,"")).map(n=>n.replace(/`/g,"")).map(n=>this.extractCommitMessageFromRawText(this.params.config.type,n)).filter(n=>!!n)}async deleteConversation(t){return(await new I({method:"DELETE",baseURL:`${this.host}/api/v1/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute()).data}getContentLength(t){return Array.from(t.entries(),([n,r])=>({[n]:{ContentLength:typeof r=="string"?r.length:r.size}}))}}class ki extends ae{constructor(t){super(t),this.params=t,this.handleError$=n=>{const r=n.message||n.toString(),u=/(\[.*?\]\s*[^[]*)/g,o=[...r.matchAll(u)],s=[];o.forEach(i=>s.push(i[1]));const a=s[1]||"An error occurred";return Z({name:`${this.errorPrefix} ${a}`,value:a,isError:!0})},this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=g.red.bold("[Gemini]"),this.genAI=new Or(this.params.config.GEMINI_KEY)}generateCommitMessage$(){return te(this.generateMessage()).pipe(Q(t=>G(t)),H(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),ee(this.handleError$))}async generateMessage(){try{const t=this.params.stagedDiff.diff,{locale:n,generate:r,type:u}=this.params.config,o=this.params.config["max-length"],s=this.buildPrompt(n,t,r,o,u),a=this.params.config["max-tokens"],D=(await(await this.genAI.getGenerativeModel({model:this.params.config.GEMINI_MODEL,generationConfig:{maxOutputTokens:a,temperature:this.params.config.temperature}}).generateContent(s)).response).text();return pe(this.sanitizeMessage(D))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new w(`Error connecting to ${n.hostname} (${n.syscall})`):n}}sanitizeMessage(t){return t.split(`
|
|
57
57
|
`).map(n=>n.trim().replace(/^\d+\.\s/,"")).map(n=>n.replace(/`/g,"")).map(n=>this.extractCommitMessageFromRawText(this.params.config.type,n)).filter(n=>!!n)}}class Li extends ae{constructor(t){super(t),this.params=t,this.host="https://huggingface.co",this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=g.red.bold("[HuggingFace]"),this.cookie=this.params.config.HUGGING_COOKIE}generateCommitMessage$(){return te(this.generateMessage()).pipe(Q(t=>G(t)),H(t=>({name:`${this.serviceName} ${t}`,value:t,isError:!1})),ee(this.handleError$))}async generateMessage(){try{const{locale:t,generate:n,type:r}=this.params.config,u=this.params.config["max-length"],o=this.params.stagedDiff.diff,s=this.buildPrompt(t,o,n,u,r);await this.prepareNewConversation();const{conversationId:a}=await this.getNewConversationId();await this.prepareConversationEvent(a);const{lastMessageId:i}=await this.getConversationInfo(a),f=await this.sendMessage(a,s,i);return await this.deleteConversation(a),pe(this.sanitizeMessage(f))}catch(t){const n=t;throw n.code==="ENOTFOUND"?new w(`Error connecting to ${n.hostname} (${n.syscall})`):n}}sanitizeMessage(t){const n=/{[^{}]*}/g,r=t.match(n);if(!r)throw new Error("Failed to extract object from generated text");let u=null;if(r.forEach((o,s)=>{try{const a=JSON.parse(o);R(a,"type")&&a.type==="finalAnswer"&&(u=a)}catch{}}),!u||!R(u,"text"))throw new Error("Cannot parse finalAnswer");return u.text.split(`
|
|
58
58
|
`).map(o=>o.trim().replace(/^\d+\.\s/,"")).map(o=>o.replace(/`/g,"")).map(o=>this.extractCommitMessageFromRawText(this.params.config.type,o)).filter(o=>!!o)}async prepareNewConversation(){return(await new I({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:"https://huggingface.co/chat/"}).execute()).data}async prepareConversationEvent(t){return(await new I({method:"POST",baseURL:`${this.host}/api/event`}).setHeaders({"content-type":"application/json",Cookie:this.cookie}).setBody({d:"huggingface.co",n:"pageview",r:"https://huggingface.co/chat/",u:`https://huggingface.co/chat/conversation/${t}`}).execute()).data}async getNewConversationId(){const t=await new I({method:"POST",baseURL:`${this.host}/chat/conversation`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Host:"huggingface.co",Origin:"https://huggingface.co"}).setBody({model:this.params.config.HUGGING_MODEL,preprompt:""}).execute();if(!t.data||!t.data.conversationId)throw new Error("No conversationId on Hugging service");return t.data}async getConversationInfo(t){const r=(await new I({method:"GET",baseURL:`${this.host}/chat/conversation/${t}/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-invalidated":"11"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data;if(!r||!r.nodes||r.nodes.length===0)throw new Error("No Nodes on conversation info");if(!r.nodes[1]||!r.nodes[1].data||r.nodes[1].data.length===0||!r.nodes[1].data[3])throw new Error("No data on node");const s=r.nodes[1]?.data[3];return{conversationInfo:r,lastMessageId:s}}async deleteConversation(t){return await new I({method:"DELETE",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({Cookie:this.cookie}).execute(),(await new I({method:"GET",baseURL:`${this.host}/chat/__data.json`,timeout:this.params.config.timeout}).setParams({"x-sveltekit-trailing-slash":"1","x-sveltekit-invalidated":"10"}).setHeaders({"Content-Type":"application/json",Cookie:this.cookie,Accept:"*/*",Connection:"keep-alive",Referer:"https://huggingface.co/chat/"}).execute()).data}async sendMessage(t,n,r){return(await new I({method:"POST",baseURL:`${this.host}/chat/conversation/${t}`,timeout:this.params.config.timeout}).setHeaders({"content-type":"application/json",Cookie:this.cookie,authority:"huggingface.co",accept:"*/*",origin:"https://huggingface.co"}).setBody({files:[],id:r,inputs:n,is_continue:!1,is_retry:!1,use_cache:!1}).execute()).data}}class ji extends ae{constructor(t){super(t),this.params=t,this.handleError$=n=>{let r="An error occurred";if(n.message){r=n.message.split(`
|