aicommit2 2.4.17 → 2.4.19

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.
Files changed (3) hide show
  1. package/README.md +80 -9
  2. package/dist/cli.mjs +185 -122
  3. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import{command as oe,cli as Xo}from"cleye";import{createRequire as Qo}from"module";import Zo from"crypto";import U from"fs";import xe from"os";import S from"path";import{Buffer as es}from"node:buffer";import ce from"node:path";import dr,{ChildProcess as ts,exec as rs}from"node:child_process";import se from"node:process";import os,{execSync as _e,exec as ss}from"child_process";import{fileURLToPath as mr}from"node:url";import ns,{constants as fr}from"node:os";import pr from"assert";import hr from"events";import{createWriteStream as is,createReadStream as as}from"node:fs";import cs from"buffer";import mt from"stream";import gr,{promisify as ls}from"util";import{debuglog as us,promisify as ds}from"node:util";import Be from"inquirer";import C from"chalk";import{of as ft,concatMap as F,from as M,map as I,catchError as R,mergeMap as yr,BehaviorSubject as wr,ReplaySubject as ms,Subscription as pt,lastValueFrom as vr,filter as br,toArray as Cr,Subject as ht}from"rxjs";import fs from"@anthropic-ai/sdk";import{fromPromise as L}from"rxjs/internal/observable/innerFrom";import{xxh64 as Pr}from"@pacote/xxhash";import B from"winston";import O from"fs/promises";import"winston-daily-rotate-file";import ps from"axios";import{CohereClientV2 as hs}from"cohere-ai";import Er from"openai";import{GoogleGenerativeAI as gs,HarmCategory as He,HarmBlockThreshold as Ue}from"@google/generative-ai";import ys from"http";import ws from"https";import vs from"net";import bs from"tls";import Cs,{fileURLToPath as Ps,pathToFileURL as Es}from"url";import $r from"tty";import $s from"groq-sdk";import{Ollama as xs}from"ollama";import{fetch as As,Agent as ks}from"undici";import ze from"readline";import xr from"figlet";import Ss from"gradient-string";import Ar from"ora";import Ms from"inquirer-reactive-list-prompt";import{readdir as kr,stat as Is,rm as Rs}from"node:fs/promises";import Os from"chokidar";import{takeUntil as Sr,finalize as Mr}from"rxjs/operators";var Ds="aicommit2",Ir="2.4.17",Fs="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",Ls=["cli","ai","git","jujutsu","jj","vcs","version-control","commit","git-commit","jujutsu-commit","command-line","commandline","aipick","aicommit","aicommits","aicommit2","openai","huggingface","anthropic","claude","claude3","gemini","gemini-pro","generative-ai","mistral","ollama","llama3","llama3.2","llama3.3","gemma","llm","chatgpt","cohere","groq","codestral","perplexity","deepseek","deepseek-r1","pre-commit"],Ts="MIT",js="tak-bro/aicommit2",Ns="Hyungtak Jin(@tak-bro)",Gs="module",_s=["dist"],Bs={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},Hs={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},Us={"@anthropic-ai/sdk":"^0.39.0","@dqbd/tiktoken":"^1.0.21","@google/generative-ai":"^0.24.1","@inquirer/prompts":"^3.3.2","@pacote/xxhash":"^0.3.2","@types/winston":"^2.4.4",axios:"^1.9.0",chalk:"^5.4.1",chokidar:"^4.0.3",cleye:"^1.3.4","cohere-ai":"^7.19.0","copy-paste":"^1.5.3",figlet:"^1.8.1","formdata-node":"^6.0.3","gradient-string":"^3.0.0","groq-sdk":"^0.7.0",inquirer:"9.2.8","inquirer-reactive-list-prompt":"^1.0.16",ollama:"^0.5.15",openai:"^6.3.0",ora:"^8.2.0",readline:"^1.3.0",rxjs:"^7.8.2",undici:"^7.10.0",uuid:"^9.0.1",winston:"^3.17.0","winston-daily-rotate-file":"^5.0.0"},zs={"@pvtnbr/eslint-config":"^0.33.0","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^12.0.0","@semantic-release/git":"^10.0.1","@semantic-release/github":"^10.3.5","@semantic-release/npm":"^12.0.1","@semantic-release/release-notes-generator":"^13.0.0","@types/figlet":"^1.7.0","@types/ini":"^1.3.34","@types/inquirer":"^9.0.8","@types/node":"^18.19.103","@types/uuid":"^9.0.8","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","clean-pkg-json":"^1.3.0","conventional-changelog-conventionalcommits":"^7.0.2","conventional-commits-parser":"^5.0.0",eslint:"^8.57.1","eslint-config-prettier":"^8.10.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","eslint-plugin-jsonc":"^2.20.1","eslint-plugin-no-use-extend-native":"^0.5.0","eslint-plugin-promise":"^6.6.0","eslint-plugin-unicorn":"^49.0.0","eslint-plugin-unused-imports":"^3.2.0",execa:"^7.2.0","fs-fixture":"^1.2.0","https-proxy-agent":"^5.0.1",ini:"^3.0.1","lint-staged":"^13.3.0",manten:"^0.7.0",pkgroll:"^1.11.1",prettier:"^3.5.3","semantic-release":"^23.1.1","simple-git-hooks":"^2.13.0",tsx:"^3.14.0",typescript:"^4.9.5","undici-types":"^7.10.0"},Ws={extends:["@pvtnbr","prettier"],rules:{"unicorn/no-process-exit":"off"},overrides:[{files:"./src/commands/prepare-commit-msg-hook.ts",rules:{"unicorn/prevent-abbreviations":"off"}}]},Ks={branches:["main"],plugins:[["@semantic-release/commit-analyzer",{preset:"conventionalcommits",releaseRules:[{type:"refactor",release:"patch"},{type:"chore",release:"patch"},{type:"feat",release:"patch"},{scope:"major",release:"major"},{scope:"minor",release:"minor"},{scope:"patch",release:"patch"}]}],"@semantic-release/release-notes-generator",["@semantic-release/changelog",{changelogFile:"CHANGELOG.md"}],"@semantic-release/github",["@semantic-release/git",{assets:["CHANGELOG.md"],message:"chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}],"@semantic-release/npm"]},Js={name:Ds,version:Ir,description:Fs,keywords:Ls,license:Ts,repository:js,author:Ns,type:Gs,files:_s,bin:Bs,scripts:Hs,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:Us,devDependencies:zs,eslintConfig:Ws,release:Ks},Vs=Qo(import.meta.url),_=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function me(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var fe={exports:{}},gt,Rr;function Ys(){if(Rr)return gt;Rr=1,gt=o,o.sync=s;var r=U;function e(n,i){var c=i.pathExt!==void 0?i.pathExt:process.env.PATHEXT;if(!c||(c=c.split(";"),c.indexOf("")!==-1))return!0;for(var a=0;a<c.length;a++){var m=c[a].toLowerCase();if(m&&n.substr(-m.length).toLowerCase()===m)return!0}return!1}function t(n,i,c){return!n.isSymbolicLink()&&!n.isFile()?!1:e(i,c)}function o(n,i,c){r.stat(n,function(a,m){c(a,a?!1:t(m,n,i))})}function s(n,i){return t(r.statSync(n),n,i)}return gt}var yt,Or;function qs(){if(Or)return yt;Or=1,yt=e,e.sync=t;var r=U;function e(n,i,c){r.stat(n,function(a,m){c(a,a?!1:o(m,i))})}function t(n,i){return o(r.statSync(n),i)}function o(n,i){return n.isFile()&&s(n,i)}function s(n,i){var c=n.mode,a=n.uid,m=n.gid,u=i.uid!==void 0?i.uid:process.getuid&&process.getuid(),l=i.gid!==void 0?i.gid:process.getgid&&process.getgid(),d=parseInt("100",8),p=parseInt("010",8),g=parseInt("001",8),h=d|p,y=c&g||c&p&&m===l||c&d&&a===u||c&h&&u===0;return y}return yt}var We;process.platform==="win32"||_.TESTING_WINDOWS?We=Ys():We=qs();var Xs=wt;wt.sync=Qs;function wt(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){wt(r,e||{},function(n,i){n?s(n):o(i)})})}We(r,e||{},function(o,s){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,s=!1),t(o,s)})}function Qs(r,e){try{return We.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}const pe=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",Dr=S,Zs=pe?";":":",Fr=Xs,Lr=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),Tr=(r,e)=>{const t=e.colon||Zs,o=r.match(/\//)||pe&&r.match(/\\/)?[""]:[...pe?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],s=pe?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=pe?s.split(t):[""];return pe&&r.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:s}},jr=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});const{pathEnv:o,pathExt:s,pathExtExe:n}=Tr(r,e),i=[],c=m=>new Promise((u,l)=>{if(m===o.length)return e.all&&i.length?u(i):l(Lr(r));const d=o[m],p=/^".*"$/.test(d)?d.slice(1,-1):d,g=Dr.join(p,r),h=!p&&/^\.[\\\/]/.test(r)?r.slice(0,2)+g:g;u(a(h,m,0))}),a=(m,u,l)=>new Promise((d,p)=>{if(l===s.length)return d(c(u+1));const g=s[l];Fr(m+g,{pathExt:n},(h,y)=>{if(!h&&y)if(e.all)i.push(m+g);else return d(m+g);return d(a(m,u,l+1))})});return t?c(0).then(m=>t(null,m),t):c(0)},en=(r,e)=>{e=e||{};const{pathEnv:t,pathExt:o,pathExtExe:s}=Tr(r,e),n=[];for(let i=0;i<t.length;i++){const c=t[i],a=/^".*"$/.test(c)?c.slice(1,-1):c,m=Dr.join(a,r),u=!a&&/^\.[\\\/]/.test(r)?r.slice(0,2)+m:m;for(let l=0;l<o.length;l++){const d=u+o[l];try{if(Fr.sync(d,{pathExt:s}))if(e.all)n.push(d);else return d}catch{}}}if(e.all&&n.length)return n;if(e.nothrow)return null;throw Lr(r)};var tn=jr;jr.sync=en;var vt={exports:{}};const Nr=(r={})=>{const e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};vt.exports=Nr,vt.exports.default=Nr;var rn=vt.exports;const Gr=S,on=tn,sn=rn;function _r(r,e){const t=r.options.env||process.env,o=process.cwd(),s=r.options.cwd!=null,n=s&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(r.options.cwd)}catch{}let i;try{i=on.sync(r.command,{path:t[sn({env:t})],pathExt:e?Gr.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return i&&(i=Gr.resolve(s?r.options.cwd:"",i)),i}function nn(r){return _r(r)||_r(r,!0)}var an=nn,bt={};const Ct=/([()\][%!^"`<>&|;, *?])/g;function cn(r){return r=r.replace(Ct,"^$1"),r}function ln(r,e){return r=`${r}`,r=r.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),r=r.replace(/(?=(\\+?)?)\1$/,"$1$1"),r=`"${r}"`,r=r.replace(Ct,"^$1"),e&&(r=r.replace(Ct,"^$1")),r}bt.command=cn,bt.argument=ln;var un=/^#!(.*)/;const dn=un;var mn=(r="")=>{const e=r.match(dn);if(!e)return null;const[t,o]=e[0].replace(/#! ?/,"").split(" "),s=t.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const Pt=U,fn=mn;function pn(r){const t=Buffer.alloc(150);let o;try{o=Pt.openSync(r,"r"),Pt.readSync(o,t,0,150,0),Pt.closeSync(o)}catch{}return fn(t.toString())}var hn=pn;const gn=S,Br=an,Hr=bt,yn=hn,wn=process.platform==="win32",vn=/\.(?:com|exe)$/i,bn=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Cn(r){r.file=Br(r);const e=r.file&&yn(r.file);return e?(r.args.unshift(r.file),r.command=e,Br(r)):r.file}function Pn(r){if(!wn)return r;const e=Cn(r),t=!vn.test(e);if(r.options.forceShell||t){const o=bn.test(e);r.command=gn.normalize(r.command),r.command=Hr.command(r.command),r.args=r.args.map(n=>Hr.argument(n,o));const s=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${s}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function En(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);const o={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?o:Pn(o)}var $n=En;const Et=process.platform==="win32";function $t(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function xn(r,e){if(!Et)return;const t=r.emit;r.emit=function(o,s){if(o==="exit"){const n=Ur(s,e);if(n)return t.call(r,"error",n)}return t.apply(r,arguments)}}function Ur(r,e){return Et&&r===1&&!e.file?$t(e.original,"spawn"):null}function An(r,e){return Et&&r===1&&!e.file?$t(e.original,"spawnSync"):null}var kn={hookChildProcess:xn,verifyENOENT:Ur,verifyENOENTSync:An,notFoundError:$t};const zr=os,xt=$n,At=kn;function Wr(r,e,t){const o=xt(r,e,t),s=zr.spawn(o.command,o.args,o.options);return At.hookChildProcess(s,o),s}function Sn(r,e,t){const o=xt(r,e,t),s=zr.spawnSync(o.command,o.args,o.options);return s.error=s.error||At.verifyENOENTSync(s.status,o),s}fe.exports=Wr,fe.exports.spawn=Wr,fe.exports.sync=Sn,fe.exports._parse=xt,fe.exports._enoent=At;var Mn=fe.exports,In=me(Mn);function Rn(r){const e=typeof r=="string"?`
2
+ import{command as ne,cli as hs}from"cleye";import{createRequire as gs}from"module";import ys from"crypto";import W from"fs";import ke from"os";import S from"path";import{Buffer as br}from"node:buffer";import ce from"node:path";import vt,{ChildProcess as Er,exec as ws}from"node:child_process";import te from"node:process";import vs,{execSync as Ue,exec as Cs}from"child_process";import{fileURLToPath as Pr}from"node:url";import bs,{constants as $r}from"node:os";import Ar from"assert";import xr from"events";import{createWriteStream as Es,createReadStream as Ps,readFileSync as $s}from"node:fs";import As from"buffer";import Ct from"stream";import kr,{promisify as xs}from"util";import{debuglog as ks,promisify as Ss}from"node:util";import ze from"inquirer";import C from"chalk";import{of as bt,concatMap as j,from as R,map as D,catchError as F,mergeMap as Sr,BehaviorSubject as Mr,ReplaySubject as Ms,Subscription as Et,lastValueFrom as Ir,filter as Rr,toArray as Dr,Subject as Pt}from"rxjs";import Is from"@anthropic-ai/sdk";import{fromPromise as T}from"rxjs/internal/observable/innerFrom";import{xxh64 as Or}from"@pacote/xxhash";import H from"winston";import O from"fs/promises";import"winston-daily-rotate-file";import Rs from"axios";import{CohereClientV2 as Ds}from"cohere-ai";import Fr from"openai";import{GoogleGenerativeAI as Os,HarmCategory as We,HarmBlockThreshold as Ye}from"@google/generative-ai";import Fs from"http";import Ls from"https";import js from"net";import Ts from"tls";import Ns,{fileURLToPath as _s,pathToFileURL as Gs}from"url";import Lr from"tty";import Bs from"groq-sdk";import{Ollama as Hs}from"ollama";import{fetch as Us,Agent as zs}from"undici";import Ke from"readline";import jr from"figlet";import Ws from"gradient-string";import Tr from"ora";import Ys from"inquirer-reactive-list-prompt";import{readdir as Nr,stat as Ks,rm as Js}from"node:fs/promises";import Vs from"chokidar";import{takeUntil as _r,finalize as Gr}from"rxjs/operators";var qs="aicommit2",Br="2.4.19",Xs="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",Qs=["cli","ai","git","jujutsu","jj","vcs","version-control","commit","git-commit","jujutsu-commit","command-line","commandline","aipick","aicommit","aicommits","aicommit2","openai","huggingface","anthropic","claude","claude3","gemini","gemini-pro","generative-ai","mistral","ollama","llama3","llama3.2","llama3.3","gemma","llm","chatgpt","cohere","groq","codestral","perplexity","deepseek","deepseek-r1","pre-commit"],Zs="MIT",en="tak-bro/aicommit2",tn="Hyungtak Jin(@tak-bro)",rn="module",on=["dist"],sn={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},nn={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},an={"@anthropic-ai/sdk":"^0.39.0","@dqbd/tiktoken":"^1.0.21","@google/generative-ai":"^0.24.1","@inquirer/prompts":"^3.3.2","@pacote/xxhash":"^0.3.2","@types/winston":"^2.4.4",axios:"^1.9.0",chalk:"^5.4.1",chokidar:"^4.0.3",cleye:"^1.3.4","cohere-ai":"^7.19.0","copy-paste":"^1.5.3",figlet:"^1.8.1","formdata-node":"^6.0.3","gradient-string":"^3.0.0","groq-sdk":"^0.7.0",inquirer:"9.2.8","inquirer-reactive-list-prompt":"^1.0.16",ollama:"^0.5.15",openai:"^6.3.0",ora:"^8.2.0",readline:"^1.3.0",rxjs:"^7.8.2",undici:"^7.10.0",uuid:"^9.0.1",winston:"^3.17.0","winston-daily-rotate-file":"^5.0.0"},cn={"@pvtnbr/eslint-config":"^0.33.0","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^12.0.0","@semantic-release/git":"^10.0.1","@semantic-release/github":"^10.3.5","@semantic-release/npm":"^12.0.1","@semantic-release/release-notes-generator":"^13.0.0","@types/figlet":"^1.7.0","@types/ini":"^1.3.34","@types/inquirer":"^9.0.8","@types/node":"^18.19.103","@types/uuid":"^9.0.8","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","clean-pkg-json":"^1.3.0","conventional-changelog-conventionalcommits":"^7.0.2","conventional-commits-parser":"^5.0.0",eslint:"^8.57.1","eslint-config-prettier":"^8.10.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","eslint-plugin-jsonc":"^2.20.1","eslint-plugin-no-use-extend-native":"^0.5.0","eslint-plugin-promise":"^6.6.0","eslint-plugin-unicorn":"^49.0.0","eslint-plugin-unused-imports":"^3.2.0",execa:"^7.2.0","fs-fixture":"^1.2.0","https-proxy-agent":"^5.0.1",ini:"^3.0.1","lint-staged":"^13.3.0",manten:"^0.7.0",pkgroll:"^1.11.1",prettier:"^3.5.3","semantic-release":"^23.1.1","simple-git-hooks":"^2.13.0",tsx:"^3.14.0",typescript:"^4.9.5","undici-types":"^7.10.0"},ln={extends:["@pvtnbr","prettier"],rules:{"unicorn/no-process-exit":"off"},overrides:[{files:"./src/commands/prepare-commit-msg-hook.ts",rules:{"unicorn/prevent-abbreviations":"off"}}]},un={branches:["main"],plugins:[["@semantic-release/commit-analyzer",{preset:"conventionalcommits",releaseRules:[{type:"refactor",release:"patch"},{type:"chore",release:"patch"},{type:"feat",release:"patch"},{scope:"major",release:"major"},{scope:"minor",release:"minor"},{scope:"patch",release:"patch"}]}],"@semantic-release/release-notes-generator",["@semantic-release/changelog",{changelogFile:"CHANGELOG.md"}],"@semantic-release/github",["@semantic-release/git",{assets:["CHANGELOG.md"],message:"chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"}],"@semantic-release/npm"]},dn={name:qs,version:Br,description:Xs,keywords:Qs,license:Zs,repository:en,author:tn,type:rn,files:on,bin:sn,scripts:nn,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:an,devDependencies:cn,eslintConfig:ln,release:un},mn=gs(import.meta.url),B=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function me(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var fe={exports:{}},$t,Hr;function fn(){if(Hr)return $t;Hr=1,$t=o,o.sync=s;var r=W;function e(n,i){var l=i.pathExt!==void 0?i.pathExt:process.env.PATHEXT;if(!l||(l=l.split(";"),l.indexOf("")!==-1))return!0;for(var a=0;a<l.length;a++){var d=l[a].toLowerCase();if(d&&n.substr(-d.length).toLowerCase()===d)return!0}return!1}function t(n,i,l){return!n.isSymbolicLink()&&!n.isFile()?!1:e(i,l)}function o(n,i,l){r.stat(n,function(a,d){l(a,a?!1:t(d,n,i))})}function s(n,i){return t(r.statSync(n),n,i)}return $t}var At,Ur;function pn(){if(Ur)return At;Ur=1,At=e,e.sync=t;var r=W;function e(n,i,l){r.stat(n,function(a,d){l(a,a?!1:o(d,i))})}function t(n,i){return o(r.statSync(n),i)}function o(n,i){return n.isFile()&&s(n,i)}function s(n,i){var l=n.mode,a=n.uid,d=n.gid,c=i.uid!==void 0?i.uid:process.getuid&&process.getuid(),u=i.gid!==void 0?i.gid:process.getgid&&process.getgid(),m=parseInt("100",8),p=parseInt("010",8),h=parseInt("001",8),g=m|p,y=l&h||l&p&&d===u||l&m&&a===c||l&g&&c===0;return y}return At}var Je;process.platform==="win32"||B.TESTING_WINDOWS?Je=fn():Je=pn();var hn=xt;xt.sync=gn;function xt(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){xt(r,e||{},function(n,i){n?s(n):o(i)})})}Je(r,e||{},function(o,s){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,s=!1),t(o,s)})}function gn(r,e){try{return Je.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}const pe=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",zr=S,yn=pe?";":":",Wr=hn,Yr=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),Kr=(r,e)=>{const t=e.colon||yn,o=r.match(/\//)||pe&&r.match(/\\/)?[""]:[...pe?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],s=pe?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=pe?s.split(t):[""];return pe&&r.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:s}},Jr=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});const{pathEnv:o,pathExt:s,pathExtExe:n}=Kr(r,e),i=[],l=d=>new Promise((c,u)=>{if(d===o.length)return e.all&&i.length?c(i):u(Yr(r));const m=o[d],p=/^".*"$/.test(m)?m.slice(1,-1):m,h=zr.join(p,r),g=!p&&/^\.[\\\/]/.test(r)?r.slice(0,2)+h:h;c(a(g,d,0))}),a=(d,c,u)=>new Promise((m,p)=>{if(u===s.length)return m(l(c+1));const h=s[u];Wr(d+h,{pathExt:n},(g,y)=>{if(!g&&y)if(e.all)i.push(d+h);else return m(d+h);return m(a(d,c,u+1))})});return t?l(0).then(d=>t(null,d),t):l(0)},wn=(r,e)=>{e=e||{};const{pathEnv:t,pathExt:o,pathExtExe:s}=Kr(r,e),n=[];for(let i=0;i<t.length;i++){const l=t[i],a=/^".*"$/.test(l)?l.slice(1,-1):l,d=zr.join(a,r),c=!a&&/^\.[\\\/]/.test(r)?r.slice(0,2)+d:d;for(let u=0;u<o.length;u++){const m=c+o[u];try{if(Wr.sync(m,{pathExt:s}))if(e.all)n.push(m);else return m}catch{}}}if(e.all&&n.length)return n;if(e.nothrow)return null;throw Yr(r)};var vn=Jr;Jr.sync=wn;var kt={exports:{}};const Vr=(r={})=>{const e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};kt.exports=Vr,kt.exports.default=Vr;var Cn=kt.exports;const qr=S,bn=vn,En=Cn;function Xr(r,e){const t=r.options.env||process.env,o=process.cwd(),s=r.options.cwd!=null,n=s&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(r.options.cwd)}catch{}let i;try{i=bn.sync(r.command,{path:t[En({env:t})],pathExt:e?qr.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return i&&(i=qr.resolve(s?r.options.cwd:"",i)),i}function Pn(r){return Xr(r)||Xr(r,!0)}var $n=Pn,St={};const Mt=/([()\][%!^"`<>&|;, *?])/g;function An(r){return r=r.replace(Mt,"^$1"),r}function xn(r,e){return r=`${r}`,r=r.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),r=r.replace(/(?=(\\+?)?)\1$/,"$1$1"),r=`"${r}"`,r=r.replace(Mt,"^$1"),e&&(r=r.replace(Mt,"^$1")),r}St.command=An,St.argument=xn;var kn=/^#!(.*)/;const Sn=kn;var Mn=(r="")=>{const e=r.match(Sn);if(!e)return null;const[t,o]=e[0].replace(/#! ?/,"").split(" "),s=t.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const It=W,In=Mn;function Rn(r){const t=Buffer.alloc(150);let o;try{o=It.openSync(r,"r"),It.readSync(o,t,0,150,0),It.closeSync(o)}catch{}return In(t.toString())}var Dn=Rn;const On=S,Qr=$n,Zr=St,Fn=Dn,Ln=process.platform==="win32",jn=/\.(?:com|exe)$/i,Tn=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Nn(r){r.file=Qr(r);const e=r.file&&Fn(r.file);return e?(r.args.unshift(r.file),r.command=e,Qr(r)):r.file}function _n(r){if(!Ln)return r;const e=Nn(r),t=!jn.test(e);if(r.options.forceShell||t){const o=Tn.test(e);r.command=On.normalize(r.command),r.command=Zr.command(r.command),r.args=r.args.map(n=>Zr.argument(n,o));const s=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${s}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function Gn(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);const o={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?o:_n(o)}var Bn=Gn;const Rt=process.platform==="win32";function Dt(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function Hn(r,e){if(!Rt)return;const t=r.emit;r.emit=function(o,s){if(o==="exit"){const n=eo(s,e);if(n)return t.call(r,"error",n)}return t.apply(r,arguments)}}function eo(r,e){return Rt&&r===1&&!e.file?Dt(e.original,"spawn"):null}function Un(r,e){return Rt&&r===1&&!e.file?Dt(e.original,"spawnSync"):null}var zn={hookChildProcess:Hn,verifyENOENT:eo,verifyENOENTSync:Un,notFoundError:Dt};const to=vs,Ot=Bn,Ft=zn;function ro(r,e,t){const o=Ot(r,e,t),s=to.spawn(o.command,o.args,o.options);return Ft.hookChildProcess(s,o),s}function Wn(r,e,t){const o=Ot(r,e,t),s=to.spawnSync(o.command,o.args,o.options);return s.error=s.error||Ft.verifyENOENTSync(s.status,o),s}fe.exports=ro,fe.exports.spawn=ro,fe.exports.sync=Wn,fe.exports._parse=Ot,fe.exports._enoent=Ft;var Yn=fe.exports,Kn=me(Yn);function Jn(r){const e=typeof r=="string"?`
3
3
  `:`
4
- `.charCodeAt(),t=typeof r=="string"?"\r":"\r".charCodeAt();return r[r.length-1]===e&&(r=r.slice(0,-1)),r[r.length-1]===t&&(r=r.slice(0,-1)),r}function Kr(r={}){const{env:e=process.env,platform:t=process.platform}=r;return t!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"}const On=({cwd:r=se.cwd(),path:e=se.env[Kr()],preferLocal:t=!0,execPath:o=se.execPath,addExecPath:s=!0}={})=>{const n=r instanceof URL?mr(r):r,i=ce.resolve(n),c=[];return t&&Dn(c,i),s&&Fn(c,o,i),[...c,e].join(ce.delimiter)},Dn=(r,e)=>{let t;for(;t!==e;)r.push(ce.join(e,"node_modules/.bin")),t=e,e=ce.resolve(e,"..")},Fn=(r,e,t)=>{const o=e instanceof URL?mr(e):e;r.push(ce.resolve(t,o,".."))},Ln=({env:r=se.env,...e}={})=>{r={...r};const t=Kr({env:r});return e.path=r[t],r[t]=On(e),r},Tn=(r,e,t,o)=>{if(t==="length"||t==="prototype"||t==="arguments"||t==="caller")return;const s=Object.getOwnPropertyDescriptor(r,t),n=Object.getOwnPropertyDescriptor(e,t);!jn(s,n)&&o||Object.defineProperty(r,t,n)},jn=function(r,e){return r===void 0||r.configurable||r.writable===e.writable&&r.enumerable===e.enumerable&&r.configurable===e.configurable&&(r.writable||r.value===e.value)},Nn=(r,e)=>{const t=Object.getPrototypeOf(e);t!==Object.getPrototypeOf(r)&&Object.setPrototypeOf(r,t)},Gn=(r,e)=>`/* Wrapped ${r}*/
5
- ${e}`,_n=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),Bn=Object.getOwnPropertyDescriptor(Function.prototype.toString,"name"),Hn=(r,e,t)=>{const o=t===""?"":`with ${t.trim()}() `,s=Gn.bind(null,o,e.toString());Object.defineProperty(s,"name",Bn),Object.defineProperty(r,"toString",{..._n,value:s})};function Un(r,e,{ignoreNonConfigurable:t=!1}={}){const{name:o}=r;for(const s of Reflect.ownKeys(e))Tn(r,e,s,t);return Nn(r,e),Hn(r,e,o),r}const Ke=new WeakMap,Jr=(r,e={})=>{if(typeof r!="function")throw new TypeError("Expected a function");let t,o=0;const s=r.displayName||r.name||"<anonymous>",n=function(...i){if(Ke.set(n,++o),o===1)t=r.apply(this,i),r=null;else if(e.throw===!0)throw new Error(`Function \`${s}\` can only be called once`);return t};return Un(n,r),Ke.set(n,o),n};Jr.callCount=r=>{if(!Ke.has(r))throw new Error(`The given function \`${r.name}\` is not wrapped by the \`onetime\` package`);return Ke.get(r)};const zn=()=>{const r=Yr-Vr+1;return Array.from({length:r},Wn)},Wn=(r,e)=>({name:`SIGRT${e+1}`,number:Vr+e,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),Vr=34,Yr=64,Kn=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}],qr=()=>{const r=zn();return[...Kn,...r].map(Jn)},Jn=({name:r,number:e,description:t,action:o,forced:s=!1,standard:n})=>{const{signals:{[r]:i}}=fr,c=i!==void 0;return{name:r,number:c?i:e,description:t,supported:c,action:o,forced:s,standard:n}},Vn=()=>{const r=qr();return Object.fromEntries(r.map(Yn))},Yn=({name:r,number:e,description:t,supported:o,action:s,forced:n,standard:i})=>[r,{name:r,number:e,description:t,supported:o,action:s,forced:n,standard:i}],qn=Vn(),Xn=()=>{const r=qr(),e=Yr+1,t=Array.from({length:e},(o,s)=>Qn(s,r));return Object.assign({},...t)},Qn=(r,e)=>{const t=Zn(r,e);if(t===void 0)return{};const{name:o,description:s,supported:n,action:i,forced:c,standard:a}=t;return{[r]:{name:o,number:r,description:s,supported:n,action:i,forced:c,standard:a}}},Zn=(r,e)=>{const t=e.find(({name:o})=>fr.signals[o]===r);return t!==void 0?t:e.find(o=>o.number===r)};Xn();const ei=({timedOut:r,timeout:e,errorCode:t,signal:o,signalDescription:s,exitCode:n,isCanceled:i})=>r?`timed out after ${e} milliseconds`:i?"was canceled":t!==void 0?`failed with ${t}`:o!==void 0?`was killed with ${o} (${s})`:n!==void 0?`failed with exit code ${n}`:"failed",Xr=({stdout:r,stderr:e,all:t,error:o,signal:s,exitCode:n,command:i,escapedCommand:c,timedOut:a,isCanceled:m,killed:u,parsed:{options:{timeout:l,cwd:d=se.cwd()}}})=>{n=n===null?void 0:n,s=s===null?void 0:s;const p=s===void 0?void 0:qn[s].description,g=o&&o.code,y=`Command ${ei({timedOut:a,timeout:l,errorCode:g,signal:s,signalDescription:p,exitCode:n,isCanceled:m})}: ${i}`,w=Object.prototype.toString.call(o)==="[object Error]",b=w?`${y}
6
- ${o.message}`:y,P=[b,e,r].filter(Boolean).join(`
7
- `);return w?(o.originalMessage=o.message,o.message=P):o=new Error(P),o.shortMessage=b,o.command=i,o.escapedCommand=c,o.exitCode=n,o.signal=s,o.signalDescription=p,o.stdout=r,o.stderr=e,o.cwd=d,t!==void 0&&(o.all=t),"bufferedData"in o&&delete o.bufferedData,o.failed=!0,o.timedOut=!!a,o.isCanceled=m,o.killed=u&&!a,o},Je=["stdin","stdout","stderr"],ti=r=>Je.some(e=>r[e]!==void 0),ri=r=>{if(!r)return;const{stdio:e}=r;if(e===void 0)return Je.map(o=>r[o]);if(ti(r))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${Je.map(o=>`\`${o}\``).join(", ")}`);if(typeof e=="string")return e;if(!Array.isArray(e))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof e}\``);const t=Math.max(e.length,Je.length);return Array.from({length:t},(o,s)=>e[s])};var he={exports:{}},Ve={exports:{}};Ve.exports;var Qr;function oi(){return Qr||(Qr=1,function(r){r.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],process.platform!=="win32"&&r.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),process.platform==="linux"&&r.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}(Ve)),Ve.exports}var T=_.process;const le=function(r){return r&&typeof r=="object"&&typeof r.removeListener=="function"&&typeof r.emit=="function"&&typeof r.reallyExit=="function"&&typeof r.listeners=="function"&&typeof r.kill=="function"&&typeof r.pid=="number"&&typeof r.on=="function"};if(!le(T))he.exports=function(){return function(){}};else{var si=pr,Ae=oi(),ni=/^win/i.test(T.platform),Ye=hr;typeof Ye!="function"&&(Ye=Ye.EventEmitter);var H;T.__signal_exit_emitter__?H=T.__signal_exit_emitter__:(H=T.__signal_exit_emitter__=new Ye,H.count=0,H.emitted={}),H.infinite||(H.setMaxListeners(1/0),H.infinite=!0),he.exports=function(r,e){if(!le(_.process))return function(){};si.equal(typeof r,"function","a callback must be provided for exit handler"),ke===!1&&Zr();var t="exit";e&&e.alwaysLast&&(t="afterexit");var o=function(){H.removeListener(t,r),H.listeners("exit").length===0&&H.listeners("afterexit").length===0&&kt()};return H.on(t,r),o};var kt=function(){!ke||!le(_.process)||(ke=!1,Ae.forEach(function(e){try{T.removeListener(e,St[e])}catch{}}),T.emit=Mt,T.reallyExit=eo,H.count-=1)};he.exports.unload=kt;var ge=function(e,t,o){H.emitted[e]||(H.emitted[e]=!0,H.emit(e,t,o))},St={};Ae.forEach(function(r){St[r]=function(){if(le(_.process)){var t=T.listeners(r);t.length===H.count&&(kt(),ge("exit",null,r),ge("afterexit",null,r),ni&&r==="SIGHUP"&&(r="SIGINT"),T.kill(T.pid,r))}}}),he.exports.signals=function(){return Ae};var ke=!1,Zr=function(){ke||!le(_.process)||(ke=!0,H.count+=1,Ae=Ae.filter(function(e){try{return T.on(e,St[e]),!0}catch{return!1}}),T.emit=ai,T.reallyExit=ii)};he.exports.load=Zr;var eo=T.reallyExit,ii=function(e){le(_.process)&&(T.exitCode=e||0,ge("exit",T.exitCode,null),ge("afterexit",T.exitCode,null),eo.call(T,T.exitCode))},Mt=T.emit,ai=function(e,t){if(e==="exit"&&le(_.process)){t!==void 0&&(T.exitCode=t);var o=Mt.apply(this,arguments);return ge("exit",T.exitCode,null),ge("afterexit",T.exitCode,null),o}else return Mt.apply(this,arguments)}}var ci=he.exports,li=me(ci);const ui=1e3*5,di=(r,e="SIGTERM",t={})=>{const o=r(e);return mi(r,e,t,o),o},mi=(r,e,t,o)=>{if(!fi(e,t,o))return;const s=hi(t),n=setTimeout(()=>{r("SIGKILL")},s);n.unref&&n.unref()},fi=(r,{forceKillAfterTimeout:e},t)=>pi(r)&&e!==!1&&t,pi=r=>r===ns.constants.signals.SIGTERM||typeof r=="string"&&r.toUpperCase()==="SIGTERM",hi=({forceKillAfterTimeout:r=!0})=>{if(r===!0)return ui;if(!Number.isFinite(r)||r<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${r}\` (${typeof r})`);return r},gi=(r,e)=>{r.kill()&&(e.isCanceled=!0)},yi=(r,e,t)=>{r.kill(e),t(Object.assign(new Error("Timed out"),{timedOut:!0,signal:e}))},wi=(r,{timeout:e,killSignal:t="SIGTERM"},o)=>{if(e===0||e===void 0)return o;let s;const n=new Promise((c,a)=>{s=setTimeout(()=>{yi(r,t,a)},e)}),i=o.finally(()=>{clearTimeout(s)});return Promise.race([n,i])},vi=({timeout:r})=>{if(r!==void 0&&(!Number.isFinite(r)||r<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${r}\` (${typeof r})`)},bi=async(r,{cleanup:e,detached:t},o)=>{if(!e||t)return o;const s=li(()=>{r.kill()});return o.finally(()=>{s()})};function to(r){return r!==null&&typeof r=="object"&&typeof r.pipe=="function"}function ro(r){return to(r)&&r.writable!==!1&&typeof r._write=="function"&&typeof r._writableState=="object"}const Ci=r=>r instanceof ts&&typeof r.then=="function",It=(r,e,t)=>{if(typeof t=="string")return r[e].pipe(is(t)),r;if(ro(t))return r[e].pipe(t),r;if(!Ci(t))throw new TypeError("The second argument must be a string, a stream or an Execa child process.");if(!ro(t.stdin))throw new TypeError("The target child process's stdin must be available.");return r[e].pipe(t.stdin),t},Pi=r=>{r.stdout!==null&&(r.pipeStdout=It.bind(void 0,r,"stdout")),r.stderr!==null&&(r.pipeStderr=It.bind(void 0,r,"stderr")),r.all!==void 0&&(r.pipeAll=It.bind(void 0,r,"all"))};var Se={exports:{}};const{PassThrough:Ei}=mt;var $i=r=>{r={...r};const{array:e}=r;let{encoding:t}=r;const o=t==="buffer";let s=!1;e?s=!(t||o):t=t||"utf8",o&&(t=null);const n=new Ei({objectMode:s});t&&n.setEncoding(t);let i=0;const c=[];return n.on("data",a=>{c.push(a),s?i=c.length:i+=a.length}),n.getBufferedValue=()=>e?c:o?Buffer.concat(c,i):c.join(""),n.getBufferedLength=()=>i,n};const{constants:xi}=cs,Ai=mt,{promisify:ki}=gr,Si=$i,Mi=ki(Ai.pipeline);class oo extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function Rt(r,e){if(!r)throw new Error("Expected a stream");e={maxBuffer:1/0,...e};const{maxBuffer:t}=e,o=Si(e);return await new Promise((s,n)=>{const i=c=>{c&&o.getBufferedLength()<=xi.MAX_LENGTH&&(c.bufferedData=o.getBufferedValue()),n(c)};(async()=>{try{await Mi(r,o),s()}catch(c){i(c)}})(),o.on("data",()=>{o.getBufferedLength()>t&&i(new oo)})}),o.getBufferedValue()}Se.exports=Rt,Se.exports.buffer=(r,e)=>Rt(r,{...e,encoding:"buffer"}),Se.exports.array=(r,e)=>Rt(r,{...e,array:!0}),Se.exports.MaxBufferError=oo;var Ii=Se.exports,so=me(Ii);const{PassThrough:Ri}=mt;var Oi=function(){var r=[],e=new Ri({objectMode:!0});return e.setMaxListeners(0),e.add=t,e.isEmpty=o,e.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(t),e;function t(n){return Array.isArray(n)?(n.forEach(t),this):(r.push(n),n.once("end",s.bind(null,n)),n.once("error",e.emit.bind(e,"error")),n.pipe(e,{end:!1}),this)}function o(){return r.length==0}function s(n){r=r.filter(function(i){return i!==n}),!r.length&&e.readable&&e.end()}},Di=me(Oi);const Fi=r=>{if(r!==void 0)throw new TypeError("The `input` and `inputFile` options cannot be both set.")},Li=({input:r,inputFile:e})=>typeof e!="string"?r:(Fi(r),as(e)),Ti=(r,e)=>{const t=Li(e);t!==void 0&&(to(t)?t.pipe(r.stdin):r.stdin.end(t))},ji=(r,{all:e})=>{if(!e||!r.stdout&&!r.stderr)return;const t=Di();return r.stdout&&t.add(r.stdout),r.stderr&&t.add(r.stderr),t},Ot=async(r,e)=>{if(!(!r||e===void 0)){r.destroy();try{return await e}catch(t){return t.bufferedData}}},Dt=(r,{encoding:e,buffer:t,maxBuffer:o})=>{if(!(!r||!t))return e?so(r,{encoding:e,maxBuffer:o}):so.buffer(r,{maxBuffer:o})},Ni=async({stdout:r,stderr:e,all:t},{encoding:o,buffer:s,maxBuffer:n},i)=>{const c=Dt(r,{encoding:o,buffer:s,maxBuffer:n}),a=Dt(e,{encoding:o,buffer:s,maxBuffer:n}),m=Dt(t,{encoding:o,buffer:s,maxBuffer:n*2});try{return await Promise.all([i,c,a,m])}catch(u){return Promise.all([{error:u,signal:u.signal,timedOut:u.timedOut},Ot(r,c),Ot(e,a),Ot(t,m)])}},Gi=(async()=>{})().constructor.prototype,_i=["then","catch","finally"].map(r=>[r,Reflect.getOwnPropertyDescriptor(Gi,r)]),no=(r,e)=>{for(const[t,o]of _i){const s=typeof e=="function"?(...n)=>Reflect.apply(o.value,e(),n):o.value.bind(e);Reflect.defineProperty(r,t,{...o,value:s})}},Bi=r=>new Promise((e,t)=>{r.on("exit",(o,s)=>{e({exitCode:o,signal:s})}),r.on("error",o=>{t(o)}),r.stdin&&r.stdin.on("error",o=>{t(o)})}),io=(r,e=[])=>Array.isArray(e)?[r,...e]:[r],Hi=/^[\w.-]+$/,Ui=/"/g,zi=r=>typeof r!="string"||Hi.test(r)?r:`"${r.replace(Ui,'\\"')}"`,Wi=(r,e)=>io(r,e).join(" "),Ki=(r,e)=>io(r,e).map(t=>zi(t)).join(" "),Ji=us("execa").enabled,qe=(r,e)=>String(r).padStart(e,"0"),Vi=()=>{const r=new Date;return`${qe(r.getHours(),2)}:${qe(r.getMinutes(),2)}:${qe(r.getSeconds(),2)}.${qe(r.getMilliseconds(),3)}`},Yi=(r,{verbose:e})=>{e&&se.stderr.write(`[${Vi()}] ${r}
8
- `)},qi=1e3*1e3*100,Xi=({env:r,extendEnv:e,preferLocal:t,localDir:o,execPath:s})=>{const n=e?{...se.env,...r}:r;return t?Ln({env:n,cwd:o,execPath:s}):n},Qi=(r,e,t={})=>{const o=In._parse(r,e,t);return r=o.command,e=o.args,t=o.options,t={maxBuffer:qi,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:t.cwd||se.cwd(),execPath:se.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:Ji,...t},t.env=Xi(t),t.stdio=ri(t),se.platform==="win32"&&ce.basename(r,".exe")==="cmd"&&e.unshift("/q"),{file:r,args:e,options:t,parsed:o}},Ft=(r,e,t)=>typeof e!="string"&&!es.isBuffer(e)?t===void 0?void 0:"":r.stripFinalNewline?Rn(e):e;function j(r,e,t){const o=Qi(r,e,t),s=Wi(r,e),n=Ki(r,e);Yi(n,o.options),vi(o.options);let i;try{i=dr.spawn(o.file,o.args,o.options)}catch(p){const g=new dr.ChildProcess,h=Promise.reject(Xr({error:p,stdout:"",stderr:"",all:"",command:s,escapedCommand:n,parsed:o,timedOut:!1,isCanceled:!1,killed:!1}));return no(g,h),g}const c=Bi(i),a=wi(i,o.options,c),m=bi(i,o.options,a),u={isCanceled:!1};i.kill=di.bind(null,i.kill.bind(i)),i.cancel=gi.bind(null,i,u);const d=Jr(async()=>{const[{error:p,exitCode:g,signal:h,timedOut:y},w,b,P]=await Ni(i,o.options,m),k=Ft(o.options,w),A=Ft(o.options,b),E=Ft(o.options,P);if(p||g!==0||h!==null){const x=Xr({error:p,exitCode:g,signal:h,stdout:k,stderr:A,all:E,command:s,escapedCommand:n,parsed:o,timedOut:y,isCanceled:u.isCanceled||(o.options.signal?o.options.signal.aborted:!1),killed:i.killed});if(!o.options.reject)return x;throw x}return{command:s,escapedCommand:n,exitCode:0,stdout:k,stderr:A,all:E,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return Ti(i,o.options),i.all=ji(i,o.options),Pi(i),no(i,d),i}class J{static create(e,t){return new e(t)}}const{hasOwnProperty:Lt}=Object.prototype,Xe=typeof process<"u"&&process.platform==="win32"?`\r
4
+ `.charCodeAt(),t=typeof r=="string"?"\r":"\r".charCodeAt();return r[r.length-1]===e&&(r=r.slice(0,-1)),r[r.length-1]===t&&(r=r.slice(0,-1)),r}function oo(r={}){const{env:e=process.env,platform:t=process.platform}=r;return t!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"}const Vn=({cwd:r=te.cwd(),path:e=te.env[oo()],preferLocal:t=!0,execPath:o=te.execPath,addExecPath:s=!0}={})=>{const n=r instanceof URL?Pr(r):r,i=ce.resolve(n),l=[];return t&&qn(l,i),s&&Xn(l,o,i),[...l,e].join(ce.delimiter)},qn=(r,e)=>{let t;for(;t!==e;)r.push(ce.join(e,"node_modules/.bin")),t=e,e=ce.resolve(e,"..")},Xn=(r,e,t)=>{const o=e instanceof URL?Pr(e):e;r.push(ce.resolve(t,o,".."))},Qn=({env:r=te.env,...e}={})=>{r={...r};const t=oo({env:r});return e.path=r[t],r[t]=Vn(e),r},Zn=(r,e,t,o)=>{if(t==="length"||t==="prototype"||t==="arguments"||t==="caller")return;const s=Object.getOwnPropertyDescriptor(r,t),n=Object.getOwnPropertyDescriptor(e,t);!ei(s,n)&&o||Object.defineProperty(r,t,n)},ei=function(r,e){return r===void 0||r.configurable||r.writable===e.writable&&r.enumerable===e.enumerable&&r.configurable===e.configurable&&(r.writable||r.value===e.value)},ti=(r,e)=>{const t=Object.getPrototypeOf(e);t!==Object.getPrototypeOf(r)&&Object.setPrototypeOf(r,t)},ri=(r,e)=>`/* Wrapped ${r}*/
5
+ ${e}`,oi=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),si=Object.getOwnPropertyDescriptor(Function.prototype.toString,"name"),ni=(r,e,t)=>{const o=t===""?"":`with ${t.trim()}() `,s=ri.bind(null,o,e.toString());Object.defineProperty(s,"name",si),Object.defineProperty(r,"toString",{...oi,value:s})};function ii(r,e,{ignoreNonConfigurable:t=!1}={}){const{name:o}=r;for(const s of Reflect.ownKeys(e))Zn(r,e,s,t);return ti(r,e),ni(r,e,o),r}const Ve=new WeakMap,so=(r,e={})=>{if(typeof r!="function")throw new TypeError("Expected a function");let t,o=0;const s=r.displayName||r.name||"<anonymous>",n=function(...i){if(Ve.set(n,++o),o===1)t=r.apply(this,i),r=null;else if(e.throw===!0)throw new Error(`Function \`${s}\` can only be called once`);return t};return ii(n,r),Ve.set(n,o),n};so.callCount=r=>{if(!Ve.has(r))throw new Error(`The given function \`${r.name}\` is not wrapped by the \`onetime\` package`);return Ve.get(r)};const ai=()=>{const r=io-no+1;return Array.from({length:r},ci)},ci=(r,e)=>({name:`SIGRT${e+1}`,number:no+e,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),no=34,io=64,li=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}],ao=()=>{const r=ai();return[...li,...r].map(ui)},ui=({name:r,number:e,description:t,action:o,forced:s=!1,standard:n})=>{const{signals:{[r]:i}}=$r,l=i!==void 0;return{name:r,number:l?i:e,description:t,supported:l,action:o,forced:s,standard:n}},di=()=>{const r=ao();return Object.fromEntries(r.map(mi))},mi=({name:r,number:e,description:t,supported:o,action:s,forced:n,standard:i})=>[r,{name:r,number:e,description:t,supported:o,action:s,forced:n,standard:i}],fi=di(),pi=()=>{const r=ao(),e=io+1,t=Array.from({length:e},(o,s)=>hi(s,r));return Object.assign({},...t)},hi=(r,e)=>{const t=gi(r,e);if(t===void 0)return{};const{name:o,description:s,supported:n,action:i,forced:l,standard:a}=t;return{[r]:{name:o,number:r,description:s,supported:n,action:i,forced:l,standard:a}}},gi=(r,e)=>{const t=e.find(({name:o})=>$r.signals[o]===r);return t!==void 0?t:e.find(o=>o.number===r)};pi();const yi=({timedOut:r,timeout:e,errorCode:t,signal:o,signalDescription:s,exitCode:n,isCanceled:i})=>r?`timed out after ${e} milliseconds`:i?"was canceled":t!==void 0?`failed with ${t}`:o!==void 0?`was killed with ${o} (${s})`:n!==void 0?`failed with exit code ${n}`:"failed",qe=({stdout:r,stderr:e,all:t,error:o,signal:s,exitCode:n,command:i,escapedCommand:l,timedOut:a,isCanceled:d,killed:c,parsed:{options:{timeout:u,cwd:m=te.cwd()}}})=>{n=n===null?void 0:n,s=s===null?void 0:s;const p=s===void 0?void 0:fi[s].description,h=o&&o.code,y=`Command ${yi({timedOut:a,timeout:u,errorCode:h,signal:s,signalDescription:p,exitCode:n,isCanceled:d})}: ${i}`,v=Object.prototype.toString.call(o)==="[object Error]",b=v?`${y}
6
+ ${o.message}`:y,E=[b,e,r].filter(Boolean).join(`
7
+ `);return v?(o.originalMessage=o.message,o.message=E):o=new Error(E),o.shortMessage=b,o.command=i,o.escapedCommand=l,o.exitCode=n,o.signal=s,o.signalDescription=p,o.stdout=r,o.stderr=e,o.cwd=m,t!==void 0&&(o.all=t),"bufferedData"in o&&delete o.bufferedData,o.failed=!0,o.timedOut=!!a,o.isCanceled=d,o.killed=c&&!a,o},Xe=["stdin","stdout","stderr"],wi=r=>Xe.some(e=>r[e]!==void 0),co=r=>{if(!r)return;const{stdio:e}=r;if(e===void 0)return Xe.map(o=>r[o]);if(wi(r))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${Xe.map(o=>`\`${o}\``).join(", ")}`);if(typeof e=="string")return e;if(!Array.isArray(e))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof e}\``);const t=Math.max(e.length,Xe.length);return Array.from({length:t},(o,s)=>e[s])},vi=r=>{const e=co(r);return e==="ipc"?"ipc":e===void 0||typeof e=="string"?[e,e,e,"ipc"]:e.includes("ipc")?e:[...e,"ipc"]};var he={exports:{}},Qe={exports:{}};Qe.exports;var lo;function Ci(){return lo||(lo=1,function(r){r.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],process.platform!=="win32"&&r.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),process.platform==="linux"&&r.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}(Qe)),Qe.exports}var N=B.process;const le=function(r){return r&&typeof r=="object"&&typeof r.removeListener=="function"&&typeof r.emit=="function"&&typeof r.reallyExit=="function"&&typeof r.listeners=="function"&&typeof r.kill=="function"&&typeof r.pid=="number"&&typeof r.on=="function"};if(!le(N))he.exports=function(){return function(){}};else{var bi=Ar,Se=Ci(),Ei=/^win/i.test(N.platform),Ze=xr;typeof Ze!="function"&&(Ze=Ze.EventEmitter);var U;N.__signal_exit_emitter__?U=N.__signal_exit_emitter__:(U=N.__signal_exit_emitter__=new Ze,U.count=0,U.emitted={}),U.infinite||(U.setMaxListeners(1/0),U.infinite=!0),he.exports=function(r,e){if(!le(B.process))return function(){};bi.equal(typeof r,"function","a callback must be provided for exit handler"),Me===!1&&uo();var t="exit";e&&e.alwaysLast&&(t="afterexit");var o=function(){U.removeListener(t,r),U.listeners("exit").length===0&&U.listeners("afterexit").length===0&&Lt()};return U.on(t,r),o};var Lt=function(){!Me||!le(B.process)||(Me=!1,Se.forEach(function(e){try{N.removeListener(e,jt[e])}catch{}}),N.emit=Tt,N.reallyExit=mo,U.count-=1)};he.exports.unload=Lt;var ge=function(e,t,o){U.emitted[e]||(U.emitted[e]=!0,U.emit(e,t,o))},jt={};Se.forEach(function(r){jt[r]=function(){if(le(B.process)){var t=N.listeners(r);t.length===U.count&&(Lt(),ge("exit",null,r),ge("afterexit",null,r),Ei&&r==="SIGHUP"&&(r="SIGINT"),N.kill(N.pid,r))}}}),he.exports.signals=function(){return Se};var Me=!1,uo=function(){Me||!le(B.process)||(Me=!0,U.count+=1,Se=Se.filter(function(e){try{return N.on(e,jt[e]),!0}catch{return!1}}),N.emit=$i,N.reallyExit=Pi)};he.exports.load=uo;var mo=N.reallyExit,Pi=function(e){le(B.process)&&(N.exitCode=e||0,ge("exit",N.exitCode,null),ge("afterexit",N.exitCode,null),mo.call(N,N.exitCode))},Tt=N.emit,$i=function(e,t){if(e==="exit"&&le(B.process)){t!==void 0&&(N.exitCode=t);var o=Tt.apply(this,arguments);return ge("exit",N.exitCode,null),ge("afterexit",N.exitCode,null),o}else return Tt.apply(this,arguments)}}var Ai=he.exports,xi=me(Ai);const ki=1e3*5,Si=(r,e="SIGTERM",t={})=>{const o=r(e);return Mi(r,e,t,o),o},Mi=(r,e,t,o)=>{if(!Ii(e,t,o))return;const s=Di(t),n=setTimeout(()=>{r("SIGKILL")},s);n.unref&&n.unref()},Ii=(r,{forceKillAfterTimeout:e},t)=>Ri(r)&&e!==!1&&t,Ri=r=>r===bs.constants.signals.SIGTERM||typeof r=="string"&&r.toUpperCase()==="SIGTERM",Di=({forceKillAfterTimeout:r=!0})=>{if(r===!0)return ki;if(!Number.isFinite(r)||r<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${r}\` (${typeof r})`);return r},Oi=(r,e)=>{r.kill()&&(e.isCanceled=!0)},Fi=(r,e,t)=>{r.kill(e),t(Object.assign(new Error("Timed out"),{timedOut:!0,signal:e}))},Li=(r,{timeout:e,killSignal:t="SIGTERM"},o)=>{if(e===0||e===void 0)return o;let s;const n=new Promise((l,a)=>{s=setTimeout(()=>{Fi(r,t,a)},e)}),i=o.finally(()=>{clearTimeout(s)});return Promise.race([n,i])},ji=({timeout:r})=>{if(r!==void 0&&(!Number.isFinite(r)||r<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${r}\` (${typeof r})`)},Ti=async(r,{cleanup:e,detached:t},o)=>{if(!e||t)return o;const s=xi(()=>{r.kill()});return o.finally(()=>{s()})};function Nt(r){return r!==null&&typeof r=="object"&&typeof r.pipe=="function"}function fo(r){return Nt(r)&&r.writable!==!1&&typeof r._write=="function"&&typeof r._writableState=="object"}const Ni=r=>r instanceof Er&&typeof r.then=="function",_t=(r,e,t)=>{if(typeof t=="string")return r[e].pipe(Es(t)),r;if(fo(t))return r[e].pipe(t),r;if(!Ni(t))throw new TypeError("The second argument must be a string, a stream or an Execa child process.");if(!fo(t.stdin))throw new TypeError("The target child process's stdin must be available.");return r[e].pipe(t.stdin),t},_i=r=>{r.stdout!==null&&(r.pipeStdout=_t.bind(void 0,r,"stdout")),r.stderr!==null&&(r.pipeStderr=_t.bind(void 0,r,"stderr")),r.all!==void 0&&(r.pipeAll=_t.bind(void 0,r,"all"))};var Ie={exports:{}};const{PassThrough:Gi}=Ct;var Bi=r=>{r={...r};const{array:e}=r;let{encoding:t}=r;const o=t==="buffer";let s=!1;e?s=!(t||o):t=t||"utf8",o&&(t=null);const n=new Gi({objectMode:s});t&&n.setEncoding(t);let i=0;const l=[];return n.on("data",a=>{l.push(a),s?i=l.length:i+=a.length}),n.getBufferedValue=()=>e?l:o?Buffer.concat(l,i):l.join(""),n.getBufferedLength=()=>i,n};const{constants:Hi}=As,Ui=Ct,{promisify:zi}=kr,Wi=Bi,Yi=zi(Ui.pipeline);class po extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function Gt(r,e){if(!r)throw new Error("Expected a stream");e={maxBuffer:1/0,...e};const{maxBuffer:t}=e,o=Wi(e);return await new Promise((s,n)=>{const i=l=>{l&&o.getBufferedLength()<=Hi.MAX_LENGTH&&(l.bufferedData=o.getBufferedValue()),n(l)};(async()=>{try{await Yi(r,o),s()}catch(l){i(l)}})(),o.on("data",()=>{o.getBufferedLength()>t&&i(new po)})}),o.getBufferedValue()}Ie.exports=Gt,Ie.exports.buffer=(r,e)=>Gt(r,{...e,encoding:"buffer"}),Ie.exports.array=(r,e)=>Gt(r,{...e,array:!0}),Ie.exports.MaxBufferError=po;var Ki=Ie.exports,ho=me(Ki);const{PassThrough:Ji}=Ct;var Vi=function(){var r=[],e=new Ji({objectMode:!0});return e.setMaxListeners(0),e.add=t,e.isEmpty=o,e.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(t),e;function t(n){return Array.isArray(n)?(n.forEach(t),this):(r.push(n),n.once("end",s.bind(null,n)),n.once("error",e.emit.bind(e,"error")),n.pipe(e,{end:!1}),this)}function o(){return r.length==0}function s(n){r=r.filter(function(i){return i!==n}),!r.length&&e.readable&&e.end()}},qi=me(Vi);const go=r=>{if(r!==void 0)throw new TypeError("The `input` and `inputFile` options cannot be both set.")},Xi=({input:r,inputFile:e})=>typeof e!="string"?r:(go(r),$s(e)),Qi=r=>{const e=Xi(r);if(Nt(e))throw new TypeError("The `input` option cannot be a stream in sync mode");return e},Zi=({input:r,inputFile:e})=>typeof e!="string"?r:(go(r),Ps(e)),ea=(r,e)=>{const t=Zi(e);t!==void 0&&(Nt(t)?t.pipe(r.stdin):r.stdin.end(t))},ta=(r,{all:e})=>{if(!e||!r.stdout&&!r.stderr)return;const t=qi();return r.stdout&&t.add(r.stdout),r.stderr&&t.add(r.stderr),t},Bt=async(r,e)=>{if(!(!r||e===void 0)){r.destroy();try{return await e}catch(t){return t.bufferedData}}},Ht=(r,{encoding:e,buffer:t,maxBuffer:o})=>{if(!(!r||!t))return e?ho(r,{encoding:e,maxBuffer:o}):ho.buffer(r,{maxBuffer:o})},ra=async({stdout:r,stderr:e,all:t},{encoding:o,buffer:s,maxBuffer:n},i)=>{const l=Ht(r,{encoding:o,buffer:s,maxBuffer:n}),a=Ht(e,{encoding:o,buffer:s,maxBuffer:n}),d=Ht(t,{encoding:o,buffer:s,maxBuffer:n*2});try{return await Promise.all([i,l,a,d])}catch(c){return Promise.all([{error:c,signal:c.signal,timedOut:c.timedOut},Bt(r,l),Bt(e,a),Bt(t,d)])}},oa=(async()=>{})().constructor.prototype,sa=["then","catch","finally"].map(r=>[r,Reflect.getOwnPropertyDescriptor(oa,r)]),yo=(r,e)=>{for(const[t,o]of sa){const s=typeof e=="function"?(...n)=>Reflect.apply(o.value,e(),n):o.value.bind(e);Reflect.defineProperty(r,t,{...o,value:s})}},na=r=>new Promise((e,t)=>{r.on("exit",(o,s)=>{e({exitCode:o,signal:s})}),r.on("error",o=>{t(o)}),r.stdin&&r.stdin.on("error",o=>{t(o)})}),wo=(r,e=[])=>Array.isArray(e)?[r,...e]:[r],ia=/^[\w.-]+$/,aa=/"/g,ca=r=>typeof r!="string"||ia.test(r)?r:`"${r.replace(aa,'\\"')}"`,vo=(r,e)=>wo(r,e).join(" "),Co=(r,e)=>wo(r,e).map(t=>ca(t)).join(" "),bo=/ +/g,Eo=r=>{const e=[];for(const t of r.trim().split(bo)){const o=e[e.length-1];o&&o.endsWith("\\")?e[e.length-1]=`${o.slice(0,-1)} ${t}`:e.push(t)}return e},Po=r=>{const e=typeof r;if(e==="string")return r;if(e==="number")return String(r);if(e==="object"&&r!==null&&!(r instanceof Er)&&"stdout"in r){const t=typeof r.stdout;if(t==="string")return r.stdout;if(br.isBuffer(r.stdout))return r.stdout.toString();throw new TypeError(`Unexpected "${t}" stdout in template expression`)}throw new TypeError(`Unexpected "${e}" in template expression`)},$o=(r,e,t)=>t||r.length===0||e.length===0?[...r,...e]:[...r.slice(0,-1),`${r[r.length-1]}${e[0]}`,...e.slice(1)],la=({templates:r,expressions:e,tokens:t,index:o,template:s})=>{const n=s??r.raw[o],i=n.split(bo).filter(Boolean),l=$o(t,i,n.startsWith(" "));if(o===e.length)return l;const a=e[o],d=Array.isArray(a)?a.map(c=>Po(c)):[Po(a)];return $o(l,d,n.endsWith(" "))},Ao=(r,e)=>{let t=[];for(const[o,s]of r.entries())t=la({templates:r,expressions:e,tokens:t,index:o,template:s});return t},ua=ks("execa").enabled,et=(r,e)=>String(r).padStart(e,"0"),da=()=>{const r=new Date;return`${et(r.getHours(),2)}:${et(r.getMinutes(),2)}:${et(r.getSeconds(),2)}.${et(r.getMilliseconds(),3)}`},xo=(r,{verbose:e})=>{e&&te.stderr.write(`[${da()}] ${r}
8
+ `)},ma=1e3*1e3*100,fa=({env:r,extendEnv:e,preferLocal:t,localDir:o,execPath:s})=>{const n=e?{...te.env,...r}:r;return t?Qn({env:n,cwd:o,execPath:s}):n},ko=(r,e,t={})=>{const o=Kn._parse(r,e,t);return r=o.command,e=o.args,t=o.options,t={maxBuffer:ma,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:t.cwd||te.cwd(),execPath:te.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:ua,...t},t.env=fa(t),t.stdio=co(t),te.platform==="win32"&&ce.basename(r,".exe")==="cmd"&&e.unshift("/q"),{file:r,args:e,options:t,parsed:o}},Re=(r,e,t)=>typeof e!="string"&&!br.isBuffer(e)?t===void 0?void 0:"":r.stripFinalNewline?Jn(e):e;function M(r,e,t){const o=ko(r,e,t),s=vo(r,e),n=Co(r,e);xo(n,o.options),ji(o.options);let i;try{i=vt.spawn(o.file,o.args,o.options)}catch(p){const h=new vt.ChildProcess,g=Promise.reject(qe({error:p,stdout:"",stderr:"",all:"",command:s,escapedCommand:n,parsed:o,timedOut:!1,isCanceled:!1,killed:!1}));return yo(h,g),h}const l=na(i),a=Li(i,o.options,l),d=Ti(i,o.options,a),c={isCanceled:!1};i.kill=Si.bind(null,i.kill.bind(i)),i.cancel=Oi.bind(null,i,c);const m=so(async()=>{const[{error:p,exitCode:h,signal:g,timedOut:y},v,b,E]=await ra(i,o.options,d),x=Re(o.options,v),A=Re(o.options,b),P=Re(o.options,E);if(p||h!==0||g!==null){const $=qe({error:p,exitCode:h,signal:g,stdout:x,stderr:A,all:P,command:s,escapedCommand:n,parsed:o,timedOut:y,isCanceled:c.isCanceled||(o.options.signal?o.options.signal.aborted:!1),killed:i.killed});if(!o.options.reject)return $;throw $}return{command:s,escapedCommand:n,exitCode:0,stdout:x,stderr:A,all:P,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return ea(i,o.options),i.all=ta(i,o.options),_i(i),yo(i,m),i}function Ut(r,e,t){const o=ko(r,e,t),s=vo(r,e),n=Co(r,e);xo(n,o.options);const i=Qi(o.options);let l;try{l=vt.spawnSync(o.file,o.args,{...o.options,input:i})}catch(c){throw qe({error:c,stdout:"",stderr:"",all:"",command:s,escapedCommand:n,parsed:o,timedOut:!1,isCanceled:!1,killed:!1})}const a=Re(o.options,l.stdout,l.error),d=Re(o.options,l.stderr,l.error);if(l.error||l.status!==0||l.signal!==null){const c=qe({stdout:a,stderr:d,error:l.error,signal:l.signal,exitCode:l.status,command:s,escapedCommand:n,parsed:o,timedOut:l.error&&l.error.code==="ETIMEDOUT",isCanceled:!1,killed:l.signal!==null});if(!o.options.reject)return c;throw c}return{command:s,escapedCommand:n,exitCode:0,stdout:a,stderr:d,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}}const pa=({input:r,inputFile:e,stdio:t})=>r===void 0&&e===void 0&&t===void 0?{stdin:"inherit"}:{},So=(r={})=>({preferLocal:!0,...pa(r),...r});function Mo(r){function e(t,...o){if(!Array.isArray(t))return Mo({...r,...t});const[s,...n]=Ao(t,o);return M(s,n,So(r))}return e.sync=(t,...o)=>{if(!Array.isArray(t))throw new TypeError("Please use $(options).sync`command` instead of $.sync(options)`command`.");const[s,...n]=Ao(t,o);return Ut(s,n,So(r))},e}const ha=Mo();function ga(r,e){const[t,...o]=Eo(r);return M(t,o,e)}function ya(r,e){const[t,...o]=Eo(r);return Ut(t,o,e)}function wa(r,e,t={}){e&&!Array.isArray(e)&&typeof e=="object"&&(t=e,e=[]);const o=vi(t),s=te.execArgv.filter(l=>!l.startsWith("--inspect")),{nodePath:n=te.execPath,nodeOptions:i=s}=t;return M(n,[...i,r,...Array.isArray(e)?e:[]],{...t,stdin:void 0,stdout:void 0,stderr:void 0,stdio:o,shell:!1})}var va=Object.freeze({__proto__:null,execa:M,execaSync:Ut,$:ha,execaCommand:ga,execaCommandSync:ya,execaNode:wa});class J{static create(e,t){return new e(t)}}const{hasOwnProperty:zt}=Object.prototype,tt=typeof process<"u"&&process.platform==="win32"?`\r
9
9
  `:`
10
- `,Tt=(r,e)=>{const t=[];let o="";typeof e=="string"?e={section:e,whitespace:!1}:(e=e||Object.create(null),e.whitespace=e.whitespace===!0);const s=e.whitespace?" = ":"=";for(const n of Object.keys(r)){const i=r[n];if(i&&Array.isArray(i))for(const c of i)o+=ye(n+"[]")+s+ye(c)+Xe;else i&&typeof i=="object"?t.push(n):o+=ye(n)+s+ye(i)+Xe}e.section&&o.length&&(o="["+ye(e.section)+"]"+Xe+o);for(const n of t){const i=ao(n).join("\\."),c=(e.section?e.section+".":"")+i,{whitespace:a}=e,m=Tt(r[n],{section:c,whitespace:a});o.length&&m.length&&(o+=Xe),o+=m}return o},ao=r=>r.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(e=>e.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),co=r=>{const e=Object.create(null);let t=e,o=null;const s=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,n=r.split(/[\r\n]+/g);for(const c of n){if(!c||c.match(/^\s*[;#]/))continue;const a=c.match(s);if(!a)continue;if(a[1]!==void 0){if(o=Qe(a[1]),o==="__proto__"){t=Object.create(null);continue}t=e[o]=e[o]||Object.create(null);continue}const m=Qe(a[2]),u=m.length>2&&m.slice(-2)==="[]",l=u?m.slice(0,-2):m;if(l==="__proto__")continue;const d=a[3]?Qe(a[4]):!0,p=d==="true"||d==="false"||d==="null"?JSON.parse(d):d;u&&(Lt.call(t,l)?Array.isArray(t[l])||(t[l]=[t[l]]):t[l]=[]),Array.isArray(t[l])?t[l].push(p):t[l]=p}const i=[];for(const c of Object.keys(e)){if(!Lt.call(e,c)||typeof e[c]!="object"||Array.isArray(e[c]))continue;const a=ao(c);t=e;const m=a.pop(),u=m.replace(/\\\./g,".");for(const l of a)l!=="__proto__"&&((!Lt.call(t,l)||typeof t[l]!="object")&&(t[l]=Object.create(null)),t=t[l]);t===e&&u===m||(t[u]=e[c],i.push(c))}for(const c of i)delete e[c];return e},lo=r=>r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'"),ye=r=>typeof r!="string"||r.match(/[=\r\n]/)||r.match(/^\[/)||r.length>1&&lo(r)||r!==r.trim()?JSON.stringify(r):r.split(";").join("\\;").split("#").join("\\#"),Qe=(r,e)=>{if(r=(r||"").trim(),lo(r)){r.charAt(0)==="'"&&(r=r.slice(1,-1));try{r=JSON.parse(r)}catch{}}else{let t=!1,o="";for(let s=0,n=r.length;s<n;s++){const i=r.charAt(s);if(t)"\\;#".indexOf(i)!==-1?o+=i:o+="\\"+i,t=!1;else{if(";#".indexOf(i)!==-1)break;i==="\\"?t=!0:o+=i}}return t&&(o+="\\"),o.trim()}return r};var Zi={parse:co,decode:co,stringify:Tt,encode:Tt,safe:ye,unsafe:Qe},we=me(Zi);class v extends Error{}const jt=" ",ie=r=>{r instanceof Error&&(r instanceof v||(r.stack&&console.error(C.dim(r.stack.split(`
10
+ `,Wt=(r,e)=>{const t=[];let o="";typeof e=="string"?e={section:e,whitespace:!1}:(e=e||Object.create(null),e.whitespace=e.whitespace===!0);const s=e.whitespace?" = ":"=";for(const n of Object.keys(r)){const i=r[n];if(i&&Array.isArray(i))for(const l of i)o+=ye(n+"[]")+s+ye(l)+tt;else i&&typeof i=="object"?t.push(n):o+=ye(n)+s+ye(i)+tt}e.section&&o.length&&(o="["+ye(e.section)+"]"+tt+o);for(const n of t){const i=Io(n).join("\\."),l=(e.section?e.section+".":"")+i,{whitespace:a}=e,d=Wt(r[n],{section:l,whitespace:a});o.length&&d.length&&(o+=tt),o+=d}return o},Io=r=>r.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(e=>e.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),Ro=r=>{const e=Object.create(null);let t=e,o=null;const s=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,n=r.split(/[\r\n]+/g);for(const l of n){if(!l||l.match(/^\s*[;#]/))continue;const a=l.match(s);if(!a)continue;if(a[1]!==void 0){if(o=rt(a[1]),o==="__proto__"){t=Object.create(null);continue}t=e[o]=e[o]||Object.create(null);continue}const d=rt(a[2]),c=d.length>2&&d.slice(-2)==="[]",u=c?d.slice(0,-2):d;if(u==="__proto__")continue;const m=a[3]?rt(a[4]):!0,p=m==="true"||m==="false"||m==="null"?JSON.parse(m):m;c&&(zt.call(t,u)?Array.isArray(t[u])||(t[u]=[t[u]]):t[u]=[]),Array.isArray(t[u])?t[u].push(p):t[u]=p}const i=[];for(const l of Object.keys(e)){if(!zt.call(e,l)||typeof e[l]!="object"||Array.isArray(e[l]))continue;const a=Io(l);t=e;const d=a.pop(),c=d.replace(/\\\./g,".");for(const u of a)u!=="__proto__"&&((!zt.call(t,u)||typeof t[u]!="object")&&(t[u]=Object.create(null)),t=t[u]);t===e&&c===d||(t[c]=e[l],i.push(l))}for(const l of i)delete e[l];return e},Do=r=>r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'"),ye=r=>typeof r!="string"||r.match(/[=\r\n]/)||r.match(/^\[/)||r.length>1&&Do(r)||r!==r.trim()?JSON.stringify(r):r.split(";").join("\\;").split("#").join("\\#"),rt=(r,e)=>{if(r=(r||"").trim(),Do(r)){r.charAt(0)==="'"&&(r=r.slice(1,-1));try{r=JSON.parse(r)}catch{}}else{let t=!1,o="";for(let s=0,n=r.length;s<n;s++){const i=r.charAt(s);if(t)"\\;#".indexOf(i)!==-1?o+=i:o+="\\"+i,t=!1;else{if(";#".indexOf(i)!==-1)break;i==="\\"?t=!0:o+=i}}return t&&(o+="\\"),o.trim()}return r};var Ca={parse:Ro,decode:Ro,stringify:Wt,encode:Wt,safe:ye,unsafe:rt},we=me(Ca);class w extends Error{}const Yt=" ",ae=r=>{r instanceof Error&&(r instanceof w||(r.stack&&console.error(C.dim(r.stack.split(`
11
11
  `).slice(1).join(`
12
12
  `))),console.error(`
13
- ${jt}${C.dim(`aicommit2 v${Ir}`)}`),console.error(`
14
- ${jt}Please open a Bug report with the information above:`),console.error(`${jt}https://github.com/tak-bro/aicommit2/issues/new/choose`)))},uo=r=>O.lstat(r).then(()=>!0,()=>!1),mo=async r=>{try{await O.mkdir(r,{recursive:!0})}catch(e){if(e.code!=="EEXIST")throw e}},Ze=r=>r&&`${r[0].toUpperCase()}${r.slice(1)}`,et=(r,e)=>{const t=Math.ceil(r),o=Math.floor(e);return Math.floor(Math.random()*(o-t+1))+t},ea=(r,e)=>r.disabled&&!e.disabled?1:!r.disabled&&e.disabled?-1:0,tt=r=>r.reduce((e,t)=>Array.isArray(t)?e.concat(tt(t)):e.concat(t),[]),fo=(r,e=5)=>r.replace(/[\n\r]/g,"").split(" ").slice(0,e).join(" "),ta=r=>{let e=0;for(let t=0;t<r.length;t++){const o=r.charCodeAt(t);e=(e<<5)-e+o,e=e&e}return Math.abs(e)},ra=r=>{const e=r%360,t=65+r%15,o=45+r%10;return`hsl(${e}, ${t}%, ${o}%)`},oa=r=>{const[e,t,o]=r.match(/\d+/g).map((l,d)=>d===0?Number(l):Number(l)/100),s=(1-Math.abs(2*o-1))*t,n=s*(1-Math.abs(e/60%2-1)),i=o-s/2;let c,a,m;e<60?[c,a,m]=[s,n,0]:e<120?[c,a,m]=[n,s,0]:e<180?[c,a,m]=[0,s,n]:e<240?[c,a,m]=[0,n,s]:e<300?[c,a,m]=[n,0,s]:[c,a,m]=[s,0,n];const u=l=>{const d=Math.round((l+i)*255).toString(16);return d.length===1?"0"+d:d};return`#${u(c)}${u(a)}${u(m)}`},sa=r=>{const e=ta(r),t=ra(e);return{primary:oa(t),secondary:"#FFFFFF"}},na=r=>{try{return{ok:!0,data:JSON.parse(r)}}catch(e){return{ok:!1,error:e}}},rt=r=>{if(!r||typeof r!="string")return"";if(S.isAbsolute(r))return S.resolve(r);if(Ie){const e=S.dirname(Ie),t=S.join(e,r);return S.resolve(t)}else return""},ia=["","conventional","gitmoji"],Nt="http://localhost:11434",{hasOwnProperty:aa}=Object.prototype,Gt=(r,e)=>aa.call(r,e),ve=["OPENAI","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS"],po=r=>{const e=xe.platform(),t=xe.homedir();let o,s;switch(r){case"config":o=process.env.XDG_CONFIG_HOME;break;case"data":o=process.env.XDG_DATA_HOME;break;case"cache":o=process.env.XDG_CACHE_HOME;break;case"state":o=process.env.XDG_STATE_HOME;break;default:o=void 0}if(e==="darwin")r==="cache"?s=S.join(t,"Library","Caches"):s=S.join(t,"Library","Application Support");else if(e==="win32")s=process.env.LOCALAPPDATA||t;else switch(r){case"config":s=S.join(t,".config");break;case"data":s=S.join(t,".local","share");break;case"cache":s=S.join(t,".cache");break;case"state":s=S.join(t,".local","state");break;default:s=t}return o||s},ca=S.join(po("config"),"aicommit2"),ee=S.join(po("state"),"aicommit2","logs"),ho=S.join(ca,"config.ini"),go=S.join(ee,"aicommit2-%DATE%.log"),yo=S.join(ee,"exceptions-%DATE%.log"),la=r=>{const e=Object.keys(r),t=new Set([...ve,...e.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(t)},D=(r,e,t)=>{if(!e)throw new v(`Invalid config property ${r}: ${t}`)},ne=(r,e=!1)=>t=>typeof t=="boolean"?t:t==null?e:(D(r,/^(?:true|false)$/.test(t),"Must be a boolean(true or false)"),t==="true"),f={systemPrompt(r){return r||""},systemPromptPath(r){return r||""},codeReviewPromptPath(r){return r||""},timeout(r){if(!r)return 6e4;D("timeout",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return D("timeout",e>=500,"Must be greater than 500ms"),e},temperature(r){if(!r)return .7;D("temperature",/^(2|\d)(\.\d{1,2})?$/.test(r),"Must be decimal between 0 and 2");const e=Number(r);return D("temperature",e>0,"Must be greater than 0"),D("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens(r){return r?(D("maxTokens",/^\d+$/.test(r),"Must be an integer"),Number(r)):1024},logLevel(r){return r?(D("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(r),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),r):"info"},logFilePath(r){return r||go},exceptionLogFilePath(r){return r||yo},locale(r){return r?(D("locale",r,"Cannot be empty"),D("locale",/^[a-z-]+$/i.test(r),"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"),r):"en"},generate(r){if(!r)return 1;D("generate",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return D("generate",e>0,"Must be greater than 0"),D("generate",e<=5,"Must be less or equal to 5"),e},type(r){return r?(D("type",ia.includes(r),"Invalid commit type"),r):"conventional"},maxLength(r){if(!r)return 50;D("maxLength",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return D("maxLength",e>=20,"Must be greater than 20 characters"),e},exclude:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):[],topP:r=>{if(!r)return .9;D("topP",/^(1|\d)(\.\d{1,2})?$/.test(r),"Must be decimal between 0 and 1");const e=Number(r);return D("topP",e>0,"Must be greater than 0"),D("topP",e<=1,"Must be less than or equal to 1"),e},logging:ne("logging",!0),includeBody:ne("includeBody"),codeReview:ne("codeReview"),disabled:ne("disabled"),watchMode:ne("watchMode"),forceGit:ne("forceGit"),disableLowerCase:ne("disableLowerCase")},Me={OPENAI:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gpt-4o-mini"],url:r=>r?(D("OPENAI.url",/^https?:\/\//.test(r),"Must be a valid URL"),r):"https://api.openai.com",path:r=>r||"/v1/chat/completions",proxy:r=>r||"",topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},HUGGINGFACE:{cookie:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,topP:f.topP,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GEMINI:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gemini-2.0-flash"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},ANTHROPIC:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["claude-3-5-haiku-20241022"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},MISTRAL:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["mistral-small-latest"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},CODESTRAL:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["codestral-latest"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},OLLAMA:{model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):[],host:r=>r?(D("OLLAMA.host",/^https?:\/\//.test(r),"Must be a valid URL"),r):Nt,timeout:r=>{if(!r)return 1e5;D("OLLAMA.timeout",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return D("OLLAMA.timeout",e>=500,"Must be greater than 500ms"),e},auth:r=>r||"",key:r=>r||"",envKey:r=>r||"",numCtx:r=>{if(!r)return 2048;D("OLLAMA.numCtx",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return D("OLLAMA.numCtx",e>=2048,"Must be greater than 2048"),e},systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},COHERE:{key:r=>r||"",envKey:r=>r||"",url:r=>r?(D("COHERE.url",/^https?:\/\//.test(r),"Must be a valid URL"),r):"https://api.cohere.ai",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["command-a-03-2025"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,timeout:f.timeout,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GROQ:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["llama-3.3-70b-versatile"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},PERPLEXITY:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["sonar"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},DEEPSEEK:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["deepseek-coder"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GITHUB_MODELS:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gpt-4o-mini"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase}};let Ie;const ua=(r=[])=>{const e={};for(const t of r)if(t.startsWith("--")){const[o,s]=t.slice(2).split("="),[n,i]=o.split(".");n&&i&&n in Me?(e[n]||(e[n]={}),e[n][i]=s):e[o]=s}return e},da=()=>{const r=xe.homedir(),e=process.env.AICOMMIT_CONFIG_PATH,t=ho,o=S.join(r,".aicommit2");return[e,t,o].filter(s=>!!s)},be=async()=>{const r=da();for(const e of r)if(await uo(e))return e;return ho},Re=async()=>{const r=await be();Ie=r;try{const e=await O.readFile(r,"utf8");return we.parse(e)}catch(e){return e.code==="ENOENT"?(Ie=void 0,{}):(console.error(`Error reading config file ${r}:`,e),Ie=void 0,{})}},ue=async(r,e=[])=>{const t=await Re(),o=ua(e),s={...r,...o},n={},i=la(t),c={};for(const m of i){const l=t[m]?.envKey||`${m}_API_KEY`,d=process.env[l];d&&(c[m]={key:d})}const a=(m,u)=>{const l=s[`${m}.${u}`]??s[m]?.[u],d=c[m]?.[u],p=t[m]?.[u],g=s[u]??t[u];return l!==void 0?l:d!==void 0?d:p!==void 0?p:g};for(const[m,u]of Object.entries(f)){const l=s[m]??t[m];n[m]=u(l)}for(const m of i){n[m]={};const u=Me[m]||ot(m);for(const[l,d]of Object.entries(u)){const p=a(m,l);n[m][l]=d(p)}}return n},_t=async r=>{const e=await Re();for(const[s,n]of r){const[i,c]=s.split(".");if(!c){const u=f[s];if(!u)throw new v(`Invalid config property: ${s}`);e[s]=u(n);continue}if(e[i]||(e[i]={}),ve.includes(i)){const u=Me[i][c];if(!u)throw new v(`Invalid config property: ${s}`);e[i][c]=u(n);continue}if(!/^[A-Z][A-Z0-9_]*$/.test(i))throw new v(`Invalid service name: ${i}. Service names must be uppercase letters, numbers, and underscores.`);const m=ot(i);if(!m[c])throw new v(`Invalid config property for custom service: ${s}`);try{e[i][c]=m[c](n)}catch(u){throw u instanceof v?u:new v(`Invalid value for ${s}: ${u.message}`)}}const t=await be(),o=S.dirname(t);await O.mkdir(o,{recursive:!0}),await O.writeFile(t,we.stringify(e),"utf8")},ma=async r=>{const e=await Re();for(const[s,n]of r){const[i,c]=s.split("."),a=e[i];if(c==="model"){a||(e[i]={});const u=e[i][c]||[],l=typeof n=="string"?n.split(",").map(d=>d.trim()).filter(d=>!!d):n;e[i][c]=tt([...u,...l]);continue}if(a&&a.compatible===!0){a||(e[i]={});const u=ot(i);if(!u[c])throw new v(`Invalid config property: ${s}`);try{e[i][c]=u[c](n)}catch(l){throw l instanceof v?l:new v(`Invalid value for ${s}: ${l.message}`)}continue}if(i in Me){a||(e[i]={});const u=Me[i][c];if(!u)throw new v(`Invalid config property: ${s}`);e[i][c]=u(n)}else{const u=ot(i);if(!u[c])throw new v(`Invalid config property: ${s}`);e[i]||(e[i]={}),e[i][c]=u[c](n)}}const t=await be(),o=S.dirname(t);await O.mkdir(o,{recursive:!0}),await O.writeFile(t,we.stringify(e),"utf8")},fa=async()=>{const r=await Re();console.log(we.stringify(r))},pa=async()=>{console.log(await be())},ot=r=>({compatible:ne("compatible"),stream:ne("stream"),url:e=>e?(D(`${r}.url`,/^https?:\/\//.test(e),"Must be a valid URL"),e):"",path:e=>e||"",key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(o=>o.trim()).filter(o=>!!o&&o.length>0):[],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase}),Oe=new Map,de=(r,e,t)=>{const o=Pr(0).update(e).digest("hex").substring(0,8),s=`${r}_${o}_${t}`;if(Oe.has(s))return Oe.get(s);const n=new Date,i=ya(n,r,e,t),c=`${ee}/${i}`,a=B.createLogger({level:"info",format:B.format.combine(B.format.timestamp({format:"YYYY-MM-DDTHH:mm:ss.SSSZ"}),B.format.printf(({timestamp:m,level:u,message:l,...d})=>d&&Object.keys(d).length>0?`[${m}] ${u}: ${l} ${JSON.stringify(d,null,2)}`:`[${m}] ${u}: ${l}`)),transports:[new B.transports.File({filename:c})]});return a.info(`=== ${r.toUpperCase()} AI SERVICE LOG ===`),a.info(`Diff Hash: ${o}`),a.info(`Request Type: ${t.toUpperCase()}`),a.info(`Start Time: ${n.toISOString()}`),a.info("=".repeat(50)),a.info(""),Oe.set(s,a),a},ha=r=>{const e={...r},t=["authorization","x-api-key","x-goog-api-key","api-key"];for(const o of t){const s=o.toLowerCase(),n=Object.keys(e).find(i=>i.toLowerCase()===s);n&&e[n]&&typeof e[n]=="string"&&(e[n].startsWith("Bearer ")?e[n]="Bearer [MASKED]":e[n]="[MASKED]")}return e},V=(r,e,t,o,s,n,i=!0)=>{if(!i)return;const c=de(t,r,e);c.info(`Making request to ${t} API with model: ${o}`),c.info(`Request URL: ${s}`),c.info("Request headers:",ha(n))},te=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).info("Request payload:",o)},Y=(r,e,t,o,s,n=!0)=>{if(!n)return;const i=de(t,r,e);i.info("System prompt:",{prompt:o}),i.info("User prompt:",{prompt:s})},q=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).info("Response received:",o)},G=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).error("API request failed:",o)},z=(r,e,t,o,s,n=!0)=>{if(!n)return;const i=de(t,r,e);o?i.info(`Request completed successfully in ${o}ms`):i.info("Request completed successfully"),s&&i.info("Final processed response:",{response:s}),i.info(""),i.info("=".repeat(50)),i.info(`End Time: ${new Date().toISOString()}`),i.info("=== REQUEST COMPLETED ===")},ga=(r,e,t,o,s,n,i,c=!0)=>{if(!c)return;const a=de(t,r,e);i?a.error(`Request failed after ${n}ms:`,{error:i}):(a.info(`Request completed in ${n}ms`),a.info("Response:",{response:s})),z(r,e,t,n,s,c)},ya=(r,e,t,o)=>{const{year:s,month:n,day:i,hours:c,minutes:a,seconds:m}=wa(r),l=Pr(0).update(t).digest("hex").substring(0,8),d=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,20);return o==="review"?`${s}-${n}-${i}_${c}-${a}-${m}_${l}_${d}_review.log`:`${s}-${n}-${i}_${c}-${a}-${m}_${l}_${d}_commit.log`},wa=r=>{const e=r.getFullYear().toString(),t=(r.getMonth()+1).toString().padStart(2,"0"),o=r.getDate().toString().padStart(2,"0"),s=r.getHours().toString().padStart(2,"0"),n=r.getMinutes().toString().padStart(2,"0"),i=r.getSeconds().toString().padStart(2,"0");return{year:e,month:t,day:o,hours:s,minutes:n,seconds:i}},Bt=()=>{for(const[r,e]of Oe.entries())try{e.close()}catch(t){console.error(`Failed to close logger ${r}:`,t)}Oe.clear()};process.on("exit",Bt),process.on("SIGINT",()=>{Bt(),process.exit(0)}),process.on("SIGTERM",()=>{Bt(),process.exit(0)});let st,wo="info";async function va(r){if(st){console.warn("Logger already initialized. Skipping re-initialization.");return}const e=r?.logLevel||"info";wo=e;const t=r?.logFilePath||go,o=r?.exceptionLogFilePath||yo,s=r?.logging??!0;await mo(S.dirname(t)),await mo(S.dirname(o));const n=[];s?n.push(new B.transports.DailyRotateFile({filename:t,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",level:e,format:B.format.combine(B.format.timestamp(),B.format.printf(({level:i,message:c,timestamp:a})=>`[${a}] ${i}: ${c}`))})):n.push(new B.transports.Console({silent:!0})),st=B.createLogger({level:e,format:B.format.json(),transports:n,exceptionHandlers:s?[new B.transports.DailyRotateFile({filename:o,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",format:B.format.combine(B.format.timestamp(),B.format.json())})]:[],exitOnError:!1,silent:!s})}const Ce=new Proxy({},{get:(r,e,t)=>{if(!st)throw new Error("Logger not initialized. Call initializeLogger() first.");return Reflect.get(st,e,t)}});function ba(){const r=B.config.npm.levels;return(r[wo]??r.info)>=r.verbose}class X{constructor(e){this.handleError$=t=>{const o=this.getDetailedErrorMessage(t),s=t.status?`HTTP ${t.status}: ${o}`:o;if(this.params.config.logging){const n=this.params.stagedDiff.diff,i=this.serviceName.replace(/\[|\]/g,"").trim();ga(n,"commit",i,"Error occurred","",void 0,s)}return Ce.error(`${this.errorPrefix} ${s}`),t.stack&&Ce.error(` ${t.stack}`),t.content&&Ce.error(` Problematic content: ${t.content}`),t.originalError&&Ce.error(` Original error: ${t.originalError}`),ft({name:`${this.errorPrefix} ${s}`,value:s,isError:!0,disabled:!0})},this.serviceName="AI",this.errorPrefix="ERROR",this.colors={primary:""},this.params=e,this.logSessionId=e.logSessionId}getDetailedErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your API key configuration":t.includes("rate_limit")||t.includes("Rate limit")||t.includes("429")||t.includes("Too Many Requests")?"Rate limit exceeded. Wait a moment and try again, or upgrade your plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the model name is correct":t.includes("timeout")||t.includes("Timeout")?"Request timed out. Try again or increase the timeout setting":t.includes("network")||t.includes("connection")||t.includes("ECONNREFUSED")?"Network error. Check your internet connection and try again":t.includes("quota")||t.includes("usage")||t.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your usage limits":t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Your API key may be invalid or expired":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your model configuration":t.includes("500")||t.includes("Internal Server Error")?"Server error. Try again later":t.includes("overloaded")||t.includes("capacity")||t.includes("SERVICE_UNAVAILABLE")||t.includes("unavailable")?"Service is temporarily unavailable. Try again in a few minutes":this.getServiceSpecificErrorMessage(e)||t||"Unknown error occurred"}getServiceSpecificErrorMessage(e){return null}cleanJsonCodeBlock(e){const t=/```(?:json|JSON)?\s*([\s\S]*?)\s*```/,o=e.match(t);return o?o[1].trim():e}parseMessage(e,t,o){const s=this.cleanJsonCodeBlock(e),n=/(\[\s*\{[\s\S]*?\}\s*\]|\{[\s\S]*?\})/,i=s.match(n);if(!i){const p=new Error("AI response did not contain a valid JSON object or array.");throw p.name="InvalidJsonResponse",p.content=e,p}const c=i[0],a=na(c);if(!a.ok){const p=new Error("Failed to parse AI response as JSON");throw p.name="JsonParseError",p.content=c,p.originalError=a.error,p}const m=a.data,u=Array.isArray(m)?m:[m];if(!u.length||!u.every(p=>typeof p.subject=="string")){const p=new Error("AI response contained malformed commit message data.");throw p.name="MalformedCommitMessage",p.content=e,p}const d=u.map(p=>this.extractMessageAsType(p,t)).map(p=>({title:`${p.subject}`,value:`${p.subject}${p.body?`
13
+ ${Yt}${C.dim(`aicommit2 v${Br}`)}`),console.error(`
14
+ ${Yt}Please open a Bug report with the information above:`),console.error(`${Yt}https://github.com/tak-bro/aicommit2/issues/new/choose`)))},Oo=r=>O.lstat(r).then(()=>!0,()=>!1),Fo=async r=>{try{await O.mkdir(r,{recursive:!0})}catch(e){if(e.code!=="EEXIST")throw e}},ot=r=>r&&`${r[0].toUpperCase()}${r.slice(1)}`,st=(r,e)=>{const t=Math.ceil(r),o=Math.floor(e);return Math.floor(Math.random()*(o-t+1))+t},ba=(r,e)=>r.disabled&&!e.disabled?1:!r.disabled&&e.disabled?-1:0,nt=r=>r.reduce((e,t)=>Array.isArray(t)?e.concat(nt(t)):e.concat(t),[]),Lo=(r,e=5)=>r.replace(/[\n\r]/g,"").split(" ").slice(0,e).join(" "),Ea=r=>{let e=0;for(let t=0;t<r.length;t++){const o=r.charCodeAt(t);e=(e<<5)-e+o,e=e&e}return Math.abs(e)},Pa=r=>{const e=r%360,t=65+r%15,o=45+r%10;return`hsl(${e}, ${t}%, ${o}%)`},$a=r=>{const[e,t,o]=r.match(/\d+/g).map((u,m)=>m===0?Number(u):Number(u)/100),s=(1-Math.abs(2*o-1))*t,n=s*(1-Math.abs(e/60%2-1)),i=o-s/2;let l,a,d;e<60?[l,a,d]=[s,n,0]:e<120?[l,a,d]=[n,s,0]:e<180?[l,a,d]=[0,s,n]:e<240?[l,a,d]=[0,n,s]:e<300?[l,a,d]=[n,0,s]:[l,a,d]=[s,0,n];const c=u=>{const m=Math.round((u+i)*255).toString(16);return m.length===1?"0"+m:m};return`#${c(l)}${c(a)}${c(d)}`},Aa=r=>{const e=Ea(r),t=Pa(e);return{primary:$a(t),secondary:"#FFFFFF"}},xa=r=>{try{return{ok:!0,data:JSON.parse(r)}}catch(e){return{ok:!1,error:e}}},it=r=>{if(!r||typeof r!="string")return"";if(S.isAbsolute(r))return S.resolve(r);if(Oe){const e=S.dirname(Oe),t=S.join(e,r);return S.resolve(t)}else return""},ka=["","conventional","gitmoji"],Kt="http://localhost:11434",{hasOwnProperty:Sa}=Object.prototype,Jt=(r,e)=>Sa.call(r,e),ve=["OPENAI","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS"],jo=r=>{const e=ke.platform(),t=ke.homedir();let o,s;switch(r){case"config":o=process.env.XDG_CONFIG_HOME;break;case"data":o=process.env.XDG_DATA_HOME;break;case"cache":o=process.env.XDG_CACHE_HOME;break;case"state":o=process.env.XDG_STATE_HOME;break;default:o=void 0}if(e==="darwin")r==="cache"?s=S.join(t,"Library","Caches"):s=S.join(t,"Library","Application Support");else if(e==="win32")s=process.env.LOCALAPPDATA||t;else switch(r){case"config":s=S.join(t,".config");break;case"data":s=S.join(t,".local","share");break;case"cache":s=S.join(t,".cache");break;case"state":s=S.join(t,".local","state");break;default:s=t}return o||s},Ma=S.join(jo("config"),"aicommit2"),re=S.join(jo("state"),"aicommit2","logs"),To=S.join(Ma,"config.ini"),No=S.join(re,"aicommit2-%DATE%.log"),_o=S.join(re,"exceptions-%DATE%.log"),Ia=r=>{const e=Object.keys(r),t=new Set([...ve,...e.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(t)},L=(r,e,t)=>{if(!e)throw new w(`Invalid config property ${r}: ${t}`)},ie=(r,e=!1)=>t=>typeof t=="boolean"?t:t==null?e:(L(r,/^(?:true|false)$/.test(t),"Must be a boolean(true or false)"),t==="true"),f={systemPrompt(r){return r||""},systemPromptPath(r){return r||""},codeReviewPromptPath(r){return r||""},timeout(r){if(!r)return 6e4;L("timeout",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return L("timeout",e>=500,"Must be greater than 500ms"),e},temperature(r){if(!r)return .7;L("temperature",/^(2|\d)(\.\d{1,2})?$/.test(r),"Must be decimal between 0 and 2");const e=Number(r);return L("temperature",e>0,"Must be greater than 0"),L("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens(r){return r?(L("maxTokens",/^\d+$/.test(r),"Must be an integer"),Number(r)):8192},logLevel(r){return r?(L("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(r),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),r):"info"},logFilePath(r){return r||No},exceptionLogFilePath(r){return r||_o},locale(r){return r?(L("locale",r,"Cannot be empty"),L("locale",/^[a-z-]+$/i.test(r),"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"),r):"en"},generate(r){if(!r)return 1;L("generate",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return L("generate",e>0,"Must be greater than 0"),L("generate",e<=5,"Must be less or equal to 5"),e},type(r){return r?(L("type",ka.includes(r),"Invalid commit type"),r):"conventional"},maxLength(r){if(!r)return 50;L("maxLength",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return L("maxLength",e>=20,"Must be greater than 20 characters"),e},exclude:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):[],topP:r=>{if(!r)return .9;L("topP",/^(1|\d)(\.\d{1,2})?$/.test(r),"Must be decimal between 0 and 1");const e=Number(r);return L("topP",e>0,"Must be greater than 0"),L("topP",e<=1,"Must be less than or equal to 1"),e},logging:ie("logging",!0),includeBody:ie("includeBody"),codeReview:ie("codeReview"),disabled:ie("disabled"),watchMode:ie("watchMode"),forceGit:ie("forceGit"),disableLowerCase:ie("disableLowerCase")},De={OPENAI:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gpt-4o-mini"],url:r=>r?(L("OPENAI.url",/^https?:\/\//.test(r),"Must be a valid URL"),r):"https://api.openai.com",path:r=>r||"/v1/chat/completions",proxy:r=>r||"",topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},HUGGINGFACE:{cookie:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,topP:f.topP,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GEMINI:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gemini-2.5-flash"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},ANTHROPIC:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["claude-3-5-haiku-20241022"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},MISTRAL:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["mistral-small-latest"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},CODESTRAL:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["codestral-latest"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},OLLAMA:{model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):[],host:r=>r?(L("OLLAMA.host",/^https?:\/\//.test(r),"Must be a valid URL"),r):Kt,timeout:r=>{if(!r)return 1e5;L("OLLAMA.timeout",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return L("OLLAMA.timeout",e>=500,"Must be greater than 500ms"),e},auth:r=>r||"",key:r=>r||"",envKey:r=>r||"",numCtx:r=>{if(!r)return 2048;L("OLLAMA.numCtx",/^\d+$/.test(r),"Must be an integer");const e=Number(r);return L("OLLAMA.numCtx",e>=2048,"Must be greater than 2048"),e},systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},COHERE:{key:r=>r||"",envKey:r=>r||"",url:r=>r?(L("COHERE.url",/^https?:\/\//.test(r),"Must be a valid URL"),r):"https://api.cohere.ai",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["command-a-03-2025"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,timeout:f.timeout,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GROQ:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["llama-3.3-70b-versatile"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},PERPLEXITY:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["sonar"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},DEEPSEEK:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["deepseek-coder"],topP:f.topP,systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase},GITHUB_MODELS:{key:r=>r||"",envKey:r=>r||"",model:r=>r?(typeof r=="string"?r?.split(","):r).map(t=>t.trim()).filter(t=>!!t&&t.length>0):["gpt-4o-mini"],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase}};let Oe;const Ra=(r=[])=>{const e={};for(const t of r)if(t.startsWith("--")){const[o,s]=t.slice(2).split("="),[n,i]=o.split(".");n&&i&&n in De?(e[n]||(e[n]={}),e[n][i]=s):e[o]=s}return e},Da=()=>{const r=ke.homedir(),e=process.env.AICOMMIT_CONFIG_PATH,t=To,o=S.join(r,".aicommit2");return[e,t,o].filter(s=>!!s)},Ce=async()=>{const r=Da();for(const e of r)if(await Oo(e))return e;return To},Fe=async()=>{const r=await Ce();Oe=r;try{const e=await O.readFile(r,"utf8");return we.parse(e)}catch(e){return e.code==="ENOENT"?(Oe=void 0,{}):(console.error(`Error reading config file ${r}:`,e),Oe=void 0,{})}},ue=async(r,e=[])=>{const t=await Fe(),o=Ra(e),s={...r,...o},n={},i=Ia(t),l={};for(const d of i){const u=t[d]?.envKey||`${d}_API_KEY`,m=process.env[u];m&&(l[d]={key:m})}const a=(d,c)=>{const u=s[`${d}.${c}`]??s[d]?.[c],m=l[d]?.[c],p=t[d]?.[c],h=s[c]??t[c];return u!==void 0?u:m!==void 0?m:p!==void 0?p:h};for(const[d,c]of Object.entries(f)){const u=s[d]??t[d];n[d]=c(u)}for(const d of i){n[d]={};const c=De[d]||at(d);for(const[u,m]of Object.entries(c)){const p=a(d,u);n[d][u]=m(p)}}return n},Vt=async r=>{const e=await Fe();for(const[s,n]of r){const[i,l]=s.split(".");if(!l){const c=f[s];if(!c)throw new w(`Invalid config property: ${s}`);e[s]=c(n);continue}if(e[i]||(e[i]={}),ve.includes(i)){const c=De[i][l];if(!c)throw new w(`Invalid config property: ${s}`);e[i][l]=c(n);continue}if(!/^[A-Z][A-Z0-9_]*$/.test(i))throw new w(`Invalid service name: ${i}. Service names must be uppercase letters, numbers, and underscores.`);const d=at(i);if(!d[l])throw new w(`Invalid config property for custom service: ${s}`);try{e[i][l]=d[l](n)}catch(c){throw c instanceof w?c:new w(`Invalid value for ${s}: ${c.message}`)}}const t=await Ce(),o=S.dirname(t);await O.mkdir(o,{recursive:!0}),await O.writeFile(t,we.stringify(e),"utf8")},Oa=async r=>{const e=await Fe();for(const[s,n]of r){const[i,l]=s.split("."),a=e[i];if(l==="model"){a||(e[i]={});const c=e[i][l]||[],u=typeof n=="string"?n.split(",").map(m=>m.trim()).filter(m=>!!m):n;e[i][l]=nt([...c,...u]);continue}if(a&&a.compatible===!0){a||(e[i]={});const c=at(i);if(!c[l])throw new w(`Invalid config property: ${s}`);try{e[i][l]=c[l](n)}catch(u){throw u instanceof w?u:new w(`Invalid value for ${s}: ${u.message}`)}continue}if(i in De){a||(e[i]={});const c=De[i][l];if(!c)throw new w(`Invalid config property: ${s}`);e[i][l]=c(n)}else{const c=at(i);if(!c[l])throw new w(`Invalid config property: ${s}`);e[i]||(e[i]={}),e[i][l]=c[l](n)}}const t=await Ce(),o=S.dirname(t);await O.mkdir(o,{recursive:!0}),await O.writeFile(t,we.stringify(e),"utf8")},Fa=async()=>{const r=await Fe();console.log(we.stringify(r))},La=async()=>{console.log(await Ce())},at=r=>({compatible:ie("compatible"),stream:ie("stream"),url:e=>e?(L(`${r}.url`,/^https?:\/\//.test(e),"Must be a valid URL"),e):"",path:e=>e||"",key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(o=>o.trim()).filter(o=>!!o&&o.length>0):[],systemPrompt:f.systemPrompt,systemPromptPath:f.systemPromptPath,codeReviewPromptPath:f.codeReviewPromptPath,timeout:f.timeout,temperature:f.temperature,maxTokens:f.maxTokens,logging:f.logging,locale:f.locale,generate:f.generate,type:f.type,maxLength:f.maxLength,includeBody:f.includeBody,topP:f.topP,codeReview:f.codeReview,disabled:f.disabled,watchMode:f.watchMode,disableLowerCase:f.disableLowerCase}),Le=new Map,de=(r,e,t)=>{const o=Or(0).update(e).digest("hex").substring(0,8),s=`${r}_${o}_${t}`;if(Le.has(s))return Le.get(s);const n=new Date,i=Na(n,r,e,t),l=`${re}/${i}`,a=H.createLogger({level:"info",format:H.format.combine(H.format.timestamp({format:"YYYY-MM-DDTHH:mm:ss.SSSZ"}),H.format.printf(({timestamp:d,level:c,message:u,...m})=>m&&Object.keys(m).length>0?`[${d}] ${c}: ${u} ${JSON.stringify(m,null,2)}`:`[${d}] ${c}: ${u}`)),transports:[new H.transports.File({filename:l})]});return a.info(`=== ${r.toUpperCase()} AI SERVICE LOG ===`),a.info(`Diff Hash: ${o}`),a.info(`Request Type: ${t.toUpperCase()}`),a.info(`Start Time: ${n.toISOString()}`),a.info("=".repeat(50)),a.info(""),Le.set(s,a),a},ja=r=>{const e={...r},t=["authorization","x-api-key","x-goog-api-key","api-key"];for(const o of t){const s=o.toLowerCase(),n=Object.keys(e).find(i=>i.toLowerCase()===s);n&&e[n]&&typeof e[n]=="string"&&(e[n].startsWith("Bearer ")?e[n]="Bearer [MASKED]":e[n]="[MASKED]")}return e},V=(r,e,t,o,s,n,i=!0)=>{if(!i)return;const l=de(t,r,e);l.info(`Making request to ${t} API with model: ${o}`),l.info(`Request URL: ${s}`),l.info("Request headers:",ja(n))},oe=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).info("Request payload:",o)},q=(r,e,t,o,s,n=!0)=>{if(!n)return;const i=de(t,r,e);i.info("System prompt:",{prompt:o}),i.info("User prompt:",{prompt:s})},X=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).info("Response received:",o)},G=(r,e,t,o,s=!0)=>{if(!s)return;de(t,r,e).error("API request failed:",o)},Y=(r,e,t,o,s,n=!0)=>{if(!n)return;const i=de(t,r,e);o?i.info(`Request completed successfully in ${o}ms`):i.info("Request completed successfully"),s&&i.info("Final processed response:",{response:s}),i.info(""),i.info("=".repeat(50)),i.info(`End Time: ${new Date().toISOString()}`),i.info("=== REQUEST COMPLETED ===")},Ta=(r,e,t,o,s,n,i,l=!0)=>{if(!l)return;const a=de(t,r,e);i?a.error(`Request failed after ${n}ms:`,{error:i}):(a.info(`Request completed in ${n}ms`),a.info("Response:",{response:s})),Y(r,e,t,n,s,l)},Na=(r,e,t,o)=>{const{year:s,month:n,day:i,hours:l,minutes:a,seconds:d}=_a(r),u=Or(0).update(t).digest("hex").substring(0,8),m=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,20);return o==="review"?`${s}-${n}-${i}_${l}-${a}-${d}_${u}_${m}_review.log`:`${s}-${n}-${i}_${l}-${a}-${d}_${u}_${m}_commit.log`},_a=r=>{const e=r.getFullYear().toString(),t=(r.getMonth()+1).toString().padStart(2,"0"),o=r.getDate().toString().padStart(2,"0"),s=r.getHours().toString().padStart(2,"0"),n=r.getMinutes().toString().padStart(2,"0"),i=r.getSeconds().toString().padStart(2,"0");return{year:e,month:t,day:o,hours:s,minutes:n,seconds:i}},qt=()=>{for(const[r,e]of Le.entries())try{e.close()}catch(t){console.error(`Failed to close logger ${r}:`,t)}Le.clear()};process.on("exit",qt),process.on("SIGINT",()=>{qt(),process.exit(0)}),process.on("SIGTERM",()=>{qt(),process.exit(0)});let ct,Go="info";async function Ga(r){if(ct){console.warn("Logger already initialized. Skipping re-initialization.");return}const e=r?.logLevel||"info";Go=e;const t=r?.logFilePath||No,o=r?.exceptionLogFilePath||_o,s=r?.logging??!0;await Fo(S.dirname(t)),await Fo(S.dirname(o));const n=[];s?n.push(new H.transports.DailyRotateFile({filename:t,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",level:e,format:H.format.combine(H.format.timestamp(),H.format.printf(({level:i,message:l,timestamp:a})=>`[${a}] ${i}: ${l}`))})):n.push(new H.transports.Console({silent:!0})),ct=H.createLogger({level:e,format:H.format.json(),transports:n,exceptionHandlers:s?[new H.transports.DailyRotateFile({filename:o,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",format:H.format.combine(H.format.timestamp(),H.format.json())})]:[],exitOnError:!1,silent:!s})}const be=new Proxy({},{get:(r,e,t)=>{if(!ct)throw new Error("Logger not initialized. Call initializeLogger() first.");return Reflect.get(ct,e,t)}});function Ba(){const r=H.config.npm.levels;return(r[Go]??r.info)>=r.verbose}class Q{constructor(e){this.handleError$=t=>{const o=this.getDetailedErrorMessage(t),s=t.status?`HTTP ${t.status}: ${o}`:o;if(this.params.config.logging){const n=this.params.stagedDiff.diff,i=this.serviceName.replace(/\[|\]/g,"").trim();Ta(n,"commit",i,"Error occurred","",void 0,s)}return be.error(`${this.errorPrefix} ${s}`),t.stack&&be.error(` ${t.stack}`),t.content&&be.error(` Problematic content: ${t.content}`),t.originalError&&be.error(` Original error: ${t.originalError}`),bt({name:`${this.errorPrefix} ${s}`,value:s,isError:!0,disabled:!0})},this.serviceName="AI",this.errorPrefix="ERROR",this.colors={primary:""},this.params=e,this.logSessionId=e.logSessionId}getDetailedErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your API key configuration":t.includes("rate_limit")||t.includes("Rate limit")||t.includes("429")||t.includes("Too Many Requests")?"Rate limit exceeded. Wait a moment and try again, or upgrade your plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the model name is correct":t.includes("timeout")||t.includes("Timeout")?"Request timed out. Try again or increase the timeout setting":t.includes("network")||t.includes("connection")||t.includes("ECONNREFUSED")?"Network error. Check your internet connection and try again":t.includes("quota")||t.includes("usage")||t.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your usage limits":t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Your API key may be invalid or expired":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your model configuration":t.includes("500")||t.includes("Internal Server Error")?"Server error. Try again later":t.includes("overloaded")||t.includes("capacity")||t.includes("SERVICE_UNAVAILABLE")||t.includes("unavailable")?"Service is temporarily unavailable. Try again in a few minutes":this.getServiceSpecificErrorMessage(e)||t||"Unknown error occurred"}getServiceSpecificErrorMessage(e){return null}cleanJsonCodeBlock(e){const t=/```(?:json|JSON)?\s*([\s\S]*?)\s*```/,o=e.match(t);return o?o[1].trim():e}extractJsonFromResponse(e){let t=e.indexOf("[");if(t!==-1){const o=this.extractBalancedJson(e,t,"[","]");if(o)return o}if(t=e.indexOf("{"),t!==-1){const o=this.extractBalancedJson(e,t,"{","}");if(o)return o}return null}extractBalancedJson(e,t,o,s){let n=0,i=!1,l=!1;for(let a=t;a<e.length;a++){const d=e[a];if(l){l=!1;continue}if(d==="\\"&&i){l=!0;continue}if(d==='"'){i=!i;continue}if(!i&&(d===o&&n++,d===s&&n--,n===0))return e.slice(t,a+1)}return null}parseMessage(e,t,o){const s=this.cleanJsonCodeBlock(e),n=this.extractJsonFromResponse(s);if(!n){const u=new Error("AI response did not contain a valid JSON object or array.");throw u.name="InvalidJsonResponse",u.content=e,u}const i=xa(n);if(!i.ok){const u=new Error("Failed to parse AI response as JSON");throw u.name="JsonParseError",u.content=n,u.originalError=i.error,u}const l=i.data,a=Array.isArray(l)?l:[l];if(!a.length||!a.every(u=>typeof u.subject=="string")){const u=new Error("AI response contained malformed commit message data.");throw u.name="MalformedCommitMessage",u.content=e,u}const c=a.map(u=>this.extractMessageAsType(u,t)).map(u=>({title:`${u.subject}`,value:`${u.subject}${u.body?`
15
15
 
16
- ${p.body}`:""}${p.footer?`
16
+ ${u.body}`:""}${u.footer?`
17
17
 
18
- ${p.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const p=d.map(g=>g.title).join(", ");Ce.info(`${this.serviceName} Parsed ${d.length} commit messages: ${p}`)}return d}extractMessageAsType(e,t){switch(t){case"conventional":const o=/(\w+)(?:\(.*?\))?:\s*(.*)/,s=e.subject.match(o),n=s?s[0]:e.subject;return{...e,subject:this.normalizeCommitMessage(n)};case"gitmoji":const i=/:\w*:\s*(.*)/,c=e.subject.match(i),a=this.params.config.disableLowerCase??!1;return{...e,subject:c&&!a?c[0].toLowerCase():e.subject};default:return e}}normalizeCommitMessage(e){const t=/^(\w+)(\(.*?\))?:\s(.*)$/,o=e.match(t);if(o){const[,s,n,i]=o,c=this.params.config.disableLowerCase??!1,a=s.toLowerCase(),m=c?i:i.charAt(0).toLowerCase()+i.slice(1);e=`${a}${n||""}: ${m}`}return e}sanitizeResponse(e){if(typeof e=="string")try{return[{title:`${fo(e)}...`,value:e}]}catch{return[]}return e.map(t=>{try{return{title:`${fo(t)}...`,value:t}}catch{return{title:"",value:""}}})}isLoggingEnabled(){return this.params.config.logging&&!!this.logSessionId}}const W={locale:"en",maxLength:50,type:"conventional",generate:1,systemPrompt:"",systemPromptPath:"",codeReviewPromptPath:""},Ca={"":"<commit message>",conventional:`<type>(<optional scope>): <description>
18
+ ${u.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const u=c.map(m=>m.title).join(", ");be.info(`${this.serviceName} Parsed ${c.length} commit messages: ${u}`)}return c}extractMessageAsType(e,t){switch(t){case"conventional":const o=/(\w+)(?:\(.*?\))?:\s*(.*)/,s=e.subject.match(o),n=s?s[0]:e.subject;return{...e,subject:this.normalizeCommitMessage(n)};case"gitmoji":const i=/:\w*:\s*(.*)/,l=e.subject.match(i),a=this.params.config.disableLowerCase??!1;return{...e,subject:l&&!a?l[0].toLowerCase():e.subject};default:return e}}normalizeCommitMessage(e){const t=/^(\w+)(\(.*?\))?:\s(.*)$/,o=e.match(t);if(o){const[,s,n,i]=o,l=this.params.config.disableLowerCase??!1,a=s.toLowerCase(),d=l?i:i.charAt(0).toLowerCase()+i.slice(1);e=`${a}${n||""}: ${d}`}return e}sanitizeResponse(e){if(typeof e=="string")try{return[{title:`${Lo(e)}...`,value:e}]}catch{return[]}return e.map(t=>{try{return{title:`${Lo(t)}...`,value:t}}catch{return{title:"",value:""}}})}isLoggingEnabled(){return this.params.config.logging&&!!this.logSessionId}}const K={locale:"en",maxLength:50,type:"conventional",generate:1,systemPrompt:"",systemPromptPath:"",codeReviewPromptPath:""},Ha={"":"<commit message>",conventional:`<type>(<optional scope>): <description>
19
19
 
20
20
  [optional body]
21
21
 
@@ -23,13 +23,13 @@ ${p.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const p=d.map(g=>g.t
23
23
 
24
24
  [optional body]
25
25
 
26
- [optional footer(s)]`},Pa={"":"",gitmoji:`
26
+ [optional footer(s)]`},Ua={"":"",gitmoji:`
27
27
  ${Object.entries({":sparkles:":"Introduce new features.",":bug:":"Fix a bug.",":memo:":"Add or update documentation.",":art:":"Improve structure / format of the code.",":zap:":"Improve performance.",":fire:":"Remove code or files.",":ambulance:":"Critical hotfix.",":white_check_mark:":"Add, update, or pass tests.",":lock:":"Fix security or privacy issues.",":rocket:":"Deploy stuff.",":lipstick:":"Add or update the UI and style files.",":tada:":"Begin a project.",":recycle:":"Refactor code.",":wrench:":"Add or update configuration files.",":bulb:":"Add or update comments in source code.",":twisted_rightwards_arrows:":"Merge branches."}).map(([r,e])=>` - ${r}: ${e}`).join(`
28
28
  `)}`,conventional:`
29
29
  ${Object.entries({docs:"Documentation only changes",style:"Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",refactor:"A code change that neither fixes a bug nor adds a feature",perf:"A code change that improves performance",test:"Adding missing tests or correcting existing tests",build:"Changes that affect the build system or external dependencies",ci:"Changes to CI configuration files, scripts",chore:"Other changes that don't modify src or test files",revert:"Reverts a previous commit",feat:"A new feature",fix:"A bug fix"}).map(([r,e])=>` - ${r}: ${e}`).join(`
30
- `)}`},vo=(r,e)=>r.replace(/{(\w+)}/g,(t,o)=>e[o]?.toString()||W[o]?.toString()),Ea=(r,e)=>{const t=e.split("-")[0].toLowerCase(),o={conventional:{en:{subject:"fix(auth): fix bug in user authentication process",body:"- Update login function to handle edge cases\\n- Add additional error logging for debugging"},zh:{subject:"fix(auth): \u4FEE\u590D\u7528\u6237\u8BA4\u8BC1\u8FC7\u7A0B\u4E2D\u7684\u9519\u8BEF",body:"- \u66F4\u65B0\u767B\u5F55\u51FD\u6570\u4EE5\u5904\u7406\u8FB9\u7F18\u60C5\u51B5\\n- \u6DFB\u52A0\u989D\u5916\u7684\u9519\u8BEF\u65E5\u5FD7\u7528\u4E8E\u8C03\u8BD5"},ja:{subject:"fix(auth): \u30E6\u30FC\u30B6\u30FC\u8A8D\u8A3C\u30D7\u30ED\u30BB\u30B9\u306E\u30D0\u30B0\u3092\u4FEE\u6B63",body:"- \u30A8\u30C3\u30B8\u30B1\u30FC\u30B9\u3092\u51E6\u7406\u3059\u308B\u305F\u3081\u306B\u30ED\u30B0\u30A4\u30F3\u6A5F\u80FD\u3092\u66F4\u65B0\\n- \u30C7\u30D0\u30C3\u30B0\u7528\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC\u30ED\u30B0\u3092\u8FFD\u52A0"},ko:{subject:"fix(auth): \uC0AC\uC6A9\uC790 \uC778\uC99D \uD504\uB85C\uC138\uC2A4\uC758 \uBC84\uADF8 \uC218\uC815",body:"- \uC5E3\uC9C0 \uCF00\uC774\uC2A4\uB97C \uCC98\uB9AC\uD558\uB3C4\uB85D \uB85C\uADF8\uC778 \uD568\uC218 \uC5C5\uB370\uC774\uD2B8\\n- \uB514\uBC84\uAE45\uC744 \uC704\uD55C \uCD94\uAC00 \uC624\uB958 \uB85C\uAE45 \uCD94\uAC00"},es:{subject:"fix(auth): corregir error en el proceso de autenticaci\xF3n",body:"- Actualizar funci\xF3n de inicio de sesi\xF3n para manejar casos extremos\\n- Agregar registro de errores adicional para depuraci\xF3n"},fr:{subject:"fix(auth): corriger un bug dans le processus d'authentification",body:"- Mettre \xE0 jour la fonction de connexion pour g\xE9rer les cas limites\\n- Ajouter une journalisation d'erreurs suppl\xE9mentaire pour le d\xE9bogage"},de:{subject:"fix(auth): Fehler im Benutzerauthentifizierungsprozess beheben",body:"- Login-Funktion aktualisiert, um Randf\xE4lle zu behandeln\\n- Zus\xE4tzliche Fehlerprotokollierung f\xFCr Debugging hinzugef\xFCgt"}},gitmoji:{en:{subject:":sparkles: Add real-time chat feature",body:"- Implement WebSocket connection\\n- Add message encryption\\n- Include typing indicators"},zh:{subject:":sparkles: \u6DFB\u52A0\u5B9E\u65F6\u804A\u5929\u529F\u80FD",body:"- \u5B9E\u73B0WebSocket\u8FDE\u63A5\\n- \u6DFB\u52A0\u6D88\u606F\u52A0\u5BC6\\n- \u5305\u542B\u8F93\u5165\u6307\u793A\u5668"},ja:{subject:":sparkles: \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30C1\u30E3\u30C3\u30C8\u6A5F\u80FD\u3092\u8FFD\u52A0",body:"- WebSocket\u63A5\u7D9A\u3092\u5B9F\u88C5\\n- \u30E1\u30C3\u30BB\u30FC\u30B8\u6697\u53F7\u5316\u3092\u8FFD\u52A0\\n- \u5165\u529B\u30A4\u30F3\u30B8\u30B1\u30FC\u30BF\u30FC\u3092\u542B\u3080"},ko:{subject:":sparkles: \uC2E4\uC2DC\uAC04 \uCC44\uD305 \uAE30\uB2A5 \uCD94\uAC00",body:"- WebSocket \uC5F0\uACB0 \uAD6C\uD604\\n- \uBA54\uC2DC\uC9C0 \uC554\uD638\uD654 \uCD94\uAC00\\n- \uC785\uB825 \uD45C\uC2DC\uAE30 \uD3EC\uD568"},es:{subject:":sparkles: Agregar funci\xF3n de chat en tiempo real",body:"- Implementar conexi\xF3n WebSocket\\n- Agregar cifrado de mensajes\\n- Incluir indicadores de escritura"},fr:{subject:":sparkles: Ajouter une fonctionnalit\xE9 de chat en temps r\xE9el",body:"- Impl\xE9menter une connexion WebSocket\\n- Ajouter le chiffrement des messages\\n- Inclure des indicateurs de saisie"},de:{subject:":sparkles: Echtzeit-Chat-Funktion hinzuf\xFCgen",body:"- WebSocket-Verbindung implementieren\\n- Nachrichtenverschl\xFCsselung hinzuf\xFCgen\\n- Tippindikatoren einschlie\xDFen"}},"":{en:{subject:"",body:""}}},s=o[r]||o[""];return s[t]||s.en},bo=r=>{const{type:e,maxLength:t,generate:o,locale:s}=r,n="You are an expert Git commit message writer specializing in analyzing code changes and creating precise, meaningful commit messages.",i=`Your task is to generate exactly ${o} ${e} style commit message${o!==1?"s":""} based on the provided git diff.`;return[n,i,"",["## Requirements:",`1. Language: Write all messages in ${s}`,`2. Format: Strictly follow the ${e} commit format:`,`${Ca[e]}`,`3. Allowed Types:${Pa[e]}`,"","## Guidelines:",`- Subject line: Max ${t} characters, imperative mood, no period`,"- Analyze the diff to understand:"," * What files were changed"," * What functionality was added, modified, or removed"," * The scope and impact of changes","- For the commit type, choose based on:"," * feat: New functionality or feature"," * fix: Bug fixes or error corrections"," * refactor: Code restructuring without changing functionality"," * docs: Documentation changes only"," * style: Formatting, missing semi-colons, etc"," * test: Adding or modifying tests"," * chore: Maintenance tasks, dependency updates"," * perf: Performance improvements"," * build: Build system or external dependency changes"," * ci: CI configuration changes","- Scope: Extract from file paths or logical grouping (e.g., auth, api, ui)","- Body (when needed):"," * Explain the motivation for the change"," * Compare previous behavior with new behavior"," * Note any breaking changes or important details","- Footer: Include references to issues, breaking changes if applicable","","## Analysis Approach:","1. Identify the primary purpose of the changes","2. Group related changes together","3. Determine the most appropriate type and scope","4. Write a clear, concise subject line","5. Add body details for complex changes","","Remember: The commit message should help future developers understand WHY this change was made, not just WHAT was changed."].join(`
30
+ `)}`},Bo=(r,e)=>r.replace(/{(\w+)}/g,(t,o)=>e[o]?.toString()||K[o]?.toString()),za=(r,e)=>{const t=e.split("-")[0].toLowerCase(),o={conventional:{en:{subject:"fix(auth): fix bug in user authentication process",body:"- Update login function to handle edge cases\\n- Add additional error logging for debugging"},zh:{subject:"fix(auth): \u4FEE\u590D\u7528\u6237\u8BA4\u8BC1\u8FC7\u7A0B\u4E2D\u7684\u9519\u8BEF",body:"- \u66F4\u65B0\u767B\u5F55\u51FD\u6570\u4EE5\u5904\u7406\u8FB9\u7F18\u60C5\u51B5\\n- \u6DFB\u52A0\u989D\u5916\u7684\u9519\u8BEF\u65E5\u5FD7\u7528\u4E8E\u8C03\u8BD5"},ja:{subject:"fix(auth): \u30E6\u30FC\u30B6\u30FC\u8A8D\u8A3C\u30D7\u30ED\u30BB\u30B9\u306E\u30D0\u30B0\u3092\u4FEE\u6B63",body:"- \u30A8\u30C3\u30B8\u30B1\u30FC\u30B9\u3092\u51E6\u7406\u3059\u308B\u305F\u3081\u306B\u30ED\u30B0\u30A4\u30F3\u6A5F\u80FD\u3092\u66F4\u65B0\\n- \u30C7\u30D0\u30C3\u30B0\u7528\u306E\u8FFD\u52A0\u30A8\u30E9\u30FC\u30ED\u30B0\u3092\u8FFD\u52A0"},ko:{subject:"fix(auth): \uC0AC\uC6A9\uC790 \uC778\uC99D \uD504\uB85C\uC138\uC2A4\uC758 \uBC84\uADF8 \uC218\uC815",body:"- \uC5E3\uC9C0 \uCF00\uC774\uC2A4\uB97C \uCC98\uB9AC\uD558\uB3C4\uB85D \uB85C\uADF8\uC778 \uD568\uC218 \uC5C5\uB370\uC774\uD2B8\\n- \uB514\uBC84\uAE45\uC744 \uC704\uD55C \uCD94\uAC00 \uC624\uB958 \uB85C\uAE45 \uCD94\uAC00"},es:{subject:"fix(auth): corregir error en el proceso de autenticaci\xF3n",body:"- Actualizar funci\xF3n de inicio de sesi\xF3n para manejar casos extremos\\n- Agregar registro de errores adicional para depuraci\xF3n"},fr:{subject:"fix(auth): corriger un bug dans le processus d'authentification",body:"- Mettre \xE0 jour la fonction de connexion pour g\xE9rer les cas limites\\n- Ajouter une journalisation d'erreurs suppl\xE9mentaire pour le d\xE9bogage"},de:{subject:"fix(auth): Fehler im Benutzerauthentifizierungsprozess beheben",body:"- Login-Funktion aktualisiert, um Randf\xE4lle zu behandeln\\n- Zus\xE4tzliche Fehlerprotokollierung f\xFCr Debugging hinzugef\xFCgt"}},gitmoji:{en:{subject:":sparkles: Add real-time chat feature",body:"- Implement WebSocket connection\\n- Add message encryption\\n- Include typing indicators"},zh:{subject:":sparkles: \u6DFB\u52A0\u5B9E\u65F6\u804A\u5929\u529F\u80FD",body:"- \u5B9E\u73B0WebSocket\u8FDE\u63A5\\n- \u6DFB\u52A0\u6D88\u606F\u52A0\u5BC6\\n- \u5305\u542B\u8F93\u5165\u6307\u793A\u5668"},ja:{subject:":sparkles: \u30EA\u30A2\u30EB\u30BF\u30A4\u30E0\u30C1\u30E3\u30C3\u30C8\u6A5F\u80FD\u3092\u8FFD\u52A0",body:"- WebSocket\u63A5\u7D9A\u3092\u5B9F\u88C5\\n- \u30E1\u30C3\u30BB\u30FC\u30B8\u6697\u53F7\u5316\u3092\u8FFD\u52A0\\n- \u5165\u529B\u30A4\u30F3\u30B8\u30B1\u30FC\u30BF\u30FC\u3092\u542B\u3080"},ko:{subject:":sparkles: \uC2E4\uC2DC\uAC04 \uCC44\uD305 \uAE30\uB2A5 \uCD94\uAC00",body:"- WebSocket \uC5F0\uACB0 \uAD6C\uD604\\n- \uBA54\uC2DC\uC9C0 \uC554\uD638\uD654 \uCD94\uAC00\\n- \uC785\uB825 \uD45C\uC2DC\uAE30 \uD3EC\uD568"},es:{subject:":sparkles: Agregar funci\xF3n de chat en tiempo real",body:"- Implementar conexi\xF3n WebSocket\\n- Agregar cifrado de mensajes\\n- Incluir indicadores de escritura"},fr:{subject:":sparkles: Ajouter une fonctionnalit\xE9 de chat en temps r\xE9el",body:"- Impl\xE9menter une connexion WebSocket\\n- Ajouter le chiffrement des messages\\n- Inclure des indicateurs de saisie"},de:{subject:":sparkles: Echtzeit-Chat-Funktion hinzuf\xFCgen",body:"- WebSocket-Verbindung implementieren\\n- Nachrichtenverschl\xFCsselung hinzuf\xFCgen\\n- Tippindikatoren einschlie\xDFen"}},"":{en:{subject:"",body:""}}},s=o[r]||o[""];return s[t]||s.en},Ho=r=>{const{type:e,maxLength:t,generate:o,locale:s}=r,n="You are an expert Git commit message writer specializing in analyzing code changes and creating precise, meaningful commit messages.",i=`Your task is to generate exactly ${o} ${e} style commit message${o!==1?"s":""} based on the provided git diff.`;return[n,i,"",["## Requirements:",`1. Language: Write all messages in ${s}`,`2. Format: Strictly follow the ${e} commit format:`,`${Ha[e]}`,`3. Allowed Types:${Ua[e]}`,"","## Guidelines:",`- Subject line: Max ${t} characters, imperative mood, no period`,"- Analyze the diff to understand:"," * What files were changed"," * What functionality was added, modified, or removed"," * The scope and impact of changes","- For the commit type, choose based on:"," * feat: New functionality or feature"," * fix: Bug fixes or error corrections"," * refactor: Code restructuring without changing functionality"," * docs: Documentation changes only"," * style: Formatting, missing semi-colons, etc"," * test: Adding or modifying tests"," * chore: Maintenance tasks, dependency updates"," * perf: Performance improvements"," * build: Build system or external dependency changes"," * ci: CI configuration changes","- Scope: Extract from file paths or logical grouping (e.g., auth, api, ui)","- Body (when needed):"," * Explain the motivation for the change"," * Compare previous behavior with new behavior"," * Note any breaking changes or important details","- Footer: Include references to issues, breaking changes if applicable","","## Analysis Approach:","1. Identify the primary purpose of the changes","2. Group related changes together","3. Determine the most appropriate type and scope","4. Write a clear, concise subject line","5. Add body details for complex changes","","Remember: The commit message should help future developers understand WHY this change was made, not just WHAT was changed."].join(`
31
31
  `)].filter(Boolean).join(`
32
- `)},nt=(r,e,t)=>{const o=s=>{const n=Ea(s,t);return s==="conventional"||s==="gitmoji"?`${Array(e).fill(null).map((i,c)=>`
32
+ `)},lt=(r,e,t)=>{const o=s=>{const n=za(s,t);return s==="conventional"||s==="gitmoji"?`${Array(e).fill(null).map((i,l)=>`
33
33
  {
34
34
  "subject": "${n.subject}",
35
35
  "body": "${n.body}",
@@ -38,11 +38,11 @@ ${Object.entries({docs:"Documentation only changes",style:"Changes that do not a
38
38
  Lastly, Provide your response as a JSON array containing exactly ${e} object${e!==1?"s":""}, each with the following keys:`,`- "subject": The main commit message using the ${r} style. It should be a concise summary of the changes.`,'- "body": An optional detailed explanation of the changes. If not needed, use an empty string.','- "footer": An optional footer for metadata like BREAKING CHANGES. If not needed, use an empty string.',`The array must always contain ${e} element${e!==1?"s":""}, no more and no less.`,`Example response format:
39
39
  [${o(r)}
40
40
  ]`,`Ensure you generate exactly ${e} commit message${e!==1?"s":""}, even if it requires creating slightly varied versions for similar changes.`,"The response should be valid JSON that can be parsed without errors."].filter(Boolean).join(`
41
- `)},Q=r=>{const{systemPrompt:e,systemPromptPath:t,type:o,generate:s,locale:n}=r;if(e)return`${e}
42
- ${nt(o,s,n)}`;if(!t)return`${bo(r)}
43
- ${nt(o,s,n)}`;try{const i=U.readFileSync(rt(t),"utf-8");return`${vo(i,r)}
44
- ${nt(o,s,n)}`}catch{return`${bo(r)}
45
- ${nt(o,s,n)}`}},Z=r=>{const{codeReviewPromptPath:e,locale:t}=r,o=`I'll give you the output of the "git diff" command as an input. Please review the following code and provide your feedback in Markdown format. Focus on:
41
+ `)},Z=r=>{const{systemPrompt:e,systemPromptPath:t,type:o,generate:s,locale:n}=r;if(e)return`${e}
42
+ ${lt(o,s,n)}`;if(!t)return`${Ho(r)}
43
+ ${lt(o,s,n)}`;try{const i=W.readFileSync(it(t),"utf-8");return`${Bo(i,r)}
44
+ ${lt(o,s,n)}`}catch{return`${Ho(r)}
45
+ ${lt(o,s,n)}`}},ee=r=>{const{codeReviewPromptPath:e,locale:t}=r,o=`I'll give you the output of the "git diff" command as an input. Please review the following code and provide your feedback in Markdown format. Focus on:
46
46
 
47
47
  1. Language: ${t}
48
48
  2. Code quality and best practices
@@ -50,7 +50,7 @@ ${nt(o,s,n)}`}},Z=r=>{const{codeReviewPromptPath:e,locale:t}=r,o=`I'll give you
50
50
  4. Performance improvements
51
51
  5. Readability and maintainability
52
52
 
53
- Please structure your response with appropriate Markdown headings, code blocks, and bullet points.`;if(!e)return o;try{const s=U.readFileSync(rt(e),"utf-8");return`${vo(s,r)}`}catch{return o}},Co=async r=>{if(r.systemPromptPath)try{U.readFileSync(rt(r.systemPromptPath),"utf-8")}catch(e){throw new v(`Error reading system prompt file: ${r.systemPromptPath}, ${e}`)}if(r.codeReview&&r.codeReviewPromptPath)try{U.readFileSync(rt(r.codeReviewPromptPath),"utf-8")}catch(e){throw new v(`Error reading code review prompt file: ${r.codeReviewPromptPath}, ${e}`)}},Pe=(r,e="commit")=>e==="review"?`Please analyze the following diff and provide a comprehensive code review:
53
+ Please structure your response with appropriate Markdown headings, code blocks, and bullet points.`;if(!e)return o;try{const s=W.readFileSync(it(e),"utf-8");return`${Bo(s,r)}`}catch{return o}},Uo=async r=>{if(r.systemPromptPath)try{W.readFileSync(it(r.systemPromptPath),"utf-8")}catch(e){throw new w(`Error reading system prompt file: ${r.systemPromptPath}, ${e}`)}if(r.codeReview&&r.codeReviewPromptPath)try{W.readFileSync(it(r.codeReviewPromptPath),"utf-8")}catch(e){throw new w(`Error reading code review prompt file: ${r.codeReviewPromptPath}, ${e}`)}},Ee=(r,e="commit")=>e==="review"?`Please analyze the following diff and provide a comprehensive code review:
54
54
 
55
55
  \`\`\`diff
56
56
  ${r}
@@ -62,106 +62,156 @@ Focus on code quality, potential issues, and improvement suggestions.`:`Please a
62
62
  ${r}
63
63
  \`\`\`
64
64
 
65
- Focus on understanding the purpose and impact of these changes to create meaningful commit message(s).`,$a=10*60*1e3;class xa extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=C.red.bold("[Anthropic]"),this.anthropic=new fs({apiKey:this.params.config.key,...this.params.config.timeout>$a&&{timeout:this.params.config.timeout}})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Anthropic API key in configuration":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your Anthropic usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Claude model name is correct":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Claude model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Claude model configuration":t.includes("500")||t.includes("Internal Server Error")?"Anthropic server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:c,locale:a,generate:m,type:u,maxLength:l,maxTokens:d,topP:p,model:g}=this.params.config,h={...W,locale:a,maxLength:l,type:u,generate:m,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?Z(h):Q(h),w=Pe(t,e),P=`${this.params.config.url||"https://api.anthropic.com"}/v1/messages`,k={"Content-Type":"application/json","x-api-key":this.params.config.key,"anthropic-version":"2023-06-01"};V(t,e,"Anthropic",g,P,k,i),Y(t,e,"Anthropic",y,w,i);const A={max_tokens:d,temperature:c,system:y,messages:[{role:"user",content:w}],top_p:p,model:g};te(t,e,"Anthropic",A,i);const E=Date.now();try{const x=await this.anthropic.messages.create(A),$=Date.now()-E;q(t,e,"Anthropic",x,i);const N=x.content.map(({text:ae})=>ae).join("");return z(t,e,"Anthropic",$,N,i),e==="review"?this.sanitizeResponse(N):this.parseMessage(N,u,m)}catch(x){throw G(t,e,"Anthropic",x,i),x}}}class De{constructor(e={}){if(!e.method)throw new Error("method should be defined!");if(!e.baseURL)throw new Error("baseURL should be defined!");this.config={...e},this.axiosInstance=ps.create(this.config)}setHeaders(e){return this.config.headers=e,this}setParams(e){return this.config.params=e,this}setBody(e){return this.config.data=e,this}addBody(e){return this.config.data={...this.config.data,...e},this}setMethod(e){return this.config.method=e,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(e){throw e}}}class Aa extends X{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#e28c58",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Codestral]"),this.errorPrefix=C.red.bold("[Codestral]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Codestral API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Codestral plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Codestral model name is correct":t.includes("Invalid model type")?"Invalid model type. Use supported models: codestral-latest, codestral-2501":t.includes("overloaded")||t.includes("capacity")?"Codestral service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Codestral model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Codestral model configuration":t.includes("500")||t.includes("Internal Server Error")?"Codestral server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u}=this.params.config,l={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},d=e==="review"?Z(l):Q(l);this.checkAvailableModels();const p=Pe(t,e),h=`${this.params.config.url||"https://codestral.mistral.ai"}/v1/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"Codestral",this.params.config.model,h,y,i),Y(t,e,"Codestral",d,p,i);const w=await this.createChatCompletions(d,e);return e==="review"?this.sanitizeResponse(w):this.parseMessage(w,m,a)}checkAvailableModels(){if(["codestral-latest","codestral-2501"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of Codestral AI")}async createChatCompletions(e,t){const o=this.params.stagedDiff.diff,{logging:s}=this.params.config,n=this.params.config.url||"https://codestral.mistral.ai",i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:Pe(this.params.stagedDiff.diff,t)}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:et(10,1e3)};t==="commit"&&(i.response_format={type:"json_object"}),te(o,t,"Codestral",i,s);const c=Date.now();try{const m=await new De({method:"POST",baseURL:`${n}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),u=Date.now()-c,l=m.data;if(q(o,t,"Codestral",l,s),!l.choices||l.choices.length===0||!l.choices[0].message?.content)throw G(o,t,"Codestral",{message:"No Content on response",result:l},s),new Error("No Content on response. Please open a Bug report");const p=l.choices[0].message.content;return z(o,t,"Codestral",u,p,s),p}catch(a){throw G(o,t,"Codestral",a,s),a}}}class ka extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#D18EE2",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Cohere]"),this.errorPrefix=C.red.bold("[Cohere]"),this.cohere=new hs({token:this.params.config.key})}isValidCohereV2Response(e){const t=e;return t?.message?.content!==void 0&&Array.isArray(t.message.content)&&t.message.content.length>0&&typeof t.message.content[0]?.text=="string"}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Cohere API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Cohere plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Cohere model name is correct":t.includes("overloaded")||t.includes("capacity")?"Cohere service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Cohere model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Cohere model configuration":t.includes("500")||t.includes("Internal Server Error")?"Cohere server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:c,locale:a,generate:m,type:u,maxLength:l,maxTokens:d}=this.params.config,p={...W,locale:a,maxLength:l,type:u,generate:m,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},g=e==="review"?Z(p):Q(p),h=`Here is the diff: ${t}`,y=[...g?[{role:"system",content:g}]:[],{role:"user",content:h}],b=`${this.params.config.url}/v2/chat`;V(t,e,"Cohere",this.params.config.model,b,{},i),Y(t,e,"Cohere",g,h,i);const P={model:this.params.config.model,messages:y,max_tokens:d,temperature:c,seed:et(10,1e3),p:this.params.config.topP};te(t,e,"Cohere",P,i);const k=Date.now();try{const A=await this.cohere.chat(P,{timeoutInSeconds:Math.floor(this.params.config.timeout/1e3)}),E=Date.now()-k;if(!this.isValidCohereV2Response(A))throw new Error("Invalid response structure from Cohere v2 API");const x=A.message.content[0].text;return q(t,e,"Cohere",A,i),z(t,e,"Cohere",E,x,i),e==="review"?this.sanitizeResponse(x):this.parseMessage(x,u,m)}catch(A){throw G(t,e,"Cohere",A,i),A}}}class Sa extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#53a3f9",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[DeepSeek]"),this.errorPrefix=C.red.bold("[DeepSeek]");const t=this.params.config.url||"https://api.deepseek.com";this.deepSeek=new Er({baseURL:t,apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your DeepSeek API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your DeepSeek plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the DeepSeek model name is correct":t.includes("Invalid model type")?"Invalid model type. Use supported models: deepseek-reasoner, deepseek-chat":t.includes("overloaded")||t.includes("capacity")?"DeepSeek service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this DeepSeek model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your DeepSeek model configuration":t.includes("500")||t.includes("Internal Server Error")?"DeepSeek server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u}=this.params.config,l={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},d=e==="review"?Z(l):Q(l);this.checkAvailableModels();const p=Pe(t,e),h=`${this.params.config.url||"https://api.deepseek.com"}/chat/completions`,y={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,"DeepSeek",this.params.config.model,h,y,i),Y(t,e,"DeepSeek",d,p,i);const w=await this.createChatCompletions(d,p,e);return e==="review"?this.sanitizeResponse(w):this.parseMessage(w,m,a)}checkAvailableModels(){if(["deepseek-reasoner","deepseek-chat"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of DeepSeek")}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={messages:[{role:"system",content:e},{role:"user",content:t}],model:this.params.config.model,max_tokens:this.params.config.maxTokens,top_p:this.params.config.topP,temperature:this.params.config.temperature};te(s,o,"DeepSeek",i,n);const c=Date.now();try{const a=await this.deepSeek.chat.completions.create(i,{timeout:this.params.config.timeout}),m=Date.now()-c,u=a.choices?.[0];if(!u?.message)throw new Error("DeepSeek API returned invalid response structure");const l=u.message.content||u.message.reasoning_content||"";if(!l)throw new Error("DeepSeek API returned empty response");return q(s,o,"DeepSeek",a,n),z(s,o,"DeepSeek",m,l,n),l}catch(a){throw G(s,o,"DeepSeek",a,n),a}}}class Ma extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=C.red.bold("[Gemini]"),this.genAI=new gs(this.params.config.key)}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Google AI Studio API key in configuration":t.includes("quota")||t.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your Google AI Studio usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Gemini model name is correct":t.includes("SAFETY")||t.includes("safety")?"Content blocked by safety filters. Try rephrasing your request":t.includes("RECITATION")||t.includes("recitation")?"Content blocked due to recitation concerns. Try a different approach":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Gemini model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Gemini model configuration":t.includes("500")||t.includes("Internal Server Error")?"Google AI service error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,logging:n,locale:i,codeReviewPromptPath:c,generate:a,type:m,maxLength:u}=this.params.config,l=this.params.config.maxTokens,d={...W,locale:i,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:c},p=e==="review"?Z(d):Q(d),g={maxOutputTokens:l,temperature:this.params.config.temperature,topP:this.params.config.topP},h=this.genAI.getGenerativeModel({model:this.params.config.model,systemInstruction:p,generationConfig:g,safetySettings:[{category:He.HARM_CATEGORY_HATE_SPEECH,threshold:Ue.BLOCK_LOW_AND_ABOVE},{category:He.HARM_CATEGORY_SEXUALLY_EXPLICIT,threshold:Ue.BLOCK_LOW_AND_ABOVE},{category:He.HARM_CATEGORY_HARASSMENT,threshold:Ue.BLOCK_LOW_AND_ABOVE},{category:He.HARM_CATEGORY_DANGEROUS_CONTENT,threshold:Ue.BLOCK_LOW_AND_ABOVE}]}),y=Pe(t,e),b=`${this.params.config.url||"https://generativelanguage.googleapis.com"}/v1beta/models/${this.params.config.model}:generateContent`,P={"Content-Type":"application/json","x-goog-api-key":this.params.config.key};V(t,e,"Gemini",this.params.config.model,b,P,n),Y(t,e,"Gemini",p,y,n),te(t,e,"Gemini",{systemInstruction:{parts:[{text:p}]},contents:[{parts:[{text:y}]}],generationConfig:g},n);const A=Date.now();try{const E=this.params.config.timeout>1e4?{request:{timeout:this.params.config.timeout}}:void 0,x=await h.generateContent(y,E),N=x.response.text(),ae=Date.now()-A;return q(t,e,"Gemini",{response:N,candidates:x.response.candidates,usageMetadata:x.response.usageMetadata},n),z(t,e,"Gemini",ae,N,n),e==="review"?this.sanitizeResponse(N):this.parseMessage(N,m,a)}catch(E){throw G(t,e,"Gemini",E,n),E}}}var Ht={},Ut={exports:{}},Fe={exports:{}},zt,Po;function Ia(){if(Po)return zt;Po=1;var r=1e3,e=r*60,t=e*60,o=t*24,s=o*7,n=o*365.25;zt=function(u,l){l=l||{};var d=typeof u;if(d==="string"&&u.length>0)return i(u);if(d==="number"&&isFinite(u))return l.long?a(u):c(u);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(u))};function i(u){if(u=String(u),!(u.length>100)){var l=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(u);if(l){var d=parseFloat(l[1]),p=(l[2]||"ms").toLowerCase();switch(p){case"years":case"year":case"yrs":case"yr":case"y":return d*n;case"weeks":case"week":case"w":return d*s;case"days":case"day":case"d":return d*o;case"hours":case"hour":case"hrs":case"hr":case"h":return d*t;case"minutes":case"minute":case"mins":case"min":case"m":return d*e;case"seconds":case"second":case"secs":case"sec":case"s":return d*r;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return d;default:return}}}}function c(u){var l=Math.abs(u);return l>=o?Math.round(u/o)+"d":l>=t?Math.round(u/t)+"h":l>=e?Math.round(u/e)+"m":l>=r?Math.round(u/r)+"s":u+"ms"}function a(u){var l=Math.abs(u);return l>=o?m(u,l,o,"day"):l>=t?m(u,l,t,"hour"):l>=e?m(u,l,e,"minute"):l>=r?m(u,l,r,"second"):u+" ms"}function m(u,l,d,p){var g=l>=d*1.5;return Math.round(u/d)+" "+p+(g?"s":"")}return zt}var Wt,Eo;function $o(){if(Eo)return Wt;Eo=1;function r(e){o.debug=o,o.default=o,o.coerce=m,o.disable=c,o.enable=n,o.enabled=a,o.humanize=Ia(),o.destroy=u,Object.keys(e).forEach(l=>{o[l]=e[l]}),o.names=[],o.skips=[],o.formatters={};function t(l){let d=0;for(let p=0;p<l.length;p++)d=(d<<5)-d+l.charCodeAt(p),d|=0;return o.colors[Math.abs(d)%o.colors.length]}o.selectColor=t;function o(l){let d,p=null,g,h;function y(...w){if(!y.enabled)return;const b=y,P=Number(new Date),k=P-(d||P);b.diff=k,b.prev=d,b.curr=P,d=P,w[0]=o.coerce(w[0]),typeof w[0]!="string"&&w.unshift("%O");let A=0;w[0]=w[0].replace(/%([a-zA-Z%])/g,(x,$)=>{if(x==="%%")return"%";A++;const N=o.formatters[$];if(typeof N=="function"){const ae=w[A];x=N.call(b,ae),w.splice(A,1),A--}return x}),o.formatArgs.call(b,w),(b.log||o.log).apply(b,w)}return y.namespace=l,y.useColors=o.useColors(),y.color=o.selectColor(l),y.extend=s,y.destroy=o.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:()=>p!==null?p:(g!==o.namespaces&&(g=o.namespaces,h=o.enabled(l)),h),set:w=>{p=w}}),typeof o.init=="function"&&o.init(y),y}function s(l,d){const p=o(this.namespace+(typeof d>"u"?":":d)+l);return p.log=this.log,p}function n(l){o.save(l),o.namespaces=l,o.names=[],o.skips=[];const d=(typeof l=="string"?l:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(const p of d)p[0]==="-"?o.skips.push(p.slice(1)):o.names.push(p)}function i(l,d){let p=0,g=0,h=-1,y=0;for(;p<l.length;)if(g<d.length&&(d[g]===l[p]||d[g]==="*"))d[g]==="*"?(h=g,y=p,g++):(p++,g++);else if(h!==-1)g=h+1,y++,p=y;else return!1;for(;g<d.length&&d[g]==="*";)g++;return g===d.length}function c(){const l=[...o.names,...o.skips.map(d=>"-"+d)].join(",");return o.enable(""),l}function a(l){for(const d of o.skips)if(i(l,d))return!1;for(const d of o.names)if(i(l,d))return!0;return!1}function m(l){return l instanceof Error?l.stack||l.message:l}function u(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return o.enable(o.load()),o}return Wt=r,Wt}Fe.exports;var xo;function Ra(){return xo||(xo=1,function(r,e){e.formatArgs=o,e.save=s,e.load=n,e.useColors=t,e.storage=i(),e.destroy=(()=>{let a=!1;return()=>{a||(a=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function t(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let a;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(a=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(a[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function o(a){if(a[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+a[0]+(this.useColors?"%c ":" ")+"+"+r.exports.humanize(this.diff),!this.useColors)return;const m="color: "+this.color;a.splice(1,0,m,"color: inherit");let u=0,l=0;a[0].replace(/%[a-zA-Z%]/g,d=>{d!=="%%"&&(u++,d==="%c"&&(l=u))}),a.splice(l,0,m)}e.log=console.debug||console.log||(()=>{});function s(a){try{a?e.storage.setItem("debug",a):e.storage.removeItem("debug")}catch{}}function n(){let a;try{a=e.storage.getItem("debug")||e.storage.getItem("DEBUG")}catch{}return!a&&typeof process<"u"&&"env"in process&&(a=process.env.DEBUG),a}function i(){try{return localStorage}catch{}}r.exports=$o()(e);const{formatters:c}=r.exports;c.j=function(a){try{return JSON.stringify(a)}catch(m){return"[UnexpectedJSONParseError]: "+m.message}}}(Fe,Fe.exports)),Fe.exports}var Le={exports:{}},Kt,Ao;function Oa(){return Ao||(Ao=1,Kt=(r,e=process.argv)=>{const t=r.startsWith("-")?"":r.length===1?"-":"--",o=e.indexOf(t+r),s=e.indexOf("--");return o!==-1&&(s===-1||o<s)}),Kt}var Jt,ko;function Da(){if(ko)return Jt;ko=1;const r=xe,e=$r,t=Oa(),{env:o}=process;let s;t("no-color")||t("no-colors")||t("color=false")||t("color=never")?s=0:(t("color")||t("colors")||t("color=true")||t("color=always"))&&(s=1),"FORCE_COLOR"in o&&(o.FORCE_COLOR==="true"?s=1:o.FORCE_COLOR==="false"?s=0:s=o.FORCE_COLOR.length===0?1:Math.min(parseInt(o.FORCE_COLOR,10),3));function n(a){return a===0?!1:{level:a,hasBasic:!0,has256:a>=2,has16m:a>=3}}function i(a,m){if(s===0)return 0;if(t("color=16m")||t("color=full")||t("color=truecolor"))return 3;if(t("color=256"))return 2;if(a&&!m&&s===void 0)return 0;const u=s||0;if(o.TERM==="dumb")return u;if(process.platform==="win32"){const l=r.release().split(".");return Number(l[0])>=10&&Number(l[2])>=10586?Number(l[2])>=14931?3:2:1}if("CI"in o)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some(l=>l in o)||o.CI_NAME==="codeship"?1:u;if("TEAMCITY_VERSION"in o)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0;if(o.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in o){const l=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return l>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(o.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)||"COLORTERM"in o?1:u}function c(a){const m=i(a,a&&a.isTTY);return n(m)}return Jt={supportsColor:c,stdout:n(i(!0,e.isatty(1))),stderr:n(i(!0,e.isatty(2)))},Jt}Le.exports;var So;function Fa(){return So||(So=1,function(r,e){const t=$r,o=gr;e.init=u,e.log=c,e.formatArgs=n,e.save=a,e.load=m,e.useColors=s,e.destroy=o.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),e.colors=[6,2,3,4,5,1];try{const d=Da();d&&(d.stderr||d).level>=2&&(e.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch{}e.inspectOpts=Object.keys(process.env).filter(d=>/^debug_/i.test(d)).reduce((d,p)=>{const g=p.substring(6).toLowerCase().replace(/_([a-z])/g,(y,w)=>w.toUpperCase());let h=process.env[p];return/^(yes|on|true|enabled)$/i.test(h)?h=!0:/^(no|off|false|disabled)$/i.test(h)?h=!1:h==="null"?h=null:h=Number(h),d[g]=h,d},{});function s(){return"colors"in e.inspectOpts?!!e.inspectOpts.colors:t.isatty(process.stderr.fd)}function n(d){const{namespace:p,useColors:g}=this;if(g){const h=this.color,y="\x1B[3"+(h<8?h:"8;5;"+h),w=` ${y};1m${p} \x1B[0m`;d[0]=w+d[0].split(`
65
+ Focus on understanding the purpose and impact of these changes to create meaningful commit message(s).`,Wa=10*60*1e3;class Ya extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=C.red.bold("[Anthropic]"),this.anthropic=new Is({apiKey:this.params.config.key,...this.params.config.timeout>Wa&&{timeout:this.params.config.timeout}})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Anthropic API key in configuration":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your Anthropic usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Claude model name is correct":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Claude model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Claude model configuration":t.includes("500")||t.includes("Internal Server Error")?"Anthropic server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:l,locale:a,generate:d,type:c,maxLength:u,maxTokens:m,topP:p,model:h}=this.params.config,g={...K,locale:a,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?ee(g):Z(g),v=Ee(t,e),E=`${this.params.config.url||"https://api.anthropic.com"}/v1/messages`,x={"Content-Type":"application/json","x-api-key":this.params.config.key,"anthropic-version":"2023-06-01"};V(t,e,"Anthropic",h,E,x,i),q(t,e,"Anthropic",y,v,i);const A={max_tokens:m,temperature:l,system:y,messages:[{role:"user",content:v}],top_p:p,model:h};oe(t,e,"Anthropic",A,i);const P=Date.now();try{const $=await this.anthropic.messages.create(A),k=Date.now()-P;X(t,e,"Anthropic",$,i);const I=$.content.map(({text:_})=>_).join("");return Y(t,e,"Anthropic",k,I,i),e==="review"?this.sanitizeResponse(I):this.parseMessage(I,c,d)}catch($){throw G(t,e,"Anthropic",$,i),$}}}class je{constructor(e={}){if(!e.method)throw new Error("method should be defined!");if(!e.baseURL)throw new Error("baseURL should be defined!");this.config={...e},this.axiosInstance=Rs.create(this.config)}setHeaders(e){return this.config.headers=e,this}setParams(e){return this.config.params=e,this}setBody(e){return this.config.data=e,this}addBody(e){return this.config.data={...this.config.data,...e},this}setMethod(e){return this.config.method=e,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(e){throw e}}}class Ka extends Q{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#e28c58",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Codestral]"),this.errorPrefix=C.red.bold("[Codestral]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Codestral API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Codestral plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Codestral model name is correct":t.includes("Invalid model type")?"Invalid model type. Use supported models: codestral-latest, codestral-2501":t.includes("overloaded")||t.includes("capacity")?"Codestral service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Codestral model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Codestral model configuration":t.includes("500")||t.includes("Internal Server Error")?"Codestral server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c}=this.params.config,u={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},m=e==="review"?ee(u):Z(u);this.checkAvailableModels();const p=Ee(t,e),g=`${this.params.config.url||"https://codestral.mistral.ai"}/v1/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"Codestral",this.params.config.model,g,y,i),q(t,e,"Codestral",m,p,i);const v=await this.createChatCompletions(m,e);return e==="review"?this.sanitizeResponse(v):this.parseMessage(v,d,a)}checkAvailableModels(){if(["codestral-latest","codestral-2501"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of Codestral AI")}async createChatCompletions(e,t){const o=this.params.stagedDiff.diff,{logging:s}=this.params.config,n=this.params.config.url||"https://codestral.mistral.ai",i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:Ee(this.params.stagedDiff.diff,t)}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:st(10,1e3)};t==="commit"&&(i.response_format={type:"json_object"}),oe(o,t,"Codestral",i,s);const l=Date.now();try{const d=await new je({method:"POST",baseURL:`${n}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),c=Date.now()-l,u=d.data;if(X(o,t,"Codestral",u,s),!u.choices||u.choices.length===0||!u.choices[0].message?.content)throw G(o,t,"Codestral",{message:"No Content on response",result:u},s),new Error("No Content on response. Please open a Bug report");const p=u.choices[0].message.content;return Y(o,t,"Codestral",c,p,s),p}catch(a){throw G(o,t,"Codestral",a,s),a}}}class Ja extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#D18EE2",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Cohere]"),this.errorPrefix=C.red.bold("[Cohere]"),this.cohere=new Ds({token:this.params.config.key})}isValidCohereV2Response(e){const t=e;return t?.message?.content!==void 0&&Array.isArray(t.message.content)&&t.message.content.length>0&&typeof t.message.content[0]?.text=="string"}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Cohere API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Cohere plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Cohere model name is correct":t.includes("overloaded")||t.includes("capacity")?"Cohere service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Cohere model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Cohere model configuration":t.includes("500")||t.includes("Internal Server Error")?"Cohere server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:l,locale:a,generate:d,type:c,maxLength:u,maxTokens:m}=this.params.config,p={...K,locale:a,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},h=e==="review"?ee(p):Z(p),g=`Here is the diff: ${t}`,y=[...h?[{role:"system",content:h}]:[],{role:"user",content:g}],b=`${this.params.config.url}/v2/chat`;V(t,e,"Cohere",this.params.config.model,b,{},i),q(t,e,"Cohere",h,g,i);const E={model:this.params.config.model,messages:y,max_tokens:m,temperature:l,seed:st(10,1e3),p:this.params.config.topP};oe(t,e,"Cohere",E,i);const x=Date.now();try{const A=await this.cohere.chat(E,{timeoutInSeconds:Math.floor(this.params.config.timeout/1e3)}),P=Date.now()-x;if(!this.isValidCohereV2Response(A))throw new Error("Invalid response structure from Cohere v2 API");const $=A.message.content[0].text;return X(t,e,"Cohere",A,i),Y(t,e,"Cohere",P,$,i),e==="review"?this.sanitizeResponse($):this.parseMessage($,c,d)}catch(A){throw G(t,e,"Cohere",A,i),A}}}class Va extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#53a3f9",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[DeepSeek]"),this.errorPrefix=C.red.bold("[DeepSeek]");const t=this.params.config.url||"https://api.deepseek.com";this.deepSeek=new Fr({baseURL:t,apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your DeepSeek API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your DeepSeek plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the DeepSeek model name is correct":t.includes("Invalid model type")?"Invalid model type. Use supported models: deepseek-reasoner, deepseek-chat":t.includes("overloaded")||t.includes("capacity")?"DeepSeek service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this DeepSeek model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your DeepSeek model configuration":t.includes("500")||t.includes("Internal Server Error")?"DeepSeek server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c}=this.params.config,u={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},m=e==="review"?ee(u):Z(u);this.checkAvailableModels();const p=Ee(t,e),g=`${this.params.config.url||"https://api.deepseek.com"}/chat/completions`,y={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,"DeepSeek",this.params.config.model,g,y,i),q(t,e,"DeepSeek",m,p,i);const v=await this.createChatCompletions(m,p,e);return e==="review"?this.sanitizeResponse(v):this.parseMessage(v,d,a)}checkAvailableModels(){if(["deepseek-reasoner","deepseek-chat"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of DeepSeek")}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={messages:[{role:"system",content:e},{role:"user",content:t}],model:this.params.config.model,max_tokens:this.params.config.maxTokens,top_p:this.params.config.topP,temperature:this.params.config.temperature};oe(s,o,"DeepSeek",i,n);const l=Date.now();try{const a=await this.deepSeek.chat.completions.create(i,{timeout:this.params.config.timeout}),d=Date.now()-l,c=a.choices?.[0];if(!c?.message)throw new Error("DeepSeek API returned invalid response structure");const u=c.message.content||c.message.reasoning_content||"";if(!u)throw new Error("DeepSeek API returned empty response");return X(s,o,"DeepSeek",a,n),Y(s,o,"DeepSeek",d,u,n),u}catch(a){throw G(s,o,"DeepSeek",a,n),a}}}class qa extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=C.red.bold("[Gemini]"),this.genAI=new Os(this.params.config.key)}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Google AI Studio API key in configuration":t.includes("quota")||t.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your Google AI Studio usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Gemini model name is correct":t.includes("SAFETY")||t.includes("safety")?"Content blocked by safety filters. Try rephrasing your request":t.includes("RECITATION")||t.includes("recitation")?"Content blocked due to recitation concerns. Try a different approach":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Gemini model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Gemini model configuration":t.includes("500")||t.includes("Internal Server Error")?"Google AI service error. Try again later":t.includes("MAX_TOKENS")||t.includes("truncated")||t.includes("maxOutputTokens")?"Response truncated due to token limit. Gemini 2.5+ models use thinking tokens. Try increasing maxTokens (recommended: 8192+)":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,logging:n,locale:i,codeReviewPromptPath:l,generate:a,type:d,maxLength:c}=this.params.config,u=this.params.config.maxTokens,m={...K,locale:i,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:l},p=e==="review"?ee(m):Z(m),h={maxOutputTokens:u,temperature:this.params.config.temperature,topP:this.params.config.topP},g=this.genAI.getGenerativeModel({model:this.params.config.model,systemInstruction:p,generationConfig:h,safetySettings:[{category:We.HARM_CATEGORY_HATE_SPEECH,threshold:Ye.BLOCK_LOW_AND_ABOVE},{category:We.HARM_CATEGORY_SEXUALLY_EXPLICIT,threshold:Ye.BLOCK_LOW_AND_ABOVE},{category:We.HARM_CATEGORY_HARASSMENT,threshold:Ye.BLOCK_LOW_AND_ABOVE},{category:We.HARM_CATEGORY_DANGEROUS_CONTENT,threshold:Ye.BLOCK_LOW_AND_ABOVE}]}),y=Ee(t,e),b=`${this.params.config.url||"https://generativelanguage.googleapis.com"}/v1beta/models/${this.params.config.model}:generateContent`,E={"Content-Type":"application/json","x-goog-api-key":this.params.config.key};V(t,e,"Gemini",this.params.config.model,b,E,n),q(t,e,"Gemini",p,y,n),oe(t,e,"Gemini",{systemInstruction:{parts:[{text:p}]},contents:[{parts:[{text:y}]}],generationConfig:h},n);const A=Date.now();try{const P=this.params.config.timeout>1e4?{request:{timeout:this.params.config.timeout}}:void 0,$=await g.generateContent(y,P),k=$.response;if(k.candidates?.[0]?.finishReason==="MAX_TOKENS"){const xe=k.usageMetadata;throw new Error(`Response truncated: maxOutputTokens exceeded. Thinking tokens: ${xe?.thoughtsTokenCount??"N/A"}, Output tokens: ${xe?.candidatesTokenCount??"N/A"}. Increase maxTokens config for Gemini 2.5+ thinking models.`)}const _=k.text(),wt=Date.now()-A;return X(t,e,"Gemini",{response:_,candidates:$.response.candidates,usageMetadata:$.response.usageMetadata},n),Y(t,e,"Gemini",wt,_,n),e==="review"?this.sanitizeResponse(_):this.parseMessage(_,d,a)}catch(P){throw G(t,e,"Gemini",P,n),P}}}var Xt={},Qt={exports:{}},Te={exports:{}},Zt,zo;function Xa(){if(zo)return Zt;zo=1;var r=1e3,e=r*60,t=e*60,o=t*24,s=o*7,n=o*365.25;Zt=function(c,u){u=u||{};var m=typeof c;if(m==="string"&&c.length>0)return i(c);if(m==="number"&&isFinite(c))return u.long?a(c):l(c);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(c))};function i(c){if(c=String(c),!(c.length>100)){var u=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(c);if(u){var m=parseFloat(u[1]),p=(u[2]||"ms").toLowerCase();switch(p){case"years":case"year":case"yrs":case"yr":case"y":return m*n;case"weeks":case"week":case"w":return m*s;case"days":case"day":case"d":return m*o;case"hours":case"hour":case"hrs":case"hr":case"h":return m*t;case"minutes":case"minute":case"mins":case"min":case"m":return m*e;case"seconds":case"second":case"secs":case"sec":case"s":return m*r;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return m;default:return}}}}function l(c){var u=Math.abs(c);return u>=o?Math.round(c/o)+"d":u>=t?Math.round(c/t)+"h":u>=e?Math.round(c/e)+"m":u>=r?Math.round(c/r)+"s":c+"ms"}function a(c){var u=Math.abs(c);return u>=o?d(c,u,o,"day"):u>=t?d(c,u,t,"hour"):u>=e?d(c,u,e,"minute"):u>=r?d(c,u,r,"second"):c+" ms"}function d(c,u,m,p){var h=u>=m*1.5;return Math.round(c/m)+" "+p+(h?"s":"")}return Zt}var er,Wo;function Yo(){if(Wo)return er;Wo=1;function r(e){o.debug=o,o.default=o,o.coerce=d,o.disable=l,o.enable=n,o.enabled=a,o.humanize=Xa(),o.destroy=c,Object.keys(e).forEach(u=>{o[u]=e[u]}),o.names=[],o.skips=[],o.formatters={};function t(u){let m=0;for(let p=0;p<u.length;p++)m=(m<<5)-m+u.charCodeAt(p),m|=0;return o.colors[Math.abs(m)%o.colors.length]}o.selectColor=t;function o(u){let m,p=null,h,g;function y(...v){if(!y.enabled)return;const b=y,E=Number(new Date),x=E-(m||E);b.diff=x,b.prev=m,b.curr=E,m=E,v[0]=o.coerce(v[0]),typeof v[0]!="string"&&v.unshift("%O");let A=0;v[0]=v[0].replace(/%([a-zA-Z%])/g,($,k)=>{if($==="%%")return"%";A++;const I=o.formatters[k];if(typeof I=="function"){const _=v[A];$=I.call(b,_),v.splice(A,1),A--}return $}),o.formatArgs.call(b,v),(b.log||o.log).apply(b,v)}return y.namespace=u,y.useColors=o.useColors(),y.color=o.selectColor(u),y.extend=s,y.destroy=o.destroy,Object.defineProperty(y,"enabled",{enumerable:!0,configurable:!1,get:()=>p!==null?p:(h!==o.namespaces&&(h=o.namespaces,g=o.enabled(u)),g),set:v=>{p=v}}),typeof o.init=="function"&&o.init(y),y}function s(u,m){const p=o(this.namespace+(typeof m>"u"?":":m)+u);return p.log=this.log,p}function n(u){o.save(u),o.namespaces=u,o.names=[],o.skips=[];const m=(typeof u=="string"?u:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(const p of m)p[0]==="-"?o.skips.push(p.slice(1)):o.names.push(p)}function i(u,m){let p=0,h=0,g=-1,y=0;for(;p<u.length;)if(h<m.length&&(m[h]===u[p]||m[h]==="*"))m[h]==="*"?(g=h,y=p,h++):(p++,h++);else if(g!==-1)h=g+1,y++,p=y;else return!1;for(;h<m.length&&m[h]==="*";)h++;return h===m.length}function l(){const u=[...o.names,...o.skips.map(m=>"-"+m)].join(",");return o.enable(""),u}function a(u){for(const m of o.skips)if(i(u,m))return!1;for(const m of o.names)if(i(u,m))return!0;return!1}function d(u){return u instanceof Error?u.stack||u.message:u}function c(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return o.enable(o.load()),o}return er=r,er}Te.exports;var Ko;function Qa(){return Ko||(Ko=1,function(r,e){e.formatArgs=o,e.save=s,e.load=n,e.useColors=t,e.storage=i(),e.destroy=(()=>{let a=!1;return()=>{a||(a=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function t(){if(typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs))return!0;if(typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;let a;return typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&(a=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(a[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function o(a){if(a[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+a[0]+(this.useColors?"%c ":" ")+"+"+r.exports.humanize(this.diff),!this.useColors)return;const d="color: "+this.color;a.splice(1,0,d,"color: inherit");let c=0,u=0;a[0].replace(/%[a-zA-Z%]/g,m=>{m!=="%%"&&(c++,m==="%c"&&(u=c))}),a.splice(u,0,d)}e.log=console.debug||console.log||(()=>{});function s(a){try{a?e.storage.setItem("debug",a):e.storage.removeItem("debug")}catch{}}function n(){let a;try{a=e.storage.getItem("debug")||e.storage.getItem("DEBUG")}catch{}return!a&&typeof process<"u"&&"env"in process&&(a=process.env.DEBUG),a}function i(){try{return localStorage}catch{}}r.exports=Yo()(e);const{formatters:l}=r.exports;l.j=function(a){try{return JSON.stringify(a)}catch(d){return"[UnexpectedJSONParseError]: "+d.message}}}(Te,Te.exports)),Te.exports}var Ne={exports:{}},tr,Jo;function Za(){return Jo||(Jo=1,tr=(r,e=process.argv)=>{const t=r.startsWith("-")?"":r.length===1?"-":"--",o=e.indexOf(t+r),s=e.indexOf("--");return o!==-1&&(s===-1||o<s)}),tr}var rr,Vo;function ec(){if(Vo)return rr;Vo=1;const r=ke,e=Lr,t=Za(),{env:o}=process;let s;t("no-color")||t("no-colors")||t("color=false")||t("color=never")?s=0:(t("color")||t("colors")||t("color=true")||t("color=always"))&&(s=1),"FORCE_COLOR"in o&&(o.FORCE_COLOR==="true"?s=1:o.FORCE_COLOR==="false"?s=0:s=o.FORCE_COLOR.length===0?1:Math.min(parseInt(o.FORCE_COLOR,10),3));function n(a){return a===0?!1:{level:a,hasBasic:!0,has256:a>=2,has16m:a>=3}}function i(a,d){if(s===0)return 0;if(t("color=16m")||t("color=full")||t("color=truecolor"))return 3;if(t("color=256"))return 2;if(a&&!d&&s===void 0)return 0;const c=s||0;if(o.TERM==="dumb")return c;if(process.platform==="win32"){const u=r.release().split(".");return Number(u[0])>=10&&Number(u[2])>=10586?Number(u[2])>=14931?3:2:1}if("CI"in o)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some(u=>u in o)||o.CI_NAME==="codeship"?1:c;if("TEAMCITY_VERSION"in o)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0;if(o.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in o){const u=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return u>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(o.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)||"COLORTERM"in o?1:c}function l(a){const d=i(a,a&&a.isTTY);return n(d)}return rr={supportsColor:l,stdout:n(i(!0,e.isatty(1))),stderr:n(i(!0,e.isatty(2)))},rr}Ne.exports;var qo;function tc(){return qo||(qo=1,function(r,e){const t=Lr,o=kr;e.init=c,e.log=l,e.formatArgs=n,e.save=a,e.load=d,e.useColors=s,e.destroy=o.deprecate(()=>{},"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),e.colors=[6,2,3,4,5,1];try{const m=ec();m&&(m.stderr||m).level>=2&&(e.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch{}e.inspectOpts=Object.keys(process.env).filter(m=>/^debug_/i.test(m)).reduce((m,p)=>{const h=p.substring(6).toLowerCase().replace(/_([a-z])/g,(y,v)=>v.toUpperCase());let g=process.env[p];return/^(yes|on|true|enabled)$/i.test(g)?g=!0:/^(no|off|false|disabled)$/i.test(g)?g=!1:g==="null"?g=null:g=Number(g),m[h]=g,m},{});function s(){return"colors"in e.inspectOpts?!!e.inspectOpts.colors:t.isatty(process.stderr.fd)}function n(m){const{namespace:p,useColors:h}=this;if(h){const g=this.color,y="\x1B[3"+(g<8?g:"8;5;"+g),v=` ${y};1m${p} \x1B[0m`;m[0]=v+m[0].split(`
66
66
  `).join(`
67
- `+w),d.push(y+"m+"+r.exports.humanize(this.diff)+"\x1B[0m")}else d[0]=i()+p+" "+d[0]}function i(){return e.inspectOpts.hideDate?"":new Date().toISOString()+" "}function c(...d){return process.stderr.write(o.formatWithOptions(e.inspectOpts,...d)+`
68
- `)}function a(d){d?process.env.DEBUG=d:delete process.env.DEBUG}function m(){return process.env.DEBUG}function u(d){d.inspectOpts={};const p=Object.keys(e.inspectOpts);for(let g=0;g<p.length;g++)d.inspectOpts[p[g]]=e.inspectOpts[p[g]]}r.exports=$o()(e);const{formatters:l}=r.exports;l.o=function(d){return this.inspectOpts.colors=this.useColors,o.inspect(d,this.inspectOpts).split(`
69
- `).map(p=>p.trim()).join(" ")},l.O=function(d){return this.inspectOpts.colors=this.useColors,o.inspect(d,this.inspectOpts)}}(Le,Le.exports)),Le.exports}typeof process>"u"||process.type==="renderer"||process.browser===!0||process.__nwjs?Ut.exports=Ra():Ut.exports=Fa();var Vt=Ut.exports,Yt={};Object.defineProperty(Yt,"__esModule",{value:!0});function La(r){return function(e,t){return new Promise((o,s)=>{r.call(this,e,t,(n,i)=>{n?s(n):o(i)})})}}Yt.default=La;var Mo=_&&_.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};const Ta=hr,ja=Mo(Vt),Na=Mo(Yt),Te=ja.default("agent-base");function Ga(r){return!!r&&typeof r.addRequest=="function"}function qt(){const{stack:r}=new Error;return typeof r!="string"?!1:r.split(`
70
- `).some(e=>e.indexOf("(https.js:")!==-1||e.indexOf("node:https:")!==-1)}function it(r,e){return new it.Agent(r,e)}(function(r){class e extends Ta.EventEmitter{constructor(o,s){super();let n=s;typeof o=="function"?this.callback=o:o&&(n=o),this.timeout=null,n&&typeof n.timeout=="number"&&(this.timeout=n.timeout),this.maxFreeSockets=1,this.maxSockets=1,this.maxTotalSockets=1/0,this.sockets={},this.freeSockets={},this.requests={},this.options={}}get defaultPort(){return typeof this.explicitDefaultPort=="number"?this.explicitDefaultPort:qt()?443:80}set defaultPort(o){this.explicitDefaultPort=o}get protocol(){return typeof this.explicitProtocol=="string"?this.explicitProtocol:qt()?"https:":"http:"}set protocol(o){this.explicitProtocol=o}callback(o,s,n){throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`')}addRequest(o,s){const n=Object.assign({},s);typeof n.secureEndpoint!="boolean"&&(n.secureEndpoint=qt()),n.host==null&&(n.host="localhost"),n.port==null&&(n.port=n.secureEndpoint?443:80),n.protocol==null&&(n.protocol=n.secureEndpoint?"https:":"http:"),n.host&&n.path&&delete n.path,delete n.agent,delete n.hostname,delete n._defaultAgent,delete n.defaultPort,delete n.createConnection,o._last=!0,o.shouldKeepAlive=!1;let i=!1,c=null;const a=n.timeout||this.timeout,m=p=>{o._hadError||(o.emit("error",p),o._hadError=!0)},u=()=>{c=null,i=!0;const p=new Error(`A "socket" was not created for HTTP request before ${a}ms`);p.code="ETIMEOUT",m(p)},l=p=>{i||(c!==null&&(clearTimeout(c),c=null),m(p))},d=p=>{if(i)return;if(c!=null&&(clearTimeout(c),c=null),Ga(p)){Te("Callback returned another Agent instance %o",p.constructor.name),p.addRequest(o,n);return}if(p){p.once("free",()=>{this.freeSocket(p,n)}),o.onSocket(p);return}const g=new Error(`no Duplex stream was returned to agent-base for \`${o.method} ${o.path}\``);m(g)};if(typeof this.callback!="function"){m(new Error("`callback` is not defined"));return}this.promisifiedCallback||(this.callback.length>=3?(Te("Converting legacy callback function to promise"),this.promisifiedCallback=Na.default(this.callback)):this.promisifiedCallback=this.callback),typeof a=="number"&&a>0&&(c=setTimeout(u,a)),"port"in n&&typeof n.port!="number"&&(n.port=Number(n.port));try{Te("Resolving socket for %o request: %o",n.protocol,`${o.method} ${o.path}`),Promise.resolve(this.promisifiedCallback(o,n)).then(d,l)}catch(p){Promise.reject(p).catch(l)}}freeSocket(o,s){Te("Freeing socket %o %o",o.constructor.name,s),o.destroy()}destroy(){Te("Destroying agent %o",this.constructor.name)}}r.Agent=e,r.prototype=r.Agent.prototype})(it||(it={}));var _a=it,Xt={},Ba=_&&_.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Xt,"__esModule",{value:!0});const Ha=Ba(Vt),je=Ha.default("https-proxy-agent:parse-proxy-response");function Ua(r){return new Promise((e,t)=>{let o=0;const s=[];function n(){const l=r.read();l?u(l):r.once("readable",n)}function i(){r.removeListener("end",a),r.removeListener("error",m),r.removeListener("close",c),r.removeListener("readable",n)}function c(l){je("onclose had error %o",l)}function a(){je("onend")}function m(l){i(),je("onerror %o",l),t(l)}function u(l){s.push(l),o+=l.length;const d=Buffer.concat(s,o);if(d.indexOf(`\r
67
+ `+v),m.push(y+"m+"+r.exports.humanize(this.diff)+"\x1B[0m")}else m[0]=i()+p+" "+m[0]}function i(){return e.inspectOpts.hideDate?"":new Date().toISOString()+" "}function l(...m){return process.stderr.write(o.formatWithOptions(e.inspectOpts,...m)+`
68
+ `)}function a(m){m?process.env.DEBUG=m:delete process.env.DEBUG}function d(){return process.env.DEBUG}function c(m){m.inspectOpts={};const p=Object.keys(e.inspectOpts);for(let h=0;h<p.length;h++)m.inspectOpts[p[h]]=e.inspectOpts[p[h]]}r.exports=Yo()(e);const{formatters:u}=r.exports;u.o=function(m){return this.inspectOpts.colors=this.useColors,o.inspect(m,this.inspectOpts).split(`
69
+ `).map(p=>p.trim()).join(" ")},u.O=function(m){return this.inspectOpts.colors=this.useColors,o.inspect(m,this.inspectOpts)}}(Ne,Ne.exports)),Ne.exports}typeof process>"u"||process.type==="renderer"||process.browser===!0||process.__nwjs?Qt.exports=Qa():Qt.exports=tc();var or=Qt.exports,sr={};Object.defineProperty(sr,"__esModule",{value:!0});function rc(r){return function(e,t){return new Promise((o,s)=>{r.call(this,e,t,(n,i)=>{n?s(n):o(i)})})}}sr.default=rc;var Xo=B&&B.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};const oc=xr,sc=Xo(or),nc=Xo(sr),_e=sc.default("agent-base");function ic(r){return!!r&&typeof r.addRequest=="function"}function nr(){const{stack:r}=new Error;return typeof r!="string"?!1:r.split(`
70
+ `).some(e=>e.indexOf("(https.js:")!==-1||e.indexOf("node:https:")!==-1)}function ut(r,e){return new ut.Agent(r,e)}(function(r){class e extends oc.EventEmitter{constructor(o,s){super();let n=s;typeof o=="function"?this.callback=o:o&&(n=o),this.timeout=null,n&&typeof n.timeout=="number"&&(this.timeout=n.timeout),this.maxFreeSockets=1,this.maxSockets=1,this.maxTotalSockets=1/0,this.sockets={},this.freeSockets={},this.requests={},this.options={}}get defaultPort(){return typeof this.explicitDefaultPort=="number"?this.explicitDefaultPort:nr()?443:80}set defaultPort(o){this.explicitDefaultPort=o}get protocol(){return typeof this.explicitProtocol=="string"?this.explicitProtocol:nr()?"https:":"http:"}set protocol(o){this.explicitProtocol=o}callback(o,s,n){throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`')}addRequest(o,s){const n=Object.assign({},s);typeof n.secureEndpoint!="boolean"&&(n.secureEndpoint=nr()),n.host==null&&(n.host="localhost"),n.port==null&&(n.port=n.secureEndpoint?443:80),n.protocol==null&&(n.protocol=n.secureEndpoint?"https:":"http:"),n.host&&n.path&&delete n.path,delete n.agent,delete n.hostname,delete n._defaultAgent,delete n.defaultPort,delete n.createConnection,o._last=!0,o.shouldKeepAlive=!1;let i=!1,l=null;const a=n.timeout||this.timeout,d=p=>{o._hadError||(o.emit("error",p),o._hadError=!0)},c=()=>{l=null,i=!0;const p=new Error(`A "socket" was not created for HTTP request before ${a}ms`);p.code="ETIMEOUT",d(p)},u=p=>{i||(l!==null&&(clearTimeout(l),l=null),d(p))},m=p=>{if(i)return;if(l!=null&&(clearTimeout(l),l=null),ic(p)){_e("Callback returned another Agent instance %o",p.constructor.name),p.addRequest(o,n);return}if(p){p.once("free",()=>{this.freeSocket(p,n)}),o.onSocket(p);return}const h=new Error(`no Duplex stream was returned to agent-base for \`${o.method} ${o.path}\``);d(h)};if(typeof this.callback!="function"){d(new Error("`callback` is not defined"));return}this.promisifiedCallback||(this.callback.length>=3?(_e("Converting legacy callback function to promise"),this.promisifiedCallback=nc.default(this.callback)):this.promisifiedCallback=this.callback),typeof a=="number"&&a>0&&(l=setTimeout(c,a)),"port"in n&&typeof n.port!="number"&&(n.port=Number(n.port));try{_e("Resolving socket for %o request: %o",n.protocol,`${o.method} ${o.path}`),Promise.resolve(this.promisifiedCallback(o,n)).then(m,u)}catch(p){Promise.reject(p).catch(u)}}freeSocket(o,s){_e("Freeing socket %o %o",o.constructor.name,s),o.destroy()}destroy(){_e("Destroying agent %o",this.constructor.name)}}r.Agent=e,r.prototype=r.Agent.prototype})(ut||(ut={}));var ac=ut,ir={},cc=B&&B.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(ir,"__esModule",{value:!0});const lc=cc(or),Ge=lc.default("https-proxy-agent:parse-proxy-response");function uc(r){return new Promise((e,t)=>{let o=0;const s=[];function n(){const u=r.read();u?c(u):r.once("readable",n)}function i(){r.removeListener("end",a),r.removeListener("error",d),r.removeListener("close",l),r.removeListener("readable",n)}function l(u){Ge("onclose had error %o",u)}function a(){Ge("onend")}function d(u){i(),Ge("onerror %o",u),t(u)}function c(u){s.push(u),o+=u.length;const m=Buffer.concat(s,o);if(m.indexOf(`\r
71
71
  \r
72
- `)===-1){je("have not received end of HTTP headers yet..."),n();return}const g=d.toString("ascii",0,d.indexOf(`\r
73
- `)),h=+g.split(" ")[1];je("got proxy server response: %o",g),e({statusCode:h,buffered:d})}r.on("error",m),r.on("close",c),r.on("end",a),n()})}Xt.default=Ua;var za=_&&_.__awaiter||function(r,e,t,o){function s(n){return n instanceof t?n:new t(function(i){i(n)})}return new(t||(t=Promise))(function(n,i){function c(u){try{m(o.next(u))}catch(l){i(l)}}function a(u){try{m(o.throw(u))}catch(l){i(l)}}function m(u){u.done?n(u.value):s(u.value).then(c,a)}m((o=o.apply(r,e||[])).next())})},Ee=_&&_.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Ht,"__esModule",{value:!0});const Io=Ee(vs),Ro=Ee(bs),Wa=Ee(Cs),Ka=Ee(pr),Ja=Ee(Vt),Va=_a,Ya=Ee(Xt),Ne=Ja.default("https-proxy-agent:agent");class qa extends Va.Agent{constructor(e){let t;if(typeof e=="string"?t=Wa.default.parse(e):t=e,!t)throw new Error("an HTTP(S) proxy server `host` and `port` must be specified!");Ne("creating new HttpsProxyAgent instance: %o",t),super(t);const o=Object.assign({},t);this.secureProxy=t.secureProxy||Za(o.protocol),o.host=o.hostname||o.host,typeof o.port=="string"&&(o.port=parseInt(o.port,10)),!o.port&&o.host&&(o.port=this.secureProxy?443:80),this.secureProxy&&!("ALPNProtocols"in o)&&(o.ALPNProtocols=["http 1.1"]),o.host&&o.path&&(delete o.path,delete o.pathname),this.proxy=o}callback(e,t){return za(this,void 0,void 0,function*(){const{proxy:o,secureProxy:s}=this;let n;s?(Ne("Creating `tls.Socket`: %o",o),n=Ro.default.connect(o)):(Ne("Creating `net.Socket`: %o",o),n=Io.default.connect(o));const i=Object.assign({},o.headers);let a=`CONNECT ${`${t.host}:${t.port}`} HTTP/1.1\r
74
- `;o.auth&&(i["Proxy-Authorization"]=`Basic ${Buffer.from(o.auth).toString("base64")}`);let{host:m,port:u,secureEndpoint:l}=t;Qa(u,l)||(m+=`:${u}`),i.Host=m,i.Connection="close";for(const y of Object.keys(i))a+=`${y}: ${i[y]}\r
75
- `;const d=Ya.default(n);n.write(`${a}\r
76
- `);const{statusCode:p,buffered:g}=yield d;if(p===200){if(e.once("socket",Xa),t.secureEndpoint){Ne("Upgrading socket connection to TLS");const y=t.servername||t.host;return Ro.default.connect(Object.assign(Object.assign({},ec(t,"host","hostname","path","port")),{socket:n,servername:y}))}return n}n.destroy();const h=new Io.default.Socket({writable:!1});return h.readable=!0,e.once("socket",y=>{Ne("replaying proxy buffer for failed request"),Ka.default(y.listenerCount("data")>0),y.push(g),y.push(null)}),h})}}Ht.default=qa;function Xa(r){r.resume()}function Qa(r,e){return!!(!e&&r===80||e&&r===443)}function Za(r){return typeof r=="string"?/^https:?$/i.test(r):!1}function ec(r,...e){const t={};let o;for(o in r)e.includes(o)||(t[o]=r[o]);return t}var tc=_&&_.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};const Qt=tc(Ht);function Zt(r){return new Qt.default(r)}(function(r){r.HttpsProxyAgent=Qt.default,r.prototype=Qt.default.prototype})(Zt||(Zt={}));var rc=Zt,oc=me(rc);const sc=async(r,e,t,o,s,n,i)=>new Promise((c,a)=>{const m=JSON.stringify(o),l=(r.protocol.includes("https")?ws:ys).request({port:i||void 0,hostname:r.hostname,path:e,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(m),...t},timeout:s,agent:n?oc(n):void 0},d=>{const p=[];d.on("data",g=>p.push(g)),d.on("end",()=>{c({request:l,response:d,data:Buffer.concat(p).toString()})})});l.on("error",a),l.on("timeout",()=>{l.destroy(),a(new v(`Time out error: request took over ${s}ms. Try increasing the \`timeout\` config`))}),l.write(m),l.end()}),nc=async(r,e,t,o,s,n)=>{const i=new URL(r),{response:c,data:a}=await sc(i,e,{Authorization:`Bearer ${t}`},o,s,n);if(!c.statusCode||c.statusCode<200||c.statusCode>299){let m=`API Error: ${c.statusCode} - ${c.statusMessage}`;throw a&&(m+=`
72
+ `)===-1){Ge("have not received end of HTTP headers yet..."),n();return}const h=m.toString("ascii",0,m.indexOf(`\r
73
+ `)),g=+h.split(" ")[1];Ge("got proxy server response: %o",h),e({statusCode:g,buffered:m})}r.on("error",d),r.on("close",l),r.on("end",a),n()})}ir.default=uc;var dc=B&&B.__awaiter||function(r,e,t,o){function s(n){return n instanceof t?n:new t(function(i){i(n)})}return new(t||(t=Promise))(function(n,i){function l(c){try{d(o.next(c))}catch(u){i(u)}}function a(c){try{d(o.throw(c))}catch(u){i(u)}}function d(c){c.done?n(c.value):s(c.value).then(l,a)}d((o=o.apply(r,e||[])).next())})},Pe=B&&B.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(Xt,"__esModule",{value:!0});const Qo=Pe(js),Zo=Pe(Ts),mc=Pe(Ns),fc=Pe(Ar),pc=Pe(or),hc=ac,gc=Pe(ir),Be=pc.default("https-proxy-agent:agent");class yc extends hc.Agent{constructor(e){let t;if(typeof e=="string"?t=mc.default.parse(e):t=e,!t)throw new Error("an HTTP(S) proxy server `host` and `port` must be specified!");Be("creating new HttpsProxyAgent instance: %o",t),super(t);const o=Object.assign({},t);this.secureProxy=t.secureProxy||Cc(o.protocol),o.host=o.hostname||o.host,typeof o.port=="string"&&(o.port=parseInt(o.port,10)),!o.port&&o.host&&(o.port=this.secureProxy?443:80),this.secureProxy&&!("ALPNProtocols"in o)&&(o.ALPNProtocols=["http 1.1"]),o.host&&o.path&&(delete o.path,delete o.pathname),this.proxy=o}callback(e,t){return dc(this,void 0,void 0,function*(){const{proxy:o,secureProxy:s}=this;let n;s?(Be("Creating `tls.Socket`: %o",o),n=Zo.default.connect(o)):(Be("Creating `net.Socket`: %o",o),n=Qo.default.connect(o));const i=Object.assign({},o.headers);let a=`CONNECT ${`${t.host}:${t.port}`} HTTP/1.1\r
74
+ `;o.auth&&(i["Proxy-Authorization"]=`Basic ${Buffer.from(o.auth).toString("base64")}`);let{host:d,port:c,secureEndpoint:u}=t;vc(c,u)||(d+=`:${c}`),i.Host=d,i.Connection="close";for(const y of Object.keys(i))a+=`${y}: ${i[y]}\r
75
+ `;const m=gc.default(n);n.write(`${a}\r
76
+ `);const{statusCode:p,buffered:h}=yield m;if(p===200){if(e.once("socket",wc),t.secureEndpoint){Be("Upgrading socket connection to TLS");const y=t.servername||t.host;return Zo.default.connect(Object.assign(Object.assign({},bc(t,"host","hostname","path","port")),{socket:n,servername:y}))}return n}n.destroy();const g=new Qo.default.Socket({writable:!1});return g.readable=!0,e.once("socket",y=>{Be("replaying proxy buffer for failed request"),fc.default(y.listenerCount("data")>0),y.push(h),y.push(null)}),g})}}Xt.default=yc;function wc(r){r.resume()}function vc(r,e){return!!(!e&&r===80||e&&r===443)}function Cc(r){return typeof r=="string"?/^https:?$/i.test(r):!1}function bc(r,...e){const t={};let o;for(o in r)e.includes(o)||(t[o]=r[o]);return t}var Ec=B&&B.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};const ar=Ec(Xt);function cr(r){return new ar.default(r)}(function(r){r.HttpsProxyAgent=ar.default,r.prototype=ar.default.prototype})(cr||(cr={}));var Pc=cr,$c=me(Pc);const Ac=async(r,e,t,o,s,n,i)=>new Promise((l,a)=>{const d=JSON.stringify(o),u=(r.protocol.includes("https")?Ls:Fs).request({port:i||void 0,hostname:r.hostname,path:e,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(d),...t},timeout:s,agent:n?$c(n):void 0},m=>{const p=[];m.on("data",h=>p.push(h)),m.on("end",()=>{l({request:u,response:m,data:Buffer.concat(p).toString()})})});u.on("error",a),u.on("timeout",()=>{u.destroy(),a(new w(`Time out error: request took over ${s}ms. Try increasing the \`timeout\` config`))}),u.write(d),u.end()}),xc=async(r,e,t,o,s,n)=>{const i=new URL(r),{response:l,data:a}=await Ac(i,e,{Authorization:`Bearer ${t}`},o,s,n);if(!l.statusCode||l.statusCode<200||l.statusCode>299){let d=`API Error: ${l.statusCode} - ${l.statusMessage}`;throw a&&(d+=`
77
77
 
78
- ${a}`),c.statusCode===500&&(m+=`
78
+ ${a}`),l.statusCode===500&&(d+=`
79
79
 
80
- Check the API status: ${r}`),new v(m)}return JSON.parse(a)},Oo=r=>r.trim(),ic=["gpt-5","gpt-5-mini","gpt-5-nano","gpt-5-codex"],er=r=>ic.some(e=>r===e||r.startsWith(`${e}-`)),ac=async(r,e,t,o,s,n,i,c,a,m,u,l,d,p)=>{try{const g=Pe(n,d),h=er(s),y={model:s,messages:[{role:"system",content:u},{role:"user",content:g}],stream:!1,n:1,frequency_penalty:0,presence_penalty:0,...h?{max_completion_tokens:c,temperature:1}:{max_tokens:c,top_p:m,temperature:a}},w=new URL(e),b=`${w.protocol}//${w.host}${t}`,P={Authorization:`Bearer ${o}`,"Content-Type":"application/json"};V(n,d,r,s,b,P,l),Y(n,d,r,u,g,l),te(n,d,r,y,l);const k=Date.now(),A=await nc(e,t,o,y,i,p),E=Date.now()-k;q(n,d,r,A,l);const x=A.choices.filter($=>$.message?.content).map($=>Oo($.message.content)).join();return z(n,d,r,E,x,l),A.choices.filter($=>$.message?.content).map($=>Oo($.message.content))}catch(g){G(n,d,r,g,l);const h=g;throw h.code==="ENOTFOUND"?new v(`Error connecting to ${h.hostname} (${h.syscall})`):h}};class cc extends X{constructor(e){super(e),this.params=e,this.baseURL="https://models.github.ai",this.colors={primary:"#24292e",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[GitHub Models]"),this.errorPrefix=C.red.bold("[GitHub Models]")}getServiceSpecificErrorMessage(e){switch(e.code){case"MISSING_TOKEN":return"GitHub token is required. Run: aicommit2 github-login";case"AUTHENTICATION_FAILED":return"Authentication failed. Your GitHub token may be expired or invalid. Run: aicommit2 github-login";case"ACCESS_DENIED":return'Access denied. Make sure your GitHub token has "Models" permission in GitHub settings';case"NO_CONTENT":return"No content received from GitHub Models. The model may have failed to generate a response";default:return null}}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){if(!this.params.config.key){const p=new Error("GitHub token is required for GitHub Models. Use: aicommit2 github-login");throw p.code="MISSING_TOKEN",p}const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,locale:i,generate:c,type:a,maxLength:m}=this.params.config,u={...W,locale:i,maxLength:m,type:a,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},l=e==="review"?Z(u):Q(u),d=await this.makeRequest(l,t,e);return e==="review"?this.sanitizeResponse(d):this.parseMessage(d,a,c)}async makeRequest(e,t,o){const s=Array.isArray(this.params.config.model)?this.params.config.model[0]:this.params.config.model||"gpt-4o-mini",n=[{role:"system",content:e},{role:"user",content:o==="review"?t:`Here's the diff:
80
+ Check the API status: ${r}`),new w(d)}return JSON.parse(a)},es=r=>r.trim(),kc=["gpt-5","gpt-5-mini","gpt-5-nano","gpt-5-codex","o1","o1-mini","o1-pro","o3","o3-mini","o3-pro","o4-mini"],lr=r=>{const e=r.toLowerCase();return kc.some(t=>e===t||e.startsWith(`${t}-`))},Sc=async(r,e,t,o,s,n,i,l,a,d,c,u,m,p)=>{try{const h=Ee(n,m),g=lr(s),y={model:s,messages:[{role:"system",content:c},{role:"user",content:h}],stream:!1,n:1,frequency_penalty:0,presence_penalty:0,...g?{max_completion_tokens:l,temperature:1}:{max_tokens:l,top_p:d,temperature:a}},v=new URL(e),b=`${v.protocol}//${v.host}${t}`,E={Authorization:`Bearer ${o}`,"Content-Type":"application/json"};V(n,m,r,s,b,E,u),q(n,m,r,c,h,u),oe(n,m,r,y,u);const x=Date.now(),A=await xc(e,t,o,y,i,p),P=Date.now()-x;X(n,m,r,A,u);const $=A.choices.filter(k=>k.message?.content).map(k=>es(k.message.content)).join();return Y(n,m,r,P,$,u),A.choices.filter(k=>k.message?.content).map(k=>es(k.message.content))}catch(h){G(n,m,r,h,u);const g=h;throw g.code==="ENOTFOUND"?new w(`Error connecting to ${g.hostname} (${g.syscall})`):g}};class Mc extends Q{constructor(e){super(e),this.params=e,this.baseURL="https://models.github.ai",this.colors={primary:"#24292e",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[GitHub Models]"),this.errorPrefix=C.red.bold("[GitHub Models]")}getServiceSpecificErrorMessage(e){switch(e.code){case"MISSING_TOKEN":return"GitHub token is required. Run: aicommit2 github-login";case"AUTHENTICATION_FAILED":return"Authentication failed. Your GitHub token may be expired or invalid. Run: aicommit2 github-login";case"ACCESS_DENIED":return'Access denied. Make sure your GitHub token has "Models" permission in GitHub settings';case"NO_CONTENT":return"No content received from GitHub Models. The model may have failed to generate a response";default:return null}}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){if(!this.params.config.key){const p=new Error("GitHub token is required for GitHub Models. Use: aicommit2 github-login");throw p.code="MISSING_TOKEN",p}const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,locale:i,generate:l,type:a,maxLength:d}=this.params.config,c={...K,locale:i,maxLength:d,type:a,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},u=e==="review"?ee(c):Z(c),m=await this.makeRequest(u,t,e);return e==="review"?this.sanitizeResponse(m):this.parseMessage(m,a,l)}async makeRequest(e,t,o){const s=Array.isArray(this.params.config.model)?this.params.config.model[0]:this.params.config.model||"gpt-4o-mini",n=[{role:"system",content:e},{role:"user",content:o==="review"?t:`Here's the diff:
81
81
 
82
- ${t}`}],i=er(s),c={messages:n,model:s,stream:!1,...i?{max_completion_tokens:this.params.config.maxTokens||1024,temperature:1}:{max_tokens:this.params.config.maxTokens||1024,top_p:this.params.config.topP||.95,temperature:this.params.config.temperature||.7}},a=`${this.baseURL}/inference/chat/completions`,m={"Content-Type":"application/json",Accept:"application/vnd.github+json",Authorization:`Bearer ${this.params.config.key}`},{logging:u}=this.params.config;V(t,o,"GitHub Models",s,a,m,u),Y(t,o,"GitHub Models",e,o==="review"?t:`Here's the diff:
82
+ ${t}`}],i=lr(s),l={messages:n,model:s,stream:!1,...i?{max_completion_tokens:this.params.config.maxTokens||1024,temperature:1}:{max_tokens:this.params.config.maxTokens||1024,top_p:this.params.config.topP||.95,temperature:this.params.config.temperature||.7}},a=`${this.baseURL}/inference/chat/completions`,d={"Content-Type":"application/json",Accept:"application/vnd.github+json",Authorization:`Bearer ${this.params.config.key}`},{logging:c}=this.params.config;V(t,o,"GitHub Models",s,a,d,c),q(t,o,"GitHub Models",e,o==="review"?t:`Here's the diff:
83
83
 
84
- ${t}`,u),te(t,o,"GitHub Models",c,u);const l=new AbortController,d=setTimeout(()=>l.abort(),this.params.config.timeout);try{const p=Date.now(),g=await fetch(a,{method:"POST",headers:m,body:JSON.stringify(c),signal:l.signal});if(clearTimeout(d),!g.ok){const b=await g.text(),P={status:g.status,statusText:g.statusText,url:a,headers:Object.fromEntries(g.headers),body:b};G(t,o,"GitHub Models",P,u);let k=`GitHub API request failed: ${g.status} ${g.statusText}`;try{const E=JSON.parse(b);E.error?.message?k+=` - ${E.error.message}`:E.message&&(k+=` - ${E.message}`)}catch{b&&(k+=` - ${b}`)}if(g.status===401){const E=new Error("GitHub authentication failed. Please run: aicommit2 github-login");throw E.status=g.status,E.code="AUTHENTICATION_FAILED",E.content=b,E}else if(g.status===403){const E=new Error('GitHub Models access denied. Make sure your token has "Models" permission.');throw E.status=g.status,E.code="ACCESS_DENIED",E.content=b,E}else if(g.status===404){const E=new Error(`Model "${s}" not found. Please check the model name.`);throw E.status=g.status,E.code="MODEL_NOT_FOUND",E.content=b,E}else if(g.status===429){const E=new Error("Rate limit exceeded. Please try again later.");throw E.status=g.status,E.code="RATE_LIMIT_EXCEEDED",E.content=b,E}const A=new Error(k);throw A.status=g.status,A.code="API_ERROR",A.content=b,A}const h=await g.json(),y=Date.now()-p;q(t,o,"GitHub Models",h,u);const w=h.choices?.[0]?.message?.content?.trim();if(!w){G(t,o,"GitHub Models",{message:"No content found in GitHub Models response",result:h},u);const P=new Error("No response content received from GitHub Models");throw P.code="NO_CONTENT",P.content=JSON.stringify(h,null,2),P}return z(t,o,"GitHub Models",y,w,u),w}catch(p){if(clearTimeout(d),p instanceof Error&&p.name==="AbortError"){const y={message:`GitHub Models request timeout after ${this.params.config.timeout}ms`,error:p};G(t,o,"GitHub Models",y,u);const w=new Error(`GitHub Models request timed out after ${this.params.config.timeout}ms`);throw w.code="REQUEST_TIMEOUT",w.originalError=p,w}if(p.code)throw p;G(t,o,"GitHub Models",{message:"GitHub Models request failed",error:p},u);const h=new Error(`GitHub Models request failed: ${p instanceof Error?p.message:String(p)}`);throw h.code="REQUEST_FAILED",h.originalError=p,h}}}class lc extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#f55036",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Groq]"),this.errorPrefix=C.red.bold("[Groq]"),this.groq=new $s({apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Groq API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Groq plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Groq model name is correct":t.includes("overloaded")||t.includes("capacity")?"Groq service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Groq model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Groq model configuration":t.includes("500")||t.includes("Internal Server Error")?"Groq server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,temperature:a,generate:m,type:u,maxLength:l}=this.params.config,d=this.params.config.maxTokens,p={...W,locale:c,maxLength:l,type:u,generate:m,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},g=e==="review"?Z(p):Q(p),h=`Here is the diff: ${t}`,w=`${this.params.config.url||"https://api.groq.com"}/openai/v1/chat/completions`,b={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,"Groq",this.params.config.model,w,b,i),Y(t,e,"Groq",g,h,i);const P={messages:[{role:"system",content:g},{role:"user",content:h}],model:this.params.config.model,max_tokens:d,top_p:this.params.config.topP,temperature:a};te(t,e,"Groq",P,i);const k=Date.now();try{const A=await this.groq.chat.completions.create(P,{timeout:this.params.config.timeout}),E=Date.now()-k,x=A.choices[0].message.content||"";return q(t,e,"Groq",A,i),z(t,e,"Groq",E,x,i),e==="review"?this.sanitizeResponse(x):this.parseMessage(x,u,m)}catch(A){throw G(t,e,"Groq",A,i),A}}}class uc extends X{constructor(e){super(e),this.params=e,this.headers={},this.models=[],this.currentModelId=null,this.currentConversation=void 0,this.currentConversionID=void 0,this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=C.red.bold("[HuggingFace]"),this.cookie=this.params.config.cookie;const t=this.params.config.url||"https://huggingface.co";this.headers={accept:"*/*","accept-language":"en-US,en;q=0.9","sec-ch-ua":'"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin",origin:t,"Referrer-Policy":"strict-origin-when-cross-origin"}}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("cookie")||t.includes("Cookie")?"Invalid cookie. Check your Hugging Face session cookie in configuration":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Hugging Face model name is correct":t.includes("conversation")||t.includes("conversion")?"Failed to create conversation. Try again or check your session":t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Your Hugging Face session may have expired":t.includes("403")||t.includes("Forbidden")?"Access denied. You may not have permission to access this model":t.includes("404")||t.includes("Not Found")?"Model not found. Check your Hugging Face model configuration":t.includes("500")||t.includes("Internal Server Error")?"Hugging Face server error. Try again later":t.includes("overloaded")||t.includes("capacity")?"Hugging Face service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){await this.initialize();const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u,temperature:l,maxTokens:d,topP:p,timeout:g}=this.params.config,h={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?Z(h):Q(h),w=`Here is the diff: ${t}`,P=`${this.params.config.url||"https://huggingface.co"}/chat/conversation`,k={...this.headers,cookie:this.cookie};V(t,e,"HuggingFace",this.params.config.model,P,k,i),Y(t,e,"HuggingFace",y,w,i);const A=Date.now();try{const E=await this.getNewChat(y),$=await(await this.sendMessage(w,E.id)).completeResponsePromise();await this.deleteConversation(E.id);const N=Date.now()-A;return q(t,e,"HuggingFace",{response:$},i),z(t,e,"HuggingFace",N,$,i),e==="review"?this.sanitizeResponse($):this.parseMessage($,m,a)}catch(E){throw G(t,e,"HuggingFace",E,i),E}}async initialize(){const e=await this.getRemoteLlms(),t=e.find(o=>o.name?.toLowerCase()===this.params.config.model.toLowerCase());if(t){this.currentModel=t,this.currentModelId=t.id;return}this.currentModel=e[0],this.currentModelId=e[0].id}async getRemoteLlms(){const e=this.params.config.url||"https://huggingface.co",t=await fetch(`${e}/chat/__data.json`,{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if(t.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${t.status}`);const s=(await t.json()).nodes[0].data,n=s[s[0].models],i=[],c=a=>a===-1?null:s[a];for(const a of n){const m=s[a];if(s[m.unlisted])continue;const u={id:c(m.id),name:c(m.name),displayName:c(m.displayName),preprompt:c(m.preprompt),promptExamples:[],websiteUrl:c(m.websiteUrl),description:c(m.description),datasetName:c(m.datasetName),datasetUrl:c(m.datasetUrl),modelUrl:c(m.modelUrl),parameters:{}},l=c(m.promptExamples);if(l!==null){const g=l.map(h=>c(h));u.promptExamples=g.map(h=>({title:s[h.title],prompt:s[h.prompt]}))}const d=c(m.parameters),p={};for(const[g,h]of Object.entries(d)){if(h===-1){p[g]=null;continue}if(Array.isArray(s[h])){p[g]=s[h].map(y=>s[y]);continue}p[g]=s[h]}u.parameters=p,i.push(u)}return this.models=i,i}async getNewChat(e){const t={model:this.currentModelId,preprompt:e};let o=0;const s=this.params.config.url||"https://huggingface.co";for(;o<5;){const n=await fetch(`${s}/chat/conversation`,{headers:{...this.headers,"content-type":"application/json",cookie:this.cookie,Referer:`${s}/chat/`},body:JSON.stringify(t),method:"POST"}),{conversationId:i}=await n.json();if(i){this.currentConversionID=i;break}else o++}if(!this.currentConversionID)throw new Error("Failed to create new conversion");return await this.getConversationHistory(this.currentConversionID)}async getConversationHistory(e){if(!e)throw new Error("conversationId is required for getConversationHistory");const t=this.params.config.url||"https://huggingface.co",o=await fetch(`${t}/chat/conversation/${e}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:`${t}/chat/`},body:null,method:"GET"});if(o.status!=200)throw new Error("Unable get conversation details "+o);{const s=await o.json();return this.metadataParser(s,e)}}metadataParser(e,t){const o={id:"",model:"",systemPrompt:"",title:"",history:[]},s=e.nodes[1].data,n=s[s[0].model],i=s[s[0].preprompt],c=s[s[0].title],a=s[s[0].messages],m=[];for(const u of a){const l=s[u],d=new Date(s[l.createdAt][1]).getTime()/1e3,p=new Date(s[l.updatedAt][1]).getTime()/1e3;m.push({id:s[l.id],role:s[l.from],content:s[l.content],createdAt:d,updatedAt:p})}return o.id=t,o.model=n,o.systemPrompt=i,o.title=c,o.history=m,this.currentConversation=o,o}async sendMessage(e,t){if(e==="")throw new Error("the prompt can not be empty.");if(!t&&!this.currentConversionID?await this.getNewChat():t?(this.currentConversionID=t,await this.getConversationHistory(t)):this.currentConversionID&&await this.getConversationHistory(this.currentConversionID),!this.currentConversation)throw new Error("Failed to create new conversion");const o={inputs:e,id:this.currentConversation.history[this.currentConversation.history.length-1].id,is_retry:!1,is_continue:!1,web_search:!1,tools:[]},s=new FormData;s.append("data",JSON.stringify(o));const n=this.params.config.url||"https://huggingface.co",i=new AbortController,c=setTimeout(()=>i.abort(),this.params.config.timeout),a=await fetch(`${n}/chat/conversation/${this.currentConversionID}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${n}/chat/conversation/${this.currentConversionID}`},body:s,method:"POST",signal:i.signal});clearTimeout(c);function m(h){try{const y=h.split(`
85
- `),w=[];for(const b of y)b.trim()&&w.push(JSON.parse(b));return w}catch{return[{}]}}const u=new TextDecoder;let l="";const d=new TransformStream({async transform(h,y){const w=u.decode(h);try{const b=m(w);for(const P of b)P.type==="finalAnswer"?(l=P?.text||"",y.terminate()):P.type==="stream"&&y.enqueue(P?.token||"")}catch{throw new Error("Error during parsing response")}}}),p=a.body?.pipeThrough(d);async function g(){return new Promise(async(h,y)=>{try{if(!p)y("ModifiedStream undefined");else{const w=p.getReader();for(;;){const{done:b,value:P}=await w.read();if(b){h(l);break}}}}catch(w){y(w)}})}return{id:this.currentConversionID,stream:p,completeResponsePromise:g}}async deleteConversation(e){const t=this.params.config.url||"https://huggingface.co";return(await fetch(`${t}/chat/conversation/${e}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${t}/chat/`},body:null,method:"DELETE"})).json()}}class dc extends X{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#ff7000",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=C.red.bold("[MistralAI]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Mistral AI API key in configuration":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your Mistral AI usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Mistral model name is correct":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Mistral model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Mistral model configuration":t.includes("500")||t.includes("Internal Server Error")?"Mistral AI server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u}=this.params.config,l={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},d=e==="review"?Z(l):Q(l);await this.checkAvailableModels();const p=`Here is the diff: ${t}`,h=`${this.params.config.url||"https://api.mistral.ai"}/v1/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"MistralAI",this.params.config.model,h,y,i),Y(t,e,"MistralAI",d,p,i);const w=await this.createChatCompletions(d,p,e);return e==="review"?this.sanitizeResponse(w):this.parseMessage(w,m,a)}async checkAvailableModels(){if((await this.getAvailableModels()).includes(this.params.config.model))return!0;throw new Error(`Invalid model type of Mistral AI: ${this.params.config.model}`)}async getAvailableModels(){const e=this.params.config.url||"https://api.mistral.ai";return(await new De({method:"GET",baseURL:`${e}/v1/models`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).execute()).data.data.filter(o=>o.object==="model").map(o=>o.id)}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:t}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:et(10,1e3)};te(s,o,"MistralAI",i,n);const c=Date.now();try{const a=this.params.config.url||"https://api.mistral.ai",m=await new De({method:"POST",baseURL:`${a}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),u=Date.now()-c,l=m.data;if(q(s,o,"MistralAI",l,n),!l.choices||l.choices.length===0||!l.choices[0].message?.content)throw G(s,o,"MistralAI",{message:"No Content on response",result:l},n),new Error("No Content on response. Please open a Bug report");const p=l.choices[0].message.content;return z(s,o,"MistralAI",u,p,n),p}catch(a){throw G(s,o,"MistralAI",a,n),a}}}class mc extends X{constructor(e){super(e),this.params=e,this.host=Nt,this.model="",this.key="",this.auth="",this.setupFetch=(t,o={})=>As(t,{...o,dispatcher:new ks({headersTimeout:this.params.config.timeout})}),this.colors={primary:"#FFF",secondary:"#000"},this.model=this.params.keyName,this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${Ze(this.model)}]`),this.errorPrefix=C.red.bold(`[${Ze(this.model)}]`),this.host=this.params.config.host||Nt,this.auth=this.params.config.auth||"Bearer",this.key=this.params.config.key||"",this.ollama=new xs({host:this.host,fetch:this.setupFetch,...this.key&&{headers:{Authorization:`${this.auth} ${this.key}`}}})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("ECONNREFUSED")||t.includes("connection")?`Cannot connect to Ollama server at ${this.host}. Make sure Ollama is running`:t.includes("model")||t.includes("Model")?`Model '${this.model}' not found. Pull the model with: ollama pull ${this.model}`:t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Check your Ollama API key if authentication is enabled":t.includes("403")||t.includes("Forbidden")?"Access denied. Check your Ollama server permissions":t.includes("404")||t.includes("Not Found")?`Model '${this.model}' not found on Ollama server. Pull it first with: ollama pull ${this.model}`:t.includes("500")||t.includes("Internal Server Error")?"Ollama server error. Check server logs and try again":t.includes("overloaded")||t.includes("capacity")?"Ollama server is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u}=this.params.config,l={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},d=e==="review"?Z(l):Q(l);await this.checkIsAvailableOllama();const p=`Here is the diff: ${t}`,g=`Ollama_${this.model}`,h=`${this.host}/api/chat`,y=this.key?{Authorization:`${this.auth} ${this.key}`}:{};V(t,e,g,this.model,h,y,i),Y(t,e,g,d,p,i);const w=await this.createChatCompletions(d,p,e);return e==="review"?this.sanitizeResponse(w):this.parseMessage(w,m,a)}async checkIsAvailableOllama(){const e=new De({method:"GET",baseURL:`${this.host}`,timeout:this.params.config.timeout});return this.key&&e.setHeaders({Authorization:`${this.auth} ${this.key}`}),(await e.execute()).data}async createChatCompletions(e,t,o){const{stream:s,numCtx:n,temperature:i,topP:c,timeout:a,maxTokens:m,logging:u}=this.params.config,l=s||!1,d=this.params.stagedDiff.diff,p=`Ollama_${this.model}`,g={model:this.model,messages:[{role:"system",content:e},{role:"user",content:t}],stream:l,keep_alive:a,options:{num_ctx:n,temperature:i,top_p:c,seed:et(10,1e3),num_predict:m??-1}};te(d,o,p,g,u);const h=Date.now();try{const y=await this.ollama.chat(g),w=Date.now()-h;let b="";if(l){if(y)for await(const P of y)b+=P.message.content}else b=y.message.content;return q(d,o,p,{response:b,fullResponse:y},u),z(d,o,p,w,b,u),b}catch(y){throw G(d,o,p,y,u),y}}}class fc extends X{constructor(e){super(e),this.params=e;const t=this.params.keyName||"OPENAI_COMPATIBLE";this.colors=sa(t),this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${Ze(t)}]`),this.errorPrefix=C.red.bold(`[${Ze(t)}]`),this.openAI=new Er({apiKey:this.params.config.key,baseURL:`${this.params.config.url}${this.params.config.path}`})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your OpenAI-compatible API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or check your service limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the model name is correct":t.includes("network")||t.includes("connection")?"Network error. Check your internet connection and API endpoint":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your usage limits":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your API configuration":t.includes("500")||t.includes("Internal Server Error")?"Server error. Try again later":t.includes("overloaded")||t.includes("capacity")?"Service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,temperature:a,generate:m,type:u,maxLength:l,timeout:d,stream:p=!1}=this.params.config,g=this.params.config.maxTokens,h={...W,locale:c,maxLength:l,type:u,generate:m,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?Z(h):Q(h),w=`Here is the diff: ${t}`,b=this.params.keyName||"OpenAI-Compatible",P=`${this.params.config.url}${this.params.config.path}`,k={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,b,this.params.config.model,P,k,i),Y(t,e,b,y,w,i);const A=er(this.params.config.model),E={messages:[{role:"system",content:y},{role:"user",content:w}],model:this.params.config.model,stream:p,...A?{max_completion_tokens:g,temperature:1}:{max_tokens:g,top_p:this.params.config.topP,temperature:a}};te(t,e,b,E,i);const x=Date.now();try{const $=await this.openAI.chat.completions.create(E,{timeout:d});let N="";if(p&&$){const Jo=$;for await(const ur of Jo){const Vo=ur.choices?.[0]?.delta?.content||"",Yo=ur.choices?.[0]?.delta?.reasoning_content||"",qo=`${Vo}${Yo}`;N+=qo}}else N=$.choices?.[0]?.message.content||"";const ae=Date.now()-x;return q(t,e,b,$,i),z(t,e,b,ae,N,i),e==="review"?this.sanitizeResponse(N):this.parseMessage(N,u,m)}catch($){throw G(t,e,b,$,i),$}}}class pc extends X{constructor(e){super(e),this.params=e,this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=C.red.bold("[ChatGPT]")}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")?"Invalid API key. Check your OpenAI API key in configuration":t.includes("quota")?"API quota exceeded. Check your OpenAI usage limits":t.includes("500")?"OpenAI server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}extractJSONFromError(e){const t=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(t);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,temperature:i,logging:c,locale:a,generate:m,type:u,maxLength:l,proxy:d,maxTokens:p,timeout:g}=this.params.config,h={...W,locale:a,maxLength:l,type:u,generate:m,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?Z(h):Q(h),w=await ac("ChatGPT",this.params.config.url,this.params.config.path,this.params.config.key,this.params.config.model,t,g,p,i,this.params.config.topP,y,c,e,d);return tt(e==="review"?w.map(b=>this.sanitizeResponse(b)):w.map(b=>this.parseMessage(b,u,m)))}}class hc extends X{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#20808D",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Perplexity]"),this.errorPrefix=C.red.bold("[Perplexity]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Perplexity API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Perplexity plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Perplexity model name is correct":t.includes("overloaded")||t.includes("capacity")?"Perplexity service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Perplexity model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Perplexity model configuration":t.includes("500")||t.includes("Internal Server Error")?"Perplexity server error. Try again later":null}generateCommitMessage$(){return L(this.generateMessage("commit")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),R(this.handleError$))}generateCodeReview$(){return L(this.generateMessage("review")).pipe(F(e=>M(e)),I(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),R(this.handleError$))}extractJSONFromError(e){const t=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(t);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:c,generate:a,type:m,maxLength:u}=this.params.config,l={...W,locale:c,maxLength:u,type:m,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},d=e==="review"?Z(l):Q(l),p=`Here is the diff: ${t}`,h=`${this.params.config.url||"https://api.perplexity.ai"}/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"Perplexity",this.params.config.model,h,y,i),Y(t,e,"Perplexity",d,p,i);const w=await this.createChatCompletions(d,p,e);return this.parseMessage(w,m,a)}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:t}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1};te(s,o,"Perplexity",i,n);const c=Date.now();try{const a=this.params.config.url||"https://api.perplexity.ai",m=await new De({method:"POST",baseURL:`${a}/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),u=Date.now()-c,l=m.data;if(q(s,o,"Perplexity",l,n),!l.choices||l.choices.length===0||!l.choices[0].message?.content)throw G(s,o,"Perplexity",{message:"No Content on response",result:l},n),new Error("No Content on response. Please open a Bug report");const p=l.choices[0].message.content;return z(s,o,"Perplexity",u,p,n),p}catch(a){throw G(s,o,"Perplexity",a,n),a}}}class at{constructor(e,t){this.config=e,this.stagedDiff=t}createCommitMsgRequests$(e){return this.createServiceRequests$(e,"commit")}createCodeReviewRequests$(e){return this.createServiceRequests$(e,"review")}createServiceRequests$(e,t){return M(e).pipe(yr(o=>{const s=this.config[o],n=Array.isArray(s.model)?s.model:[s.model];return M(n).pipe(yr(i=>{if(s.compatible){const c=J.create(fc,{config:{...s,url:s.url||"",path:s.path||"",model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?c.generateCommitMessage$():c.generateCodeReview$()}switch(o){case"OPENAI":{const a=J.create(pc,{config:{...this.config.OPENAI,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GEMINI":{const a=J.create(Ma,{config:{...this.config.GEMINI,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"ANTHROPIC":{const a=J.create(xa,{config:{...this.config.ANTHROPIC,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"HUGGINGFACE":{const a=J.create(uc,{config:{...this.config.HUGGINGFACE,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"MISTRAL":{const a=J.create(dc,{config:{...this.config.MISTRAL,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"CODESTRAL":{const a=J.create(Aa,{config:{...this.config.CODESTRAL,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"OLLAMA":{const a=J.create(mc,{config:{...this.config.OLLAMA,model:i},keyName:i,stagedDiff:this.stagedDiff});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"COHERE":{const a=J.create(ka,{config:{...this.config.COHERE,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GROQ":{const a=J.create(lc,{config:{...this.config.GROQ,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"PERPLEXITY":{const a=J.create(hc,{config:{...this.config.PERPLEXITY,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GITHUB_MODELS":{const a=J.create(cc,{config:{...this.config.GITHUB_MODELS,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"DEEPSEEK":{const a=J.create(Sa,{config:{...this.config.DEEPSEEK,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}default:const c=C.red.bold(`[${o}]`);return ft({name:c+" Invalid AI type",value:"Invalid AI type",isError:!0,disabled:!0})}}))}),R(o=>{const s=C.red.bold("[UNKNOWN]");return ft({name:s+` ${o.message||""}`,value:"Unknown error",isError:!0,disabled:!0})}))}}class Do{getDetectedMessage(e){return`Detected ${e.files.length.toLocaleString()} changed file${e.files.length>1?"s":""} (${e.diff.length.toLocaleString()} characters)`}getDetectedFiles(e){return`Detected ${e.length.toLocaleString()} changed file${e.length>1?"s":""}`}}class tr extends Do{constructor(){super(...arguments),this.name="git",this.excludeFromDiff=e=>`:(exclude)${e}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:e}=await j("git",["rev-parse","--show-toplevel"],{reject:!0});return e.trim()}catch(e){const t=e;if(t.code==="ENOENT")throw new v(`Git command not found!
84
+ ${t}`,c),oe(t,o,"GitHub Models",l,c);const u=new AbortController,m=setTimeout(()=>u.abort(),this.params.config.timeout);try{const p=Date.now(),h=await fetch(a,{method:"POST",headers:d,body:JSON.stringify(l),signal:u.signal});if(clearTimeout(m),!h.ok){const b=await h.text(),E={status:h.status,statusText:h.statusText,url:a,headers:Object.fromEntries(h.headers),body:b};G(t,o,"GitHub Models",E,c);let x=`GitHub API request failed: ${h.status} ${h.statusText}`;try{const P=JSON.parse(b);P.error?.message?x+=` - ${P.error.message}`:P.message&&(x+=` - ${P.message}`)}catch{b&&(x+=` - ${b}`)}if(h.status===401){const P=new Error("GitHub authentication failed. Please run: aicommit2 github-login");throw P.status=h.status,P.code="AUTHENTICATION_FAILED",P.content=b,P}else if(h.status===403){const P=new Error('GitHub Models access denied. Make sure your token has "Models" permission.');throw P.status=h.status,P.code="ACCESS_DENIED",P.content=b,P}else if(h.status===404){const P=new Error(`Model "${s}" not found. Please check the model name.`);throw P.status=h.status,P.code="MODEL_NOT_FOUND",P.content=b,P}else if(h.status===429){const P=new Error("Rate limit exceeded. Please try again later.");throw P.status=h.status,P.code="RATE_LIMIT_EXCEEDED",P.content=b,P}const A=new Error(x);throw A.status=h.status,A.code="API_ERROR",A.content=b,A}const g=await h.json(),y=Date.now()-p;X(t,o,"GitHub Models",g,c);const v=g.choices?.[0]?.message?.content?.trim();if(!v){G(t,o,"GitHub Models",{message:"No content found in GitHub Models response",result:g},c);const E=new Error("No response content received from GitHub Models");throw E.code="NO_CONTENT",E.content=JSON.stringify(g,null,2),E}return Y(t,o,"GitHub Models",y,v,c),v}catch(p){if(clearTimeout(m),p instanceof Error&&p.name==="AbortError"){const y={message:`GitHub Models request timeout after ${this.params.config.timeout}ms`,error:p};G(t,o,"GitHub Models",y,c);const v=new Error(`GitHub Models request timed out after ${this.params.config.timeout}ms`);throw v.code="REQUEST_TIMEOUT",v.originalError=p,v}if(p.code)throw p;G(t,o,"GitHub Models",{message:"GitHub Models request failed",error:p},c);const g=new Error(`GitHub Models request failed: ${p instanceof Error?p.message:String(p)}`);throw g.code="REQUEST_FAILED",g.originalError=p,g}}}class Ic extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#f55036",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Groq]"),this.errorPrefix=C.red.bold("[Groq]"),this.groq=new Bs({apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Groq API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Groq plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Groq model name is correct":t.includes("overloaded")||t.includes("capacity")?"Groq service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Groq model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Groq model configuration":t.includes("500")||t.includes("Internal Server Error")?"Groq server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,temperature:a,generate:d,type:c,maxLength:u}=this.params.config,m=this.params.config.maxTokens,p={...K,locale:l,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},h=e==="review"?ee(p):Z(p),g=`Here is the diff: ${t}`,v=`${this.params.config.url||"https://api.groq.com"}/openai/v1/chat/completions`,b={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,"Groq",this.params.config.model,v,b,i),q(t,e,"Groq",h,g,i);const E={messages:[{role:"system",content:h},{role:"user",content:g}],model:this.params.config.model,max_tokens:m,top_p:this.params.config.topP,temperature:a};oe(t,e,"Groq",E,i);const x=Date.now();try{const A=await this.groq.chat.completions.create(E,{timeout:this.params.config.timeout}),P=Date.now()-x,$=A.choices[0].message.content||"";return X(t,e,"Groq",A,i),Y(t,e,"Groq",P,$,i),e==="review"?this.sanitizeResponse($):this.parseMessage($,c,d)}catch(A){throw G(t,e,"Groq",A,i),A}}}class Rc extends Q{constructor(e){super(e),this.params=e,this.headers={},this.models=[],this.currentModelId=null,this.currentConversation=void 0,this.currentConversionID=void 0,this.cookie="",this.colors={primary:"#FED21F",secondary:"#000"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=C.red.bold("[HuggingFace]"),this.cookie=this.params.config.cookie;const t=this.params.config.url||"https://huggingface.co";this.headers={accept:"*/*","accept-language":"en-US,en;q=0.9","sec-ch-ua":'"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin",origin:t,"Referrer-Policy":"strict-origin-when-cross-origin"}}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("cookie")||t.includes("Cookie")?"Invalid cookie. Check your Hugging Face session cookie in configuration":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Hugging Face model name is correct":t.includes("conversation")||t.includes("conversion")?"Failed to create conversation. Try again or check your session":t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Your Hugging Face session may have expired":t.includes("403")||t.includes("Forbidden")?"Access denied. You may not have permission to access this model":t.includes("404")||t.includes("Not Found")?"Model not found. Check your Hugging Face model configuration":t.includes("500")||t.includes("Internal Server Error")?"Hugging Face server error. Try again later":t.includes("overloaded")||t.includes("capacity")?"Hugging Face service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){await this.initialize();const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c,temperature:u,maxTokens:m,topP:p,timeout:h}=this.params.config,g={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?ee(g):Z(g),v=`Here is the diff: ${t}`,E=`${this.params.config.url||"https://huggingface.co"}/chat/conversation`,x={...this.headers,cookie:this.cookie};V(t,e,"HuggingFace",this.params.config.model,E,x,i),q(t,e,"HuggingFace",y,v,i);const A=Date.now();try{const P=await this.getNewChat(y),k=await(await this.sendMessage(v,P.id)).completeResponsePromise();await this.deleteConversation(P.id);const I=Date.now()-A;return X(t,e,"HuggingFace",{response:k},i),Y(t,e,"HuggingFace",I,k,i),e==="review"?this.sanitizeResponse(k):this.parseMessage(k,d,a)}catch(P){throw G(t,e,"HuggingFace",P,i),P}}async initialize(){const e=await this.getRemoteLlms(),t=e.find(o=>o.name?.toLowerCase()===this.params.config.model.toLowerCase());if(t){this.currentModel=t,this.currentModelId=t.id;return}this.currentModel=e[0],this.currentModelId=e[0].id}async getRemoteLlms(){const e=this.params.config.url||"https://huggingface.co",t=await fetch(`${e}/chat/__data.json`,{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if(t.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${t.status}`);const s=(await t.json()).nodes[0].data,n=s[s[0].models],i=[],l=a=>a===-1?null:s[a];for(const a of n){const d=s[a];if(s[d.unlisted])continue;const c={id:l(d.id),name:l(d.name),displayName:l(d.displayName),preprompt:l(d.preprompt),promptExamples:[],websiteUrl:l(d.websiteUrl),description:l(d.description),datasetName:l(d.datasetName),datasetUrl:l(d.datasetUrl),modelUrl:l(d.modelUrl),parameters:{}},u=l(d.promptExamples);if(u!==null){const h=u.map(g=>l(g));c.promptExamples=h.map(g=>({title:s[g.title],prompt:s[g.prompt]}))}const m=l(d.parameters),p={};for(const[h,g]of Object.entries(m)){if(g===-1){p[h]=null;continue}if(Array.isArray(s[g])){p[h]=s[g].map(y=>s[y]);continue}p[h]=s[g]}c.parameters=p,i.push(c)}return this.models=i,i}async getNewChat(e){const t={model:this.currentModelId,preprompt:e};let o=0;const s=this.params.config.url||"https://huggingface.co";for(;o<5;){const n=await fetch(`${s}/chat/conversation`,{headers:{...this.headers,"content-type":"application/json",cookie:this.cookie,Referer:`${s}/chat/`},body:JSON.stringify(t),method:"POST"}),{conversationId:i}=await n.json();if(i){this.currentConversionID=i;break}else o++}if(!this.currentConversionID)throw new Error("Failed to create new conversion");return await this.getConversationHistory(this.currentConversionID)}async getConversationHistory(e){if(!e)throw new Error("conversationId is required for getConversationHistory");const t=this.params.config.url||"https://huggingface.co",o=await fetch(`${t}/chat/conversation/${e}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:`${t}/chat/`},body:null,method:"GET"});if(o.status!=200)throw new Error("Unable get conversation details "+o);{const s=await o.json();return this.metadataParser(s,e)}}metadataParser(e,t){const o={id:"",model:"",systemPrompt:"",title:"",history:[]},s=e.nodes[1].data,n=s[s[0].model],i=s[s[0].preprompt],l=s[s[0].title],a=s[s[0].messages],d=[];for(const c of a){const u=s[c],m=new Date(s[u.createdAt][1]).getTime()/1e3,p=new Date(s[u.updatedAt][1]).getTime()/1e3;d.push({id:s[u.id],role:s[u.from],content:s[u.content],createdAt:m,updatedAt:p})}return o.id=t,o.model=n,o.systemPrompt=i,o.title=l,o.history=d,this.currentConversation=o,o}async sendMessage(e,t){if(e==="")throw new Error("the prompt can not be empty.");if(!t&&!this.currentConversionID?await this.getNewChat():t?(this.currentConversionID=t,await this.getConversationHistory(t)):this.currentConversionID&&await this.getConversationHistory(this.currentConversionID),!this.currentConversation)throw new Error("Failed to create new conversion");const o={inputs:e,id:this.currentConversation.history[this.currentConversation.history.length-1].id,is_retry:!1,is_continue:!1,web_search:!1,tools:[]},s=new FormData;s.append("data",JSON.stringify(o));const n=this.params.config.url||"https://huggingface.co",i=new AbortController,l=setTimeout(()=>i.abort(),this.params.config.timeout),a=await fetch(`${n}/chat/conversation/${this.currentConversionID}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${n}/chat/conversation/${this.currentConversionID}`},body:s,method:"POST",signal:i.signal});clearTimeout(l);function d(g){try{const y=g.split(`
85
+ `),v=[];for(const b of y)b.trim()&&v.push(JSON.parse(b));return v}catch{return[{}]}}const c=new TextDecoder;let u="";const m=new TransformStream({async transform(g,y){const v=c.decode(g);try{const b=d(v);for(const E of b)E.type==="finalAnswer"?(u=E?.text||"",y.terminate()):E.type==="stream"&&y.enqueue(E?.token||"")}catch{throw new Error("Error during parsing response")}}}),p=a.body?.pipeThrough(m);async function h(){return new Promise(async(g,y)=>{try{if(!p)y("ModifiedStream undefined");else{const v=p.getReader();for(;;){const{done:b,value:E}=await v.read();if(b){g(u);break}}}}catch(v){y(v)}})}return{id:this.currentConversionID,stream:p,completeResponsePromise:h}}async deleteConversation(e){const t=this.params.config.url||"https://huggingface.co";return(await fetch(`${t}/chat/conversation/${e}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${t}/chat/`},body:null,method:"DELETE"})).json()}}class Dc extends Q{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#ff7000",secondary:"#fff"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=C.red.bold("[MistralAI]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Mistral AI API key in configuration":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your Mistral AI usage limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Mistral model name is correct":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Mistral model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Mistral model configuration":t.includes("500")||t.includes("Internal Server Error")?"Mistral AI server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c}=this.params.config,u={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},m=e==="review"?ee(u):Z(u);await this.checkAvailableModels();const p=`Here is the diff: ${t}`,g=`${this.params.config.url||"https://api.mistral.ai"}/v1/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"MistralAI",this.params.config.model,g,y,i),q(t,e,"MistralAI",m,p,i);const v=await this.createChatCompletions(m,p,e);return e==="review"?this.sanitizeResponse(v):this.parseMessage(v,d,a)}async checkAvailableModels(){if((await this.getAvailableModels()).includes(this.params.config.model))return!0;throw new Error(`Invalid model type of Mistral AI: ${this.params.config.model}`)}async getAvailableModels(){const e=this.params.config.url||"https://api.mistral.ai";return(await new je({method:"GET",baseURL:`${e}/v1/models`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).execute()).data.data.filter(o=>o.object==="model").map(o=>o.id)}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:t}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:st(10,1e3)};oe(s,o,"MistralAI",i,n);const l=Date.now();try{const a=this.params.config.url||"https://api.mistral.ai",d=await new je({method:"POST",baseURL:`${a}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),c=Date.now()-l,u=d.data;if(X(s,o,"MistralAI",u,n),!u.choices||u.choices.length===0||!u.choices[0].message?.content)throw G(s,o,"MistralAI",{message:"No Content on response",result:u},n),new Error("No Content on response. Please open a Bug report");const p=u.choices[0].message.content;return Y(s,o,"MistralAI",c,p,n),p}catch(a){throw G(s,o,"MistralAI",a,n),a}}}class Oc extends Q{constructor(e){super(e),this.params=e,this.host=Kt,this.model="",this.key="",this.auth="",this.setupFetch=(t,o={})=>Us(t,{...o,dispatcher:new zs({headersTimeout:this.params.config.timeout})}),this.colors={primary:"#FFF",secondary:"#000"},this.model=this.params.keyName,this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${ot(this.model)}]`),this.errorPrefix=C.red.bold(`[${ot(this.model)}]`),this.host=this.params.config.host||Kt,this.auth=this.params.config.auth||"Bearer",this.key=this.params.config.key||"",this.ollama=new Hs({host:this.host,fetch:this.setupFetch,...this.key&&{headers:{Authorization:`${this.auth} ${this.key}`}}})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("ECONNREFUSED")||t.includes("connection")?`Cannot connect to Ollama server at ${this.host}. Make sure Ollama is running`:t.includes("model")||t.includes("Model")?`Model '${this.model}' not found. Pull the model with: ollama pull ${this.model}`:t.includes("401")||t.includes("Unauthorized")?"Authentication failed. Check your Ollama API key if authentication is enabled":t.includes("403")||t.includes("Forbidden")?"Access denied. Check your Ollama server permissions":t.includes("404")||t.includes("Not Found")?`Model '${this.model}' not found on Ollama server. Pull it first with: ollama pull ${this.model}`:t.includes("500")||t.includes("Internal Server Error")?"Ollama server error. Check server logs and try again":t.includes("overloaded")||t.includes("capacity")?"Ollama server is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c}=this.params.config,u={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},m=e==="review"?ee(u):Z(u);await this.checkIsAvailableOllama();const p=`Here is the diff: ${t}`,h=`Ollama_${this.model}`,g=`${this.host}/api/chat`,y=this.key?{Authorization:`${this.auth} ${this.key}`}:{};V(t,e,h,this.model,g,y,i),q(t,e,h,m,p,i);const v=await this.createChatCompletions(m,p,e);return e==="review"?this.sanitizeResponse(v):this.parseMessage(v,d,a)}async checkIsAvailableOllama(){const e=new je({method:"GET",baseURL:`${this.host}`,timeout:this.params.config.timeout});return this.key&&e.setHeaders({Authorization:`${this.auth} ${this.key}`}),(await e.execute()).data}async createChatCompletions(e,t,o){const{stream:s,numCtx:n,temperature:i,topP:l,timeout:a,maxTokens:d,logging:c}=this.params.config,u=s||!1,m=this.params.stagedDiff.diff,p=`Ollama_${this.model}`,h={model:this.model,messages:[{role:"system",content:e},{role:"user",content:t}],stream:u,keep_alive:a,options:{num_ctx:n,temperature:i,top_p:l,seed:st(10,1e3),num_predict:d??-1}};oe(m,o,p,h,c);const g=Date.now();try{const y=await this.ollama.chat(h),v=Date.now()-g;let b="";if(u){if(y)for await(const E of y)b+=E.message.content}else b=y.message.content;return X(m,o,p,{response:b,fullResponse:y},c),Y(m,o,p,v,b,c),b}catch(y){throw G(m,o,p,y,c),y}}}class Fc extends Q{constructor(e){super(e),this.params=e;const t=this.params.keyName||"OPENAI_COMPATIBLE";this.colors=Aa(t),this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${ot(t)}]`),this.errorPrefix=C.red.bold(`[${ot(t)}]`),this.openAI=new Fr({apiKey:this.params.config.key,baseURL:`${this.params.config.url}${this.params.config.path}`})}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your OpenAI-compatible API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or check your service limits":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the model name is correct":t.includes("network")||t.includes("connection")?"Network error. Check your internet connection and API endpoint":t.includes("quota")||t.includes("usage")?"API quota exceeded. Check your usage limits":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your API configuration":t.includes("500")||t.includes("Internal Server Error")?"Server error. Try again later":t.includes("overloaded")||t.includes("capacity")?"Service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,temperature:a,generate:d,type:c,maxLength:u,timeout:m,stream:p=!1}=this.params.config,h=this.params.config.maxTokens,g={...K,locale:l,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?ee(g):Z(g),v=`Here is the diff: ${t}`,b=this.params.keyName||"OpenAI-Compatible",E=`${this.params.config.url}${this.params.config.path}`,x={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};V(t,e,b,this.params.config.model,E,x,i),q(t,e,b,y,v,i);const A=lr(this.params.config.model),P={messages:[{role:"system",content:y},{role:"user",content:v}],model:this.params.config.model,stream:p,...A?{max_completion_tokens:h,temperature:1}:{max_tokens:h,top_p:this.params.config.topP,temperature:a}};oe(t,e,b,P,i);const $=Date.now();try{const k=await this.openAI.chat.completions.create(P,{timeout:m});let I="";if(p&&k){const wt=k;for await(const xe of wt){const ms=xe.choices?.[0]?.delta?.content||"",fs=xe.choices?.[0]?.delta?.reasoning_content||"",ps=`${ms}${fs}`;I+=ps}}else I=k.choices?.[0]?.message.content||"";const _=Date.now()-$;return X(t,e,b,k,i),Y(t,e,b,_,I,i),e==="review"?this.sanitizeResponse(I):this.parseMessage(I,c,d)}catch(k){throw G(t,e,b,k,i),k}}}class Lc extends Q{constructor(e){super(e),this.params=e,this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=C.red.bold("[ChatGPT]")}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")?"Invalid API key. Check your OpenAI API key in configuration":t.includes("quota")?"API quota exceeded. Check your OpenAI usage limits":t.includes("500")?"OpenAI server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}extractJSONFromError(e){const t=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(t);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,temperature:i,logging:l,locale:a,generate:d,type:c,maxLength:u,proxy:m,maxTokens:p,timeout:h}=this.params.config,g={...K,locale:a,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},y=e==="review"?ee(g):Z(g),v=await Sc("ChatGPT",this.params.config.url,this.params.config.path,this.params.config.key,this.params.config.model,t,h,p,i,this.params.config.topP,y,l,e,m);return nt(e==="review"?v.map(b=>this.sanitizeResponse(b)):v.map(b=>this.parseMessage(b,c,d)))}}class jc extends Q{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#20808D",secondary:"#FFF"},this.serviceName=C.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Perplexity]"),this.errorPrefix=C.red.bold("[Perplexity]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const t=e.message||"";return t.includes("API key")||t.includes("api_key")?"Invalid API key. Check your Perplexity API key in configuration":t.includes("rate_limit")||t.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Perplexity plan":t.includes("model")||t.includes("Model")?"Model not found or not accessible. Check if the Perplexity model name is correct":t.includes("overloaded")||t.includes("capacity")?"Perplexity service is overloaded. Try again in a few minutes":t.includes("403")||t.includes("Forbidden")?"Access denied. Your API key may not have permission for this Perplexity model":t.includes("404")||t.includes("Not Found")?"Model or endpoint not found. Check your Perplexity model configuration":t.includes("500")||t.includes("Internal Server Error")?"Perplexity server error. Try again later":null}generateCommitMessage$(){return T(this.generateMessage("commit")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:this.params.config.includeBody?e.value:e.title,description:this.params.config.includeBody?e.value:"",isError:!1})),F(this.handleError$))}generateCodeReview$(){return T(this.generateMessage("review")).pipe(j(e=>R(e)),D(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),F(this.handleError$))}extractJSONFromError(e){const t=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(t);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const t=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:l,generate:a,type:d,maxLength:c}=this.params.config,u={...K,locale:l,maxLength:c,type:d,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n},m=e==="review"?ee(u):Z(u),p=`Here is the diff: ${t}`,g=`${this.params.config.url||"https://api.perplexity.ai"}/chat/completions`,y={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};V(t,e,"Perplexity",this.params.config.model,g,y,i),q(t,e,"Perplexity",m,p,i);const v=await this.createChatCompletions(m,p,e);return this.parseMessage(v,d,a)}async createChatCompletions(e,t,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={model:this.params.config.model,messages:[{role:"system",content:e},{role:"user",content:t}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1};oe(s,o,"Perplexity",i,n);const l=Date.now();try{const a=this.params.config.url||"https://api.perplexity.ai",d=await new je({method:"POST",baseURL:`${a}/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),c=Date.now()-l,u=d.data;if(X(s,o,"Perplexity",u,n),!u.choices||u.choices.length===0||!u.choices[0].message?.content)throw G(s,o,"Perplexity",{message:"No Content on response",result:u},n),new Error("No Content on response. Please open a Bug report");const p=u.choices[0].message.content;return Y(s,o,"Perplexity",c,p,n),p}catch(a){throw G(s,o,"Perplexity",a,n),a}}}class dt{constructor(e,t){this.config=e,this.stagedDiff=t}createCommitMsgRequests$(e){return this.createServiceRequests$(e,"commit")}createCodeReviewRequests$(e){return this.createServiceRequests$(e,"review")}createServiceRequests$(e,t){return R(e).pipe(Sr(o=>{const s=this.config[o],n=Array.isArray(s.model)?s.model:[s.model];return R(n).pipe(Sr(i=>{if(s.compatible){const l=J.create(Fc,{config:{...s,url:s.url||"",path:s.path||"",model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?l.generateCommitMessage$():l.generateCodeReview$()}switch(o){case"OPENAI":{const a=J.create(Lc,{config:{...this.config.OPENAI,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GEMINI":{const a=J.create(qa,{config:{...this.config.GEMINI,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"ANTHROPIC":{const a=J.create(Ya,{config:{...this.config.ANTHROPIC,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"HUGGINGFACE":{const a=J.create(Rc,{config:{...this.config.HUGGINGFACE,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"MISTRAL":{const a=J.create(Dc,{config:{...this.config.MISTRAL,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"CODESTRAL":{const a=J.create(Ka,{config:{...this.config.CODESTRAL,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"OLLAMA":{const a=J.create(Oc,{config:{...this.config.OLLAMA,model:i},keyName:i,stagedDiff:this.stagedDiff});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"COHERE":{const a=J.create(Ja,{config:{...this.config.COHERE,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GROQ":{const a=J.create(Ic,{config:{...this.config.GROQ,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"PERPLEXITY":{const a=J.create(jc,{config:{...this.config.PERPLEXITY,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"GITHUB_MODELS":{const a=J.create(Mc,{config:{...this.config.GITHUB_MODELS,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}case"DEEPSEEK":{const a=J.create(Va,{config:{...this.config.DEEPSEEK,model:i},stagedDiff:this.stagedDiff,keyName:i});return t==="commit"?a.generateCommitMessage$():a.generateCodeReview$()}default:const l=C.red.bold(`[${o}]`);return bt({name:l+" Invalid AI type",value:"Invalid AI type",isError:!0,disabled:!0})}}))}),F(o=>{const s=C.red.bold("[UNKNOWN]");return bt({name:s+` ${o.message||""}`,value:"Unknown error",isError:!0,disabled:!0})}))}}class ur{getDetectedMessage(e){return`Detected ${e.files.length.toLocaleString()} changed file${e.files.length>1?"s":""} (${e.diff.length.toLocaleString()} characters)`}getDetectedFiles(e){return`Detected ${e.length.toLocaleString()} changed file${e.length>1?"s":""}`}}class mt extends ur{constructor(){super(...arguments),this.name="git",this.excludeFromDiff=e=>`:(exclude)${e}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:e}=await M("git",["rev-parse","--show-toplevel"],{reject:!0});return e.trim()}catch(e){const t=e;if(t.code==="ENOENT")throw new w(`Git command not found!
86
86
 
87
- Please install Git first: https://git-scm.com/downloads`);if(t.stderr){if(t.stderr.includes("not a git repository"))throw new v(`Not in a Git repository!
87
+ Please install Git first: https://git-scm.com/downloads`);if(t.stderr){if(t.stderr.includes("not a git repository"))throw new w(`Not in a Git repository!
88
88
 
89
89
  Initialize with: git init
90
- Or navigate to an existing Git repository.`);if(t.stderr.includes("permission denied"))throw new v(`Git permission denied: ${t.stderr.trim()}
90
+ Or navigate to an existing Git repository.`);if(t.stderr.includes("permission denied"))throw new w(`Git permission denied: ${t.stderr.trim()}
91
91
 
92
- Check file permissions and repository access.`)}throw new v(`Failed to verify Git repository: ${t.message||"Unknown error"}`)}}async getStagedDiff(e,t){const o=["diff","--cached","--diff-algorithm=minimal"],{stdout:s}=await j("git",[...o,"--name-only",...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]);if(!s)return null;const{stdout:n}=await j("git",[...o,...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),i=s.split(`
93
- `).filter(Boolean),{stdout:c}=await j("git",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),a=[],m=c.split(`
94
- `).filter(Boolean);for(const d of m){const p=d.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let u=n;if(a.length>0){n.trim()||(u=""),u+=`
92
+ Check file permissions and repository access.`)}throw new w(`Failed to verify Git repository: ${t.message||"Unknown error"}`)}}async getStagedDiff(e,t){const o=["diff","--cached","--diff-algorithm=minimal"],{stdout:s}=await M("git",[...o,"--name-only",...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]);if(!s)return null;const{stdout:n}=await M("git",[...o,...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),i=s.split(`
93
+ `).filter(Boolean),{stdout:l}=await M("git",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),a=[],d=l.split(`
94
+ `).filter(Boolean);for(const m of d){const p=m.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let c=n;if(a.length>0){n.trim()||(c=""),c+=`
95
95
 
96
96
  --- Binary Files Changed ---
97
- `;for(const d of a){const{stdout:p}=await j("git",["status","--porcelain",d]),g=p.substring(0,2).trim();u+=`Binary file ${d} ${g==="A"?"added":g==="M"?"modified":g==="D"?"deleted":"changed"}
98
- `}}const l=[...new Set([...i,...a])];return{files:l,diff:u||`Files changed: ${l.join(", ")}`}}async getCommitDiff(e,t,o){const s=["diff-tree","-r","--no-commit-id","--name-only",e],{stdout:n}=await j("git",[...s,...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]);if(!n)return null;const{stdout:i}=await j("git",["show",e,"--",...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),{stdout:c}=await j("git",["diff-tree","-r","--numstat",e,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),a=[],m=c.split(`
99
- `).filter(Boolean);for(const d of m){const p=d.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let u=i;if(a.length>0){i.trim()||(u=""),u+=`
97
+ `;for(const m of a){const{stdout:p}=await M("git",["status","--porcelain",m]),h=p.substring(0,2).trim();c+=`Binary file ${m} ${h==="A"?"added":h==="M"?"modified":h==="D"?"deleted":"changed"}
98
+ `}}const u=[...new Set([...i,...a])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async getCommitDiff(e,t,o){const s=["diff-tree","-r","--no-commit-id","--name-only",e],{stdout:n}=await M("git",[...s,...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]);if(!n)return null;const{stdout:i}=await M("git",["show",e,"--",...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),{stdout:l}=await M("git",["diff-tree","-r","--numstat",e,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),a=[],d=l.split(`
99
+ `).filter(Boolean);for(const m of d){const p=m.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let c=i;if(a.length>0){i.trim()||(c=""),c+=`
100
100
 
101
101
  --- Binary Files Changed ---
102
- `;for(const d of a)u+=`Binary file ${d} changed
103
- `}const l=[...new Set([...n.split(`
104
- `).filter(Boolean),...a])];return{files:l,diff:u||`Files changed: ${l.join(", ")}`}}async commit(e,t=[]){try{await j("git",["commit","-m",e,...t],{stdio:"inherit"})}catch(o){const s=o;throw s.stderr?s.stderr.includes("nothing to commit")?new v(`Nothing to commit.
102
+ `;for(const m of a)c+=`Binary file ${m} changed
103
+ `}const u=[...new Set([...n.split(`
104
+ `).filter(Boolean),...a])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async commit(e,t=[]){try{await M("git",["commit","-m",e,...t],{stdio:"inherit"})}catch(o){const s=o;throw s.stderr?s.stderr.includes("nothing to commit")?new w(`Nothing to commit.
105
105
 
106
106
  Stage your changes with: git add <files>
107
- Or use the --all flag to stage all changes.`):s.stderr.includes("Please enter the commit message")?new v(`Commit message cannot be empty.
107
+ Or use the --all flag to stage all changes.`):s.stderr.includes("Please enter the commit message")?new w(`Commit message cannot be empty.
108
108
 
109
- Provide a meaningful commit message.`):s.stderr.includes("Author identity unknown")?new v(`Git author identity not configured.
109
+ Provide a meaningful commit message.`):s.stderr.includes("Author identity unknown")?new w(`Git author identity not configured.
110
110
 
111
111
  Configure with:
112
112
  git config --global user.name "Your Name"
113
- git config --global user.email "your.email@example.com"`):s.stderr.includes("Permission denied")?new v(`Git permission error: ${s.stderr.trim()}
113
+ git config --global user.email "your.email@example.com"`):s.stderr.includes("Permission denied")?new w(`Git permission error: ${s.stderr.trim()}
114
114
 
115
- Check repository permissions and file access.`):new v(`Git commit failed: ${s.stderr.trim()}`):s.exitCode===1?new v("Git commit failed. Check your staged changes and try again."):new v(`Failed to commit with Git: ${s.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await j("git",["config","--get","core.commentChar"]);return e}catch{return"#"}}}class gc extends Do{constructor(){super(...arguments),this.name="jujutsu",this.excludeFromDiff=e=>e.includes("*")||e.includes("?")||e.includes("[")?`~glob:"${e}"`:`~"${e}"`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"]}async assertRepo(){try{const{stdout:e}=await j("jj",["--version"],{reject:!0});process.env.DEBUG&&console.log(`Jujutsu version: ${e}`)}catch(e){const t=e;throw t.code==="ENOENT"?new v(`Jujutsu (jj) command not found!
115
+ Check repository permissions and file access.`):new w(`Git commit failed: ${s.stderr.trim()}`):s.exitCode===1?new w("Git commit failed. Check your staged changes and try again."):new w(`Failed to commit with Git: ${s.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await M("git",["config","--get","core.commentChar"]);return e}catch{return"#"}}}class dr extends ur{constructor(){super(...arguments),this.name="jujutsu",this.excludeFromDiff=e=>e.includes("*")||e.includes("?")||e.includes("[")?`~glob:"${e}"`:`~"${e}"`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"]}async assertRepo(){try{const{stdout:e}=await M("jj",["--version"],{reject:!0});process.env.DEBUG&&console.log(`Jujutsu version: ${e}`)}catch(e){const t=e;throw t.code==="ENOENT"?new w(`Jujutsu (jj) command not found!
116
116
 
117
117
  Please install Jujutsu:
118
118
  - macOS: brew install jj
119
119
  - Linux: cargo install jj-cli
120
120
  - Windows: cargo install jj-cli
121
- - See: https://github.com/martinvonz/jj#installation`):new v(`Failed to execute jj command: ${t.message}`)}try{const{stdout:e,stderr:t}=await j("jj",["workspace","root"],{reject:!0}),o=e.trim();if(!o)throw new v("jj workspace root returned empty path");const s=S.join(o,".jj");if(!U.existsSync(s))throw new v(`Jujutsu repository directory not found at ${s}
121
+ - See: https://github.com/martinvonz/jj#installation`):new w(`Failed to execute jj command: ${t.message}`)}try{const{stdout:e,stderr:t}=await M("jj",["workspace","root"],{reject:!0}),o=e.trim();if(!o)throw new w("jj workspace root returned empty path");const s=S.join(o,".jj");if(!W.existsSync(s))throw new w(`Jujutsu repository directory not found at ${s}
122
122
 
123
- Initialize a jj repository with: jj init`);return o}catch(e){if(e instanceof v)throw e;const t=e;throw t.stderr?t.stderr.includes("not in a jj repo")?new v(`Not in a Jujutsu repository!
123
+ Initialize a jj repository with: jj init`);return o}catch(e){if(e instanceof w)throw e;const t=e;throw t.stderr?t.stderr.includes("not in a jj repo")?new w(`Not in a Jujutsu repository!
124
124
 
125
125
  Initialize with: jj init
126
- Or navigate to an existing jj repository.`):t.stderr.includes("No workspace found")?new v(`No Jujutsu workspace found!
126
+ Or navigate to an existing jj repository.`):t.stderr.includes("No workspace found")?new w(`No Jujutsu workspace found!
127
127
 
128
- This may be a bare repository. Navigate to a workspace directory.`):new v(`Jujutsu error: ${t.stderr.trim()}`):new v(`Failed to verify Jujutsu repository: ${t.message||"Unknown error"}`)}}async getStagedDiff(e,t){try{const{stdout:o}=await j("jj",["status","--no-pager"]);if(process.env.DEBUG&&(console.log("jj status output:",JSON.stringify(o)),console.log("excludeFiles:",e),console.log("exclude:",t)),o.includes("No changes.")||o.includes("The working copy is clean"))return null;const s=this.filesToExclude.map(this.excludeFromDiff),n=[...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]],i=[...s,...n];let c="all()";i.length>0&&(c=`all() & ${i.join(" & ")}`);const a=["diff","--name-only"],m=["diff","--git"];i.length>0&&(a.push(c),m.push(c)),process.env.DEBUG&&(console.log("jj diff command with fileset:",a),console.log("fileset expression:",c));const{stdout:u}=await j("jj",a);if(process.env.DEBUG&&console.log("jj diff --name-only output:",JSON.stringify(u)),!u.trim())return null;const{stdout:l}=await j("jj",m),{stdout:d}=await j("jj",["status","--no-pager"]),p=u.split(`
129
- `).filter(Boolean),g=[],h=d.split(`
130
- `);for(const b of h)if(b.includes("(binary)")||b.includes("Binary file")){const P=b.match(/([^\s]+)\s*\(binary\)/);P&&P[1]&&g.push(P[1])}let y=l;if(g.length>0){y+=`
128
+ This may be a bare repository. Navigate to a workspace directory.`):new w(`Jujutsu error: ${t.stderr.trim()}`):new w(`Failed to verify Jujutsu repository: ${t.message||"Unknown error"}`)}}async getStagedDiff(e,t){try{const{stdout:o}=await M("jj",["status","--no-pager"]);if(process.env.DEBUG&&(console.log("jj status output:",JSON.stringify(o)),console.log("excludeFiles:",e),console.log("exclude:",t)),o.includes("No changes.")||o.includes("The working copy is clean"))return null;const s=this.filesToExclude.map(this.excludeFromDiff),n=[...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]],i=[...s,...n];let l="all()";i.length>0&&(l=`all() & ${i.join(" & ")}`);const a=["diff","--name-only"],d=["diff","--git"];i.length>0&&(a.push(l),d.push(l)),process.env.DEBUG&&(console.log("jj diff command with fileset:",a),console.log("fileset expression:",l));const{stdout:c}=await M("jj",a);if(process.env.DEBUG&&console.log("jj diff --name-only output:",JSON.stringify(c)),!c.trim())return null;const{stdout:u}=await M("jj",d),{stdout:m}=await M("jj",["status","--no-pager"]),p=c.split(`
129
+ `).filter(Boolean),h=[],g=m.split(`
130
+ `);for(const b of g)if(b.includes("(binary)")||b.includes("Binary file")){const E=b.match(/([^\s]+)\s*\(binary\)/);E&&E[1]&&h.push(E[1])}let y=u;if(h.length>0){y+=`
131
131
 
132
132
  --- Binary Files Changed ---
133
- `;for(const b of g)y+=`Binary file ${b} changed
134
- `}const w=[...new Set([...p,...g])];return{files:w,diff:y||`Files changed: ${w.join(", ")}`}}catch(o){const s=o;if(s.stderr){if(s.stderr.includes("No changes to show"))return null;if(s.stderr.includes("Operation not allowed"))throw new v(`Jujutsu diff failed: ${s.stderr.trim()}
133
+ `;for(const b of h)y+=`Binary file ${b} changed
134
+ `}const v=[...new Set([...p,...h])];return{files:v,diff:y||`Files changed: ${v.join(", ")}`}}catch(o){const s=o;if(s.stderr){if(s.stderr.includes("No changes to show"))return null;if(s.stderr.includes("Operation not allowed"))throw new w(`Jujutsu diff failed: ${s.stderr.trim()}
135
135
 
136
- Try: jj status --no-pager`);if(s.stderr.includes("Invalid revision"))throw new v(`Jujutsu revision error: ${s.stderr.trim()}
136
+ Try: jj status --no-pager`);if(s.stderr.includes("Invalid revision"))throw new w(`Jujutsu revision error: ${s.stderr.trim()}
137
137
 
138
- Check if you're in a valid workspace.`)}if(s.exitCode===1&&!s.stderr)return null;if(process.env.DEBUG)throw new v(`Jujutsu diff failed: ${s.message}
138
+ Check if you're in a valid workspace.`)}if(s.exitCode===1&&!s.stderr)return null;if(process.env.DEBUG)throw new w(`Jujutsu diff failed: ${s.message}
139
139
  stderr: ${s.stderr}
140
- exitCode: ${s.exitCode}`);return null}}async getCommitDiff(e,t,o){const s=[...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]];try{const n=["diff","--name-only","--revision",e],i=["diff","--git","--revision",e];if(s.length>0){const u=`all() & ${s.join(" & ")}`;n.push(u),i.push(u),process.env.DEBUG&&console.log("jj getCommitDiff fileset expression:",u)}const{stdout:c}=await j("jj",n);if(!c.trim())return null;const{stdout:a}=await j("jj",i),m=c.split(`
141
- `).filter(Boolean);return{files:m,diff:a||`Files changed: ${m.join(", ")}`}}catch(n){if(process.env.DEBUG){const i=n;console.log("jj getCommitDiff error:",i.message,i.stderr)}return null}}async commit(e,t=[]){try{await j("jj",["describe","-m",e,...t],{stdio:"inherit"}),await j("jj",["new"],{stdio:"inherit"})}catch(o){const s=o;throw s.stderr?s.stderr.includes("Empty commit message")?new v(`Commit message cannot be empty.
140
+ exitCode: ${s.exitCode}`);return null}}async getCommitDiff(e,t,o){const s=[...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]];try{const n=["diff","--name-only","--revision",e],i=["diff","--git","--revision",e];if(s.length>0){const c=`all() & ${s.join(" & ")}`;n.push(c),i.push(c),process.env.DEBUG&&console.log("jj getCommitDiff fileset expression:",c)}const{stdout:l}=await M("jj",n);if(!l.trim())return null;const{stdout:a}=await M("jj",i),d=l.split(`
141
+ `).filter(Boolean);return{files:d,diff:a||`Files changed: ${d.join(", ")}`}}catch(n){if(process.env.DEBUG){const i=n;console.log("jj getCommitDiff error:",i.message,i.stderr)}return null}}async commit(e,t=[]){try{await M("jj",["describe","-m",e,...t],{stdio:"inherit"}),await M("jj",["new"],{stdio:"inherit"})}catch(o){const s=o;throw s.stderr?s.stderr.includes("Empty commit message")?new w(`Commit message cannot be empty.
142
142
 
143
- Provide a meaningful commit message.`):s.stderr.includes("No changes to commit")?new v(`No changes to commit.
143
+ Provide a meaningful commit message.`):s.stderr.includes("No changes to commit")?new w(`No changes to commit.
144
144
 
145
- Make some changes first, then try again.`):s.stderr.includes("Invalid revision")?new v(`Jujutsu commit error: ${s.stderr.trim()}
145
+ Make some changes first, then try again.`):s.stderr.includes("Invalid revision")?new w(`Jujutsu commit error: ${s.stderr.trim()}
146
146
 
147
- Ensure you're in a valid workspace with changes.`):s.stderr.includes("Operation not allowed")?new v(`Jujutsu operation not allowed: ${s.stderr.trim()}
147
+ Ensure you're in a valid workspace with changes.`):s.stderr.includes("Operation not allowed")?new w(`Jujutsu operation not allowed: ${s.stderr.trim()}
148
148
 
149
- Check repository state with: jj status`):new v(`Jujutsu describe failed: ${s.stderr.trim()}`):s.exitCode===1?new v("Jujutsu commit failed. Check your changes and repository state."):new v(`Failed to commit with Jujutsu: ${s.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await j("jj",["config","get","ui.comment-char"]);return e.trim()||"#"}catch{return"#"}}}let rr=null;async function yc(){if(process.env.FORCE_GIT==="true")try{const s=new tr;return await s.assertRepo(),s}catch(s){throw new v(`FORCE_GIT="true" environment variable is set, but Git is not available or not in a git repository.
150
- ${s instanceof Error?s.message:String(s)}`)}let e=!1;try{e=(await ue({})).forceGit===!0}catch{e=!1}if(e)try{const s=new tr;return await s.assertRepo(),s}catch(s){throw new v(`forceGit=true is set in config, but Git is not available or not in a git repository.
151
- ${s instanceof Error?s.message:String(s)}`)}let t=null,o=null;try{const s=new gc;return await s.assertRepo(),s}catch(s){t=s instanceof Error?s:new Error(String(s))}try{const s=new tr;return await s.assertRepo(),s}catch(s){o=s instanceof Error?s:new Error(String(s))}if(t&&o){const s=t.message.replace("KnownError: ","").trim(),n=o.message.replace("KnownError: ","").trim();throw new v(`No supported VCS repository found.
149
+ Check repository state with: jj status`):new w(`Jujutsu describe failed: ${s.stderr.trim()}`):s.exitCode===1?new w("Jujutsu commit failed. Check your changes and repository state."):new w(`Failed to commit with Jujutsu: ${s.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await M("jj",["config","get","ui.comment-char"]);return e.trim()||"#"}catch{return"#"}}}class mr extends ur{constructor(){super(...arguments),this.name="yadm",this.excludeFromDiff=e=>`:(exclude)${e}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:e}=await M("yadm",["rev-parse","--show-toplevel"],{reject:!0}),t=e.trim(),o=process.env.HOME||process.env.USERPROFILE;if(!o)throw new w("HOME environment variable not set. Cannot determine YADM repository.");const s=await import("path"),n=s.resolve(t),i=s.resolve(o);if(n!==i)throw new w(`Not a YADM repository (work tree is not $HOME).
150
+
151
+ YADM work tree: ${n}
152
+ Expected: ${i}
153
+
154
+ This appears to be a regular Git repository.`);const{stdout:l}=await M("yadm",["rev-parse","--git-dir"],{reject:!0}),a=l.trim();if(!a.includes("yadm"))throw new w(`Not a YADM repository (git-dir does not contain "yadm").
155
+
156
+ Git directory: ${a}
157
+
158
+ This appears to be a regular Git repository.`);return t}catch(e){if(e instanceof w)throw e;const t=e;if(t.code==="ENOENT")throw new w(`YADM command not found!
159
+
160
+ Please install YADM first: https://yadm.io/`);if(t.stderr){if(t.stderr.includes("not a git repository"))throw new w(`Not in a YADM repository!
161
+
162
+ Initialize with: yadm init
163
+ Or clone your dotfiles: yadm clone <url>`);if(t.stderr.includes("permission denied"))throw new w(`YADM permission denied: ${t.stderr.trim()}
164
+
165
+ Check file permissions and repository access.`)}throw new w(`Failed to verify YADM repository: ${t.message||"Unknown error"}`)}}async getStagedDiff(e,t){const o=["diff","--cached","--diff-algorithm=minimal"],{stdout:s}=await M("yadm",[...o,"--name-only",...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]);if(!s)return null;const{stdout:n}=await M("yadm",[...o,...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),i=s.split(`
166
+ `).filter(Boolean),{stdout:l}=await M("yadm",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...t?t.map(this.excludeFromDiff):[]]),a=[],d=l.split(`
167
+ `).filter(Boolean);for(const m of d){const p=m.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let c=n;if(a.length>0){n.trim()||(c=""),c+=`
168
+
169
+ --- Binary Files Changed ---
170
+ `;for(const m of a){const{stdout:p}=await M("yadm",["status","--porcelain",m]),h=p.substring(0,2).trim();c+=`Binary file ${m} ${h==="A"?"added":h==="M"?"modified":h==="D"?"deleted":"changed"}
171
+ `}}const u=[...new Set([...i,...a])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async getCommitDiff(e,t,o){const s=["diff-tree","-r","--no-commit-id","--name-only",e],{stdout:n}=await M("yadm",[...s,...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]);if(!n)return null;const{stdout:i}=await M("yadm",["show",e,"--",...this.filesToExclude,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),{stdout:l}=await M("yadm",["diff-tree","-r","--numstat",e,...t?t.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),a=[],d=l.split(`
172
+ `).filter(Boolean);for(const m of d){const p=m.split(" ");p[0]==="-"&&p[1]==="-"&&p[2]&&a.push(p[2])}let c=i;if(a.length>0){i.trim()||(c=""),c+=`
173
+
174
+ --- Binary Files Changed ---
175
+ `;for(const m of a)c+=`Binary file ${m} changed
176
+ `}const u=[...new Set([...n.split(`
177
+ `).filter(Boolean),...a])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async commit(e,t=[]){try{await M("yadm",["commit","-m",e,...t],{stdio:"inherit"})}catch(o){const s=o;throw s.stderr?s.stderr.includes("nothing to commit")?new w(`Nothing to commit.
178
+
179
+ Stage your changes with: yadm add <file>
180
+ Or stage tracked file modifications: aicommit2 --all
181
+
182
+ Note: The --all flag only stages already-tracked files (YADM best practice).`):s.stderr.includes("Please enter the commit message")?new w(`Commit message cannot be empty.
183
+
184
+ Provide a meaningful commit message.`):s.stderr.includes("Author identity unknown")?new w(`YADM author identity not configured.
185
+
186
+ Configure with:
187
+ yadm config --global user.name "Your Name"
188
+ yadm config --global user.email "your.email@example.com"`):s.stderr.includes("Permission denied")?new w(`YADM permission error: ${s.stderr.trim()}
189
+
190
+ Check repository permissions and file access.`):new w(`YADM commit failed: ${s.stderr.trim()}`):s.exitCode===1?new w("YADM commit failed. Check your staged changes and try again."):new w(`Failed to commit with YADM: ${s.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await M("yadm",["config","--get","core.commentChar"]);return e}catch{return"#"}}}let fr=null;async function Tc(){const r=process.argv.includes("--git"),e=process.argv.includes("--yadm"),t=process.argv.includes("--jj");if(r)try{const c=new mt;return await c.assertRepo(),c}catch(c){throw new w(`--git flag is set, but Git is not available or not in a git repository.
191
+ ${c instanceof Error?c.message:String(c)}`)}if(e)try{const c=new mr;return await c.assertRepo(),c}catch(c){throw new w(`--yadm flag is set, but YADM is not available or not in a YADM repository.
192
+ ${c instanceof Error?c.message:String(c)}`)}if(t)try{const c=new dr;return await c.assertRepo(),c}catch(c){throw new w(`--jj flag is set, but Jujutsu is not available or not in a jj repository.
193
+ ${c instanceof Error?c.message:String(c)}`)}const o=process.env.FORCE_GIT==="true",s=process.env.FORCE_YADM==="true",n=process.env.FORCE_JJ==="true";if(o)try{const c=new mt;return await c.assertRepo(),c}catch(c){throw new w(`FORCE_GIT="true" environment variable is set, but Git is not available or not in a git repository.
194
+ ${c instanceof Error?c.message:String(c)}`)}if(s)try{const c=new mr;return await c.assertRepo(),c}catch(c){throw new w(`FORCE_YADM="true" environment variable is set, but YADM is not available or not in a YADM repository.
195
+ ${c instanceof Error?c.message:String(c)}`)}if(n)try{const c=new dr;return await c.assertRepo(),c}catch(c){throw new w(`FORCE_JJ="true" environment variable is set, but Jujutsu is not available or not in a jj repository.
196
+ ${c instanceof Error?c.message:String(c)}`)}let i=!1;try{i=(await ue({})).forceGit===!0}catch{i=!1}if(i)try{const c=new mt;return await c.assertRepo(),c}catch(c){throw new w(`forceGit=true is set in config, but Git is not available or not in a git repository.
197
+ ${c instanceof Error?c.message:String(c)}`)}let l=null,a=null,d=null;try{const c=new dr;return await c.assertRepo(),c}catch(c){l=c instanceof Error?c:new Error(String(c))}try{const c=new mt;return await c.assertRepo(),c}catch(c){a=c instanceof Error?c:new Error(String(c))}try{const c=new mr;return await c.assertRepo(),c}catch(c){d=c instanceof Error?c:new Error(String(c))}if(l&&a&&d){const c=l.message.replace("KnownError: ","").trim(),u=a.message.replace("KnownError: ","").trim(),m=d.message.replace("KnownError: ","").trim();throw new w(`No supported VCS repository found.
152
198
 
153
199
  Jujutsu Error:
154
- ${s}
200
+ ${c}
155
201
 
156
202
  Git Error:
157
- ${n}
203
+ ${u}
204
+
205
+ YADM Error:
206
+ ${m}
158
207
 
159
208
  Solutions:
160
209
  \u2022 Initialize a Jujutsu repository: jj init
161
210
  \u2022 Initialize a Git repository: git init
162
- \u2022 Navigate to an existing Jujutsu or Git repository
163
- \u2022 Set FORCE_GIT="true" environment variable to force Git detection in a jj repository
164
- \u2022 Set forceGit=true in config file to prefer Git detection`)}throw new v("Unexpected error during VCS detection")}async function $e(){return rr||(rr=await yc()),rr}const or=async()=>(await $e()).assertRepo(),sr=async(r,e)=>(await $e()).getStagedDiff(r,e),wc=async(r,e,t)=>{const o=await $e();if(!o.getCommitDiff)throw new v(`Commit diff not supported for ${o.name}`);return o.getCommitDiff(r,e,t)},vc=async()=>(await $e()).getCommentChar(),bc=r=>`Detected ${r.files.length.toLocaleString()} changed file${r.files.length>1?"s":""} (${r.diff.length.toLocaleString()} characters)`,Cc=async()=>(await $e()).name,Pc=async(r,e)=>{await(await $e()).commit(r,e||[])};class re{constructor(){this.title="aicommit2"}printTitle(){try{const e=xr.textSync(this.title,{font:"Small Slant"}),t=Ss(["#8B5CF6","#A020F0","#D946EF"]);console.log(C.bold(t.multiline(e)))}catch{console.log(C.bold(xr.textSync(this.title,{font:"Small Slant"})))}}showLoader(e){if(this.loader){this.loader.text=e;return}this.loader=Ar(e).start()}stopLoader(){this.loader?.stop(),this.loader=void 0}displaySpinner(e){return Ar(e).start()}stopSpinner(e){e.stop(),e.clear()}printStagedFiles(e){console.log(C.bold.green("\u2714 ")+C.bold(`${bc(e)}:`)),console.log(`${e.files.map(t=>` ${t}`).join(`
211
+ \u2022 Initialize a YADM repository: yadm init (or yadm clone <url>)
212
+ \u2022 Navigate to an existing Jujutsu, Git, or YADM repository
213
+ \u2022 Set FORCE_GIT="true" environment variable to force Git detection
214
+ \u2022 Set forceGit=true in config file to prefer Git detection`)}throw new w("Unexpected error during VCS detection")}async function $e(){return fr||(fr=await Tc()),fr}const pr=async()=>(await $e()).assertRepo(),hr=async(r,e)=>(await $e()).getStagedDiff(r,e),Nc=async(r,e,t)=>{const o=await $e();if(!o.getCommitDiff)throw new w(`Commit diff not supported for ${o.name}`);return o.getCommitDiff(r,e,t)},_c=async()=>(await $e()).getCommentChar(),Gc=r=>`Detected ${r.files.length.toLocaleString()} changed file${r.files.length>1?"s":""} (${r.diff.length.toLocaleString()} characters)`,ft=async()=>(await $e()).name,Bc=async(r,e)=>{await(await $e()).commit(r,e||[])};class se{constructor(){this.title="aicommit2"}printTitle(){try{const e=jr.textSync(this.title,{font:"Small Slant"}),t=Ws(["#8B5CF6","#A020F0","#D946EF"]);console.log(C.bold(t.multiline(e)))}catch{console.log(C.bold(jr.textSync(this.title,{font:"Small Slant"})))}}showLoader(e){if(this.loader){this.loader.text=e;return}this.loader=Tr(e).start()}stopLoader(){this.loader?.stop(),this.loader=void 0}displaySpinner(e){return Tr(e).start()}stopSpinner(e){e.stop(),e.clear()}printStagedFiles(e){console.log(C.bold.green("\u2714 ")+C.bold(`${Gc(e)}:`)),console.log(`${e.files.map(t=>` ${t}`).join(`
165
215
  `)}
166
216
  `)}printAnalyzed(){console.log(`
167
217
  ${C.bold.green("\u2714")} ${C.bold("Changes analyzed")}`)}printCommitted(){console.log(`
@@ -173,61 +223,74 @@ ${C.bold.red("\u2716")} ${C.red(`${e}`)}`)}printWarning(e){console.log(`
173
223
  ${C.bold.yellow("\u26A0")} ${C.red(`${e}`)}`)}printSuccess(e){console.log(`
174
224
  ${C.bold.green("\u2714")} ${C.green(`${e}`)}`)}printInfo(e){console.log(`
175
225
  ${C.bold.blue("\u2139")} ${C.blue(`${e}`)}`)}printSetupGitEvent(e){console.log(`
176
- ${C.bold.green("\u2714")} ${C.bold(`Git ${e} hook has been set up`)}`)}moveCursorUp(){const e=ze.createInterface({input:process.stdin,output:process.stdout});ze.moveCursor(process.stdout,0,-1),e.close()}moveCursorDown(){const e=ze.createInterface({input:process.stdin,output:process.stdout});ze.moveCursor(process.stdout,0,2),e.close()}print(e){console.log(e)}}const Ec={isLoading:!1,startOption:{text:"AI is analyzing your changes"}},Fo={isLoading:!1,startOption:{text:"AI is performing a code review"}},nr="No commit messages were generated",Lo="No code reviews were generated",ir={type:"reactiveListPrompt",name:"aicommit2Prompt",message:"Pick a commit message to use: ",emptyMessage:`\u26A0 ${nr}`,loop:!1,descPageSize:15,showDescription:!0,pickKey:"short",isDescriptionDim:!0,stopMessage:"Changes analyzed"};class ar{constructor(e){this.choices$=new wr([]),this.destroyed$=new ms(1),this.stopMessage="Changes analyzed",this.isDestroyed=!1,this.subscriptions=new pt,this.inquirerInstance=null,this.loader$=new wr(e)}addSubscription(e){if(this.isDestroyed){e.unsubscribe();return}this.subscriptions.add(e)}initPrompt(e=ir){return this.stopMessage=e.stopMessage,Be.registerPrompt("reactiveListPrompt",Ms),this.inquirerInstance=Be.prompt({choices$:this.choices$,loader$:this.loader$,...e}),this.inquirerInstance}startLoader(){this.loader$.next({isLoading:!0})}clearLoader(){this.inquirerInstance&&this.loader$.next({isLoading:!1,clear:!0})}refreshChoices(e){this.isDestroyed||!e||!e.value||this.choices$.next([...this.currentChoices,e].sort(ea))}checkErrorOnChoices(e=!0){if(this.choices$.getValue().map(o=>o).every(o=>o?.isError||o?.disabled)){this.alertNoGeneratedMessage(),this.logEmptyCommitMessage(),e&&process.exit(1);return}this.stopLoaderOnSuccess()}completeSubject(){try{this.destroyed$.next(!0),this.destroyed$.complete(),this.choices$.closed||this.choices$.complete(),this.loader$.closed||this.loader$.complete()}catch(e){console.warn("Error completing subjects:",e)}}closeInquirerInstance(){if(!this.inquirerInstance)return;const e=this.inquirerInstance.ui;e?.rl&&!e.rl.closed&&e.close()}cancel(){this.inquirerInstance?.ui?.activePrompt&&this.inquirerInstance.ui.activePrompt.abortPrompt()}destroy(){if(!this.isDestroyed){this.isDestroyed=!0;try{this.cancel(),this.closeInquirerInstance(),this.subscriptions.unsubscribe(),this.completeSubject()}catch(e){ba()&&console.warn("Error during ReactivePromptManager destruction:",e)}finally{this.inquirerInstance=null}}}alertNoGeneratedMessage(){this.loader$.next({isLoading:!1,message:nr,stopOption:{doneFrame:"\u26A0",color:"yellow"}})}stopLoaderOnSuccess(){this.loader$.next({isLoading:!1,message:this.stopMessage})}logEmptyCommitMessage(){console.log(`
177
- ${C.bold.yellow("\u26A0")} ${C.yellow(`${nr}`)}`)}get currentChoices(){return this.choices$.getValue().map(e=>e)}}const K=new re;var $c=async(r,e,t,o,s,n,i,c,a,m,u,l,d,p)=>(async()=>{K.printTitle(),await or(),o&&await Cc()==="git"&&await j("git",["add","--update"]);const g={locale:r?.toString(),generate:e?.toString(),type:s?.toString(),systemPrompt:c?.toString(),includeBody:a?.toString(),disableLowerCase:l?.toString()};d&&(g.logLevel="verbose");const h=await ue(g,p);(a===!0||h.includeBody===!0)&&Object.keys(h).forEach($=>{typeof h[$]=="object"&&h[$]!==null&&"includeBody"in h[$]&&(h[$].includeBody=!0)}),l&&Object.keys(h).forEach($=>{typeof h[$]=="object"&&h[$]!==null&&"disableLowerCase"in h[$]&&(h[$].disableLowerCase=!0)}),await Co(h);const w=K.displaySpinner("Detecting staged files"),b=await sr(t,h.exclude);if(w.stop(),!b)throw new v("No staged changes found. Stage your changes manually, or automatically stage all changes with the `--all` flag.");K.printStagedFiles(b);const P=To(h,"commit");if(P.length===0)throw new v("Please set at least one API key via the `aicommit2 config set` command");const k=new at(h,b),A=To(h,"review");A.length>0&&await xc(k,A);let E=await Ac(k,P,m);if(u){if(K.printInfo("Opening editor to modify commit message..."),E=await kc(E),!E.trim())throw new v("Commit message cannot be empty");K.printSuccess("Commit message edited successfully!"),console.log(`
178
- ${E}
179
- `)}i&&(Vs("copy-paste").copy(E),K.printCopied(),process.exit()),(n||m&&P.length===1)&&(await jo(E,p),process.exit());const{confirmationPrompt:x}=await Be.prompt([{type:"confirm",name:"confirmationPrompt",message:"Use selected message?",default:!0}]);x?await jo(E,p):K.printCancelledCommit(),process.exit()})().catch(g=>{K.printError(g.message),ie(g),process.exit(1)});function To(r,e){return Object.entries(r).map(([t,o])=>[t,o]).filter(([t,o])=>!o.disabled).filter(([t,o])=>ve.includes(t)||o.compatible===!0).filter(([t,o])=>{switch(e){case"commit":return t==="OLLAMA"?!!o&&!!o.model&&o.model.length>0:t==="HUGGINGFACE"?!!o&&!!o.cookie:!!o.key&&o.key.length>0;case"review":const s=r.codeReview||o.codeReview;return t==="OLLAMA"?!!o&&!!o.model&&o.model.length>0&&s:t==="HUGGINGFACE"?!!o&&!!o.cookie&&s:!!o.key&&o.key.length>0&&s}}).map(([t])=>t)}async function xc(r,e){const t=new ar(Fo);let o=null;try{const s=t.initPrompt({...ir,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Lo}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20});if(t.startLoader(),o=r.createCodeReviewRequests$(e).subscribe({next:a=>t.refreshChoices(a),error:a=>{console.error("Code review request error:",a),t.checkErrorOnChoices()},complete:()=>t.checkErrorOnChoices()}),!(await s).codeReviewPrompt?.value)throw new v("An error occurred! No selected code review");K.moveCursorUp();const{continuePrompt:c}=await Be.prompt([{type:"confirm",name:"continuePrompt",message:"Will you continue without changing the code?",default:!0}]);c||(K.printCancelledCommit(),process.exit())}finally{o&&o.unsubscribe(),t.destroy()}}async function Ac(r,e,t){const o=new ar(Ec);let s=null;try{if(t&&e.length===1){const a=[];o.startLoader(),s=r.createCommitMsgRequests$(e).subscribe({next:u=>{a.push(u),o.refreshChoices(u)},error:u=>{console.error("Commit message generation error:",u),o.checkErrorOnChoices(!1)},complete:()=>o.checkErrorOnChoices(!1)}),await new Promise(u=>{s?.add(()=>u())}),o.clearLoader(),K.moveCursorUp();const m=a.find(u=>u.value&&!u.isError&&!u.disabled);if(!m||!m.value)throw new v("No valid commit message was generated");return K.print(`
180
- ${m.name}
181
- `),m.value}const n=o.initPrompt();o.startLoader(),s=r.createCommitMsgRequests$(e).subscribe({next:a=>o.refreshChoices(a),error:a=>{console.error("Commit message generation error:",a),o.checkErrorOnChoices()},complete:()=>o.checkErrorOnChoices()});const i=await n;K.moveCursorUp();const c=i.aicommit2Prompt?.value;if(!c)throw new v("An error occurred! No selected message");return c}finally{s&&s.unsubscribe(),o.destroy()}}async function kc(r){const e=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),t=S.join(xe.tmpdir(),`aicommit2-${Date.now()}-${Zo.randomBytes(4).toString("hex")}.txt`);try{U.writeFileSync(t,r,"utf8");const o=e.split(" "),[s,...n]=o;await j(s,[...n,t],{stdio:"inherit"});const i=U.readFileSync(t,"utf8").trim();if(U.unlinkSync(t),!i)throw new v("Commit cancelled - empty message");return i}catch(o){throw U.existsSync(t)&&U.unlinkSync(t),o instanceof v?o:o&&typeof o=="object"&&"exitCode"in o&&o.exitCode!==0?new v("Commit cancelled"):process.env.VISUAL||process.env.EDITOR?new v(`Failed to open editor "${e}". Please check:
226
+ ${C.bold.green("\u2714")} ${C.bold(`Git ${e} hook has been set up`)}`)}moveCursorUp(){const e=Ke.createInterface({input:process.stdin,output:process.stdout});Ke.moveCursor(process.stdout,0,-1),e.close()}moveCursorDown(){const e=Ke.createInterface({input:process.stdin,output:process.stdout});Ke.moveCursor(process.stdout,0,2),e.close()}print(e){console.log(e)}}const Hc={isLoading:!1,startOption:{text:"AI is analyzing your changes"}},ts={isLoading:!1,startOption:{text:"AI is performing a code review"}},gr="No commit messages were generated",rs="No code reviews were generated",yr={type:"reactiveListPrompt",name:"aicommit2Prompt",message:"Pick a commit message to use: ",emptyMessage:`\u26A0 ${gr}`,loop:!1,descPageSize:15,showDescription:!0,pickKey:"short",isDescriptionDim:!0,stopMessage:"Changes analyzed"};class wr{constructor(e){this.choices$=new Mr([]),this.destroyed$=new Ms(1),this.stopMessage="Changes analyzed",this.isDestroyed=!1,this.subscriptions=new Et,this.inquirerInstance=null,this.loader$=new Mr(e)}addSubscription(e){if(this.isDestroyed){e.unsubscribe();return}this.subscriptions.add(e)}initPrompt(e=yr){return this.stopMessage=e.stopMessage,ze.registerPrompt("reactiveListPrompt",Ys),this.inquirerInstance=ze.prompt({choices$:this.choices$,loader$:this.loader$,...e}),this.inquirerInstance}startLoader(){this.loader$.next({isLoading:!0})}clearLoader(){this.inquirerInstance&&this.loader$.next({isLoading:!1,clear:!0})}refreshChoices(e){this.isDestroyed||!e||!e.value||this.choices$.next([...this.currentChoices,e].sort(ba))}checkErrorOnChoices(e=!0){if(this.choices$.getValue().map(o=>o).every(o=>o?.isError||o?.disabled)){this.alertNoGeneratedMessage(),this.logEmptyCommitMessage(),e&&process.exit(1);return}this.stopLoaderOnSuccess()}completeSubject(){try{this.destroyed$.next(!0),this.destroyed$.complete(),this.choices$.closed||this.choices$.complete(),this.loader$.closed||this.loader$.complete()}catch(e){console.warn("Error completing subjects:",e)}}closeInquirerInstance(){if(!this.inquirerInstance)return;const e=this.inquirerInstance.ui;e?.rl&&!e.rl.closed&&e.close()}cancel(){this.inquirerInstance?.ui?.activePrompt&&this.inquirerInstance.ui.activePrompt.abortPrompt()}destroy(){if(!this.isDestroyed){this.isDestroyed=!0;try{this.cancel(),this.closeInquirerInstance(),this.subscriptions.unsubscribe(),this.completeSubject()}catch(e){Ba()&&console.warn("Error during ReactivePromptManager destruction:",e)}finally{this.inquirerInstance=null}}}alertNoGeneratedMessage(){this.loader$.next({isLoading:!1,message:gr,stopOption:{doneFrame:"\u26A0",color:"yellow"}})}stopLoaderOnSuccess(){this.loader$.next({isLoading:!1,message:this.stopMessage})}logEmptyCommitMessage(){console.log(`
227
+ ${C.bold.yellow("\u26A0")} ${C.yellow(`${gr}`)}`)}get currentChoices(){return this.choices$.getValue().map(e=>e)}}const z=new se;var Uc=async(r,e,t,o,s,n,i,l,a,d,c,u,m,p,h)=>(async()=>{if(z.printTitle(),await pr(),o){const I=await ft();I==="git"?await M("git",["add","."]):I==="yadm"&&await M("yadm",["add","--update"])}const g={locale:r?.toString(),generate:e?.toString(),type:s?.toString(),systemPrompt:l?.toString(),...a===!0&&{includeBody:"true"},...u===!0&&{disableLowerCase:"true"}};m&&(g.logLevel="verbose");const y=await ue(g,h);(a===!0||y.includeBody===!0)&&Object.keys(y).forEach(I=>{typeof y[I]=="object"&&y[I]!==null&&"includeBody"in y[I]&&(y[I].includeBody=!0)}),u&&Object.keys(y).forEach(I=>{typeof y[I]=="object"&&y[I]!==null&&"disableLowerCase"in y[I]&&(y[I].disableLowerCase=!0)}),await Uo(y);const b=z.displaySpinner("Detecting staged files"),E=await hr(t,y.exclude);if(b.stop(),!E){const I=await ft();let _="No staged changes found.";throw I==="yadm"?(_+=`
228
+
229
+ Stage your changes with: yadm add <file>`,_+=`
230
+ Or stage tracked file modifications: aicommit2 --all`,_+=`
231
+
232
+ Note: The --all flag only stages already-tracked files (YADM best practice).`,_+=`
233
+ To track new dotfiles, explicitly add them first: yadm add <file>`):I==="git"?(_+=`
234
+
235
+ Stage your changes with: git add <file>`,_+=`
236
+ Or automatically stage all changes: aicommit2 --all`):I==="jujutsu"&&(_+=`
237
+
238
+ Jujutsu automatically tracks all changes in the working copy.`,_+=`
239
+ Make some changes to your files and try again.`),new w(_)}z.printStagedFiles(E);const x=os(y,"commit");if(x.length===0)throw new w("Please set at least one API key via the `aicommit2 config set` command");const A=new dt(y,E),P=os(y,"review");P.length>0&&await zc(A,P);let $=await Wc(A,x,d);if(c){if(z.printInfo("Opening editor to modify commit message..."),$=await Yc($),!$.trim())throw new w("Commit message cannot be empty");z.printSuccess("Commit message edited successfully!"),z.print(`
240
+ ${$}
241
+ `)}i&&(mn("copy-paste").copy($),z.printCopied(),p||process.exit()),p&&(process.stdout.write($+`
242
+ `),process.exit()),(n||d&&x.length===1)&&(await ss($,h),process.exit());const{confirmationPrompt:k}=await ze.prompt([{type:"confirm",name:"confirmationPrompt",message:"Use selected message?",default:!0}]);k?await ss($,h):z.printCancelledCommit(),process.exit()})().catch(g=>{z.printError(g.message),ae(g),process.exit(1)});function os(r,e){return Object.entries(r).map(([t,o])=>[t,o]).filter(([t,o])=>!o.disabled).filter(([t,o])=>ve.includes(t)||o.compatible===!0).filter(([t,o])=>{switch(e){case"commit":return t==="OLLAMA"?!!o&&!!o.model&&o.model.length>0:t==="HUGGINGFACE"?!!o&&!!o.cookie:!!o.key&&o.key.length>0;case"review":const s=r.codeReview||o.codeReview;return t==="OLLAMA"?!!o&&!!o.model&&o.model.length>0&&s:t==="HUGGINGFACE"?!!o&&!!o.cookie&&s:!!o.key&&o.key.length>0&&s}}).map(([t])=>t)}async function zc(r,e){const t=new wr(ts);let o=null;try{const s=t.initPrompt({...yr,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${rs}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20});if(t.startLoader(),o=r.createCodeReviewRequests$(e).subscribe({next:a=>t.refreshChoices(a),error:a=>{console.error("Code review request error:",a),t.checkErrorOnChoices()},complete:()=>t.checkErrorOnChoices()}),!(await s).codeReviewPrompt?.value)throw new w("An error occurred! No selected code review");z.moveCursorUp();const{continuePrompt:l}=await ze.prompt([{type:"confirm",name:"continuePrompt",message:"Will you continue without changing the code?",default:!0}]);l||(z.printCancelledCommit(),process.exit())}finally{o&&o.unsubscribe(),t.destroy()}}async function Wc(r,e,t){const o=new wr(Hc);let s=null;try{if(t&&e.length===1){const a=[];o.startLoader(),s=r.createCommitMsgRequests$(e).subscribe({next:c=>{a.push(c),o.refreshChoices(c)},error:c=>{console.error("Commit message generation error:",c),o.checkErrorOnChoices(!1)},complete:()=>o.checkErrorOnChoices(!1)}),await new Promise(c=>{s?.add(()=>c())}),o.clearLoader(),z.moveCursorUp();const d=a.find(c=>c.value&&!c.isError&&!c.disabled);if(!d||!d.value)throw new w("No valid commit message was generated");return z.print(`
243
+ ${d.name}
244
+ `),d.value}const n=o.initPrompt();o.startLoader(),s=r.createCommitMsgRequests$(e).subscribe({next:a=>o.refreshChoices(a),error:a=>{console.error("Commit message generation error:",a),o.checkErrorOnChoices()},complete:()=>o.checkErrorOnChoices()});const i=await n;z.moveCursorUp();const l=i.aicommit2Prompt?.value;if(!l)throw new w("An error occurred! No selected message");return l}finally{s&&s.unsubscribe(),o.destroy()}}async function Yc(r){const e=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),t=S.join(ke.tmpdir(),`aicommit2-${Date.now()}-${ys.randomBytes(4).toString("hex")}.txt`);try{W.writeFileSync(t,r,"utf8");const o=e.split(" "),[s,...n]=o;await M(s,[...n,t],{stdio:"inherit"});const i=W.readFileSync(t,"utf8").trim();if(W.unlinkSync(t),!i)throw new w("Commit cancelled - empty message");return i}catch(o){throw W.existsSync(t)&&W.unlinkSync(t),o instanceof w?o:o&&typeof o=="object"&&"exitCode"in o&&o.exitCode!==0?new w("Commit cancelled"):process.env.VISUAL||process.env.EDITOR?new w(`Failed to open editor "${e}". Please check:
182
245
  - Editor binary exists in PATH
183
246
  - Editor flags are correct
184
- - EDITOR/VISUAL is set correctly`):new v(`Failed to open editor "${e}". Please set your EDITOR or VISUAL environment variable to a valid editor command.`)}}async function jo(r,e){await Pc(r,e),K.printCommitted()}var Sc=oe({name:"config",parameters:["<mode>","[key=value...]"],help:{description:"Manage configuration settings",examples:["aic2 config set <key>=<value> [<key>=<value> ...]","aic2 config get [<key> [<key> ...]]","aic2 config add <key>=<value> [<key>=<value> ...]","aic2 config del <key>","aic2 config list"]},commands:[oe({name:"set",parameters:["<key>=<value>","[<key>=<value> ...]"],help:{description:"Set configuration values. Multiple key-value pairs can be set at once.",examples:["aic2 config set OPENAI.key=<your key>","aic2 config set ANTHROPIC.topP=0.8 ANTHROPIC.generate=2"]}}),oe({name:"get",parameters:["[<key>","[<key> ...]]"],help:{description:"Retrieve configuration values for specified AI provider.",examples:["aic2 config get OPENAI","aic2 config get ANTHROPIC"]}}),oe({name:"add",parameters:["<key>=<value>","[<key>=<value> ...]"],help:{description:"Add new model to existing configuration. Only Ollama.model can be added.",examples:['aic2 config add OLLAMA.model="gemma2"']}}),oe({name:"list",parameters:[],help:{description:"Display all configuration keys and their values.",examples:["aic2 config list"]}}),oe({name:"del",parameters:["<config-name>"],help:{description:"Delete a configuration setting or section.",examples:["aic2 config del <config-name>","aic2 config del OPENAI.key","aic2 config del OPENAI"]}}),oe({name:"path",parameters:[],help:{description:"Display the path of the loaded configuration file.",examples:["aic2 config path"]}})]},r=>{(async()=>{const{mode:e,keyValue:t}=r._,o=r._[1];if(e==="get"){const s=await ue({},[]);if(t.length===0){console.log(s);return}for(const n of t){const i=n.split(".");let c=s,a=!0;for(const m of i)if(Gt(c,m))c=c[m];else{a=!1;break}a?console.log(n,c):console.log(`${n} not found`)}return}if(e==="set"){await _t(t.map(s=>{const n=s.indexOf("=");if(n===-1)throw new v("Invalid format. Use: key=value");const i=s.slice(0,n),c=s.slice(n+1);return[i,c]}));return}if(e==="add"){await ma(t.map(s=>{const n=s.indexOf("=");if(n===-1)throw new v("Invalid format. Use: key=value");const i=s.slice(0,n),c=s.slice(n+1);return[i,c]}));return}if(e==="list"){await fa();return}if(e==="del"){if(!o)throw new v("Please provide the config name to delete.");const s=await Re(),n=o.split(".");if(n.length===2){const[i,c]=n;if(s[i]&&typeof s[i]=="object"&&Gt(s[i],c)){delete s[i][c],Object.keys(s[i]).length===0&&delete s[i];const a=await be();await O.writeFile(a,we.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const m=await O.readFile(a,"utf8");console.log("--- Updated Config Content ---"),console.log(m),console.log("----------------------------")}else throw new v(`Config not found: ${o}`)}else if(n.length===1){const i=n[0];if(Gt(s,i)){delete s[i];const c=await be();await O.writeFile(c,we.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const a=await O.readFile(c,"utf8");console.log("--- Updated Config Content ---"),console.log(a),console.log("----------------------------")}else throw new v(`Config not found: ${o}`)}else throw new v(`Invalid config name format: ${o}`);return}if(e==="path"){await pa();return}throw new v(`Invalid mode: ${e}`)})().catch(e=>{new re().printError(e.message),ie(e),process.exit(1)})}),Mc=oe({name:"github-login",parameters:[],flags:{token:{type:String,description:"Manually provide a GitHub token for authentication",alias:"t"}},help:{description:"Login to GitHub and setup access to GitHub Models",examples:["aic2 github-login","aic2 github-login --token ghp_xxxxxxxxxxxxxxxxxxxx"]}},r=>{(async()=>{const e=new re;if(r.flags.token){try{await Ic(r.flags.token,e)}catch(t){throw new v(`Token authentication failed: ${t.message}`)}return}try{await Rc(e)}catch(t){throw new v(`Browser authentication failed: ${t.message}`)}})().catch(e=>{new re().printError(e.message),ie(e),process.exit(1)})});async function Ic(r,e){if(e.printWarning("Authenticating with provided token..."),!r.startsWith("ghp_")&&!r.startsWith("gho_")&&!r.startsWith("ghu_"))throw new Error("Invalid token format. GitHub tokens should start with ghp_, gho_, or ghu_");try{const t=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${r}`,Accept:"application/vnd.github.v3+json","User-Agent":"aicommit2-github-models"}});if(!t.ok)throw new Error(`GitHub API request failed: ${t.status} ${t.statusText}`);const o=await t.json();try{(await fetch("https://models.github.ai/inference/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/vnd.github+json",Authorization:`Bearer ${r}`,"User-Agent":"aicommit2-github-models"},body:JSON.stringify({messages:[{role:"user",content:"test"}],model:"gpt-4o-mini",max_tokens:1})})).ok?e.printSuccess("GitHub Models access verified!"):e.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}catch{e.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}await _t([["GITHUB_MODELS.key",r]]),e.printSuccess(`Successfully authenticated as ${o.login}`)}catch(t){throw new Error(`Token validation failed: ${t.message}`)}}async function Rc(r){r.printInfo("Starting GitHub browser authentication for GitHub Models...");try{try{_e("gh --version",{stdio:"ignore"})}catch{throw new Error("GitHub CLI (gh) is not installed. Please install it first: https://cli.github.com/")}try{_e("gh auth status",{encoding:"utf8",stdio:"pipe"}).includes("Logged in to github.com")&&r.printInfo("Already authenticated with GitHub CLI")}catch{r.printInfo("Authenticating with GitHub CLI..."),r.printInfo("Please follow the instructions in your browser to complete authentication.");try{_e("gh auth login --web -h github.com",{stdio:"inherit"})}catch{throw new Error("GitHub CLI authentication failed")}}r.printInfo("Verifying GitHub Models access...");try{const e=_e("gh auth token",{encoding:"utf8"}).trim();e&&(await _t([["GITHUB_MODELS.key",e]]),r.printSuccess("GitHub token stored for GitHub Models access"))}catch{r.printWarning("Could not extract token from GitHub CLI, but authentication completed")}r.printSuccess("GitHub authentication completed and GitHub Models access verified!"),r.printInfo("See usage guide: https://github.com/tak-bro/aicommit2/blob/main/docs/providers/github-models.md"),r.printInfo("Available models: gpt-4o-mini, gpt-4o, meta-llama-3.1-405b-instruct, etc."),r.printInfo("Using GitHub Models API: https://models.github.ai")}catch(e){throw e}}const No="prepare-commit-msg",Go=`.git/hooks/${No}`,ct=Ps(new URL("cli.mjs",import.meta.url)),Oc=process.argv[1].replace(/\\/g,"/").endsWith(`/${Go}`),_o=process.platform==="win32",Bo=`
247
+ - EDITOR/VISUAL is set correctly`):new w(`Failed to open editor "${e}". Please set your EDITOR or VISUAL environment variable to a valid editor command.`)}}async function ss(r,e){await Bc(r,e),z.printCommitted()}var Kc=ne({name:"config",parameters:["<mode>","[key=value...]"],help:{description:"Manage configuration settings",examples:["aic2 config set <key>=<value> [<key>=<value> ...]","aic2 config get [<key> [<key> ...]]","aic2 config add <key>=<value> [<key>=<value> ...]","aic2 config del <key>","aic2 config list"]},commands:[ne({name:"set",parameters:["<key>=<value>","[<key>=<value> ...]"],help:{description:"Set configuration values. Multiple key-value pairs can be set at once.",examples:["aic2 config set OPENAI.key=<your key>","aic2 config set ANTHROPIC.topP=0.8 ANTHROPIC.generate=2"]}}),ne({name:"get",parameters:["[<key>","[<key> ...]]"],help:{description:"Retrieve configuration values for specified AI provider.",examples:["aic2 config get OPENAI","aic2 config get ANTHROPIC"]}}),ne({name:"add",parameters:["<key>=<value>","[<key>=<value> ...]"],help:{description:"Add new model to existing configuration. Only Ollama.model can be added.",examples:['aic2 config add OLLAMA.model="gemma2"']}}),ne({name:"list",parameters:[],help:{description:"Display all configuration keys and their values.",examples:["aic2 config list"]}}),ne({name:"del",parameters:["<config-name>"],help:{description:"Delete a configuration setting or section.",examples:["aic2 config del <config-name>","aic2 config del OPENAI.key","aic2 config del OPENAI"]}}),ne({name:"path",parameters:[],help:{description:"Display the path of the loaded configuration file.",examples:["aic2 config path"]}})]},r=>{(async()=>{const{mode:e,keyValue:t}=r._,o=r._[1];if(e==="get"){const s=await ue({},[]);if(t.length===0){console.log(s);return}for(const n of t){const i=n.split(".");let l=s,a=!0;for(const d of i)if(Jt(l,d))l=l[d];else{a=!1;break}a?console.log(n,l):console.log(`${n} not found`)}return}if(e==="set"){await Vt(t.map(s=>{const n=s.indexOf("=");if(n===-1)throw new w("Invalid format. Use: key=value");const i=s.slice(0,n),l=s.slice(n+1);return[i,l]}));return}if(e==="add"){await Oa(t.map(s=>{const n=s.indexOf("=");if(n===-1)throw new w("Invalid format. Use: key=value");const i=s.slice(0,n),l=s.slice(n+1);return[i,l]}));return}if(e==="list"){await Fa();return}if(e==="del"){if(!o)throw new w("Please provide the config name to delete.");const s=await Fe(),n=o.split(".");if(n.length===2){const[i,l]=n;if(s[i]&&typeof s[i]=="object"&&Jt(s[i],l)){delete s[i][l],Object.keys(s[i]).length===0&&delete s[i];const a=await Ce();await O.writeFile(a,we.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const d=await O.readFile(a,"utf8");console.log("--- Updated Config Content ---"),console.log(d),console.log("----------------------------")}else throw new w(`Config not found: ${o}`)}else if(n.length===1){const i=n[0];if(Jt(s,i)){delete s[i];const l=await Ce();await O.writeFile(l,we.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const a=await O.readFile(l,"utf8");console.log("--- Updated Config Content ---"),console.log(a),console.log("----------------------------")}else throw new w(`Config not found: ${o}`)}else throw new w(`Invalid config name format: ${o}`);return}if(e==="path"){await La();return}throw new w(`Invalid mode: ${e}`)})().catch(e=>{new se().printError(e.message),ae(e),process.exit(1)})}),Jc=ne({name:"github-login",parameters:[],flags:{token:{type:String,description:"Manually provide a GitHub token for authentication",alias:"t"}},help:{description:"Login to GitHub and setup access to GitHub Models",examples:["aic2 github-login","aic2 github-login --token ghp_xxxxxxxxxxxxxxxxxxxx"]}},r=>{(async()=>{const e=new se;if(r.flags.token){try{await Vc(r.flags.token,e)}catch(t){throw new w(`Token authentication failed: ${t.message}`)}return}try{await qc(e)}catch(t){throw new w(`Browser authentication failed: ${t.message}`)}})().catch(e=>{new se().printError(e.message),ae(e),process.exit(1)})});async function Vc(r,e){if(e.printWarning("Authenticating with provided token..."),!r.startsWith("ghp_")&&!r.startsWith("gho_")&&!r.startsWith("ghu_"))throw new Error("Invalid token format. GitHub tokens should start with ghp_, gho_, or ghu_");try{const t=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${r}`,Accept:"application/vnd.github.v3+json","User-Agent":"aicommit2-github-models"}});if(!t.ok)throw new Error(`GitHub API request failed: ${t.status} ${t.statusText}`);const o=await t.json();try{(await fetch("https://models.github.ai/inference/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/vnd.github+json",Authorization:`Bearer ${r}`,"User-Agent":"aicommit2-github-models"},body:JSON.stringify({messages:[{role:"user",content:"test"}],model:"gpt-4o-mini",max_tokens:1})})).ok?e.printSuccess("GitHub Models access verified!"):e.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}catch{e.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}await Vt([["GITHUB_MODELS.key",r]]),e.printSuccess(`Successfully authenticated as ${o.login}`)}catch(t){throw new Error(`Token validation failed: ${t.message}`)}}async function qc(r){r.printInfo("Starting GitHub browser authentication for GitHub Models...");try{try{Ue("gh --version",{stdio:"ignore"})}catch{throw new Error("GitHub CLI (gh) is not installed. Please install it first: https://cli.github.com/")}try{Ue("gh auth status",{encoding:"utf8",stdio:"pipe"}).includes("Logged in to github.com")&&r.printInfo("Already authenticated with GitHub CLI")}catch{r.printInfo("Authenticating with GitHub CLI..."),r.printInfo("Please follow the instructions in your browser to complete authentication.");try{Ue("gh auth login --web -h github.com",{stdio:"inherit"})}catch{throw new Error("GitHub CLI authentication failed")}}r.printInfo("Verifying GitHub Models access...");try{const e=Ue("gh auth token",{encoding:"utf8"}).trim();e&&(await Vt([["GITHUB_MODELS.key",e]]),r.printSuccess("GitHub token stored for GitHub Models access"))}catch{r.printWarning("Could not extract token from GitHub CLI, but authentication completed")}r.printSuccess("GitHub authentication completed and GitHub Models access verified!"),r.printInfo("See usage guide: https://github.com/tak-bro/aicommit2/blob/main/docs/providers/github-models.md"),r.printInfo("Available models: gpt-4o-mini, gpt-4o, meta-llama-3.1-405b-instruct, etc."),r.printInfo("Using GitHub Models API: https://models.github.ai")}catch(e){throw e}}const Ae="prepare-commit-msg",Xc=async()=>{const r=await ft();if(r==="git")return`.git/hooks/${Ae}`;if(r==="yadm"){const e=process.env.HOME||process.env.USERPROFILE;if(!e)throw new w("HOME environment variable not set. Cannot determine YADM hook path.");try{const{execa:s}=await Promise.resolve().then(function(){return va}),{stdout:n}=await s("yadm",["introspect","repo"]),i=n.trim();if(i)return S.join(i,"hooks",Ae)}catch{}const t=S.join(e,".config/yadm/hooks"),o=S.join(e,".yadm/hooks");try{return await O.access(t),S.join(t,Ae)}catch{return S.join(o,Ae)}}throw r==="jujutsu"?new w("Hooks are not supported for Jujutsu repositories."):new w(`Hooks are not supported for ${r} repositories.`)},pt=_s(new URL("cli.mjs",import.meta.url)),Qc=process.argv[1].replace(/\\/g,"/").includes(`/hooks/${Ae}`),ns=process.platform==="win32",is=`
185
248
  #!/usr/bin/env node
186
- import(${JSON.stringify(Es(ct))})
187
- `.trim();var Dc=oe({name:"hook",parameters:["<install/uninstall>"],help:{description:"Install or uninstall the Git prepare-commit-msg hook",examples:["aic2 hook install","aic2 hook uninstall"]}},r=>{(async()=>{const e=await or(),{installUninstall:t}=r._,o=S.join(e,Go),s=await uo(o);if(t==="install"){if(s){if(await O.realpath(o).catch(()=>{})===ct){console.warn("The hook is already installed");return}throw new v(`A different ${No} hook seems to be installed. Please remove it before installing aicommit2.`)}await O.mkdir(S.dirname(o),{recursive:!0}),_o?await O.writeFile(o,Bo):(await O.symlink(ct,o,"file"),await O.chmod(o,493)),console.log(`${C.green("\u2714")} Hook installed`);return}if(t==="uninstall"){if(!s){console.warn("Hook is not installed");return}if(_o){if(await O.readFile(o,"utf8")!==Bo){console.warn("Hook is not installed");return}}else if(await O.realpath(o)!==ct){console.warn("Hook is not installed");return}await O.rm(o),console.log(`${C.green("\u2714")} Hook uninstalled`);return}throw new v(`Invalid mode: ${t}`)})().catch(e=>{console.error(`${C.red("\u2716")} ${e.message}`),ie(e),process.exit(1)})});const Fc=ds(rs),Lc=r=>{const e=["B","KB","MB","GB"];if(r===0)return"0 B";const t=Math.floor(Math.log(r)/Math.log(1024));return Math.round(r/Math.pow(1024,t)*100)/100+" "+e[t]},Tc=r=>r.toLocaleDateString()+" "+r.toLocaleTimeString(),jc=async r=>{try{const e=await kr(ee);if(e.length===0){console.log(`${C.yellow("No log files found.")}`);return}console.log(`${C.blue("Log files in")} ${ee}:
188
- `);const t=await Promise.all(e.map(async o=>{const s=ce.join(ee,o),n=await Is(s);return{name:o,size:Lc(n.size),modified:Tc(n.mtime)}}));t.sort((o,s)=>new Date(s.modified).getTime()-new Date(o.modified).getTime()),t.forEach((o,s)=>{console.log(`${s===0?"\u{1F4C4}":" "} ${C.cyan(o.name)} ${C.gray(`(${o.size}, ${o.modified})`)}`)}),console.log(`
189
- ${C.green("Total:")} ${e.length} file${e.length!==1?"s":""}`)}catch(e){if(e.code==="ENOENT")console.log(`${C.yellow("Logs directory does not exist yet.")}`);else throw e}},Nc=async r=>{try{await kr(ee);const e=process.platform;let t;switch(e){case"darwin":t=`open "${ee}"`;break;case"win32":t=`start "" "${ee}"`;break;default:t=`xdg-open "${ee}"`;break}await Fc(t),console.log(`${C.green("\u2714")} Opened logs directory in file manager`)}catch(e){e.code==="ENOENT"?console.log(`${C.yellow("Logs directory does not exist yet.")}`):r.printError(`Failed to open logs directory: ${e.message}`)}},Gc=async r=>{try{await Rs(ee,{recursive:!0,force:!0}),console.log(`${C.green("\u2714")} All log files removed!`)}catch(e){r.printError(`Failed to remove log files: ${e.message}`)}};var _c=oe({name:"log",parameters:["<action>"],help:{description:"Manage log files generated by the application",examples:["aic2 log list # List all log files","aic2 log path # Show logs directory path","aic2 log open # Open logs directory","aic2 log removeAll # Remove all log files"]}},r=>{(async()=>{const{action:e}=r._,t=new re;switch(e){case"list":await jc();break;case"path":console.log(`${C.blue("Logs directory:")} ${ee}`);break;case"open":await Nc(t);break;case"removeAll":await Gc(t);break;default:throw new v(`Invalid action: ${e}. Use 'list', 'path', 'open', or 'removeAll'`)}})().catch(e=>{new re().printError(e.message),ie(e),process.exit(1)})});const Bc=process.argv.slice(2).filter(r=>!r.startsWith("--pre-commit")),[lt,Ho]=Bc;var Hc=(r=!1)=>(async()=>{if(!lt)throw new v('Commit message file path is missing. This file should be called from the "pre-commit framework"');if(Ho){console.log(`Skipping aicommit2 message generation for ${Ho} commit`);return}const e=await sr();if(!e)return;const t=new re;t.printTitle();const o={};r&&(o.logLevel="verbose");const s=await ue(o);if(s.systemPromptPath)try{await O.readFile(S.resolve(s.systemPromptPath),"utf-8")}catch{throw new v(`Error reading system prompt file: ${s.systemPromptPath}`)}const n=Object.entries(s).filter(([h])=>ve.includes(h)).map(([h,y])=>[h,y]).filter(([h,y])=>!y.disabled).filter(([h,y])=>h==="OLLAMA"?!!y&&!!y.model&&y.model.length>0:h==="HUGGINGFACE"?!!y&&!!y.cookie:!!y.key&&y.key.length>0).map(([h])=>h);if(n.length===0)throw new v("Please set at least one API key via the `aicommit2 config set` command");const c=new at(s,e);let a;try{a=await vr(c.createCommitMsgRequests$(n).pipe(br(h=>!h.isError),I(h=>h.value),Cr()))}finally{t.printAnalyzed()}const u=await O.readFile(lt,"utf8")!=="",l=a.length>1;let d="";u&&(d=`# \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
190
- `,d+=`# ----------------------------------------
191
- `,d+=`# How to use:
192
- `,l?(d+=`# 1. Remove the "#" from your chosen message
193
- `,d+=`# 2. Edit the message if needed
194
- `,d+=`# 3. Save and close the editor
195
- `):(d+=`# 1. The message below will be used
196
- `,d+=`# 2. Edit the message if needed
197
- `,d+=`# 3. Save and close the editor
198
- `),d+=`# ----------------------------------------
199
- `),l?(u&&(d+=`
249
+ import(${JSON.stringify(Gs(pt))})
250
+ `.trim();var Zc=ne({name:"hook",parameters:["<install/uninstall>"],help:{description:"Install or uninstall the Git prepare-commit-msg hook",examples:["aic2 hook install","aic2 hook uninstall"]}},r=>{(async()=>{const e=await pr(),{installUninstall:t}=r._,o=await Xc(),s=S.isAbsolute(o)?o:S.join(e,o),n=await Oo(s);if(t==="install"){if(n){if(await O.realpath(s).catch(()=>{})===pt){console.warn("The hook is already installed");return}throw new w(`A different ${Ae} hook seems to be installed. Please remove it before installing aicommit2.`)}await O.mkdir(S.dirname(s),{recursive:!0}),ns?await O.writeFile(s,is):(await O.symlink(pt,s,"file"),await O.chmod(s,493)),console.log(`${C.green("\u2714")} Hook installed`);return}if(t==="uninstall"){if(!n){console.warn("Hook is not installed");return}if(ns){if(await O.readFile(s,"utf8")!==is){console.warn("Hook is not installed");return}}else if(await O.realpath(s)!==pt){console.warn("Hook is not installed");return}await O.rm(s),console.log(`${C.green("\u2714")} Hook uninstalled`);return}throw new w(`Invalid mode: ${t}`)})().catch(e=>{console.error(`${C.red("\u2716")} ${e.message}`),ae(e),process.exit(1)})});const el=Ss(ws),tl=r=>{const e=["B","KB","MB","GB"];if(r===0)return"0 B";const t=Math.floor(Math.log(r)/Math.log(1024));return Math.round(r/Math.pow(1024,t)*100)/100+" "+e[t]},rl=r=>r.toLocaleDateString()+" "+r.toLocaleTimeString(),ol=async r=>{try{const e=await Nr(re);if(e.length===0){console.log(`${C.yellow("No log files found.")}`);return}console.log(`${C.blue("Log files in")} ${re}:
251
+ `);const t=await Promise.all(e.map(async o=>{const s=ce.join(re,o),n=await Ks(s);return{name:o,size:tl(n.size),modified:rl(n.mtime)}}));t.sort((o,s)=>new Date(s.modified).getTime()-new Date(o.modified).getTime()),t.forEach((o,s)=>{console.log(`${s===0?"\u{1F4C4}":" "} ${C.cyan(o.name)} ${C.gray(`(${o.size}, ${o.modified})`)}`)}),console.log(`
252
+ ${C.green("Total:")} ${e.length} file${e.length!==1?"s":""}`)}catch(e){if(e.code==="ENOENT")console.log(`${C.yellow("Logs directory does not exist yet.")}`);else throw e}},sl=async r=>{try{await Nr(re);const e=process.platform;let t;switch(e){case"darwin":t=`open "${re}"`;break;case"win32":t=`start "" "${re}"`;break;default:t=`xdg-open "${re}"`;break}await el(t),console.log(`${C.green("\u2714")} Opened logs directory in file manager`)}catch(e){e.code==="ENOENT"?console.log(`${C.yellow("Logs directory does not exist yet.")}`):r.printError(`Failed to open logs directory: ${e.message}`)}},nl=async r=>{try{await Js(re,{recursive:!0,force:!0}),console.log(`${C.green("\u2714")} All log files removed!`)}catch(e){r.printError(`Failed to remove log files: ${e.message}`)}};var il=ne({name:"log",parameters:["<action>"],help:{description:"Manage log files generated by the application",examples:["aic2 log list # List all log files","aic2 log path # Show logs directory path","aic2 log open # Open logs directory","aic2 log removeAll # Remove all log files"]}},r=>{(async()=>{const{action:e}=r._,t=new se;switch(e){case"list":await ol();break;case"path":console.log(`${C.blue("Logs directory:")} ${re}`);break;case"open":await sl(t);break;case"removeAll":await nl(t);break;default:throw new w(`Invalid action: ${e}. Use 'list', 'path', 'open', or 'removeAll'`)}})().catch(e=>{new se().printError(e.message),ae(e),process.exit(1)})});const al=process.argv.slice(2).filter(r=>!r.startsWith("--pre-commit")),[ht,as]=al;var cl=(r=!1)=>(async()=>{if(!ht)throw new w('Commit message file path is missing. This file should be called from the "pre-commit framework"');if(as){console.log(`Skipping aicommit2 message generation for ${as} commit`);return}const e=await hr();if(!e)return;const t=new se;t.printTitle();const o={};r&&(o.logLevel="verbose");const s=await ue(o);if(s.systemPromptPath)try{await O.readFile(S.resolve(s.systemPromptPath),"utf-8")}catch{throw new w(`Error reading system prompt file: ${s.systemPromptPath}`)}const n=Object.entries(s).filter(([g])=>ve.includes(g)).map(([g,y])=>[g,y]).filter(([g,y])=>!y.disabled).filter(([g,y])=>g==="OLLAMA"?!!y&&!!y.model&&y.model.length>0:g==="HUGGINGFACE"?!!y&&!!y.cookie:!!y.key&&y.key.length>0).map(([g])=>g);if(n.length===0)throw new w("Please set at least one API key via the `aicommit2 config set` command");const l=new dt(s,e);let a;try{a=await Ir(l.createCommitMsgRequests$(n).pipe(Rr(g=>!g.isError),D(g=>g.value),Dr()))}finally{t.printAnalyzed()}const c=await O.readFile(ht,"utf8")!=="",u=a.length>1;let m="";c&&(m=`# \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
253
+ `,m+=`# ----------------------------------------
254
+ `,m+=`# How to use:
255
+ `,u?(m+=`# 1. Remove the "#" from your chosen message
256
+ `,m+=`# 2. Edit the message if needed
257
+ `,m+=`# 3. Save and close the editor
258
+ `):(m+=`# 1. The message below will be used
259
+ `,m+=`# 2. Edit the message if needed
260
+ `,m+=`# 3. Save and close the editor
261
+ `),m+=`# ----------------------------------------
262
+ `),u?(c&&(m+=`
200
263
  # \u{1F4DD} Choose one of these messages:
201
- `),d+=`
202
- ${a.map(h=>`# ${h}`).join(`
203
- `)}`):(u&&(d+=`
264
+ `),m+=`
265
+ ${a.map(g=>`# ${g}`).join(`
266
+ `)}`):(c&&(m+=`
204
267
  # \u{1F4DD} Generated commit message:
205
- `),d+=`
268
+ `),m+=`
206
269
  ${a[0]}
207
- `);const p=await O.readFile(lt,"utf8"),g=d+`
208
- `+p;await O.writeFile(lt,g),t.printSavedCommitMessage()})().catch(e=>{new re().printError(e.message),ie(e),process.exit(1)});const cr=process.argv.slice(2),Uo=[];let lr=!1;for(let r=0;r<cr.length;r++){const e=cr[r];if(lr){lr=!1;continue}if(e!=="--hook-mode"){if(e.startsWith("-")){const t=cr[r+1];t&&!t.startsWith("-")&&(lr=!0);continue}Uo.push(e)}}const[ut,zo]=Uo;var Uc=(r,e,t,o,s,n,i)=>(async()=>{if(!ut)throw new v('Commit message file path is missing. This file should be called from the "prepare-commit-msg" git hook or with --hook-mode flag');if(zo){console.log(`Skipping aicommit2 message generation for ${zo} commit`);return}const c=await sr();if(!c)return;const a=new re;a.printTitle();const m={locale:r?.toString(),generate:e?.toString(),type:o?.toString(),systemPrompt:s?.toString(),includeBody:n?.toString()};i&&(m.logLevel="verbose");const u=await ue(m,t);if(u.systemPromptPath)try{await O.readFile(S.resolve(u.systemPromptPath),"utf-8")}catch{throw new v(`Error reading system prompt file: ${u.systemPromptPath}`)}const l=Object.entries(u).filter(([x])=>ve.includes(x)).map(([x,$])=>[x,$]).filter(([x,$])=>!$.disabled).filter(([x,$])=>x==="OLLAMA"?!!$&&!!$.model&&$.model.length>0:x==="HUGGINGFACE"?!!$&&!!$.cookie:!!$.key&&$.key.length>0).map(([x])=>x);if(l.length===0)throw new v("Please set at least one API key via the `aicommit2 config set` command");const p=new at(u,c),g=a.displaySpinner("The AI is analyzing your changes");let h;try{h=await vr(p.createCommitMsgRequests$(l).pipe(br(x=>!x.isError),I(x=>x.value),Cr()))}finally{g.stop(),g.clear(),a.printAnalyzed()}const w=await O.readFile(ut,"utf8")!=="",b=h.length>1,P=await vc();let k="";w&&(k=`${P} \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
209
- `,k+=`${P} ----------------------------------------
210
- `,k+=`${P} How to use:
211
- `,b?(k+=`${P} 1. Remove the "${P}" from your chosen message
212
- `,k+=`${P} 2. Edit the message if needed
213
- `,k+=`${P} 3. Save and close the editor
214
- `):(k+=`${P} 1. The message below will be used
215
- `,k+=`${P} 2. Edit the message if needed
216
- `,k+=`${P} 3. Save and close the editor
217
- `),k+=`${P} ----------------------------------------
218
- `),b?(w&&(k+=`
219
- ${P} \u{1F4DD} Choose one of these messages:
220
- `),k+=`
221
- ${h.map(x=>`${P} ${x}`).join(`
222
- `)}`):(w&&(k+=`
223
- ${P} \u{1F4DD} Generated commit message:
224
- `),k+=`
225
- ${h[0]}
226
- `);const A=await O.readFile(ut,"utf8"),E=k+`
227
- `+A;await O.writeFile(ut,E),a.printSavedCommitMessage()})().catch(c=>{new re().printError(c.message),ie(c),process.exit(1)});class Wo{constructor(e="SubscriptionManager"){this.destroyed$=new ht,this.subscriptions=new pt,this.isDestroyed=!1,this.name=e}add(e,t){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`);const s=new pt;return s.unsubscribe(),s}const o=e.pipe(Sr(this.destroyed$),Mr(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Observable finalized`)})).subscribe({next:t?.next,error:s=>{console.error(`${this.name}: Observable error:`,s),t?.error?.(s)},complete:t?.complete});return this.subscriptions.add(o),o}pipe(e){return this.isDestroyed?(console.warn(`${this.name}: Cannot pipe - manager is destroyed`),e):e.pipe(Sr(this.destroyed$),Mr(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Piped observable finalized`)}))}addSubscription(e){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`),e.unsubscribe();return}this.subscriptions.add(e)}get destroySignal$(){return this.destroyed$.asObservable()}get isActive(){return!this.isDestroyed}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.subscriptions.unsubscribe(),this.destroyed$.next(),this.destroyed$.complete(),process.env.NODE_ENV==="development"&&console.log(`${this.name}: Destroyed successfully`))}}const zc=new Wo("Global"),Ge=()=>{zc.destroy()};process.on("exit",Ge),process.on("SIGINT",Ge),process.on("SIGTERM",Ge),process.on("uncaughtException",r=>{console.error("Uncaught exception:",r),Ge(),process.exit(1)}),process.on("unhandledRejection",(r,e)=>{console.error("Unhandled rejection at:",e,"reason:",r),Ge(),process.exit(1)});class Wc{constructor(){this.destroyed$=new ht,this.consoleManager=new re,this.subscriptionManager=new Wo,this.currentCodeReviewSubscription=null,this.currentCodeReviewPromptManager=null,this.watcher=null,this.lastCommitHash=null,this.isProcessingCommit=!1,this.REPO_PATH=process.cwd(),this.GIT_PATH=S.join(this.REPO_PATH,".git"),this.HEAD_PATH=S.join(this.GIT_PATH,"HEAD"),this.REFS_PATH=S.join(this.GIT_PATH,"refs","heads"),this.COMMIT_MSG_PATH=S.join(this.GIT_PATH,"COMMIT_EDITMSG"),this.setupProcessHandlers()}setupProcessHandlers(){const e=()=>{this.destroy(),process.exit(0)};process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGQUIT",e)}async watch(e,t,o,s,n,i){this.consoleManager.printTitle(),await or();const c=await this.initializeConfig(e,t,s,n,i);await this.initializeCurrentCommit();try{await this.watchGitEvents(c)}catch(a){return await this.handleWatchGitError(a),this.watch(e,t,o,s,n,i)}}async initializeConfig(e,t,o,s,n){const i={locale:e?.toString(),generate:t?.toString(),systemPrompt:o?.toString()};s&&(i.logLevel="verbose");const c=await ue(i,n);return await Co(c),this.getAvailableAIs(c).length===0&&(this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
270
+ `);const p=await O.readFile(ht,"utf8"),h=m+`
271
+ `+p;await O.writeFile(ht,h),t.printSavedCommitMessage()})().catch(e=>{new se().printError(e.message),ae(e),process.exit(1)});const vr=process.argv.slice(2),cs=[];let Cr=!1;for(let r=0;r<vr.length;r++){const e=vr[r];if(Cr){Cr=!1;continue}if(e!=="--hook-mode"){if(e.startsWith("-")){const t=vr[r+1];t&&!t.startsWith("-")&&(Cr=!0);continue}cs.push(e)}}const[gt,ls]=cs;var ll=(r,e,t,o,s,n,i)=>(async()=>{if(!gt)throw new w('Commit message file path is missing. This file should be called from the "prepare-commit-msg" git hook or with --hook-mode flag');if(ls){console.log(`Skipping aicommit2 message generation for ${ls} commit`);return}const l=await hr();if(!l)return;const a=new se;a.printTitle();const d={locale:r?.toString(),generate:e?.toString(),type:o?.toString(),systemPrompt:s?.toString(),...n===!0&&{includeBody:"true"}};i&&(d.logLevel="verbose");const c=await ue(d,t);if(c.systemPromptPath)try{await O.readFile(S.resolve(c.systemPromptPath),"utf-8")}catch{throw new w(`Error reading system prompt file: ${c.systemPromptPath}`)}const u=Object.entries(c).filter(([$])=>ve.includes($)).map(([$,k])=>[$,k]).filter(([$,k])=>!k.disabled).filter(([$,k])=>$==="OLLAMA"?!!k&&!!k.model&&k.model.length>0:$==="HUGGINGFACE"?!!k&&!!k.cookie:!!k.key&&k.key.length>0).map(([$])=>$);if(u.length===0)throw new w("Please set at least one API key via the `aicommit2 config set` command");const p=new dt(c,l),h=a.displaySpinner("The AI is analyzing your changes");let g;try{g=await Ir(p.createCommitMsgRequests$(u).pipe(Rr($=>!$.isError),D($=>$.value),Dr()))}finally{h.stop(),h.clear(),a.printAnalyzed()}const v=await O.readFile(gt,"utf8")!=="",b=g.length>1,E=await _c();let x="";v&&(x=`${E} \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
272
+ `,x+=`${E} ----------------------------------------
273
+ `,x+=`${E} How to use:
274
+ `,b?(x+=`${E} 1. Remove the "${E}" from your chosen message
275
+ `,x+=`${E} 2. Edit the message if needed
276
+ `,x+=`${E} 3. Save and close the editor
277
+ `):(x+=`${E} 1. The message below will be used
278
+ `,x+=`${E} 2. Edit the message if needed
279
+ `,x+=`${E} 3. Save and close the editor
280
+ `),x+=`${E} ----------------------------------------
281
+ `),b?(v&&(x+=`
282
+ ${E} \u{1F4DD} Choose one of these messages:
283
+ `),x+=`
284
+ ${g.map($=>`${E} ${$}`).join(`
285
+ `)}`):(v&&(x+=`
286
+ ${E} \u{1F4DD} Generated commit message:
287
+ `),x+=`
288
+ ${g[0]}
289
+ `);const A=await O.readFile(gt,"utf8"),P=x+`
290
+ `+A;await O.writeFile(gt,P),a.printSavedCommitMessage()})().catch(l=>{new se().printError(l.message),ae(l),process.exit(1)});class us{constructor(e="SubscriptionManager"){this.destroyed$=new Pt,this.subscriptions=new Et,this.isDestroyed=!1,this.name=e}add(e,t){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`);const s=new Et;return s.unsubscribe(),s}const o=e.pipe(_r(this.destroyed$),Gr(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Observable finalized`)})).subscribe({next:t?.next,error:s=>{console.error(`${this.name}: Observable error:`,s),t?.error?.(s)},complete:t?.complete});return this.subscriptions.add(o),o}pipe(e){return this.isDestroyed?(console.warn(`${this.name}: Cannot pipe - manager is destroyed`),e):e.pipe(_r(this.destroyed$),Gr(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Piped observable finalized`)}))}addSubscription(e){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`),e.unsubscribe();return}this.subscriptions.add(e)}get destroySignal$(){return this.destroyed$.asObservable()}get isActive(){return!this.isDestroyed}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.subscriptions.unsubscribe(),this.destroyed$.next(),this.destroyed$.complete(),process.env.NODE_ENV==="development"&&console.log(`${this.name}: Destroyed successfully`))}}const ul=new us("Global"),He=()=>{ul.destroy()};process.on("exit",He),process.on("SIGINT",He),process.on("SIGTERM",He),process.on("uncaughtException",r=>{console.error("Uncaught exception:",r),He(),process.exit(1)}),process.on("unhandledRejection",(r,e)=>{console.error("Unhandled rejection at:",e,"reason:",r),He(),process.exit(1)});class dl{constructor(){this.destroyed$=new Pt,this.consoleManager=new se,this.subscriptionManager=new us,this.currentCodeReviewSubscription=null,this.currentCodeReviewPromptManager=null,this.watcher=null,this.lastCommitHash=null,this.isProcessingCommit=!1,this.REPO_PATH=process.cwd(),this.GIT_PATH=S.join(this.REPO_PATH,".git"),this.HEAD_PATH=S.join(this.GIT_PATH,"HEAD"),this.REFS_PATH=S.join(this.GIT_PATH,"refs","heads"),this.COMMIT_MSG_PATH=S.join(this.GIT_PATH,"COMMIT_EDITMSG"),this.setupProcessHandlers()}setupProcessHandlers(){const e=()=>{this.destroy(),process.exit(0)};process.on("SIGINT",e),process.on("SIGTERM",e),process.on("SIGQUIT",e)}async watch(e,t,o,s,n,i){this.consoleManager.printTitle(),await pr();const l=await ft();if(l!=="git")throw new w(`Watch mode is only supported for Git repositories. Current VCS: ${l}`);const a=await this.initializeConfig(e,t,s,n,i);await this.initializeCurrentCommit();try{await this.watchGitEvents(a)}catch(d){return await this.handleWatchGitError(d),this.watch(e,t,o,s,n,i)}}async initializeConfig(e,t,o,s,n){const i={locale:e?.toString(),generate:t?.toString(),systemPrompt:o?.toString()};s&&(i.logLevel="verbose");const l=await ue(i,n);return await Uo(l),this.getAvailableAIs(l).length===0&&(this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
228
291
  aicommit2 config set [MODEL].key="YOUR_API_KEY"
229
- aicommit2 config set [MODEL].watchMode="true"`),process.exit()),c}async handleWatchGitError(e){this.consoleManager.printError(`An error occurred: ${e.message}`),ie(e),await new Promise(t=>setTimeout(t,3e3)),this.consoleManager.printWarning("Restarting the commit monitoring process...")}async initializeCurrentCommit(){try{const e=await this.executeGitCommand("git rev-parse HEAD");this.lastCommitHash=e.trim(),this.consoleManager.printInfo(`Starting watch from commit: ${this.lastCommitHash.substring(0,8)}`)}catch{this.consoleManager.printWarning("No commits found in repository"),this.lastCommitHash=null}}async executeGitCommand(e){const t=ls(ss),{stdout:o}=await t(e,{cwd:this.REPO_PATH});return o}getAvailableAIs(e){return Object.entries(e).filter(([t,o])=>ve.includes(t)||o.compatible===!0).map(([t,o])=>[t,o]).filter(([t,o])=>!o.disabled).filter(([t,o])=>this.isAIAvailable(t,o,e)).map(([t])=>t)}isAIAvailable(e,t,o){const s=o.watchMode||t.watchMode;return e==="OLLAMA"?!!t&&!!t.model&&t.model.length>0&&s:e==="HUGGINGFACE"?!!t&&!!t.cookie&&s:t.compatible?!!t.url&&!!t.key&&s:!!t.key&&t.key.length>0&&s}clearTerminal(){process.stdout.write("\x1Bc")}async handleCommitEvent(e,t){try{const o=await wc(t);if(!o){this.consoleManager.printWarning("No changes found in this commit");return}this.consoleManager.stopLoader(),this.consoleManager.printStagedFiles(o);const s=this.getAvailableAIs(e);if(s.length===0){this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
292
+ aicommit2 config set [MODEL].watchMode="true"`),process.exit()),l}async handleWatchGitError(e){this.consoleManager.printError(`An error occurred: ${e.message}`),ae(e),await new Promise(t=>setTimeout(t,3e3)),this.consoleManager.printWarning("Restarting the commit monitoring process...")}async initializeCurrentCommit(){try{const e=await this.executeGitCommand("git rev-parse HEAD");this.lastCommitHash=e.trim(),this.consoleManager.printInfo(`Starting watch from commit: ${this.lastCommitHash.substring(0,8)}`)}catch{this.consoleManager.printWarning("No commits found in repository"),this.lastCommitHash=null}}async executeGitCommand(e){const t=xs(Cs),{stdout:o}=await t(e,{cwd:this.REPO_PATH});return o}getAvailableAIs(e){return Object.entries(e).filter(([t,o])=>ve.includes(t)||o.compatible===!0).map(([t,o])=>[t,o]).filter(([t,o])=>!o.disabled).filter(([t,o])=>this.isAIAvailable(t,o,e)).map(([t])=>t)}isAIAvailable(e,t,o){const s=o.watchMode||t.watchMode;return e==="OLLAMA"?!!t&&!!t.model&&t.model.length>0&&s:e==="HUGGINGFACE"?!!t&&!!t.cookie&&s:t.compatible?!!t.url&&!!t.key&&s:!!t.key&&t.key.length>0&&s}clearTerminal(){process.stdout.write("\x1Bc")}async handleCommitEvent(e,t){try{const o=await Nc(t);if(!o){this.consoleManager.printWarning("No changes found in this commit");return}this.consoleManager.stopLoader(),this.consoleManager.printStagedFiles(o);const s=this.getAvailableAIs(e);if(s.length===0){this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
230
293
  aicommit2 config set [MODEL].key="YOUR_API_KEY"
231
- aicommit2 config set [MODEL].watchMode="true"`),process.exit();return}await this.performCodeReview(e,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${t}: ${o.message}`)}}async performCodeReview(e,t,o){this.cleanupPreviousCodeReview();const s=new at(e,t);this.currentCodeReviewPromptManager=new ar(Fo);try{const n=this.initializeCodeReviewInquirer();this.currentCodeReviewPromptManager.startLoader(),this.currentCodeReviewSubscription=this.subscribeToCodeReviewRequests(s,o),await n}finally{this.cleanupCodeReview()}}cleanupPreviousCodeReview(){this.cleanupCurrentReviewResources(),this.destroyed$.closed||(this.destroyed$.next(),this.destroyed$.complete()),this.destroyed$=new ht}initializeCodeReviewInquirer(){return this.currentCodeReviewPromptManager.initPrompt({...ir,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Lo}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20})}subscribeToCodeReviewRequests(e,t){return this.subscriptionManager.add(e.createCodeReviewRequests$(t),{next:o=>{this.currentCodeReviewPromptManager?.refreshChoices(o)},error:o=>{console.error("Code review request error:",o),this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)},complete:()=>{this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)}})}cleanupCurrentReviewResources(){this.currentCodeReviewSubscription&&(this.currentCodeReviewSubscription.unsubscribe(),this.currentCodeReviewSubscription=null),this.currentCodeReviewPromptManager&&(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)}cleanupCodeReview(){this.cleanupCurrentReviewResources(),this.clearTerminal(),this.consoleManager.showLoader("Watching for new Git commits...")}async isGitReset(e){if(!this.lastCommitHash)return!1;try{const t=await this.executeGitCommand(`git merge-base --is-ancestor ${e} ${this.lastCommitHash}`);return!0}catch{return!1}}cancelCurrentReview(){this.currentCodeReviewPromptManager&&this.currentCodeReviewPromptManager.cancel(),this.cleanupCurrentReviewResources(),this.destroyed$.next()}async watchGitEvents(e){this.consoleManager.showLoader("Watching for new Git commits...");const o=[this.HEAD_PATH,this.REFS_PATH,this.COMMIT_MSG_PATH,S.join(this.GIT_PATH,"logs","HEAD")].filter(s=>{try{return U.accessSync(s),!0}catch{return!1}});this.watcher=Os.watch(o,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100}}),this.watcher.on("change",async s=>{await this.handleGitChange(e,s)}),this.watcher.on("add",async s=>{await this.handleGitChange(e,s)}),this.watcher.on("error",s=>{this.consoleManager.printError(`Watcher error: ${s.message}`),setTimeout(()=>this.watchGitEvents(e),1e3)})}async handleGitChange(e,t){try{const s=(await this.executeGitCommand("git rev-parse HEAD")).trim();if(s!==this.lastCommitHash){if(await this.isGitReset(s)){this.clearTerminal(),this.consoleManager.printInfo(`\u21A9\uFE0F Git reset detected: ${s.substring(0,8)}`),this.lastCommitHash=s,this.isProcessingCommit&&(this.cancelCurrentReview(),this.isProcessingCommit=!1);return}if(this.isProcessingCommit){this.consoleManager.printInfo(`
294
+ aicommit2 config set [MODEL].watchMode="true"`),process.exit();return}await this.performCodeReview(e,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${t}: ${o.message}`)}}async performCodeReview(e,t,o){this.cleanupPreviousCodeReview();const s=new dt(e,t);this.currentCodeReviewPromptManager=new wr(ts);try{const n=this.initializeCodeReviewInquirer();this.currentCodeReviewPromptManager.startLoader(),this.currentCodeReviewSubscription=this.subscribeToCodeReviewRequests(s,o),await n}finally{this.cleanupCodeReview()}}cleanupPreviousCodeReview(){this.cleanupCurrentReviewResources(),this.destroyed$.closed||(this.destroyed$.next(),this.destroyed$.complete()),this.destroyed$=new Pt}initializeCodeReviewInquirer(){return this.currentCodeReviewPromptManager.initPrompt({...yr,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${rs}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20})}subscribeToCodeReviewRequests(e,t){return this.subscriptionManager.add(e.createCodeReviewRequests$(t),{next:o=>{this.currentCodeReviewPromptManager?.refreshChoices(o)},error:o=>{console.error("Code review request error:",o),this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)},complete:()=>{this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)}})}cleanupCurrentReviewResources(){this.currentCodeReviewSubscription&&(this.currentCodeReviewSubscription.unsubscribe(),this.currentCodeReviewSubscription=null),this.currentCodeReviewPromptManager&&(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)}cleanupCodeReview(){this.cleanupCurrentReviewResources(),this.clearTerminal(),this.consoleManager.showLoader("Watching for new Git commits...")}async isGitReset(e){if(!this.lastCommitHash)return!1;try{const t=await this.executeGitCommand(`git merge-base --is-ancestor ${e} ${this.lastCommitHash}`);return!0}catch{return!1}}cancelCurrentReview(){this.currentCodeReviewPromptManager&&this.currentCodeReviewPromptManager.cancel(),this.cleanupCurrentReviewResources(),this.destroyed$.next()}async watchGitEvents(e){this.consoleManager.showLoader("Watching for new Git commits...");const o=[this.HEAD_PATH,this.REFS_PATH,this.COMMIT_MSG_PATH,S.join(this.GIT_PATH,"logs","HEAD")].filter(s=>{try{return W.accessSync(s),!0}catch{return!1}});this.watcher=Vs.watch(o,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100}}),this.watcher.on("change",async s=>{await this.handleGitChange(e,s)}),this.watcher.on("add",async s=>{await this.handleGitChange(e,s)}),this.watcher.on("error",s=>{this.consoleManager.printError(`Watcher error: ${s.message}`),setTimeout(()=>this.watchGitEvents(e),1e3)})}async handleGitChange(e,t){try{const s=(await this.executeGitCommand("git rev-parse HEAD")).trim();if(s!==this.lastCommitHash){if(await this.isGitReset(s)){this.clearTerminal(),this.consoleManager.printInfo(`\u21A9\uFE0F Git reset detected: ${s.substring(0,8)}`),this.lastCommitHash=s,this.isProcessingCommit&&(this.cancelCurrentReview(),this.isProcessingCommit=!1);return}if(this.isProcessingCommit){this.consoleManager.printInfo(`
232
295
  \u{1F504} New commit detected, cancelling current review...`);try{this.cancelCurrentReview(),await new Promise(i=>setTimeout(i,200))}catch(i){console.warn("Error during review cancellation:",i)}}this.isProcessingCommit=!0;try{this.consoleManager.stopLoader(),this.consoleManager.printInfo(`
233
- \u{1F50D} New commit detected: ${s.substring(0,8)}`);const i=this.lastCommitHash;this.lastCommitHash=s,this.clearTerminal(),await this.handleCommitEvent(e,s)}catch(i){this.consoleManager.printError(`Error processing commit ${s.substring(0,8)}: ${i.message}`)}finally{this.isProcessingCommit=!1}}}catch(o){this.isProcessingCommit=!1,o.message?.includes("fatal: not a git repository")||this.consoleManager.printError(`Error checking for new commits: ${o.message}`)}}destroy(){this.isProcessingCommit=!1,this.lastCommitHash=null;try{this.subscriptionManager.destroy(),this.cleanupCurrentReviewResources(),this.watcher&&(this.watcher.close(),this.watcher=null),this.consoleManager.stopLoader(),this.destroyed$.next(),this.destroyed$.complete()}catch(e){console.warn("Error during WatchGitManager destruction:",e)}}}const Kc=new Wc,Jc=async(r,e,t,o,s,n)=>Kc.watch(r,e,t,o,s,n),dt=process.argv.slice(2),{version:Ko,description:Vc}=Js;Xo({name:"aicommit2",version:Ko,flags:{locale:{type:String,description:"Locale to use for the generated commit messages (default: en)",alias:"l"},generate:{type:Number,description:"Number of messages to generate (Warning: generating multiple costs more) (default: 1)",alias:"g"},exclude:{type:[String],description:"Files to exclude from AI analysis",alias:"x"},all:{type:Boolean,description:"Automatically stage changes in tracked files for the commit",alias:"a",default:!1},type:{type:String,description:"Type of commit message to generate (default: conventional)",alias:"t"},confirm:{type:Boolean,description:"Skip confirmation when committing after message generation (default: false)",alias:"y",default:!1},clipboard:{type:Boolean,description:"Copy the selected message to the clipboard",alias:"c",default:!1},prompt:{type:String,description:"Custom prompt to let users fine-tune provided prompt",alias:"p"},"watch-commit":{type:Boolean,default:!1},"hook-mode":{type:Boolean,description:"Run in git hook mode, allowing chaining with other hooks",default:!1},"pre-commit":{type:Boolean,description:"Run in pre-commit Framework, allowing chaining with other hooks",default:!1},"include-body":{type:Boolean,description:"Force include commit body in all generated messages",alias:"i",default:!1},"auto-select":{type:Boolean,description:"Automatically select the message when only one is generated",alias:"s",default:!1},edit:{type:Boolean,description:"Open the AI-generated commit message in your default editor",alias:"e",default:!1},"disable-lowercase":{type:Boolean,description:"Disable automatic lowercase conversion of commit messages",default:!1},verbose:{type:Boolean,description:"Enable verbose logging for this run",alias:"v",default:!1}},commands:[Sc,Mc,Dc,_c],help:{description:Vc},ignoreArgv:r=>r==="unknown-flag"||r==="argument"},async r=>{const e={};r.flags.verbose&&(e.logLevel="verbose");const t=await ue(e,dt);if(await va(t),Ce.info(`aicommit2 version: ${Ko}`),r.flags["pre-commit"]){Hc(r.flags.verbose);return}if(r.flags["hook-mode"]||Oc){Uc(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.type,r.flags.prompt,r.flags["include-body"],r.flags.verbose);return}if(r.flags["watch-commit"]){Jc(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.prompt,r.flags.verbose,dt);return}$c(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.all,r.flags.type,r.flags.confirm,r.flags.clipboard,r.flags.prompt,r.flags["include-body"],r.flags["auto-select"],r.flags.edit,r.flags["disable-lowercase"],r.flags.verbose,dt)},dt);
296
+ \u{1F50D} New commit detected: ${s.substring(0,8)}`);const i=this.lastCommitHash;this.lastCommitHash=s,this.clearTerminal(),await this.handleCommitEvent(e,s)}catch(i){this.consoleManager.printError(`Error processing commit ${s.substring(0,8)}: ${i.message}`)}finally{this.isProcessingCommit=!1}}}catch(o){this.isProcessingCommit=!1,o.message?.includes("fatal: not a git repository")||this.consoleManager.printError(`Error checking for new commits: ${o.message}`)}}destroy(){this.isProcessingCommit=!1,this.lastCommitHash=null;try{this.subscriptionManager.destroy(),this.cleanupCurrentReviewResources(),this.watcher&&(this.watcher.close(),this.watcher=null),this.consoleManager.stopLoader(),this.destroyed$.next(),this.destroyed$.complete()}catch(e){console.warn("Error during WatchGitManager destruction:",e)}}}const ml=new dl,fl=async(r,e,t,o,s,n)=>ml.watch(r,e,t,o,s,n),yt=process.argv.slice(2),{version:ds,description:pl}=dn;hs({name:"aicommit2",version:ds,flags:{locale:{type:String,description:"Locale to use for the generated commit messages (default: en)",alias:"l"},generate:{type:Number,description:"Number of messages to generate (Warning: generating multiple costs more) (default: 1)",alias:"g"},exclude:{type:[String],description:"Files to exclude from AI analysis",alias:"x"},all:{type:Boolean,description:"Automatically stage changes in tracked files for the commit",alias:"a",default:!1},type:{type:String,description:"Type of commit message to generate (default: conventional)",alias:"t"},confirm:{type:Boolean,description:"Skip confirmation when committing after message generation (default: false)",alias:"y",default:!1},clipboard:{type:Boolean,description:"Copy the selected message to the clipboard",alias:"c",default:!1},prompt:{type:String,description:"Custom prompt to let users fine-tune provided prompt",alias:"p"},"watch-commit":{type:Boolean,default:!1},"hook-mode":{type:Boolean,description:"Run in git hook mode, allowing chaining with other hooks",default:!1},"pre-commit":{type:Boolean,description:"Run in pre-commit Framework, allowing chaining with other hooks",default:!1},"include-body":{type:Boolean,description:"Force include commit body in all generated messages",alias:"i",default:!1},"auto-select":{type:Boolean,description:"Automatically select the message when only one is generated",alias:"s",default:!1},edit:{type:Boolean,description:"Open the AI-generated commit message in your default editor",alias:"e",default:!1},"disable-lowercase":{type:Boolean,description:"Disable automatic lowercase conversion of commit messages",default:!1},verbose:{type:Boolean,description:"Enable verbose logging for this run",alias:"v",default:!1},git:{type:Boolean,description:"Force use Git (overrides auto-detection)",default:!1},yadm:{type:Boolean,description:"Force use YADM (overrides auto-detection)",default:!1},jj:{type:Boolean,description:"Force use Jujutsu (overrides auto-detection)",default:!1},"dry-run":{type:Boolean,description:"Generate commit message without committing (output only)",alias:"d",default:!1}},commands:[Kc,Jc,Zc,il],help:{description:pl},ignoreArgv:r=>r==="unknown-flag"||r==="argument"},async r=>{const e={};r.flags.verbose&&(e.logLevel="verbose");const t=await ue(e,yt);if(await Ga(t),be.info(`aicommit2 version: ${ds}`),r.flags["pre-commit"]){cl(r.flags.verbose);return}if(r.flags["hook-mode"]||Qc){ll(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.type,r.flags.prompt,r.flags["include-body"],r.flags.verbose);return}if(r.flags["watch-commit"]){fl(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.prompt,r.flags.verbose,yt);return}Uc(r.flags.locale,r.flags.generate,r.flags.exclude,r.flags.all,r.flags.type,r.flags.confirm,r.flags.clipboard,r.flags.prompt,r.flags["include-body"],r.flags["auto-select"],r.flags.edit,r.flags["disable-lowercase"],r.flags.verbose,r.flags["dry-run"],yt)},yt);