aicommit2 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -12
- package/dist/cli.mjs +94 -94
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{command as ce,cli as Ks}from"cleye";import{createRequire as zs}from"module";import Ws from"crypto";import Z from"fs";import Le from"os";import M from"path";import{Buffer as Kr}from"node:buffer";import we from"node:path";import jt,{ChildProcess as zr,exec as Ys}from"node:child_process";import le from"node:process";import Vs,{execSync as rt,exec as qs}from"child_process";import{fileURLToPath as Wr}from"node:url";import Js,{constants as Yr}from"node:os";import Vr from"assert";import qr from"events";import{createWriteStream as Xs,createReadStream as Qs,readFileSync as Zs}from"node:fs";import en from"buffer";import Bt from"stream";import Jr,{promisify as tn}from"util";import{debuglog as rn,promisify as on}from"node:util";import ot from"inquirer";import{of as Xr,concatMap as F,from as N,map as T,catchError as L,tap as Qr,mergeMap as Zr,BehaviorSubject as eo,ReplaySubject as sn,Subscription as Gt,lastValueFrom as Ut,toArray as Ht,filter as to,Subject as Kt}from"rxjs";import D from"fs/promises";import g from"chalk";import ro from"openai";import{fromPromise as j}from"rxjs/internal/observable/innerFrom";import{xxh64 as oo}from"@pacote/xxhash";import K from"winston";import"winston-daily-rotate-file";import nn from"http";import so from"https";import an from"net";import cn from"tls";import ln,{fileURLToPath as un,pathToFileURL as dn}from"url";import no from"tty";import mn from"@anthropic-ai/sdk";import pn from"axios";import{CohereClientV2 as fn}from"cohere-ai";import{GoogleGenerativeAI as hn,HarmCategory as st,HarmBlockThreshold as nt}from"@google/generative-ai";import gn from"groq-sdk";import{Ollama as yn}from"ollama";import{fetch as wn,Agent as vn}from"undici";import it from"readline";import io from"figlet";import Cn from"gradient-string";import ao from"ora";import bn from"inquirer-reactive-list-prompt";import{readdir as co,stat as En,rm as $n}from"node:fs/promises";import Pn from"chokidar";import{takeUntil as lo,finalize as uo}from"rxjs/operators";var An="aicommit2",mo="2.5.1",Sn="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",kn=["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"],In="MIT",Mn="tak-bro/aicommit2",xn="Hyungtak Jin(@tak-bro)",Rn="module",On=["dist"],Dn={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},_n={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},Nn={"@anthropic-ai/sdk":"^0.39.0","@aws-sdk/client-bedrock-runtime":"^3.678.0","@aws-sdk/credential-providers":"^3.678.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"},Tn={"@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"}}]},Fn={branches:["main"],plugins:[["@semantic-release/commit-analyzer",{preset:"conventionalcommits",releaseRules:[{type:"docs",release:!1},{type:"style",release:!1},{type:"test",release:!1},{type:"ci",release:!1},{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"]},jn={name:An,version:mo,description:Sn,keywords:kn,license:In,repository:Mn,author:xn,type:Rn,files:On,bin:Dn,scripts:_n,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:Nn,devDependencies:Tn,eslintConfig:Ln,release:Fn},Bn=zs(import.meta.url),H=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Pe(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Ae={exports:{}},zt,po;function Gn(){if(po)return zt;po=1,zt=o,o.sync=s;var t=Z;function e(n,i){var a=i.pathExt!==void 0?i.pathExt:process.env.PATHEXT;if(!a||(a=a.split(";"),a.indexOf("")!==-1))return!0;for(var c=0;c<a.length;c++){var d=a[c].toLowerCase();if(d&&n.substr(-d.length).toLowerCase()===d)return!0}return!1}function r(n,i,a){return!n.isSymbolicLink()&&!n.isFile()?!1:e(i,a)}function o(n,i,a){t.stat(n,function(c,d){a(c,c?!1:r(d,n,i))})}function s(n,i){return r(t.statSync(n),n,i)}return zt}var Wt,fo;function Un(){if(fo)return Wt;fo=1,Wt=e,e.sync=r;var t=Z;function e(n,i,a){t.stat(n,function(c,d){a(c,c?!1:o(d,i))})}function r(n,i){return o(t.statSync(n),i)}function o(n,i){return n.isFile()&&s(n,i)}function s(n,i){var a=n.mode,c=n.uid,d=n.gid,l=i.uid!==void 0?i.uid:process.getuid&&process.getuid(),u=i.gid!==void 0?i.gid:process.getgid&&process.getgid(),p=parseInt("100",8),f=parseInt("010",8),h=parseInt("001",8),y=p|f,w=a&h||a&f&&d===u||a&p&&c===l||a&y&&l===0;return w}return Wt}var at;process.platform==="win32"||H.TESTING_WINDOWS?at=Gn():at=Un();var Hn=Yt;Yt.sync=Kn;function Yt(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){Yt(t,e||{},function(n,i){n?s(n):o(i)})})}at(t,e||{},function(o,s){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,s=!1),r(o,s)})}function Kn(t,e){try{return at.sync(t,e||{})}catch(r){if(e&&e.ignoreErrors||r.code==="EACCES")return!1;throw r}}const Se=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",ho=M,zn=Se?";":":",go=Hn,yo=t=>Object.assign(new Error(`not found: ${t}`),{code:"ENOENT"}),wo=(t,e)=>{const r=e.colon||zn,o=t.match(/\//)||Se&&t.match(/\\/)?[""]:[...Se?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(r)],s=Se?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=Se?s.split(r):[""];return Se&&t.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:s}},vo=(t,e,r)=>{typeof e=="function"&&(r=e,e={}),e||(e={});const{pathEnv:o,pathExt:s,pathExtExe:n}=wo(t,e),i=[],a=d=>new Promise((l,u)=>{if(d===o.length)return e.all&&i.length?l(i):u(yo(t));const p=o[d],f=/^".*"$/.test(p)?p.slice(1,-1):p,h=ho.join(f,t),y=!f&&/^\.[\\\/]/.test(t)?t.slice(0,2)+h:h;l(c(y,d,0))}),c=(d,l,u)=>new Promise((p,f)=>{if(u===s.length)return p(a(l+1));const h=s[u];go(d+h,{pathExt:n},(y,w)=>{if(!y&&w)if(e.all)i.push(d+h);else return p(d+h);return p(c(d,l,u+1))})});return r?a(0).then(d=>r(null,d),r):a(0)},Wn=(t,e)=>{e=e||{};const{pathEnv:r,pathExt:o,pathExtExe:s}=wo(t,e),n=[];for(let i=0;i<r.length;i++){const a=r[i],c=/^".*"$/.test(a)?a.slice(1,-1):a,d=ho.join(c,t),l=!c&&/^\.[\\\/]/.test(t)?t.slice(0,2)+d:d;for(let u=0;u<o.length;u++){const p=l+o[u];try{if(go.sync(p,{pathExt:s}))if(e.all)n.push(p);else return p}catch{}}}if(e.all&&n.length)return n;if(e.nothrow)return null;throw yo(t)};var Yn=vo;vo.sync=Wn;var Vt={exports:{}};const Co=(t={})=>{const e=t.env||process.env;return(t.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};Vt.exports=Co,Vt.exports.default=Co;var Vn=Vt.exports;const bo=M,qn=Yn,Jn=Vn;function Eo(t,e){const r=t.options.env||process.env,o=process.cwd(),s=t.options.cwd!=null,n=s&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(t.options.cwd)}catch{}let i;try{i=qn.sync(t.command,{path:r[Jn({env:r})],pathExt:e?bo.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return i&&(i=bo.resolve(s?t.options.cwd:"",i)),i}function Xn(t){return Eo(t)||Eo(t,!0)}var Qn=Xn,qt={};const Jt=/([()\][%!^"`<>&|;, *?])/g;function Zn(t){return t=t.replace(Jt,"^$1"),t}function ei(t,e){return t=`${t}`,t=t.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),t=t.replace(/(?=(\\+?)?)\1$/,"$1$1"),t=`"${t}"`,t=t.replace(Jt,"^$1"),e&&(t=t.replace(Jt,"^$1")),t}qt.command=Zn,qt.argument=ei;var ti=/^#!(.*)/;const ri=ti;var oi=(t="")=>{const e=t.match(ri);if(!e)return null;const[r,o]=e[0].replace(/#! ?/,"").split(" "),s=r.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const Xt=Z,si=oi;function ni(t){const r=Buffer.alloc(150);let o;try{o=Xt.openSync(t,"r"),Xt.readSync(o,r,0,150,0),Xt.closeSync(o)}catch{}return si(r.toString())}var ii=ni;const ai=M,$o=Qn,Po=qt,ci=ii,li=process.platform==="win32",ui=/\.(?:com|exe)$/i,di=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function mi(t){t.file=$o(t);const e=t.file&&ci(t.file);return e?(t.args.unshift(t.file),t.command=e,$o(t)):t.file}function pi(t){if(!li)return t;const e=mi(t),r=!ui.test(e);if(t.options.forceShell||r){const o=di.test(e);t.command=ai.normalize(t.command),t.command=Po.command(t.command),t.args=t.args.map(n=>Po.argument(n,o));const s=[t.command].concat(t.args).join(" ");t.args=["/d","/s","/c",`"${s}"`],t.command=process.env.comspec||"cmd.exe",t.options.windowsVerbatimArguments=!0}return t}function fi(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],r=Object.assign({},r);const o={command:t,args:e,options:r,file:void 0,original:{command:t,args:e}};return r.shell?o:pi(o)}var hi=fi;const Qt=process.platform==="win32";function Zt(t,e){return Object.assign(new Error(`${e} ${t.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${t.command}`,path:t.command,spawnargs:t.args})}function gi(t,e){if(!Qt)return;const r=t.emit;t.emit=function(o,s){if(o==="exit"){const n=Ao(s,e);if(n)return r.call(t,"error",n)}return r.apply(t,arguments)}}function Ao(t,e){return Qt&&t===1&&!e.file?Zt(e.original,"spawn"):null}function yi(t,e){return Qt&&t===1&&!e.file?Zt(e.original,"spawnSync"):null}var wi={hookChildProcess:gi,verifyENOENT:Ao,verifyENOENTSync:yi,notFoundError:Zt};const So=Vs,er=hi,tr=wi;function ko(t,e,r){const o=er(t,e,r),s=So.spawn(o.command,o.args,o.options);return tr.hookChildProcess(s,o),s}function vi(t,e,r){const o=er(t,e,r),s=So.spawnSync(o.command,o.args,o.options);return s.error=s.error||tr.verifyENOENTSync(s.status,o),s}Ae.exports=ko,Ae.exports.spawn=ko,Ae.exports.sync=vi,Ae.exports._parse=er,Ae.exports._enoent=tr;var Ci=Ae.exports,bi=Pe(Ci);function Ei(t){const e=typeof t=="string"?`
|
|
2
|
+
import{command as ae,cli as Ys}from"cleye";import{createRequire as Vs}from"module";import qs from"crypto";import Q from"fs";import Fe from"os";import M from"path";import{Buffer as zr}from"node:buffer";import we from"node:path";import Bt,{ChildProcess as Wr,exec as Js}from"node:child_process";import ce from"node:process";import Xs,{execSync as ot,exec as Qs}from"child_process";import{fileURLToPath as Yr}from"node:url";import Zs,{constants as Vr}from"node:os";import qr from"assert";import Jr from"events";import{createWriteStream as en,createReadStream as tn,readFileSync as rn}from"node:fs";import on from"buffer";import Gt from"stream";import Xr,{promisify as sn}from"util";import{debuglog as nn,promisify as an}from"node:util";import st from"inquirer";import{of as Qr,concatMap as F,from as N,map as T,catchError as L,tap as Zr,mergeMap as eo,BehaviorSubject as to,ReplaySubject as cn,Subscription as Ut,lastValueFrom as Ht,toArray as Kt,filter as ro,Subject as zt}from"rxjs";import D from"fs/promises";import g from"chalk";import oo from"openai";import{fromPromise as j}from"rxjs/internal/observable/innerFrom";import{xxh64 as so}from"@pacote/xxhash";import K from"winston";import"winston-daily-rotate-file";import ln from"http";import no from"https";import un from"net";import dn from"tls";import mn,{fileURLToPath as pn,pathToFileURL as fn}from"url";import io from"tty";import hn from"@anthropic-ai/sdk";import gn from"axios";import{CohereClientV2 as yn}from"cohere-ai";import{GoogleGenerativeAI as wn,HarmCategory as nt,HarmBlockThreshold as it}from"@google/generative-ai";import vn from"groq-sdk";import{Ollama as Cn}from"ollama";import{fetch as bn,Agent as En}from"undici";import at from"readline";import ao from"figlet";import $n from"gradient-string";import co from"ora";import Pn from"inquirer-reactive-list-prompt";import{readdir as lo,stat as An,rm as Sn}from"node:fs/promises";import kn from"chokidar";import{takeUntil as uo,finalize as mo}from"rxjs/operators";var In="aicommit2",po="2.5.3",Mn="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",xn=["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"],Rn="MIT",On="tak-bro/aicommit2",Dn="Hyungtak Jin(@tak-bro)",_n="module",Nn=["dist"],Tn={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},Ln={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},Fn={"@anthropic-ai/sdk":"^0.39.0","@aws-sdk/client-bedrock-runtime":"^3.678.0","@aws-sdk/credential-providers":"^3.678.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"},jn={"@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"},Bn={extends:["@pvtnbr","prettier"],rules:{"unicorn/no-process-exit":"off"},overrides:[{files:"./src/commands/prepare-commit-msg-hook.ts",rules:{"unicorn/prevent-abbreviations":"off"}}]},Gn={branches:["main"],plugins:[["@semantic-release/commit-analyzer",{preset:"conventionalcommits",releaseRules:[{type:"docs",release:!1},{type:"style",release:!1},{type:"test",release:!1},{type:"ci",release:!1},{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"]},Un={name:In,version:po,description:Mn,keywords:xn,license:Rn,repository:On,author:Dn,type:_n,files:Nn,bin:Tn,scripts:Ln,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:Fn,devDependencies:jn,eslintConfig:Bn,release:Gn},Hn=Vs(import.meta.url),H=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ae(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Se={exports:{}},Wt,fo;function Kn(){if(fo)return Wt;fo=1,Wt=o,o.sync=s;var t=Q;function e(n,i){var a=i.pathExt!==void 0?i.pathExt:process.env.PATHEXT;if(!a||(a=a.split(";"),a.indexOf("")!==-1))return!0;for(var l=0;l<a.length;l++){var d=a[l].toLowerCase();if(d&&n.substr(-d.length).toLowerCase()===d)return!0}return!1}function r(n,i,a){return!n.isSymbolicLink()&&!n.isFile()?!1:e(i,a)}function o(n,i,a){t.stat(n,function(l,d){a(l,l?!1:r(d,n,i))})}function s(n,i){return r(t.statSync(n),n,i)}return Wt}var Yt,ho;function zn(){if(ho)return Yt;ho=1,Yt=e,e.sync=r;var t=Q;function e(n,i,a){t.stat(n,function(l,d){a(l,l?!1:o(d,i))})}function r(n,i){return o(t.statSync(n),i)}function o(n,i){return n.isFile()&&s(n,i)}function s(n,i){var a=n.mode,l=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),f=parseInt("010",8),h=parseInt("001",8),y=m|f,w=a&h||a&f&&d===u||a&m&&l===c||a&y&&c===0;return w}return Yt}var ct;process.platform==="win32"||H.TESTING_WINDOWS?ct=Kn():ct=zn();var Wn=Vt;Vt.sync=Yn;function Vt(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){Vt(t,e||{},function(n,i){n?s(n):o(i)})})}ct(t,e||{},function(o,s){o&&(o.code==="EACCES"||e&&e.ignoreErrors)&&(o=null,s=!1),r(o,s)})}function Yn(t,e){try{return ct.sync(t,e||{})}catch(r){if(e&&e.ignoreErrors||r.code==="EACCES")return!1;throw r}}const ke=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",go=M,Vn=ke?";":":",yo=Wn,wo=t=>Object.assign(new Error(`not found: ${t}`),{code:"ENOENT"}),vo=(t,e)=>{const r=e.colon||Vn,o=t.match(/\//)||ke&&t.match(/\\/)?[""]:[...ke?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(r)],s=ke?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",n=ke?s.split(r):[""];return ke&&t.indexOf(".")!==-1&&n[0]!==""&&n.unshift(""),{pathEnv:o,pathExt:n,pathExtExe:s}},Co=(t,e,r)=>{typeof e=="function"&&(r=e,e={}),e||(e={});const{pathEnv:o,pathExt:s,pathExtExe:n}=vo(t,e),i=[],a=d=>new Promise((c,u)=>{if(d===o.length)return e.all&&i.length?c(i):u(wo(t));const m=o[d],f=/^".*"$/.test(m)?m.slice(1,-1):m,h=go.join(f,t),y=!f&&/^\.[\\\/]/.test(t)?t.slice(0,2)+h:h;c(l(y,d,0))}),l=(d,c,u)=>new Promise((m,f)=>{if(u===s.length)return m(a(c+1));const h=s[u];yo(d+h,{pathExt:n},(y,w)=>{if(!y&&w)if(e.all)i.push(d+h);else return m(d+h);return m(l(d,c,u+1))})});return r?a(0).then(d=>r(null,d),r):a(0)},qn=(t,e)=>{e=e||{};const{pathEnv:r,pathExt:o,pathExtExe:s}=vo(t,e),n=[];for(let i=0;i<r.length;i++){const a=r[i],l=/^".*"$/.test(a)?a.slice(1,-1):a,d=go.join(l,t),c=!l&&/^\.[\\\/]/.test(t)?t.slice(0,2)+d:d;for(let u=0;u<o.length;u++){const m=c+o[u];try{if(yo.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 wo(t)};var Jn=Co;Co.sync=qn;var qt={exports:{}};const bo=(t={})=>{const e=t.env||process.env;return(t.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};qt.exports=bo,qt.exports.default=bo;var Xn=qt.exports;const Eo=M,Qn=Jn,Zn=Xn;function $o(t,e){const r=t.options.env||process.env,o=process.cwd(),s=t.options.cwd!=null,n=s&&process.chdir!==void 0&&!process.chdir.disabled;if(n)try{process.chdir(t.options.cwd)}catch{}let i;try{i=Qn.sync(t.command,{path:r[Zn({env:r})],pathExt:e?Eo.delimiter:void 0})}catch{}finally{n&&process.chdir(o)}return i&&(i=Eo.resolve(s?t.options.cwd:"",i)),i}function ei(t){return $o(t)||$o(t,!0)}var ti=ei,Jt={};const Xt=/([()\][%!^"`<>&|;, *?])/g;function ri(t){return t=t.replace(Xt,"^$1"),t}function oi(t,e){return t=`${t}`,t=t.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),t=t.replace(/(?=(\\+?)?)\1$/,"$1$1"),t=`"${t}"`,t=t.replace(Xt,"^$1"),e&&(t=t.replace(Xt,"^$1")),t}Jt.command=ri,Jt.argument=oi;var si=/^#!(.*)/;const ni=si;var ii=(t="")=>{const e=t.match(ni);if(!e)return null;const[r,o]=e[0].replace(/#! ?/,"").split(" "),s=r.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const Qt=Q,ai=ii;function ci(t){const r=Buffer.alloc(150);let o;try{o=Qt.openSync(t,"r"),Qt.readSync(o,r,0,150,0),Qt.closeSync(o)}catch{}return ai(r.toString())}var li=ci;const ui=M,Po=ti,Ao=Jt,di=li,mi=process.platform==="win32",pi=/\.(?:com|exe)$/i,fi=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function hi(t){t.file=Po(t);const e=t.file&&di(t.file);return e?(t.args.unshift(t.file),t.command=e,Po(t)):t.file}function gi(t){if(!mi)return t;const e=hi(t),r=!pi.test(e);if(t.options.forceShell||r){const o=fi.test(e);t.command=ui.normalize(t.command),t.command=Ao.command(t.command),t.args=t.args.map(n=>Ao.argument(n,o));const s=[t.command].concat(t.args).join(" ");t.args=["/d","/s","/c",`"${s}"`],t.command=process.env.comspec||"cmd.exe",t.options.windowsVerbatimArguments=!0}return t}function yi(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],r=Object.assign({},r);const o={command:t,args:e,options:r,file:void 0,original:{command:t,args:e}};return r.shell?o:gi(o)}var wi=yi;const Zt=process.platform==="win32";function er(t,e){return Object.assign(new Error(`${e} ${t.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${t.command}`,path:t.command,spawnargs:t.args})}function vi(t,e){if(!Zt)return;const r=t.emit;t.emit=function(o,s){if(o==="exit"){const n=So(s,e);if(n)return r.call(t,"error",n)}return r.apply(t,arguments)}}function So(t,e){return Zt&&t===1&&!e.file?er(e.original,"spawn"):null}function Ci(t,e){return Zt&&t===1&&!e.file?er(e.original,"spawnSync"):null}var bi={hookChildProcess:vi,verifyENOENT:So,verifyENOENTSync:Ci,notFoundError:er};const ko=Xs,tr=wi,rr=bi;function Io(t,e,r){const o=tr(t,e,r),s=ko.spawn(o.command,o.args,o.options);return rr.hookChildProcess(s,o),s}function Ei(t,e,r){const o=tr(t,e,r),s=ko.spawnSync(o.command,o.args,o.options);return s.error=s.error||rr.verifyENOENTSync(s.status,o),s}Se.exports=Io,Se.exports.spawn=Io,Se.exports.sync=Ei,Se.exports._parse=tr,Se.exports._enoent=rr;var $i=Se.exports,Pi=Ae($i);function Ai(t){const e=typeof t=="string"?`
|
|
3
3
|
`:`
|
|
4
|
-
`.charCodeAt(),r=typeof t=="string"?"\r":"\r".charCodeAt();return t[t.length-1]===e&&(t=t.slice(0,-1)),t[t.length-1]===r&&(t=t.slice(0,-1)),t}function
|
|
5
|
-
${e}`,
|
|
4
|
+
`.charCodeAt(),r=typeof t=="string"?"\r":"\r".charCodeAt();return t[t.length-1]===e&&(t=t.slice(0,-1)),t[t.length-1]===r&&(t=t.slice(0,-1)),t}function Mo(t={}){const{env:e=process.env,platform:r=process.platform}=t;return r!=="win32"?"PATH":Object.keys(e).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"}const Si=({cwd:t=ce.cwd(),path:e=ce.env[Mo()],preferLocal:r=!0,execPath:o=ce.execPath,addExecPath:s=!0}={})=>{const n=t instanceof URL?Yr(t):t,i=we.resolve(n),a=[];return r&&ki(a,i),s&&Ii(a,o,i),[...a,e].join(we.delimiter)},ki=(t,e)=>{let r;for(;r!==e;)t.push(we.join(e,"node_modules/.bin")),r=e,e=we.resolve(e,"..")},Ii=(t,e,r)=>{const o=e instanceof URL?Yr(e):e;t.push(we.resolve(r,o,".."))},Mi=({env:t=ce.env,...e}={})=>{t={...t};const r=Mo({env:t});return e.path=t[r],t[r]=Si(e),t},xi=(t,e,r,o)=>{if(r==="length"||r==="prototype"||r==="arguments"||r==="caller")return;const s=Object.getOwnPropertyDescriptor(t,r),n=Object.getOwnPropertyDescriptor(e,r);!Ri(s,n)&&o||Object.defineProperty(t,r,n)},Ri=function(t,e){return t===void 0||t.configurable||t.writable===e.writable&&t.enumerable===e.enumerable&&t.configurable===e.configurable&&(t.writable||t.value===e.value)},Oi=(t,e)=>{const r=Object.getPrototypeOf(e);r!==Object.getPrototypeOf(t)&&Object.setPrototypeOf(t,r)},Di=(t,e)=>`/* Wrapped ${t}*/
|
|
5
|
+
${e}`,_i=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),Ni=Object.getOwnPropertyDescriptor(Function.prototype.toString,"name"),Ti=(t,e,r)=>{const o=r===""?"":`with ${r.trim()}() `,s=Di.bind(null,o,e.toString());Object.defineProperty(s,"name",Ni),Object.defineProperty(t,"toString",{..._i,value:s})};function Li(t,e,{ignoreNonConfigurable:r=!1}={}){const{name:o}=t;for(const s of Reflect.ownKeys(e))xi(t,e,s,r);return Oi(t,e),Ti(t,e,o),t}const lt=new WeakMap,xo=(t,e={})=>{if(typeof t!="function")throw new TypeError("Expected a function");let r,o=0;const s=t.displayName||t.name||"<anonymous>",n=function(...i){if(lt.set(n,++o),o===1)r=t.apply(this,i),t=null;else if(e.throw===!0)throw new Error(`Function \`${s}\` can only be called once`);return r};return Li(n,t),lt.set(n,o),n};xo.callCount=t=>{if(!lt.has(t))throw new Error(`The given function \`${t.name}\` is not wrapped by the \`onetime\` package`);return lt.get(t)};const Fi=()=>{const t=Oo-Ro+1;return Array.from({length:t},ji)},ji=(t,e)=>({name:`SIGRT${e+1}`,number:Ro+e,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),Ro=34,Oo=64,Bi=[{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"}],Do=()=>{const t=Fi();return[...Bi,...t].map(Gi)},Gi=({name:t,number:e,description:r,action:o,forced:s=!1,standard:n})=>{const{signals:{[t]:i}}=Vr,a=i!==void 0;return{name:t,number:a?i:e,description:r,supported:a,action:o,forced:s,standard:n}},Ui=()=>{const t=Do();return Object.fromEntries(t.map(Hi))},Hi=({name:t,number:e,description:r,supported:o,action:s,forced:n,standard:i})=>[t,{name:t,number:e,description:r,supported:o,action:s,forced:n,standard:i}],Ki=Ui(),zi=()=>{const t=Do(),e=Oo+1,r=Array.from({length:e},(o,s)=>Wi(s,t));return Object.assign({},...r)},Wi=(t,e)=>{const r=Yi(t,e);if(r===void 0)return{};const{name:o,description:s,supported:n,action:i,forced:a,standard:l}=r;return{[t]:{name:o,number:t,description:s,supported:n,action:i,forced:a,standard:l}}},Yi=(t,e)=>{const r=e.find(({name:o})=>Vr.signals[o]===t);return r!==void 0?r:e.find(o=>o.number===t)};zi();const Vi=({timedOut:t,timeout:e,errorCode:r,signal:o,signalDescription:s,exitCode:n,isCanceled:i})=>t?`timed out after ${e} milliseconds`:i?"was canceled":r!==void 0?`failed with ${r}`:o!==void 0?`was killed with ${o} (${s})`:n!==void 0?`failed with exit code ${n}`:"failed",ut=({stdout:t,stderr:e,all:r,error:o,signal:s,exitCode:n,command:i,escapedCommand:a,timedOut:l,isCanceled:d,killed:c,parsed:{options:{timeout:u,cwd:m=ce.cwd()}}})=>{n=n===null?void 0:n,s=s===null?void 0:s;const f=s===void 0?void 0:Ki[s].description,h=o&&o.code,w=`Command ${Vi({timedOut:l,timeout:u,errorCode:h,signal:s,signalDescription:f,exitCode:n,isCanceled:d})}: ${i}`,C=Object.prototype.toString.call(o)==="[object Error]",b=C?`${w}
|
|
6
6
|
${o.message}`:w,E=[b,e,t].filter(Boolean).join(`
|
|
7
|
-
`);return C?(o.originalMessage=o.message,o.message=E):o=new Error(E),o.shortMessage=b,o.command=i,o.escapedCommand=a,o.exitCode=n,o.signal=s,o.signalDescription=f,o.stdout=t,o.stderr=e,o.cwd=
|
|
8
|
-
`)},
|
|
7
|
+
`);return C?(o.originalMessage=o.message,o.message=E):o=new Error(E),o.shortMessage=b,o.command=i,o.escapedCommand=a,o.exitCode=n,o.signal=s,o.signalDescription=f,o.stdout=t,o.stderr=e,o.cwd=m,r!==void 0&&(o.all=r),"bufferedData"in o&&delete o.bufferedData,o.failed=!0,o.timedOut=!!l,o.isCanceled=d,o.killed=c&&!l,o},dt=["stdin","stdout","stderr"],qi=t=>dt.some(e=>t[e]!==void 0),_o=t=>{if(!t)return;const{stdio:e}=t;if(e===void 0)return dt.map(o=>t[o]);if(qi(t))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${dt.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 r=Math.max(e.length,dt.length);return Array.from({length:r},(o,s)=>e[s])},Ji=t=>{const e=_o(t);return e==="ipc"?"ipc":e===void 0||typeof e=="string"?[e,e,e,"ipc"]:e.includes("ipc")?e:[...e,"ipc"]};var Ie={exports:{}},mt={exports:{}};mt.exports;var No;function Xi(){return No||(No=1,function(t){t.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],process.platform!=="win32"&&t.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),process.platform==="linux"&&t.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}(mt)),mt.exports}var B=H.process;const ve=function(t){return t&&typeof t=="object"&&typeof t.removeListener=="function"&&typeof t.emit=="function"&&typeof t.reallyExit=="function"&&typeof t.listeners=="function"&&typeof t.kill=="function"&&typeof t.pid=="number"&&typeof t.on=="function"};if(!ve(B))Ie.exports=function(){return function(){}};else{var Qi=qr,je=Xi(),Zi=/^win/i.test(B.platform),pt=Jr;typeof pt!="function"&&(pt=pt.EventEmitter);var z;B.__signal_exit_emitter__?z=B.__signal_exit_emitter__:(z=B.__signal_exit_emitter__=new pt,z.count=0,z.emitted={}),z.infinite||(z.setMaxListeners(1/0),z.infinite=!0),Ie.exports=function(t,e){if(!ve(H.process))return function(){};Qi.equal(typeof t,"function","a callback must be provided for exit handler"),Be===!1&&To();var r="exit";e&&e.alwaysLast&&(r="afterexit");var o=function(){z.removeListener(r,t),z.listeners("exit").length===0&&z.listeners("afterexit").length===0&&or()};return z.on(r,t),o};var or=function(){!Be||!ve(H.process)||(Be=!1,je.forEach(function(e){try{B.removeListener(e,sr[e])}catch{}}),B.emit=nr,B.reallyExit=Lo,z.count-=1)};Ie.exports.unload=or;var Me=function(e,r,o){z.emitted[e]||(z.emitted[e]=!0,z.emit(e,r,o))},sr={};je.forEach(function(t){sr[t]=function(){if(ve(H.process)){var r=B.listeners(t);r.length===z.count&&(or(),Me("exit",null,t),Me("afterexit",null,t),Zi&&t==="SIGHUP"&&(t="SIGINT"),B.kill(B.pid,t))}}}),Ie.exports.signals=function(){return je};var Be=!1,To=function(){Be||!ve(H.process)||(Be=!0,z.count+=1,je=je.filter(function(e){try{return B.on(e,sr[e]),!0}catch{return!1}}),B.emit=ta,B.reallyExit=ea)};Ie.exports.load=To;var Lo=B.reallyExit,ea=function(e){ve(H.process)&&(B.exitCode=e||0,Me("exit",B.exitCode,null),Me("afterexit",B.exitCode,null),Lo.call(B,B.exitCode))},nr=B.emit,ta=function(e,r){if(e==="exit"&&ve(H.process)){r!==void 0&&(B.exitCode=r);var o=nr.apply(this,arguments);return Me("exit",B.exitCode,null),Me("afterexit",B.exitCode,null),o}else return nr.apply(this,arguments)}}var ra=Ie.exports,oa=Ae(ra);const sa=1e3*5,na=(t,e="SIGTERM",r={})=>{const o=t(e);return ia(t,e,r,o),o},ia=(t,e,r,o)=>{if(!aa(e,r,o))return;const s=la(r),n=setTimeout(()=>{t("SIGKILL")},s);n.unref&&n.unref()},aa=(t,{forceKillAfterTimeout:e},r)=>ca(t)&&e!==!1&&r,ca=t=>t===Zs.constants.signals.SIGTERM||typeof t=="string"&&t.toUpperCase()==="SIGTERM",la=({forceKillAfterTimeout:t=!0})=>{if(t===!0)return sa;if(!Number.isFinite(t)||t<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${t}\` (${typeof t})`);return t},ua=(t,e)=>{t.kill()&&(e.isCanceled=!0)},da=(t,e,r)=>{t.kill(e),r(Object.assign(new Error("Timed out"),{timedOut:!0,signal:e}))},ma=(t,{timeout:e,killSignal:r="SIGTERM"},o)=>{if(e===0||e===void 0)return o;let s;const n=new Promise((a,l)=>{s=setTimeout(()=>{da(t,r,l)},e)}),i=o.finally(()=>{clearTimeout(s)});return Promise.race([n,i])},pa=({timeout:t})=>{if(t!==void 0&&(!Number.isFinite(t)||t<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${t}\` (${typeof t})`)},fa=async(t,{cleanup:e,detached:r},o)=>{if(!e||r)return o;const s=oa(()=>{t.kill()});return o.finally(()=>{s()})};function ir(t){return t!==null&&typeof t=="object"&&typeof t.pipe=="function"}function Fo(t){return ir(t)&&t.writable!==!1&&typeof t._write=="function"&&typeof t._writableState=="object"}const ha=t=>t instanceof Wr&&typeof t.then=="function",ar=(t,e,r)=>{if(typeof r=="string")return t[e].pipe(en(r)),t;if(Fo(r))return t[e].pipe(r),t;if(!ha(r))throw new TypeError("The second argument must be a string, a stream or an Execa child process.");if(!Fo(r.stdin))throw new TypeError("The target child process's stdin must be available.");return t[e].pipe(r.stdin),r},ga=t=>{t.stdout!==null&&(t.pipeStdout=ar.bind(void 0,t,"stdout")),t.stderr!==null&&(t.pipeStderr=ar.bind(void 0,t,"stderr")),t.all!==void 0&&(t.pipeAll=ar.bind(void 0,t,"all"))};var Ge={exports:{}};const{PassThrough:ya}=Gt;var wa=t=>{t={...t};const{array:e}=t;let{encoding:r}=t;const o=r==="buffer";let s=!1;e?s=!(r||o):r=r||"utf8",o&&(r=null);const n=new ya({objectMode:s});r&&n.setEncoding(r);let i=0;const a=[];return n.on("data",l=>{a.push(l),s?i=a.length:i+=l.length}),n.getBufferedValue=()=>e?a:o?Buffer.concat(a,i):a.join(""),n.getBufferedLength=()=>i,n};const{constants:va}=on,Ca=Gt,{promisify:ba}=Xr,Ea=wa,$a=ba(Ca.pipeline);class jo extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function cr(t,e){if(!t)throw new Error("Expected a stream");e={maxBuffer:1/0,...e};const{maxBuffer:r}=e,o=Ea(e);return await new Promise((s,n)=>{const i=a=>{a&&o.getBufferedLength()<=va.MAX_LENGTH&&(a.bufferedData=o.getBufferedValue()),n(a)};(async()=>{try{await $a(t,o),s()}catch(a){i(a)}})(),o.on("data",()=>{o.getBufferedLength()>r&&i(new jo)})}),o.getBufferedValue()}Ge.exports=cr,Ge.exports.buffer=(t,e)=>cr(t,{...e,encoding:"buffer"}),Ge.exports.array=(t,e)=>cr(t,{...e,array:!0}),Ge.exports.MaxBufferError=jo;var Pa=Ge.exports,Bo=Ae(Pa);const{PassThrough:Aa}=Gt;var Sa=function(){var t=[],e=new Aa({objectMode:!0});return e.setMaxListeners(0),e.add=r,e.isEmpty=o,e.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(r),e;function r(n){return Array.isArray(n)?(n.forEach(r),this):(t.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 t.length==0}function s(n){t=t.filter(function(i){return i!==n}),!t.length&&e.readable&&e.end()}},ka=Ae(Sa);const Go=t=>{if(t!==void 0)throw new TypeError("The `input` and `inputFile` options cannot be both set.")},Ia=({input:t,inputFile:e})=>typeof e!="string"?t:(Go(t),rn(e)),Ma=t=>{const e=Ia(t);if(ir(e))throw new TypeError("The `input` option cannot be a stream in sync mode");return e},xa=({input:t,inputFile:e})=>typeof e!="string"?t:(Go(t),tn(e)),Ra=(t,e)=>{const r=xa(e);r!==void 0&&(ir(r)?r.pipe(t.stdin):t.stdin.end(r))},Oa=(t,{all:e})=>{if(!e||!t.stdout&&!t.stderr)return;const r=ka();return t.stdout&&r.add(t.stdout),t.stderr&&r.add(t.stderr),r},lr=async(t,e)=>{if(!(!t||e===void 0)){t.destroy();try{return await e}catch(r){return r.bufferedData}}},ur=(t,{encoding:e,buffer:r,maxBuffer:o})=>{if(!(!t||!r))return e?Bo(t,{encoding:e,maxBuffer:o}):Bo.buffer(t,{maxBuffer:o})},Da=async({stdout:t,stderr:e,all:r},{encoding:o,buffer:s,maxBuffer:n},i)=>{const a=ur(t,{encoding:o,buffer:s,maxBuffer:n}),l=ur(e,{encoding:o,buffer:s,maxBuffer:n}),d=ur(r,{encoding:o,buffer:s,maxBuffer:n*2});try{return await Promise.all([i,a,l,d])}catch(c){return Promise.all([{error:c,signal:c.signal,timedOut:c.timedOut},lr(t,a),lr(e,l),lr(r,d)])}},_a=(async()=>{})().constructor.prototype,Na=["then","catch","finally"].map(t=>[t,Reflect.getOwnPropertyDescriptor(_a,t)]),Uo=(t,e)=>{for(const[r,o]of Na){const s=typeof e=="function"?(...n)=>Reflect.apply(o.value,e(),n):o.value.bind(e);Reflect.defineProperty(t,r,{...o,value:s})}},Ta=t=>new Promise((e,r)=>{t.on("exit",(o,s)=>{e({exitCode:o,signal:s})}),t.on("error",o=>{r(o)}),t.stdin&&t.stdin.on("error",o=>{r(o)})}),Ho=(t,e=[])=>Array.isArray(e)?[t,...e]:[t],La=/^[\w.-]+$/,Fa=/"/g,ja=t=>typeof t!="string"||La.test(t)?t:`"${t.replace(Fa,'\\"')}"`,Ko=(t,e)=>Ho(t,e).join(" "),zo=(t,e)=>Ho(t,e).map(r=>ja(r)).join(" "),Wo=/ +/g,Yo=t=>{const e=[];for(const r of t.trim().split(Wo)){const o=e[e.length-1];o&&o.endsWith("\\")?e[e.length-1]=`${o.slice(0,-1)} ${r}`:e.push(r)}return e},Vo=t=>{const e=typeof t;if(e==="string")return t;if(e==="number")return String(t);if(e==="object"&&t!==null&&!(t instanceof Wr)&&"stdout"in t){const r=typeof t.stdout;if(r==="string")return t.stdout;if(zr.isBuffer(t.stdout))return t.stdout.toString();throw new TypeError(`Unexpected "${r}" stdout in template expression`)}throw new TypeError(`Unexpected "${e}" in template expression`)},qo=(t,e,r)=>r||t.length===0||e.length===0?[...t,...e]:[...t.slice(0,-1),`${t[t.length-1]}${e[0]}`,...e.slice(1)],Ba=({templates:t,expressions:e,tokens:r,index:o,template:s})=>{const n=s??t.raw[o],i=n.split(Wo).filter(Boolean),a=qo(r,i,n.startsWith(" "));if(o===e.length)return a;const l=e[o],d=Array.isArray(l)?l.map(c=>Vo(c)):[Vo(l)];return qo(a,d,n.endsWith(" "))},Jo=(t,e)=>{let r=[];for(const[o,s]of t.entries())r=Ba({templates:t,expressions:e,tokens:r,index:o,template:s});return r},Ga=nn("execa").enabled,ft=(t,e)=>String(t).padStart(e,"0"),Ua=()=>{const t=new Date;return`${ft(t.getHours(),2)}:${ft(t.getMinutes(),2)}:${ft(t.getSeconds(),2)}.${ft(t.getMilliseconds(),3)}`},Xo=(t,{verbose:e})=>{e&&ce.stderr.write(`[${Ua()}] ${t}
|
|
8
|
+
`)},Ha=1e3*1e3*100,Ka=({env:t,extendEnv:e,preferLocal:r,localDir:o,execPath:s})=>{const n=e?{...ce.env,...t}:t;return r?Mi({env:n,cwd:o,execPath:s}):n},Qo=(t,e,r={})=>{const o=Pi._parse(t,e,r);return t=o.command,e=o.args,r=o.options,r={maxBuffer:Ha,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:r.cwd||ce.cwd(),execPath:ce.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:Ga,...r},r.env=Ka(r),r.stdio=_o(r),ce.platform==="win32"&&we.basename(t,".exe")==="cmd"&&e.unshift("/q"),{file:t,args:e,options:r,parsed:o}},Ue=(t,e,r)=>typeof e!="string"&&!zr.isBuffer(e)?r===void 0?void 0:"":t.stripFinalNewline?Ai(e):e;function I(t,e,r){const o=Qo(t,e,r),s=Ko(t,e),n=zo(t,e);Xo(n,o.options),pa(o.options);let i;try{i=Bt.spawn(o.file,o.args,o.options)}catch(f){const h=new Bt.ChildProcess,y=Promise.reject(ut({error:f,stdout:"",stderr:"",all:"",command:s,escapedCommand:n,parsed:o,timedOut:!1,isCanceled:!1,killed:!1}));return Uo(h,y),h}const a=Ta(i),l=ma(i,o.options,a),d=fa(i,o.options,l),c={isCanceled:!1};i.kill=na.bind(null,i.kill.bind(i)),i.cancel=ua.bind(null,i,c);const m=xo(async()=>{const[{error:f,exitCode:h,signal:y,timedOut:w},C,b,E]=await Da(i,o.options,d),k=Ue(o.options,C),$=Ue(o.options,b),P=Ue(o.options,E);if(f||h!==0||y!==null){const O=ut({error:f,exitCode:h,signal:y,stdout:k,stderr:$,all:P,command:s,escapedCommand:n,parsed:o,timedOut:w,isCanceled:c.isCanceled||(o.options.signal?o.options.signal.aborted:!1),killed:i.killed});if(!o.options.reject)return O;throw O}return{command:s,escapedCommand:n,exitCode:0,stdout:k,stderr:$,all:P,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return Ra(i,o.options),i.all=Oa(i,o.options),ga(i),Uo(i,m),i}function dr(t,e,r){const o=Qo(t,e,r),s=Ko(t,e),n=zo(t,e);Xo(n,o.options);const i=Ma(o.options);let a;try{a=Bt.spawnSync(o.file,o.args,{...o.options,input:i})}catch(c){throw ut({error:c,stdout:"",stderr:"",all:"",command:s,escapedCommand:n,parsed:o,timedOut:!1,isCanceled:!1,killed:!1})}const l=Ue(o.options,a.stdout,a.error),d=Ue(o.options,a.stderr,a.error);if(a.error||a.status!==0||a.signal!==null){const c=ut({stdout:l,stderr:d,error:a.error,signal:a.signal,exitCode:a.status,command:s,escapedCommand:n,parsed:o,timedOut:a.error&&a.error.code==="ETIMEDOUT",isCanceled:!1,killed:a.signal!==null});if(!o.options.reject)return c;throw c}return{command:s,escapedCommand:n,exitCode:0,stdout:l,stderr:d,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}}const za=({input:t,inputFile:e,stdio:r})=>t===void 0&&e===void 0&&r===void 0?{stdin:"inherit"}:{},Zo=(t={})=>({preferLocal:!0,...za(t),...t});function es(t){function e(r,...o){if(!Array.isArray(r))return es({...t,...r});const[s,...n]=Jo(r,o);return I(s,n,Zo(t))}return e.sync=(r,...o)=>{if(!Array.isArray(r))throw new TypeError("Please use $(options).sync`command` instead of $.sync(options)`command`.");const[s,...n]=Jo(r,o);return dr(s,n,Zo(t))},e}const Wa=es();function Ya(t,e){const[r,...o]=Yo(t);return I(r,o,e)}function Va(t,e){const[r,...o]=Yo(t);return dr(r,o,e)}function qa(t,e,r={}){e&&!Array.isArray(e)&&typeof e=="object"&&(r=e,e=[]);const o=Ji(r),s=ce.execArgv.filter(a=>!a.startsWith("--inspect")),{nodePath:n=ce.execPath,nodeOptions:i=s}=r;return I(n,[...i,t,...Array.isArray(e)?e:[]],{...r,stdin:void 0,stdout:void 0,stderr:void 0,stdio:o,shell:!1})}var Ja=Object.freeze({__proto__:null,execa:I,execaSync:dr,$:Wa,execaCommand:Ya,execaCommandSync:Va,execaNode:qa});const{hasOwnProperty:mr}=Object.prototype,ht=typeof process<"u"&&process.platform==="win32"?`\r
|
|
9
9
|
`:`
|
|
10
|
-
`,
|
|
10
|
+
`,pr=(t,e)=>{const r=[];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(t)){const i=t[n];if(i&&Array.isArray(i))for(const a of i)o+=xe(n+"[]")+s+xe(a)+ht;else i&&typeof i=="object"?r.push(n):o+=xe(n)+s+xe(i)+ht}e.section&&o.length&&(o="["+xe(e.section)+"]"+ht+o);for(const n of r){const i=ts(n).join("\\."),a=(e.section?e.section+".":"")+i,{whitespace:l}=e,d=pr(t[n],{section:a,whitespace:l});o.length&&d.length&&(o+=ht),o+=d}return o},ts=t=>t.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(e=>e.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),rs=t=>{const e=Object.create(null);let r=e,o=null;const s=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,n=t.split(/[\r\n]+/g);for(const a of n){if(!a||a.match(/^\s*[;#]/))continue;const l=a.match(s);if(!l)continue;if(l[1]!==void 0){if(o=gt(l[1]),o==="__proto__"){r=Object.create(null);continue}r=e[o]=e[o]||Object.create(null);continue}const d=gt(l[2]),c=d.length>2&&d.slice(-2)==="[]",u=c?d.slice(0,-2):d;if(u==="__proto__")continue;const m=l[3]?gt(l[4]):!0,f=m==="true"||m==="false"||m==="null"?JSON.parse(m):m;c&&(mr.call(r,u)?Array.isArray(r[u])||(r[u]=[r[u]]):r[u]=[]),Array.isArray(r[u])?r[u].push(f):r[u]=f}const i=[];for(const a of Object.keys(e)){if(!mr.call(e,a)||typeof e[a]!="object"||Array.isArray(e[a]))continue;const l=ts(a);r=e;const d=l.pop(),c=d.replace(/\\\./g,".");for(const u of l)u!=="__proto__"&&((!mr.call(r,u)||typeof r[u]!="object")&&(r[u]=Object.create(null)),r=r[u]);r===e&&c===d||(r[c]=e[a],i.push(a))}for(const a of i)delete e[a];return e},os=t=>t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"),xe=t=>typeof t!="string"||t.match(/[=\r\n]/)||t.match(/^\[/)||t.length>1&&os(t)||t!==t.trim()?JSON.stringify(t):t.split(";").join("\\;").split("#").join("\\#"),gt=(t,e)=>{if(t=(t||"").trim(),os(t)){t.charAt(0)==="'"&&(t=t.slice(1,-1));try{t=JSON.parse(t)}catch{}}else{let r=!1,o="";for(let s=0,n=t.length;s<n;s++){const i=t.charAt(s);if(r)"\\;#".indexOf(i)!==-1?o+=i:o+="\\"+i,r=!1;else{if(";#".indexOf(i)!==-1)break;i==="\\"?r=!0:o+=i}}return r&&(o+="\\"),o.trim()}return t};var Xa={parse:rs,decode:rs,stringify:pr,encode:pr,safe:xe,unsafe:gt},Re=Ae(Xa);class v extends Error{constructor(e,r={}){super(e,{cause:r.cause}),this.name="KnownError",this.code=r.code,this.suggestions=r.suggestions||[]}}const He=" ",pe=t=>{if(t instanceof Error){if(t instanceof v){t.suggestions.length>0&&(console.error(""),console.error(`${He}${g.yellow("Suggestions:")}`),t.suggestions.forEach(e=>{console.error(`${He} ${g.dim("\u2022")} ${e}`)}));return}t.stack&&console.error(g.dim(t.stack.split(`
|
|
11
11
|
`).slice(1).join(`
|
|
12
12
|
`))),console.error(`
|
|
13
|
-
${
|
|
14
|
-
${Ue}Please open a Bug report with the information above:`),console.error(`${Ue}https://github.com/tak-bro/aicommit2/issues/new/choose`)}},gt=t=>D.lstat(t).then(()=>!0,()=>!1),os=async t=>{try{await D.mkdir(t,{recursive:!0})}catch(e){if(e.code!=="EEXIST")throw e}},yt=t=>t&&`${t[0].toUpperCase()}${t.slice(1)}`,wt=(t,e)=>{const r=Math.ceil(t),o=Math.floor(e);return Math.floor(Math.random()*(o-r+1))+r},qa=(t,e)=>t.disabled&&!e.disabled?1:!t.disabled&&e.disabled?-1:0,vt=t=>t.reduce((e,r)=>Array.isArray(r)?e.concat(vt(r)):e.concat(r),[]),ss=(t,e=5)=>t.replace(/[\n\r]/g,"").split(" ").slice(0,e).join(" "),Ja=t=>{let e=0;for(let r=0;r<t.length;r++){const o=t.charCodeAt(r);e=(e<<5)-e+o,e=e&e}return Math.abs(e)},Xa=t=>{const e=t%360,r=65+t%15,o=45+t%10;return`hsl(${e}, ${r}%, ${o}%)`},Qa=t=>{const[e,r,o]=t.match(/\d+/g).map((u,p)=>p===0?Number(u):Number(u)/100),s=(1-Math.abs(2*o-1))*r,n=s*(1-Math.abs(e/60%2-1)),i=o-s/2;let a,c,d;e<60?[a,c,d]=[s,n,0]:e<120?[a,c,d]=[n,s,0]:e<180?[a,c,d]=[0,s,n]:e<240?[a,c,d]=[0,n,s]:e<300?[a,c,d]=[n,0,s]:[a,c,d]=[s,0,n];const l=u=>{const p=Math.round((u+i)*255).toString(16);return p.length===1?"0"+p:p};return`#${l(a)}${l(c)}${l(d)}`},Za=t=>{const e=Ja(t),r=Xa(e);return{primary:Qa(r),secondary:"#FFFFFF"}},ns=t=>{try{return{ok:!0,data:JSON.parse(t)}}catch(e){return{ok:!1,error:e}}},Ct=t=>{if(!t||typeof t!="string")return"";if(M.isAbsolute(t))return M.resolve(t);if(ze){const e=M.dirname(ze),r=M.join(e,t);return M.resolve(r)}else return""},ec=["","conventional","gitmoji"],bt="http://localhost:11434",{hasOwnProperty:tc}=Object.prototype,pr=(t,e)=>tc.call(t,e),He=["OPENAI","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS","BEDROCK"],is=t=>{const e=Le.platform(),r=Le.homedir();let o,s;switch(t){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")t==="cache"?s=M.join(r,"Library","Caches"):s=M.join(r,"Library","Application Support");else if(e==="win32")s=process.env.LOCALAPPDATA||r;else switch(t){case"config":s=M.join(r,".config");break;case"data":s=M.join(r,".local","share");break;case"cache":s=M.join(r,".cache");break;case"state":s=M.join(r,".local","state");break;default:s=r}return o||s},as=M.join(is("config"),"aicommit2"),ue=M.join(is("state"),"aicommit2","logs"),cs=M.join(as,"config.ini"),ls=M.join(ue,"aicommit2-%DATE%.log"),us=M.join(ue,"exceptions-%DATE%.log"),rc=t=>{const e=Object.keys(t),r=new Set([...He,...e.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(r)},R=(t,e,r)=>{if(!e)throw new v(`Invalid config property ${t}: ${r}`)},pe=(t,e=!1)=>r=>typeof r=="boolean"?r:r==null?e:(R(t,/^(?:true|false)$/.test(r),"Must be a boolean(true or false)"),r==="true"),m={systemPrompt(t){return t||""},systemPromptPath(t){return t||""},codeReviewPromptPath(t){return t||""},timeout(t){if(!t)return 6e4;R("timeout",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return R("timeout",e>=500,"Must be greater than 500ms"),e},temperature(t){if(!t)return .7;R("temperature",/^(2|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 2");const e=Number(t);return R("temperature",e>0,"Must be greater than 0"),R("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens(t){return t?(R("maxTokens",/^\d+$/.test(t),"Must be an integer"),Number(t)):8192},logLevel(t){return t?(R("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(t),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),t):"info"},logFilePath(t){return t||ls},exceptionLogFilePath(t){return t||us},locale(t){return t?(R("locale",t,"Cannot be empty"),R("locale",/^[a-z-]+$/i.test(t),"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"),t):"en"},generate(t){if(!t)return 1;R("generate",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return R("generate",e>0,"Must be greater than 0"),R("generate",e<=5,"Must be less or equal to 5"),e},type(t){return t?(R("type",ec.includes(t),"Invalid commit type"),t):"conventional"},maxLength(t){if(!t)return 50;R("maxLength",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return R("maxLength",e>=20,"Must be greater than 20 characters"),e},exclude:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):[],topP:t=>{if(!t)return .9;R("topP",/^(1|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 1");const e=Number(t);return R("topP",e>0,"Must be greater than 0"),R("topP",e<=1,"Must be less than or equal to 1"),e},logging:pe("logging",!0),includeBody:pe("includeBody"),codeReview:pe("codeReview"),disabled:pe("disabled"),watchMode:pe("watchMode"),forceGit:pe("forceGit"),disableLowerCase:pe("disableLowerCase"),jjAutoNew:pe("jjAutoNew")},Ke={OPENAI:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gpt-4o-mini"],url:t=>t?(R("OPENAI.url",/^https?:\/\//.test(t),"Must be a valid URL"),t):"https://api.openai.com",path:t=>t||"/v1/chat/completions",proxy:t=>t||"",topP:m.topP,systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},HUGGINGFACE:{cookie:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,topP:m.topP,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},GEMINI:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gemini-3-flash-preview"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},ANTHROPIC:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["claude-sonnet-4-20250514"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},MISTRAL:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["mistral-small-latest"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},CODESTRAL:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["codestral-latest"],topP:m.topP,systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},OLLAMA:{model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):[],host:t=>t?(R("OLLAMA.host",/^https?:\/\//.test(t),"Must be a valid URL"),t):bt,timeout:t=>{if(!t)return 1e5;R("OLLAMA.timeout",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return R("OLLAMA.timeout",e>=500,"Must be greater than 500ms"),e},auth:t=>t||"",key:t=>t||"",envKey:t=>t||"",numCtx:t=>{if(!t)return 2048;R("OLLAMA.numCtx",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return R("OLLAMA.numCtx",e>=2048,"Must be greater than 2048"),e},systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},COHERE:{key:t=>t||"",envKey:t=>t||"",url:t=>t?(R("COHERE.url",/^https?:\/\//.test(t),"Must be a valid URL"),t):"https://api.cohere.ai",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["command-a-03-2025"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,timeout:m.timeout,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},GROQ:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["llama-3.3-70b-versatile"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},PERPLEXITY:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["sonar"],topP:m.topP,systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},DEEPSEEK:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["deepseek-chat"],topP:m.topP,systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},GITHUB_MODELS:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gpt-4o-mini"],systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase},BEDROCK:{key:t=>t||"",envKey:t=>t&&t.length>0?t:"BEDROCK_API_KEY",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>{const o=r.trim();return o&&!o.includes(".")&&!o.includes(":")&&console.warn(`[Bedrock] Model ID "${o}" may be invalid.
|
|
13
|
+
${He}${g.dim(`aicommit2 v${po}`)}`),console.error(`
|
|
14
|
+
${He}Please open a Bug report with the information above:`),console.error(`${He}https://github.com/tak-bro/aicommit2/issues/new/choose`)}},yt=t=>D.lstat(t).then(()=>!0,()=>!1),ss=async t=>{try{await D.mkdir(t,{recursive:!0})}catch(e){if(e.code!=="EEXIST")throw e}},wt=t=>t&&`${t[0].toUpperCase()}${t.slice(1)}`,vt=(t,e)=>{const r=Math.ceil(t),o=Math.floor(e);return Math.floor(Math.random()*(o-r+1))+r},Qa=(t,e)=>t.disabled&&!e.disabled?1:!t.disabled&&e.disabled?-1:0,Ct=t=>t.reduce((e,r)=>Array.isArray(r)?e.concat(Ct(r)):e.concat(r),[]),ns=(t,e=5)=>t.replace(/[\n\r]/g,"").split(" ").slice(0,e).join(" "),Za=t=>{let e=0;for(let r=0;r<t.length;r++){const o=t.charCodeAt(r);e=(e<<5)-e+o,e=e&e}return Math.abs(e)},ec=t=>{const e=t%360,r=65+t%15,o=45+t%10;return`hsl(${e}, ${r}%, ${o}%)`},tc=t=>{const[e,r,o]=t.match(/\d+/g).map((u,m)=>m===0?Number(u):Number(u)/100),s=(1-Math.abs(2*o-1))*r,n=s*(1-Math.abs(e/60%2-1)),i=o-s/2;let a,l,d;e<60?[a,l,d]=[s,n,0]:e<120?[a,l,d]=[n,s,0]:e<180?[a,l,d]=[0,s,n]:e<240?[a,l,d]=[0,n,s]:e<300?[a,l,d]=[n,0,s]:[a,l,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(a)}${c(l)}${c(d)}`},rc=t=>{const e=Za(t),r=ec(e);return{primary:tc(r),secondary:"#FFFFFF"}},is=t=>{try{return{ok:!0,data:JSON.parse(t)}}catch(e){return{ok:!1,error:e}}},bt=t=>{if(!t||typeof t!="string")return"";if(M.isAbsolute(t))return M.resolve(t);if(We){const e=M.dirname(We),r=M.join(e,t);return M.resolve(r)}else return""},oc=["","conventional","gitmoji"],Et="http://localhost:11434",{hasOwnProperty:sc}=Object.prototype,fr=(t,e)=>sc.call(t,e),Ke=["OPENAI","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS","BEDROCK"],as=t=>{const e=Fe.platform(),r=Fe.homedir();let o,s;switch(t){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")t==="cache"?s=M.join(r,"Library","Caches"):s=M.join(r,"Library","Application Support");else if(e==="win32")s=process.env.LOCALAPPDATA||r;else switch(t){case"config":s=M.join(r,".config");break;case"data":s=M.join(r,".local","share");break;case"cache":s=M.join(r,".cache");break;case"state":s=M.join(r,".local","state");break;default:s=r}return o||s},cs=M.join(as("config"),"aicommit2"),le=M.join(as("state"),"aicommit2","logs"),ls=M.join(cs,"config.ini"),us=M.join(le,"aicommit2-%DATE%.log"),ds=M.join(le,"exceptions-%DATE%.log"),nc=t=>{const e=Object.keys(t),r=new Set([...Ke,...e.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(r)},x=(t,e,r)=>{if(!e)throw new v(`Invalid config property ${t}: ${r}`)},ue=(t,e=!1)=>r=>typeof r=="boolean"?r:r==null?e:(x(t,/^(?:true|false)$/.test(r),"Must be a boolean(true or false)"),r==="true"),p={systemPrompt(t){return t||""},systemPromptPath(t){return t||""},codeReviewPromptPath(t){return t||""},timeout(t){if(!t)return 6e4;x("timeout",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("timeout",e>=500,"Must be greater than 500ms"),e},temperature(t){if(!t)return .7;x("temperature",/^(2|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 2");const e=Number(t);return x("temperature",e>0,"Must be greater than 0"),x("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens(t){return t?(x("maxTokens",/^\d+$/.test(t),"Must be an integer"),Number(t)):8192},logLevel(t){return t?(x("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(t),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),t):"info"},logFilePath(t){return t||us},exceptionLogFilePath(t){return t||ds},locale(t){return t?(x("locale",t,"Cannot be empty"),x("locale",/^[a-z-]+$/i.test(t),"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"),t):"en"},generate(t){if(!t)return 1;x("generate",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("generate",e>0,"Must be greater than 0"),x("generate",e<=5,"Must be less or equal to 5"),e},type(t){return t?(x("type",oc.includes(t),"Invalid commit type"),t):"conventional"},maxLength(t){if(!t)return 50;x("maxLength",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("maxLength",e>=20,"Must be greater than 20 characters"),e},exclude:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):[],topP:t=>{if(!t)return .9;x("topP",/^(1|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 1");const e=Number(t);return x("topP",e>0,"Must be greater than 0"),x("topP",e<=1,"Must be less than or equal to 1"),e},logging:ue("logging",!0),includeBody:ue("includeBody"),codeReview:ue("codeReview"),disabled:ue("disabled"),watchMode:ue("watchMode"),forceGit:ue("forceGit"),disableLowerCase:ue("disableLowerCase"),jjAutoNew:ue("jjAutoNew"),autoCopy:ue("autoCopy"),useStats:ue("useStats",!0),statsDays:t=>{if(!t)return 30;x("statsDays",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("statsDays",e>0,"Must be greater than 0"),e}},ze={OPENAI:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gpt-4o-mini"],url:t=>t?(x("OPENAI.url",/^https?:\/\//.test(t),"Must be a valid URL"),t):"https://api.openai.com",path:t=>t||"/v1/chat/completions",proxy:t=>t||"",topP:p.topP,systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},HUGGINGFACE:{cookie:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,topP:p.topP,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},GEMINI:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gemini-3-flash-preview"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},ANTHROPIC:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["claude-sonnet-4-20250514"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},MISTRAL:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["mistral-small-latest"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},CODESTRAL:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["codestral-latest"],topP:p.topP,systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},OLLAMA:{model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):[],host:t=>t?(x("OLLAMA.host",/^https?:\/\//.test(t),"Must be a valid URL"),t):Et,timeout:t=>{if(!t)return 1e5;x("OLLAMA.timeout",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("OLLAMA.timeout",e>=500,"Must be greater than 500ms"),e},auth:t=>t||"",key:t=>t||"",envKey:t=>t||"",numCtx:t=>{if(!t)return 2048;x("OLLAMA.numCtx",/^\d+$/.test(t),"Must be an integer");const e=Number(t);return x("OLLAMA.numCtx",e>=2048,"Must be greater than 2048"),e},systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},COHERE:{key:t=>t||"",envKey:t=>t||"",url:t=>t?(x("COHERE.url",/^https?:\/\//.test(t),"Must be a valid URL"),t):"https://api.cohere.ai",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["command-a-03-2025"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,timeout:p.timeout,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},GROQ:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["llama-3.3-70b-versatile"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},PERPLEXITY:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["sonar"],topP:p.topP,systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},DEEPSEEK:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["deepseek-chat"],topP:p.topP,systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},GITHUB_MODELS:{key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>r.trim()).filter(r=>!!r&&r.length>0):["gpt-4o-mini"],systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase},BEDROCK:{key:t=>t||"",envKey:t=>t&&t.length>0?t:"BEDROCK_API_KEY",model:t=>t?(typeof t=="string"?t?.split(","):t).map(r=>{const o=r.trim();return o&&!o.includes(".")&&!o.includes(":")&&console.warn(`[Bedrock] Model ID "${o}" may be invalid.
|
|
15
15
|
Expected formats:
|
|
16
16
|
- Foundation model: "provider.model-name-version" (e.g., "anthropic.claude-haiku-4-5-20251001-v1:0")
|
|
17
17
|
- Inference profile: "prefix.provider.model-name-version" (e.g., "us.anthropic.claude-haiku-4-5-20251001-v1:0")
|
|
18
18
|
- ARN: Full Amazon Resource Name
|
|
19
|
-
See https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html`),o}).filter(r=>!!r&&r.length>0):["anthropic.claude-haiku-4-5-20251001-v1:0"],runtimeMode:t=>{t&&console.warn("[Bedrock] DEPRECATION: runtimeMode is no longer used. Authentication method is now auto-detected from configured credentials.")},region:t=>t||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"",profile:t=>t||process.env.AWS_PROFILE||"",accessKeyId:t=>t||process.env.AWS_ACCESS_KEY_ID||"",secretAccessKey:t=>t||process.env.AWS_SECRET_ACCESS_KEY||"",sessionToken:t=>t||process.env.AWS_SESSION_TOKEN||"",applicationEndpointId:t=>t||process.env.BEDROCK_APPLICATION_ENDPOINT_ID||"",applicationInferenceProfileArn:t=>t||process.env.BEDROCK_APPLICATION_INFERENCE_PROFILE_ARN||process.env.BEDROCK_INFERENCE_PROFILE_ARN||"",applicationBaseUrl:t=>t||process.env.BEDROCK_APPLICATION_BASE_URL||"",systemPrompt:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:t=>{if(!t)return;R("temperature",/^(2|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 2");const e=Number(t);return R("temperature",e>0,"Must be greater than 0"),R("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens:t=>{if(t)return R("maxTokens",/^\d+$/.test(t),"Must be an integer"),Number(t)},logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:t=>{if(!t)return;R("topP",/^(1|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 1");const e=Number(t);return R("topP",e>0,"Must be greater than 0"),R("topP",e<=1,"Must be less than or equal to 1"),e},codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase,inferenceParameters:t=>{if(!t)return{};if(typeof t=="object")return t;try{const e=JSON.parse(t);return R("BEDROCK.inferenceParameters",typeof e=="object"&&e!==null&&!Array.isArray(e),"Must be a valid JSON object"),e}catch(e){throw new v(`Invalid BEDROCK.inferenceParameters: Must be valid JSON. Error: ${e.message}`)}}}},oc=t=>typeof t=="object"&&t!==null,ds=(t,e)=>{Object.keys(t).forEach(r=>{const o=t[r];oc(o)&&e in o&&(o[e]=!0)})},sc=t=>{ds(t,"includeBody")},nc=t=>{ds(t,"disableLowerCase")};let ze;const ic=(t=[])=>{const e={};for(const r of t)if(r.startsWith("--")){const[o,s]=r.slice(2).split("="),[n,i]=o.split(".");n&&i&&n in Ke?(e[n]||(e[n]={}),e[n][i]=s):e[o]=s}return e},ac=()=>{const t=Le.homedir(),e=process.env.AICOMMIT_CONFIG_PATH,r=cs,o=M.join(t,".aicommit2");return[e,r,o].filter(s=>!!s)},Re=async()=>{const t=ac();for(const e of t)if(await gt(e))return e;return cs},cc=t=>t.replace(/\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}|\$([a-zA-Z_][a-zA-Z0-9_]*)/g,(e,r,o)=>{const s=r||o;return process.env[s]??""}),We=async()=>{const t=await Re();ze=t;try{const e=await D.readFile(t,"utf8"),r=cc(e);return xe.parse(r)}catch(e){return e.code==="ENOENT"?(ze=void 0,{}):(console.error(`Error reading config file ${t}:`,e),ze=void 0,{})}},ge=async(t,e=[])=>{const r=await We(),o=ic(e),s={...t,...o},n={},i=rc(r),a={};for(const d of i){const l=r[d]?.envKey;let u;l?(u=[l],d==="BEDROCK"&&l!=="BEDROCK_APPLICATION_API_KEY"&&u.push("BEDROCK_APPLICATION_API_KEY")):d==="BEDROCK"?u=["BEDROCK_API_KEY","BEDROCK_APPLICATION_API_KEY"]:u=[`${d}_API_KEY`];const p=u.map(f=>f?process.env[f]:void 0).find(f=>typeof f=="string"&&f.length>0);p&&(a[d]={key:p})}const c=(d,l)=>{const u=s[`${d}.${l}`]??s[d]?.[l],p=a[d]?.[l],f=r[d]?.[l],h=s[l]??r[l];return u!==void 0?u:p!==void 0?p:f!==void 0?f:h};for(const[d,l]of Object.entries(m)){const u=s[d]??r[d];n[d]=l(u)}for(const d of i){n[d]={};const l=Ke[d]||Et(d);for(const[u,p]of Object.entries(l)){const f=c(d,u);n[d][u]=p(f)}}return n},fr=async t=>{const e=await We();for(const[s,n]of t){const[i,a]=s.split(".");if(!a){const l=m[s];if(!l)throw new v(`Invalid config property: ${s}`);e[s]=l(n);continue}if(e[i]||(e[i]={}),He.includes(i)){const l=Ke[i][a];if(!l)throw new v(`Invalid config property: ${s}`);e[i][a]=l(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 d=Et(i);if(!d[a])throw new v(`Invalid config property for custom service: ${s}`);try{e[i][a]=d[a](n)}catch(l){throw l instanceof v?l:new v(`Invalid value for ${s}: ${l.message}`)}}const r=await Re(),o=M.dirname(r);await D.mkdir(o,{recursive:!0}),await D.writeFile(r,xe.stringify(e),"utf8")},lc=async t=>{const e=await We();for(const[s,n]of t){const[i,a]=s.split("."),c=e[i];if(a==="model"){c||(e[i]={});const l=e[i][a]||[],u=typeof n=="string"?n.split(",").map(p=>p.trim()).filter(p=>!!p):n;e[i][a]=vt([...l,...u]);continue}if(c&&c.compatible===!0){c||(e[i]={});const l=Et(i);if(!l[a])throw new v(`Invalid config property: ${s}`);try{e[i][a]=l[a](n)}catch(u){throw u instanceof v?u:new v(`Invalid value for ${s}: ${u.message}`)}continue}if(i in Ke){c||(e[i]={});const l=Ke[i][a];if(!l)throw new v(`Invalid config property: ${s}`);e[i][a]=l(n)}else{const l=Et(i);if(!l[a])throw new v(`Invalid config property: ${s}`);e[i]||(e[i]={}),e[i][a]=l[a](n)}}const r=await Re(),o=M.dirname(r);await D.mkdir(o,{recursive:!0}),await D.writeFile(r,xe.stringify(e),"utf8")},uc=async()=>{const t=await We();console.log(xe.stringify(t))},dc=async()=>{console.log(await Re())},Et=t=>({compatible:pe("compatible"),stream:pe("stream"),url:e=>e?(R(`${t}.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:m.systemPrompt,systemPromptPath:m.systemPromptPath,codeReviewPromptPath:m.codeReviewPromptPath,timeout:m.timeout,temperature:m.temperature,maxTokens:m.maxTokens,logging:m.logging,locale:m.locale,generate:m.generate,type:m.type,maxLength:m.maxLength,includeBody:m.includeBody,topP:m.topP,codeReview:m.codeReview,disabled:m.disabled,watchMode:m.watchMode,disableLowerCase:m.disableLowerCase}),Y=t=>typeof t=="string"&&t.trim().length>0,Ce=t=>(Array.isArray(t.model)?t.model:Y(t.model)?[t.model.trim()]:[]).length>0,$t=t=>{const e=Y(t.key),r=Y(t.region)||Y(process.env.AWS_REGION)||Y(process.env.AWS_DEFAULT_REGION),o=Y(t.profile)||Y(process.env.AWS_PROFILE),s=Y(t.accessKeyId)&&Y(t.secretAccessKey)||Y(process.env.AWS_ACCESS_KEY_ID)&&Y(process.env.AWS_SECRET_ACCESS_KEY),n=Y(t.applicationBaseUrl)||Y(process.env.BEDROCK_APPLICATION_BASE_URL),i=Y(t.applicationEndpointId)||Y(process.env.BEDROCK_APPLICATION_ENDPOINT_ID),a=Y(process.env.BEDROCK_APPLICATION_API_KEY);return r&&(e||o||s)||(n&&e||i&&a)},Oe=(t,e)=>Object.entries(t).map(([r,o])=>[r,o]).filter(([r,o])=>!o.disabled).filter(([r,o])=>He.includes(r)||o.compatible===!0).filter(([r,o])=>{switch(e){case"commit":return r==="OLLAMA"?!!o&&Ce(o):r==="HUGGINGFACE"?!!o&&!!o.cookie:r==="BEDROCK"?Ce(o)&&$t(o):!!o.key&&o.key.length>0;case"review":const s=t.codeReview||o.codeReview;return r==="OLLAMA"?!!o&&Ce(o)&&s:r==="HUGGINGFACE"?!!o&&!!o.cookie&&s:r==="BEDROCK"?Ce(o)&&$t(o)&&s:!!o.key&&o.key.length>0&&s;case"watch":const n=t.watchMode||o.watchMode;return r==="OLLAMA"?!!o&&Ce(o)&&n:r==="HUGGINGFACE"?!!o&&!!o.cookie&&n:r==="BEDROCK"?Ce(o)&&$t(o)&&n:o.compatible?!!o.url&&!!o.key&&n:!!o.key&&o.key.length>0&&n}}).map(([r])=>r);class mc{static create(e,r){return new e(r)}}const Ye=new Map,be=(t,e,r)=>{const o=oo(0).update(e).digest("hex").substring(0,8),s=`${t}_${o}_${r}`;if(Ye.has(s))return Ye.get(s);const n=new Date,i=hc(n,t,e,r),a=`${ue}/${i}`,c=K.createLogger({level:"info",format:K.format.combine(K.format.timestamp({format:"YYYY-MM-DDTHH:mm:ss.SSSZ"}),K.format.printf(({timestamp:d,level:l,message:u,...p})=>p&&Object.keys(p).length>0?`[${d}] ${l}: ${u} ${JSON.stringify(p,null,2)}`:`[${d}] ${l}: ${u}`)),transports:[new K.transports.File({filename:a})]});return c.info(`=== ${t.toUpperCase()} AI SERVICE LOG ===`),c.info(`Diff Hash: ${o}`),c.info(`Request Type: ${r.toUpperCase()}`),c.info(`Start Time: ${n.toISOString()}`),c.info("=".repeat(50)),c.info(""),Ye.set(s,c),c},pc=t=>{const e={...t},r=["authorization","x-api-key","x-goog-api-key","api-key","x-amzn-bedrock-application-key"];for(const o of r){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},ee=(t,e,r,o,s,n,i=!0)=>{if(!i)return;const a=be(r,t,e);a.info(`Making request to ${r} API with model: ${o}`),a.info(`Request URL: ${s}`),a.info("Request headers:",pc(n))},ne=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).info("Request payload:",o)},te=(t,e,r,o,s,n=!0)=>{if(!n)return;const i=be(r,t,e);i.info("System prompt:",{prompt:o}),i.info("User prompt:",{prompt:s})},V=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).info("Response received:",o)},G=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).error("API request failed:",o)},q=(t,e,r,o,s,n=!0)=>{if(!n)return;const i=be(r,t,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 ===")},fc=(t,e,r,o,s,n,i,a=!0)=>{if(!a)return;const c=be(r,t,e);i?c.error(`Request failed after ${n}ms:`,{error:i}):(c.info(`Request completed in ${n}ms`),c.info("Response:",{response:s})),q(t,e,r,n,s,a)},hc=(t,e,r,o)=>{const{year:s,month:n,day:i,hours:a,minutes:c,seconds:d}=gc(t),u=oo(0).update(r).digest("hex").substring(0,8),p=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,20);return o==="review"?`${s}-${n}-${i}_${a}-${c}-${d}_${u}_${p}_review.log`:`${s}-${n}-${i}_${a}-${c}-${d}_${u}_${p}_commit.log`},gc=t=>{const e=t.getFullYear().toString(),r=(t.getMonth()+1).toString().padStart(2,"0"),o=t.getDate().toString().padStart(2,"0"),s=t.getHours().toString().padStart(2,"0"),n=t.getMinutes().toString().padStart(2,"0"),i=t.getSeconds().toString().padStart(2,"0");return{year:e,month:r,day:o,hours:s,minutes:n,seconds:i}},hr=()=>{for(const[t,e]of Ye.entries())try{e.close()}catch(r){console.error(`Failed to close logger ${t}:`,r)}Ye.clear()};process.on("exit",hr),process.on("SIGINT",()=>{hr(),process.exit(0)}),process.on("SIGTERM",()=>{hr(),process.exit(0)});const A={label:g.bold.green,command:g.bold.white,hint:g.gray,highlight:g.bold.magenta,dim:g.dim},x={MISSING_API_KEY:"MISSING_API_KEY",INVALID_API_KEY:"INVALID_API_KEY",AUTH_FAILED:"AUTH_FAILED",RATE_LIMITED:"RATE_LIMITED",QUOTA_EXCEEDED:"QUOTA_EXCEEDED",MODEL_NOT_FOUND:"MODEL_NOT_FOUND",MODEL_ACCESS_DENIED:"MODEL_ACCESS_DENIED",NETWORK_ERROR:"NETWORK_ERROR",TIMEOUT:"TIMEOUT",SERVICE_UNAVAILABLE:"SERVICE_UNAVAILABLE",NO_STAGED_CHANGES:"NO_STAGED_CHANGES",EMPTY_COMMIT_MESSAGE:"EMPTY_COMMIT_MESSAGE",VCS_NOT_FOUND:"VCS_NOT_FOUND",INVALID_CONFIG:"INVALID_CONFIG",CONFIG_NOT_FOUND:"CONFIG_NOT_FOUND",SERVER_ERROR:"SERVER_ERROR",UNKNOWN:"UNKNOWN"},gr={missingApiKey:t=>{const e=t.toUpperCase();return[`Missing API key for ${A.highlight(e)}.`,"",`${A.label("\u2192")} Run: ${A.command(`aicommit2 config set ${e}.key=YOUR_API_KEY`)}`].join(`
|
|
19
|
+
See https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html`),o}).filter(r=>!!r&&r.length>0):["anthropic.claude-haiku-4-5-20251001-v1:0"],runtimeMode:t=>{t&&console.warn("[Bedrock] DEPRECATION: runtimeMode is no longer used. Authentication method is now auto-detected from configured credentials.")},region:t=>t||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"",profile:t=>t||process.env.AWS_PROFILE||"",accessKeyId:t=>t||process.env.AWS_ACCESS_KEY_ID||"",secretAccessKey:t=>t||process.env.AWS_SECRET_ACCESS_KEY||"",sessionToken:t=>t||process.env.AWS_SESSION_TOKEN||"",applicationEndpointId:t=>t||process.env.BEDROCK_APPLICATION_ENDPOINT_ID||"",applicationInferenceProfileArn:t=>t||process.env.BEDROCK_APPLICATION_INFERENCE_PROFILE_ARN||process.env.BEDROCK_INFERENCE_PROFILE_ARN||"",applicationBaseUrl:t=>t||process.env.BEDROCK_APPLICATION_BASE_URL||"",systemPrompt:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:t=>{if(!t)return;x("temperature",/^(2|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 2");const e=Number(t);return x("temperature",e>0,"Must be greater than 0"),x("temperature",e<=2,"Must be less than or equal to 2"),e},maxTokens:t=>{if(t)return x("maxTokens",/^\d+$/.test(t),"Must be an integer"),Number(t)},logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:t=>{if(!t)return;x("topP",/^(1|\d)(\.\d{1,2})?$/.test(t),"Must be decimal between 0 and 1");const e=Number(t);return x("topP",e>0,"Must be greater than 0"),x("topP",e<=1,"Must be less than or equal to 1"),e},codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase,inferenceParameters:t=>{if(!t)return{};if(typeof t=="object")return t;try{const e=JSON.parse(t);return x("BEDROCK.inferenceParameters",typeof e=="object"&&e!==null&&!Array.isArray(e),"Must be a valid JSON object"),e}catch(e){throw new v(`Invalid BEDROCK.inferenceParameters: Must be valid JSON. Error: ${e.message}`)}}}},ic=t=>typeof t=="object"&&t!==null,ms=(t,e)=>{Object.keys(t).forEach(r=>{const o=t[r];ic(o)&&e in o&&(o[e]=!0)})},ac=t=>{ms(t,"includeBody")},cc=t=>{ms(t,"disableLowerCase")};let We;const lc=(t=[])=>{const e={};for(const r of t)if(r.startsWith("--")){const[o,s]=r.slice(2).split("="),[n,i]=o.split(".");n&&i&&n in ze?(e[n]||(e[n]={}),e[n][i]=s):e[o]=s}return e},uc=()=>{const t=Fe.homedir(),e=process.env.AICOMMIT_CONFIG_PATH,r=ls,o=M.join(t,".aicommit2");return[e,r,o].filter(s=>!!s)},Oe=async()=>{const t=uc();for(const e of t)if(await yt(e))return e;return ls},dc=t=>t.replace(/\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}|\$([a-zA-Z_][a-zA-Z0-9_]*)/g,(e,r,o)=>{const s=r||o;return process.env[s]??""}),Ye=async()=>{const t=await Oe();We=t;try{const e=await D.readFile(t,"utf8"),r=dc(e);return Re.parse(r)}catch(e){return e.code==="ENOENT"?(We=void 0,{}):(console.error(`Error reading config file ${t}:`,e),We=void 0,{})}},ge=async(t,e=[])=>{const r=await Ye(),o=lc(e),s={...t,...o},n={},i=nc(r),a={};for(const d of i){const c=r[d]?.envKey;let u;c?(u=[c],d==="BEDROCK"&&c!=="BEDROCK_APPLICATION_API_KEY"&&u.push("BEDROCK_APPLICATION_API_KEY")):d==="BEDROCK"?u=["BEDROCK_API_KEY","BEDROCK_APPLICATION_API_KEY"]:u=[`${d}_API_KEY`];const m=u.map(f=>f?process.env[f]:void 0).find(f=>typeof f=="string"&&f.length>0);m&&(a[d]={key:m})}const l=(d,c)=>{const u=s[`${d}.${c}`]??s[d]?.[c],m=a[d]?.[c],f=r[d]?.[c],h=s[c]??r[c];return u!==void 0?u:m!==void 0?m:f!==void 0?f:h};for(const[d,c]of Object.entries(p)){const u=s[d]??r[d];n[d]=c(u)}for(const d of i){n[d]={};const c=ze[d]||$t(d);for(const[u,m]of Object.entries(c)){const f=l(d,u);n[d][u]=m(f)}}return n},hr=async t=>{const e=await Ye();for(const[s,n]of t){const[i,a]=s.split(".");if(!a){const c=p[s];if(!c)throw new v(`Invalid config property: ${s}`);e[s]=c(n);continue}if(e[i]||(e[i]={}),Ke.includes(i)){const c=ze[i][a];if(!c)throw new v(`Invalid config property: ${s}`);e[i][a]=c(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 d=$t(i);if(!d[a])throw new v(`Invalid config property for custom service: ${s}`);try{e[i][a]=d[a](n)}catch(c){throw c instanceof v?c:new v(`Invalid value for ${s}: ${c.message}`)}}const r=await Oe(),o=M.dirname(r);await D.mkdir(o,{recursive:!0}),await D.writeFile(r,Re.stringify(e),"utf8")},mc=async t=>{const e=await Ye();for(const[s,n]of t){const[i,a]=s.split("."),l=e[i];if(a==="model"){l||(e[i]={});const c=e[i][a]||[],u=typeof n=="string"?n.split(",").map(m=>m.trim()).filter(m=>!!m):n;e[i][a]=Ct([...c,...u]);continue}if(l&&l.compatible===!0){l||(e[i]={});const c=$t(i);if(!c[a])throw new v(`Invalid config property: ${s}`);try{e[i][a]=c[a](n)}catch(u){throw u instanceof v?u:new v(`Invalid value for ${s}: ${u.message}`)}continue}if(i in ze){l||(e[i]={});const c=ze[i][a];if(!c)throw new v(`Invalid config property: ${s}`);e[i][a]=c(n)}else{const c=$t(i);if(!c[a])throw new v(`Invalid config property: ${s}`);e[i]||(e[i]={}),e[i][a]=c[a](n)}}const r=await Oe(),o=M.dirname(r);await D.mkdir(o,{recursive:!0}),await D.writeFile(r,Re.stringify(e),"utf8")},pc=async()=>{const t=await Ye();console.log(Re.stringify(t))},fc=async()=>{console.log(await Oe())},$t=t=>({compatible:ue("compatible"),stream:ue("stream"),url:e=>e?(x(`${t}.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:p.systemPrompt,systemPromptPath:p.systemPromptPath,codeReviewPromptPath:p.codeReviewPromptPath,timeout:p.timeout,temperature:p.temperature,maxTokens:p.maxTokens,logging:p.logging,locale:p.locale,generate:p.generate,type:p.type,maxLength:p.maxLength,includeBody:p.includeBody,topP:p.topP,codeReview:p.codeReview,disabled:p.disabled,watchMode:p.watchMode,disableLowerCase:p.disableLowerCase,autoCopy:p.autoCopy}),Y=t=>typeof t=="string"&&t.trim().length>0,Ce=t=>(Array.isArray(t.model)?t.model:Y(t.model)?[t.model.trim()]:[]).length>0,Pt=t=>{const e=Y(t.key),r=Y(t.region)||Y(process.env.AWS_REGION)||Y(process.env.AWS_DEFAULT_REGION),o=Y(t.profile)||Y(process.env.AWS_PROFILE),s=Y(t.accessKeyId)&&Y(t.secretAccessKey)||Y(process.env.AWS_ACCESS_KEY_ID)&&Y(process.env.AWS_SECRET_ACCESS_KEY),n=Y(t.applicationBaseUrl)||Y(process.env.BEDROCK_APPLICATION_BASE_URL),i=Y(t.applicationEndpointId)||Y(process.env.BEDROCK_APPLICATION_ENDPOINT_ID),a=Y(process.env.BEDROCK_APPLICATION_API_KEY);return r&&(e||o||s)||(n&&e||i&&a)},De=(t,e)=>Object.entries(t).map(([r,o])=>[r,o]).filter(([r,o])=>!o.disabled).filter(([r,o])=>Ke.includes(r)||o.compatible===!0).filter(([r,o])=>{switch(e){case"commit":return r==="OLLAMA"?!!o&&Ce(o):r==="HUGGINGFACE"?!!o&&!!o.cookie:r==="BEDROCK"?Ce(o)&&Pt(o):!!o.key&&o.key.length>0;case"review":const s=t.codeReview||o.codeReview;return r==="OLLAMA"?!!o&&Ce(o)&&s:r==="HUGGINGFACE"?!!o&&!!o.cookie&&s:r==="BEDROCK"?Ce(o)&&Pt(o)&&s:!!o.key&&o.key.length>0&&s;case"watch":const n=t.watchMode||o.watchMode;return r==="OLLAMA"?!!o&&Ce(o)&&n:r==="HUGGINGFACE"?!!o&&!!o.cookie&&n:r==="BEDROCK"?Ce(o)&&Pt(o)&&n:o.compatible?!!o.url&&!!o.key&&n:!!o.key&&o.key.length>0&&n}}).map(([r])=>r);class hc{static create(e,r){return new e(r)}}const Ve=new Map,be=(t,e,r)=>{const o=so(0).update(e).digest("hex").substring(0,8),s=`${t}_${o}_${r}`;if(Ve.has(s))return Ve.get(s);const n=new Date,i=wc(n,t,e,r),a=`${le}/${i}`,l=K.createLogger({level:"info",format:K.format.combine(K.format.timestamp({format:"YYYY-MM-DDTHH:mm:ss.SSSZ"}),K.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 K.transports.File({filename:a})]});return l.info(`=== ${t.toUpperCase()} AI SERVICE LOG ===`),l.info(`Diff Hash: ${o}`),l.info(`Request Type: ${r.toUpperCase()}`),l.info(`Start Time: ${n.toISOString()}`),l.info("=".repeat(50)),l.info(""),Ve.set(s,l),l},gc=t=>{const e={...t},r=["authorization","x-api-key","x-goog-api-key","api-key","x-amzn-bedrock-application-key"];for(const o of r){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},Z=(t,e,r,o,s,n,i=!0)=>{if(!i)return;const a=be(r,t,e);a.info(`Making request to ${r} API with model: ${o}`),a.info(`Request URL: ${s}`),a.info("Request headers:",gc(n))},se=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).info("Request payload:",o)},ee=(t,e,r,o,s,n=!0)=>{if(!n)return;const i=be(r,t,e);i.info("System prompt:",{prompt:o}),i.info("User prompt:",{prompt:s})},V=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).info("Response received:",o)},G=(t,e,r,o,s=!0)=>{if(!s)return;be(r,t,e).error("API request failed:",o)},q=(t,e,r,o,s,n=!0)=>{if(!n)return;const i=be(r,t,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 ===")},yc=(t,e,r,o,s,n,i,a=!0)=>{if(!a)return;const l=be(r,t,e);i?l.error(`Request failed after ${n}ms:`,{error:i}):(l.info(`Request completed in ${n}ms`),l.info("Response:",{response:s})),q(t,e,r,n,s,a)},wc=(t,e,r,o)=>{const{year:s,month:n,day:i,hours:a,minutes:l,seconds:d}=vc(t),u=so(0).update(r).digest("hex").substring(0,8),m=e.toLowerCase().replace(/[^a-z0-9]/g,"").substring(0,20);return o==="review"?`${s}-${n}-${i}_${a}-${l}-${d}_${u}_${m}_review.log`:`${s}-${n}-${i}_${a}-${l}-${d}_${u}_${m}_commit.log`},vc=t=>{const e=t.getFullYear().toString(),r=(t.getMonth()+1).toString().padStart(2,"0"),o=t.getDate().toString().padStart(2,"0"),s=t.getHours().toString().padStart(2,"0"),n=t.getMinutes().toString().padStart(2,"0"),i=t.getSeconds().toString().padStart(2,"0");return{year:e,month:r,day:o,hours:s,minutes:n,seconds:i}},gr=()=>{for(const[t,e]of Ve.entries())try{e.close()}catch(r){console.error(`Failed to close logger ${t}:`,r)}Ve.clear()};process.on("exit",gr),process.on("SIGINT",()=>{gr(),process.exit(0)}),process.on("SIGTERM",()=>{gr(),process.exit(0)});const A={label:g.bold.green,command:g.bold.white,hint:g.gray,highlight:g.bold.magenta,dim:g.dim},R={MISSING_API_KEY:"MISSING_API_KEY",INVALID_API_KEY:"INVALID_API_KEY",AUTH_FAILED:"AUTH_FAILED",RATE_LIMITED:"RATE_LIMITED",QUOTA_EXCEEDED:"QUOTA_EXCEEDED",MODEL_NOT_FOUND:"MODEL_NOT_FOUND",MODEL_ACCESS_DENIED:"MODEL_ACCESS_DENIED",NETWORK_ERROR:"NETWORK_ERROR",TIMEOUT:"TIMEOUT",SERVICE_UNAVAILABLE:"SERVICE_UNAVAILABLE",NO_STAGED_CHANGES:"NO_STAGED_CHANGES",EMPTY_COMMIT_MESSAGE:"EMPTY_COMMIT_MESSAGE",VCS_NOT_FOUND:"VCS_NOT_FOUND",INVALID_CONFIG:"INVALID_CONFIG",CONFIG_NOT_FOUND:"CONFIG_NOT_FOUND",SERVER_ERROR:"SERVER_ERROR",UNKNOWN:"UNKNOWN"},yr={missingApiKey:t=>{const e=t.toUpperCase();return[`Missing API key for ${A.highlight(e)}.`,"",`${A.label("\u2192")} Run: ${A.command(`aicommit2 config set ${e}.key=YOUR_API_KEY`)}`].join(`
|
|
20
20
|
`)},invalidApiKey:t=>{const e=t.toUpperCase();return[`Invalid or expired API key for ${A.highlight(e)}.`,"",`${A.label("\u2192")} Update: ${A.command(`aicommit2 config set ${e}.key=YOUR_NEW_KEY`)}`].join(`
|
|
21
21
|
`)},noApiKeysConfigured:()=>["No AI provider API keys configured.","",`${A.label("\u2192")} Please set at least one API key:`,` ${A.command("aicommit2 config set OPENAI.key=sk-...")}`,` ${A.command("aicommit2 config set ANTHROPIC.key=sk-ant-...")}`,` ${A.command("aicommit2 config set OLLAMA.model=llama3.2")} ${A.dim("(no key needed)")}`,"",`${A.hint("Tip:")} ${A.command("aicommit2 config get")} ${A.hint("to see current config")}`].join(`
|
|
22
22
|
`),rateLimited:t=>[`Rate limit exceeded${t?` for ${A.highlight(t)}`:""}.`,"",`${A.label("\u2192")} Wait a moment and try again`,`${A.label("\u2192")} Or use a different AI provider`].join(`
|
|
@@ -33,22 +33,22 @@ See https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html
|
|
|
33
33
|
`),invalidConfigValue:(t,e)=>[`Invalid value for ${A.highlight(`"${t}"`)}`,"",`${A.label("\u2192")} Expected: ${A.dim(e)}`].join(`
|
|
34
34
|
`),serverError:(t,e)=>{const r=e?` ${A.dim(`(HTTP ${e})`)}`:"";return`${A.highlight(t)} server error${r}. Try again later.`},ollamaNotRunning:()=>[`${A.highlight("Ollama")} is not running or not accessible.`,"",`${A.label("\u2192")} Start: ${A.command("ollama serve")}`].join(`
|
|
35
35
|
`),ollamaModelNotPulled:t=>[`Ollama model ${A.highlight(`"${t}"`)} is not available locally.`,"",`${A.label("\u2192")} Pull: ${A.command(`ollama pull ${t}`)}`].join(`
|
|
36
|
-
`)},
|
|
36
|
+
`)},Cc=t=>({401:R.INVALID_API_KEY,403:R.MODEL_ACCESS_DENIED,404:R.MODEL_NOT_FOUND,429:R.RATE_LIMITED,500:R.SERVER_ERROR,502:R.SERVICE_UNAVAILABLE,503:R.SERVICE_UNAVAILABLE,504:R.TIMEOUT})[t]||R.UNKNOWN,bc=t=>{const e=t.toLowerCase();return e.includes("api key")||e.includes("api_key")||e.includes("apikey")?e.includes("missing")?R.MISSING_API_KEY:R.INVALID_API_KEY:e.includes("401")||e.includes("unauthorized")||e.includes("authentication")?R.AUTH_FAILED:e.includes("rate")||e.includes("429")||e.includes("too many")?R.RATE_LIMITED:e.includes("quota")||e.includes("usage")||e.includes("limit exceeded")?R.QUOTA_EXCEEDED:e.includes("model")&&(e.includes("not found")||e.includes("404"))?R.MODEL_NOT_FOUND:e.includes("403")||e.includes("forbidden")||e.includes("access denied")?R.MODEL_ACCESS_DENIED:e.includes("econnrefused")||e.includes("network")||e.includes("connection")?R.NETWORK_ERROR:e.includes("timeout")||e.includes("timed out")||e.includes("504")?R.TIMEOUT:e.includes("unavailable")||e.includes("overloaded")||e.includes("503")||e.includes("502")?R.SERVICE_UNAVAILABLE:e.includes("500")||e.includes("internal server error")?R.SERVER_ERROR:R.UNKNOWN},ne={missingApiKey:t=>`Missing API key for ${t.toUpperCase()}`,invalidApiKey:t=>`Invalid API key for ${t.toUpperCase()}`,rateLimited:t=>`Rate limit exceeded${t?` for ${t}`:""}`,quotaExceeded:t=>`API quota exceeded${t?` for ${t}`:""}`,modelNotFound:(t,e)=>`Model "${t}" not found for ${e.toUpperCase()}`,modelAccessDenied:(t,e)=>`Access denied to model "${t}" on ${e}`,networkError:t=>`Network connection failed${t?` to ${t}`:""}`,timeout:(t,e)=>`Request timed out${e?` from ${e}`:""} after ${t}ms`,serviceUnavailable:t=>`${t} service is temporarily unavailable`,serverError:(t,e)=>`${t} server error${e?` (HTTP ${e})`:""}`,unknown:t=>`An error occurred with ${t}. Please try again.`,ollamaNotRunning:()=>"Ollama is not running. Start with: ollama serve",ollamaModelNotPulled:t=>`Ollama model "${t}" not found. Pull with: ollama pull ${t}`},Ec=(t,e={})=>{const{provider:r="AI",model:o,timeout:s}=e;switch(t){case R.MISSING_API_KEY:return ne.missingApiKey(r);case R.INVALID_API_KEY:case R.AUTH_FAILED:return ne.invalidApiKey(r);case R.RATE_LIMITED:return ne.rateLimited(r);case R.QUOTA_EXCEEDED:return ne.quotaExceeded(r);case R.MODEL_NOT_FOUND:return ne.modelNotFound(o||"unknown",r);case R.MODEL_ACCESS_DENIED:return ne.modelAccessDenied(o||"unknown",r);case R.NETWORK_ERROR:return ne.networkError(r);case R.TIMEOUT:return ne.timeout(s||1e4,r);case R.SERVICE_UNAVAILABLE:return ne.serviceUnavailable(r);case R.SERVER_ERROR:return ne.serverError(r);default:return ne.unknown(r)}};let At,ps="info";async function $c(t){if(At){console.warn("Logger already initialized. Skipping re-initialization.");return}const e=t?.logLevel||"info";ps=e;const r=t?.logFilePath||us,o=t?.exceptionLogFilePath||ds,s=t?.logging??!0;await ss(M.dirname(r)),await ss(M.dirname(o));const n=[];s?n.push(new K.transports.DailyRotateFile({filename:r,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",level:e,format:K.format.combine(K.format.timestamp(),K.format.printf(({level:i,message:a,timestamp:l})=>`[${l}] ${i}: ${a}`))})):n.push(new K.transports.Console({silent:!0})),At=K.createLogger({level:e,format:K.format.json(),transports:n,exceptionHandlers:s?[new K.transports.DailyRotateFile({filename:o,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",format:K.format.combine(K.format.timestamp(),K.format.json())})]:[],exitOnError:!1,silent:!s})}const _e=new Proxy({},{get:(t,e,r)=>{if(!At)throw new Error("Logger not initialized. Call initializeLogger() first.");return Reflect.get(At,e,r)}});function St(){const t=K.config.npm.levels;return(t[ps]??t.info)>=t.verbose}class te{constructor(e){this.handleError$=r=>{const o=this.getDetailedErrorMessage(r),s=r.status?`HTTP ${r.status}: ${o}`:o;if(this.params.config.logging){const n=this.params.stagedDiff.diff,i=this.serviceName.replace(/\[|\]/g,"").trim();yc(n,"commit",i,"Error occurred","",void 0,s)}return _e.error(`${this.errorPrefix} ${s}`),r.stack&&_e.error(` ${r.stack}`),r.content&&_e.error(` Problematic content: ${r.content}`),r.originalError&&_e.error(` Original error: ${r.originalError}`),Qr({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}getProviderName(){const e=String.fromCharCode(27),r=new RegExp(`${e}\\[[0-9;]*m`,"g");return this.serviceName.replace(r,"").replace(/\[|\]/g,"").trim()}getDetailedErrorMessage(e){const r=e.message||"",o=this.getProviderName(),s=this.params.config.model?.[0],n=this.params.config.timeout,i=this.getServiceSpecificErrorMessage(e);if(i)return i;const a=e.code||(e.status?Cc(e.status):bc(r));return a!==R.UNKNOWN?Ec(a,{provider:o,model:s,timeout:n}):r||"Unknown error occurred"}getServiceSpecificErrorMessage(e){return null}cleanJsonCodeBlock(e){const r=/```(?:json|JSON)?\s*([\s\S]*?)\s*```/,o=e.match(r);return o?o[1].trim():e}extractJsonFromResponse(e){let r=e.indexOf("[");if(r!==-1){const o=this.extractBalancedJson(e,r,"[","]");if(o)return o}if(r=e.indexOf("{"),r!==-1){const o=this.extractBalancedJson(e,r,"{","}");if(o)return o}return null}extractBalancedJson(e,r,o,s){let n=0,i=!1,a=!1;for(let l=r;l<e.length;l++){const d=e[l];if(a){a=!1;continue}if(d==="\\"&&i){a=!0;continue}if(d==='"'){i=!i;continue}if(!i&&(d===o&&n++,d===s&&n--,n===0))return e.slice(r,l+1)}return null}parseMessage(e,r,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=is(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 a=i.data,l=Array.isArray(a)?a:[a];if(!l.length||!l.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=l.map(u=>this.extractMessageAsType(u,r)).map(u=>({title:`${u.subject}`,value:`${u.subject}${u.body?`
|
|
37
37
|
|
|
38
38
|
${u.body}`:""}${u.footer?`
|
|
39
39
|
|
|
40
|
-
${u.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const u=l.map(p=>p.title).join(", ");De.info(`${this.serviceName} Parsed ${l.length} commit messages: ${u}`)}return l}extractMessageAsType(e,r){switch(r){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*(.*)/,a=e.subject.match(i),c=this.params.config.disableLowerCase??!1;return{...e,subject:a&&!c?a[0].toLowerCase():e.subject};default:return e}}normalizeCommitMessage(e){const r=/^(\w+)(\(.*?\))?:\s(.*)$/,o=e.match(r);if(o){const[,s,n,i]=o,a=this.params.config.disableLowerCase??!1,c=s.toLowerCase(),d=a?i:i.charAt(0).toLowerCase()+i.slice(1);e=`${c}${n||""}: ${d}`}return e}sanitizeResponse(e){if(typeof e=="string")try{return[{title:`${ss(e)}...`,value:e}]}catch{return[]}return e.map(r=>{try{return{title:`${ss(r)}...`,value:r}}catch{return{title:"",value:""}}})}isLoggingEnabled(){return this.params.config.logging&&!!this.logSessionId}}var yr={},wr={exports:{}},Ve={exports:{}},vr,ps;function bc(){if(ps)return vr;ps=1;var t=1e3,e=t*60,r=e*60,o=r*24,s=o*7,n=o*365.25;vr=function(l,u){u=u||{};var p=typeof l;if(p==="string"&&l.length>0)return i(l);if(p==="number"&&isFinite(l))return u.long?c(l):a(l);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(l))};function i(l){if(l=String(l),!(l.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(l);if(u){var p=parseFloat(u[1]),f=(u[2]||"ms").toLowerCase();switch(f){case"years":case"year":case"yrs":case"yr":case"y":return p*n;case"weeks":case"week":case"w":return p*s;case"days":case"day":case"d":return p*o;case"hours":case"hour":case"hrs":case"hr":case"h":return p*r;case"minutes":case"minute":case"mins":case"min":case"m":return p*e;case"seconds":case"second":case"secs":case"sec":case"s":return p*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return p;default:return}}}}function a(l){var u=Math.abs(l);return u>=o?Math.round(l/o)+"d":u>=r?Math.round(l/r)+"h":u>=e?Math.round(l/e)+"m":u>=t?Math.round(l/t)+"s":l+"ms"}function c(l){var u=Math.abs(l);return u>=o?d(l,u,o,"day"):u>=r?d(l,u,r,"hour"):u>=e?d(l,u,e,"minute"):u>=t?d(l,u,t,"second"):l+" ms"}function d(l,u,p,f){var h=u>=p*1.5;return Math.round(l/p)+" "+f+(h?"s":"")}return vr}var Cr,fs;function hs(){if(fs)return Cr;fs=1;function t(e){o.debug=o,o.default=o,o.coerce=d,o.disable=a,o.enable=n,o.enabled=c,o.humanize=bc(),o.destroy=l,Object.keys(e).forEach(u=>{o[u]=e[u]}),o.names=[],o.skips=[],o.formatters={};function r(u){let p=0;for(let f=0;f<u.length;f++)p=(p<<5)-p+u.charCodeAt(f),p|=0;return o.colors[Math.abs(p)%o.colors.length]}o.selectColor=r;function o(u){let p,f=null,h,y;function w(...C){if(!w.enabled)return;const b=w,E=Number(new Date),k=E-(p||E);b.diff=k,b.prev=p,b.curr=E,p=E,C[0]=o.coerce(C[0]),typeof C[0]!="string"&&C.unshift("%O");let $=0;C[0]=C[0].replace(/%([a-zA-Z%])/g,(O,S)=>{if(O==="%%")return"%";$++;const U=o.formatters[S];if(typeof U=="function"){const _=C[$];O=U.call(b,_),C.splice($,1),$--}return O}),o.formatArgs.call(b,C),(b.log||o.log).apply(b,C)}return w.namespace=u,w.useColors=o.useColors(),w.color=o.selectColor(u),w.extend=s,w.destroy=o.destroy,Object.defineProperty(w,"enabled",{enumerable:!0,configurable:!1,get:()=>f!==null?f:(h!==o.namespaces&&(h=o.namespaces,y=o.enabled(u)),y),set:C=>{f=C}}),typeof o.init=="function"&&o.init(w),w}function s(u,p){const f=o(this.namespace+(typeof p>"u"?":":p)+u);return f.log=this.log,f}function n(u){o.save(u),o.namespaces=u,o.names=[],o.skips=[];const p=(typeof u=="string"?u:"").trim().replace(/\s+/g,",").split(",").filter(Boolean);for(const f of p)f[0]==="-"?o.skips.push(f.slice(1)):o.names.push(f)}function i(u,p){let f=0,h=0,y=-1,w=0;for(;f<u.length;)if(h<p.length&&(p[h]===u[f]||p[h]==="*"))p[h]==="*"?(y=h,w=f,h++):(f++,h++);else if(y!==-1)h=y+1,w++,f=w;else return!1;for(;h<p.length&&p[h]==="*";)h++;return h===p.length}function a(){const u=[...o.names,...o.skips.map(p=>"-"+p)].join(",");return o.enable(""),u}function c(u){for(const p of o.skips)if(i(u,p))return!1;for(const p of o.names)if(i(u,p))return!0;return!1}function d(u){return u instanceof Error?u.stack||u.message:u}function l(){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 Cr=t,Cr}Ve.exports;var gs;function Ec(){return gs||(gs=1,function(t,e){e.formatArgs=o,e.save=s,e.load=n,e.useColors=r,e.storage=i(),e.destroy=(()=>{let c=!1;return()=>{c||(c=!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 r(){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 c;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&&(c=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(c[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function o(c){if(c[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+c[0]+(this.useColors?"%c ":" ")+"+"+t.exports.humanize(this.diff),!this.useColors)return;const d="color: "+this.color;c.splice(1,0,d,"color: inherit");let l=0,u=0;c[0].replace(/%[a-zA-Z%]/g,p=>{p!=="%%"&&(l++,p==="%c"&&(u=l))}),c.splice(u,0,d)}e.log=console.debug||console.log||(()=>{});function s(c){try{c?e.storage.setItem("debug",c):e.storage.removeItem("debug")}catch{}}function n(){let c;try{c=e.storage.getItem("debug")||e.storage.getItem("DEBUG")}catch{}return!c&&typeof process<"u"&&"env"in process&&(c=process.env.DEBUG),c}function i(){try{return localStorage}catch{}}t.exports=hs()(e);const{formatters:a}=t.exports;a.j=function(c){try{return JSON.stringify(c)}catch(d){return"[UnexpectedJSONParseError]: "+d.message}}}(Ve,Ve.exports)),Ve.exports}var qe={exports:{}},br,ys;function $c(){return ys||(ys=1,br=(t,e=process.argv)=>{const r=t.startsWith("-")?"":t.length===1?"-":"--",o=e.indexOf(r+t),s=e.indexOf("--");return o!==-1&&(s===-1||o<s)}),br}var Er,ws;function Pc(){if(ws)return Er;ws=1;const t=Le,e=no,r=$c(),{env:o}=process;let s;r("no-color")||r("no-colors")||r("color=false")||r("color=never")?s=0:(r("color")||r("colors")||r("color=true")||r("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(c){return c===0?!1:{level:c,hasBasic:!0,has256:c>=2,has16m:c>=3}}function i(c,d){if(s===0)return 0;if(r("color=16m")||r("color=full")||r("color=truecolor"))return 3;if(r("color=256"))return 2;if(c&&!d&&s===void 0)return 0;const l=s||0;if(o.TERM==="dumb")return l;if(process.platform==="win32"){const u=t.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:l;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:l}function a(c){const d=i(c,c&&c.isTTY);return n(d)}return Er={supportsColor:a,stdout:n(i(!0,e.isatty(1))),stderr:n(i(!0,e.isatty(2)))},Er}qe.exports;var vs;function Ac(){return vs||(vs=1,function(t,e){const r=no,o=Jr;e.init=l,e.log=a,e.formatArgs=n,e.save=c,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 p=Pc();p&&(p.stderr||p).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(p=>/^debug_/i.test(p)).reduce((p,f)=>{const h=f.substring(6).toLowerCase().replace(/_([a-z])/g,(w,C)=>C.toUpperCase());let y=process.env[f];return/^(yes|on|true|enabled)$/i.test(y)?y=!0:/^(no|off|false|disabled)$/i.test(y)?y=!1:y==="null"?y=null:y=Number(y),p[h]=y,p},{});function s(){return"colors"in e.inspectOpts?!!e.inspectOpts.colors:r.isatty(process.stderr.fd)}function n(p){const{namespace:f,useColors:h}=this;if(h){const y=this.color,w="\x1B[3"+(y<8?y:"8;5;"+y),C=` ${w};1m${f} \x1B[0m`;p[0]=C+p[0].split(`
|
|
40
|
+
${u.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const u=c.map(m=>m.title).join(", ");_e.info(`${this.serviceName} Parsed ${c.length} commit messages: ${u}`)}return c}extractMessageAsType(e,r){switch(r){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*(.*)/,a=e.subject.match(i),l=this.params.config.disableLowerCase??!1;return{...e,subject:a&&!l?a[0].toLowerCase():e.subject};default:return e}}normalizeCommitMessage(e){const r=/^(\w+)(\(.*?\))?:\s(.*)$/,o=e.match(r);if(o){const[,s,n,i]=o,a=this.params.config.disableLowerCase??!1,l=s.toLowerCase(),d=a?i:i.charAt(0).toLowerCase()+i.slice(1);e=`${l}${n||""}: ${d}`}return e}sanitizeResponse(e){if(typeof e=="string")try{return[{title:`${ns(e)}...`,value:e}]}catch{return[]}return e.map(r=>{try{return{title:`${ns(r)}...`,value:r}}catch{return{title:"",value:""}}})}isLoggingEnabled(){return this.params.config.logging&&!!this.logSessionId}}var wr={},vr={exports:{}},qe={exports:{}},Cr,fs;function Pc(){if(fs)return Cr;fs=1;var t=1e3,e=t*60,r=e*60,o=r*24,s=o*7,n=o*365.25;Cr=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?l(c):a(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]),f=(u[2]||"ms").toLowerCase();switch(f){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*r;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*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return m;default:return}}}}function a(c){var u=Math.abs(c);return u>=o?Math.round(c/o)+"d":u>=r?Math.round(c/r)+"h":u>=e?Math.round(c/e)+"m":u>=t?Math.round(c/t)+"s":c+"ms"}function l(c){var u=Math.abs(c);return u>=o?d(c,u,o,"day"):u>=r?d(c,u,r,"hour"):u>=e?d(c,u,e,"minute"):u>=t?d(c,u,t,"second"):c+" ms"}function d(c,u,m,f){var h=u>=m*1.5;return Math.round(c/m)+" "+f+(h?"s":"")}return Cr}var br,hs;function gs(){if(hs)return br;hs=1;function t(e){o.debug=o,o.default=o,o.coerce=d,o.disable=a,o.enable=n,o.enabled=l,o.humanize=Pc(),o.destroy=c,Object.keys(e).forEach(u=>{o[u]=e[u]}),o.names=[],o.skips=[],o.formatters={};function r(u){let m=0;for(let f=0;f<u.length;f++)m=(m<<5)-m+u.charCodeAt(f),m|=0;return o.colors[Math.abs(m)%o.colors.length]}o.selectColor=r;function o(u){let m,f=null,h,y;function w(...C){if(!w.enabled)return;const b=w,E=Number(new Date),k=E-(m||E);b.diff=k,b.prev=m,b.curr=E,m=E,C[0]=o.coerce(C[0]),typeof C[0]!="string"&&C.unshift("%O");let $=0;C[0]=C[0].replace(/%([a-zA-Z%])/g,(O,S)=>{if(O==="%%")return"%";$++;const U=o.formatters[S];if(typeof U=="function"){const _=C[$];O=U.call(b,_),C.splice($,1),$--}return O}),o.formatArgs.call(b,C),(b.log||o.log).apply(b,C)}return w.namespace=u,w.useColors=o.useColors(),w.color=o.selectColor(u),w.extend=s,w.destroy=o.destroy,Object.defineProperty(w,"enabled",{enumerable:!0,configurable:!1,get:()=>f!==null?f:(h!==o.namespaces&&(h=o.namespaces,y=o.enabled(u)),y),set:C=>{f=C}}),typeof o.init=="function"&&o.init(w),w}function s(u,m){const f=o(this.namespace+(typeof m>"u"?":":m)+u);return f.log=this.log,f}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 f of m)f[0]==="-"?o.skips.push(f.slice(1)):o.names.push(f)}function i(u,m){let f=0,h=0,y=-1,w=0;for(;f<u.length;)if(h<m.length&&(m[h]===u[f]||m[h]==="*"))m[h]==="*"?(y=h,w=f,h++):(f++,h++);else if(y!==-1)h=y+1,w++,f=w;else return!1;for(;h<m.length&&m[h]==="*";)h++;return h===m.length}function a(){const u=[...o.names,...o.skips.map(m=>"-"+m)].join(",");return o.enable(""),u}function l(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 br=t,br}qe.exports;var ys;function Ac(){return ys||(ys=1,function(t,e){e.formatArgs=o,e.save=s,e.load=n,e.useColors=r,e.storage=i(),e.destroy=(()=>{let l=!1;return()=>{l||(l=!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 r(){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 l;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&&(l=navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/))&&parseInt(l[1],10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function o(l){if(l[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+l[0]+(this.useColors?"%c ":" ")+"+"+t.exports.humanize(this.diff),!this.useColors)return;const d="color: "+this.color;l.splice(1,0,d,"color: inherit");let c=0,u=0;l[0].replace(/%[a-zA-Z%]/g,m=>{m!=="%%"&&(c++,m==="%c"&&(u=c))}),l.splice(u,0,d)}e.log=console.debug||console.log||(()=>{});function s(l){try{l?e.storage.setItem("debug",l):e.storage.removeItem("debug")}catch{}}function n(){let l;try{l=e.storage.getItem("debug")||e.storage.getItem("DEBUG")}catch{}return!l&&typeof process<"u"&&"env"in process&&(l=process.env.DEBUG),l}function i(){try{return localStorage}catch{}}t.exports=gs()(e);const{formatters:a}=t.exports;a.j=function(l){try{return JSON.stringify(l)}catch(d){return"[UnexpectedJSONParseError]: "+d.message}}}(qe,qe.exports)),qe.exports}var Je={exports:{}},Er,ws;function Sc(){return ws||(ws=1,Er=(t,e=process.argv)=>{const r=t.startsWith("-")?"":t.length===1?"-":"--",o=e.indexOf(r+t),s=e.indexOf("--");return o!==-1&&(s===-1||o<s)}),Er}var $r,vs;function kc(){if(vs)return $r;vs=1;const t=Fe,e=io,r=Sc(),{env:o}=process;let s;r("no-color")||r("no-colors")||r("color=false")||r("color=never")?s=0:(r("color")||r("colors")||r("color=true")||r("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(l){return l===0?!1:{level:l,hasBasic:!0,has256:l>=2,has16m:l>=3}}function i(l,d){if(s===0)return 0;if(r("color=16m")||r("color=full")||r("color=truecolor"))return 3;if(r("color=256"))return 2;if(l&&!d&&s===void 0)return 0;const c=s||0;if(o.TERM==="dumb")return c;if(process.platform==="win32"){const u=t.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 a(l){const d=i(l,l&&l.isTTY);return n(d)}return $r={supportsColor:a,stdout:n(i(!0,e.isatty(1))),stderr:n(i(!0,e.isatty(2)))},$r}Je.exports;var Cs;function Ic(){return Cs||(Cs=1,function(t,e){const r=io,o=Xr;e.init=c,e.log=a,e.formatArgs=n,e.save=l,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=kc();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,f)=>{const h=f.substring(6).toLowerCase().replace(/_([a-z])/g,(w,C)=>C.toUpperCase());let y=process.env[f];return/^(yes|on|true|enabled)$/i.test(y)?y=!0:/^(no|off|false|disabled)$/i.test(y)?y=!1:y==="null"?y=null:y=Number(y),m[h]=y,m},{});function s(){return"colors"in e.inspectOpts?!!e.inspectOpts.colors:r.isatty(process.stderr.fd)}function n(m){const{namespace:f,useColors:h}=this;if(h){const y=this.color,w="\x1B[3"+(y<8?y:"8;5;"+y),C=` ${w};1m${f} \x1B[0m`;m[0]=C+m[0].split(`
|
|
41
41
|
`).join(`
|
|
42
|
-
`+C),
|
|
43
|
-
`)}function
|
|
44
|
-
`).map(f=>f.trim()).join(" ")},u.O=function(
|
|
45
|
-
`).some(e=>e.indexOf("(https.js:")!==-1||e.indexOf("node:https:")!==-1)}function
|
|
42
|
+
`+C),m.push(w+"m+"+t.exports.humanize(this.diff)+"\x1B[0m")}else m[0]=i()+f+" "+m[0]}function i(){return e.inspectOpts.hideDate?"":new Date().toISOString()+" "}function a(...m){return process.stderr.write(o.formatWithOptions(e.inspectOpts,...m)+`
|
|
43
|
+
`)}function l(m){m?process.env.DEBUG=m:delete process.env.DEBUG}function d(){return process.env.DEBUG}function c(m){m.inspectOpts={};const f=Object.keys(e.inspectOpts);for(let h=0;h<f.length;h++)m.inspectOpts[f[h]]=e.inspectOpts[f[h]]}t.exports=gs()(e);const{formatters:u}=t.exports;u.o=function(m){return this.inspectOpts.colors=this.useColors,o.inspect(m,this.inspectOpts).split(`
|
|
44
|
+
`).map(f=>f.trim()).join(" ")},u.O=function(m){return this.inspectOpts.colors=this.useColors,o.inspect(m,this.inspectOpts)}}(Je,Je.exports)),Je.exports}typeof process>"u"||process.type==="renderer"||process.browser===!0||process.__nwjs?vr.exports=Ac():vr.exports=Ic();var Pr=vr.exports,Ar={};Object.defineProperty(Ar,"__esModule",{value:!0});function Mc(t){return function(e,r){return new Promise((o,s)=>{t.call(this,e,r,(n,i)=>{n?s(n):o(i)})})}}Ar.default=Mc;var bs=H&&H.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};const xc=Jr,Rc=bs(Pr),Oc=bs(Ar),Xe=Rc.default("agent-base");function Dc(t){return!!t&&typeof t.addRequest=="function"}function Sr(){const{stack:t}=new Error;return typeof t!="string"?!1:t.split(`
|
|
45
|
+
`).some(e=>e.indexOf("(https.js:")!==-1||e.indexOf("node:https:")!==-1)}function kt(t,e){return new kt.Agent(t,e)}(function(t){class e extends xc.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:Sr()?443:80}set defaultPort(o){this.explicitDefaultPort=o}get protocol(){return typeof this.explicitProtocol=="string"?this.explicitProtocol:Sr()?"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=Sr()),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,a=null;const l=n.timeout||this.timeout,d=f=>{o._hadError||(o.emit("error",f),o._hadError=!0)},c=()=>{a=null,i=!0;const f=new Error(`A "socket" was not created for HTTP request before ${l}ms`);f.code="ETIMEOUT",d(f)},u=f=>{i||(a!==null&&(clearTimeout(a),a=null),d(f))},m=f=>{if(i)return;if(a!=null&&(clearTimeout(a),a=null),Dc(f)){Xe("Callback returned another Agent instance %o",f.constructor.name),f.addRequest(o,n);return}if(f){f.once("free",()=>{this.freeSocket(f,n)}),o.onSocket(f);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?(Xe("Converting legacy callback function to promise"),this.promisifiedCallback=Oc.default(this.callback)):this.promisifiedCallback=this.callback),typeof l=="number"&&l>0&&(a=setTimeout(c,l)),"port"in n&&typeof n.port!="number"&&(n.port=Number(n.port));try{Xe("Resolving socket for %o request: %o",n.protocol,`${o.method} ${o.path}`),Promise.resolve(this.promisifiedCallback(o,n)).then(m,u)}catch(f){Promise.reject(f).catch(u)}}freeSocket(o,s){Xe("Freeing socket %o %o",o.constructor.name,s),o.destroy()}destroy(){Xe("Destroying agent %o",this.constructor.name)}}t.Agent=e,t.prototype=t.Agent.prototype})(kt||(kt={}));var _c=kt,kr={},Nc=H&&H.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(kr,"__esModule",{value:!0});const Tc=Nc(Pr),Qe=Tc.default("https-proxy-agent:parse-proxy-response");function Lc(t){return new Promise((e,r)=>{let o=0;const s=[];function n(){const u=t.read();u?c(u):t.once("readable",n)}function i(){t.removeListener("end",l),t.removeListener("error",d),t.removeListener("close",a),t.removeListener("readable",n)}function a(u){Qe("onclose had error %o",u)}function l(){Qe("onend")}function d(u){i(),Qe("onerror %o",u),r(u)}function c(u){s.push(u),o+=u.length;const m=Buffer.concat(s,o);if(m.indexOf(`\r
|
|
46
46
|
\r
|
|
47
|
-
`)===-1){
|
|
48
|
-
`)),y=+h.split(" ")[1];
|
|
49
|
-
`;o.auth&&(i["Proxy-Authorization"]=`Basic ${Buffer.from(o.auth).toString("base64")}`);let{host:d,port:
|
|
50
|
-
`;const
|
|
51
|
-
`);const{statusCode:f,buffered:h}=yield
|
|
47
|
+
`)===-1){Qe("have not received end of HTTP headers yet..."),n();return}const h=m.toString("ascii",0,m.indexOf(`\r
|
|
48
|
+
`)),y=+h.split(" ")[1];Qe("got proxy server response: %o",h),e({statusCode:y,buffered:m})}t.on("error",d),t.on("close",a),t.on("end",l),n()})}kr.default=Lc;var Fc=H&&H.__awaiter||function(t,e,r,o){function s(n){return n instanceof r?n:new r(function(i){i(n)})}return new(r||(r=Promise))(function(n,i){function a(c){try{d(o.next(c))}catch(u){i(u)}}function l(c){try{d(o.throw(c))}catch(u){i(u)}}function d(c){c.done?n(c.value):s(c.value).then(a,l)}d((o=o.apply(t,e||[])).next())})},Ne=H&&H.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(wr,"__esModule",{value:!0});const Es=Ne(un),$s=Ne(dn),jc=Ne(mn),Bc=Ne(qr),Gc=Ne(Pr),Uc=_c,Hc=Ne(kr),Ze=Gc.default("https-proxy-agent:agent");class Kc extends Uc.Agent{constructor(e){let r;if(typeof e=="string"?r=jc.default.parse(e):r=e,!r)throw new Error("an HTTP(S) proxy server `host` and `port` must be specified!");Ze("creating new HttpsProxyAgent instance: %o",r),super(r);const o=Object.assign({},r);this.secureProxy=r.secureProxy||Yc(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,r){return Fc(this,void 0,void 0,function*(){const{proxy:o,secureProxy:s}=this;let n;s?(Ze("Creating `tls.Socket`: %o",o),n=$s.default.connect(o)):(Ze("Creating `net.Socket`: %o",o),n=Es.default.connect(o));const i=Object.assign({},o.headers);let l=`CONNECT ${`${r.host}:${r.port}`} HTTP/1.1\r
|
|
49
|
+
`;o.auth&&(i["Proxy-Authorization"]=`Basic ${Buffer.from(o.auth).toString("base64")}`);let{host:d,port:c,secureEndpoint:u}=r;Wc(c,u)||(d+=`:${c}`),i.Host=d,i.Connection="close";for(const w of Object.keys(i))l+=`${w}: ${i[w]}\r
|
|
50
|
+
`;const m=Hc.default(n);n.write(`${l}\r
|
|
51
|
+
`);const{statusCode:f,buffered:h}=yield m;if(f===200){if(e.once("socket",zc),r.secureEndpoint){Ze("Upgrading socket connection to TLS");const w=r.servername||r.host;return $s.default.connect(Object.assign(Object.assign({},Vc(r,"host","hostname","path","port")),{socket:n,servername:w}))}return n}n.destroy();const y=new Es.default.Socket({writable:!1});return y.readable=!0,e.once("socket",w=>{Ze("replaying proxy buffer for failed request"),Bc.default(w.listenerCount("data")>0),w.push(h),w.push(null)}),y})}}wr.default=Kc;function zc(t){t.resume()}function Wc(t,e){return!!(!e&&t===80||e&&t===443)}function Yc(t){return typeof t=="string"?/^https:?$/i.test(t):!1}function Vc(t,...e){const r={};let o;for(o in t)e.includes(o)||(r[o]=t[o]);return r}var qc=H&&H.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};const Ir=qc(wr);function Mr(t){return new Ir.default(t)}(function(t){t.HttpsProxyAgent=Ir.default,t.prototype=Ir.default.prototype})(Mr||(Mr={}));var Jc=Mr,Xc=Ae(Jc);const J={locale:"en",maxLength:50,type:"conventional",generate:1,systemPrompt:"",systemPromptPath:"",codeReviewPromptPath:"",vcs_branch:""},Qc={"":"<commit message>",conventional:`<type>(<optional scope>): <description>
|
|
52
52
|
|
|
53
53
|
[optional body]
|
|
54
54
|
|
|
@@ -56,13 +56,13 @@ ${u.footer}`:""}`})).slice(0,o);if(this.isLoggingEnabled()){const u=l.map(p=>p.t
|
|
|
56
56
|
|
|
57
57
|
[optional body]
|
|
58
58
|
|
|
59
|
-
[optional footer(s)]`},
|
|
59
|
+
[optional footer(s)]`},Zc={"":"",gitmoji:`
|
|
60
60
|
${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(([t,e])=>` - ${t}: ${e}`).join(`
|
|
61
61
|
`)}`,conventional:`
|
|
62
62
|
${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(([t,e])=>` - ${t}: ${e}`).join(`
|
|
63
|
-
`)}`},
|
|
63
|
+
`)}`},xr=(t,e)=>t.replace(/{(\w+)}/g,(r,o)=>e[o]?.toString()||J[o]?.toString()),el=(t,e)=>{const r=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[t]||o[""];return s[r]||s.en},Ps=t=>{const{type:e,maxLength:r,generate:o,locale:s}=t,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:`,`${Qc[e]}`,`3. Allowed Types:${Zc[e]}`,"","## Guidelines:",`- Subject line: Max ${r} 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(`
|
|
64
64
|
`)].filter(Boolean).join(`
|
|
65
|
-
`)},
|
|
65
|
+
`)},It=(t,e,r)=>{const o=s=>{const n=el(s,r);return s==="conventional"||s==="gitmoji"?`${Array(e).fill(null).map((i,a)=>`
|
|
66
66
|
{
|
|
67
67
|
"subject": "${n.subject}",
|
|
68
68
|
"body": "${n.body}",
|
|
@@ -71,11 +71,11 @@ ${Object.entries({docs:"Documentation only changes",style:"Changes that do not a
|
|
|
71
71
|
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 ${t} 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:
|
|
72
72
|
[${o(t)}
|
|
73
73
|
]`,`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(`
|
|
74
|
-
`)},
|
|
75
|
-
${
|
|
76
|
-
${
|
|
77
|
-
${
|
|
78
|
-
${
|
|
74
|
+
`)},re=t=>{const{systemPrompt:e,systemPromptPath:r,type:o,generate:s,locale:n}=t;if(e)return`${xr(e,t)}
|
|
75
|
+
${It(o,s,n)}`;if(!r)return`${Ps(t)}
|
|
76
|
+
${It(o,s,n)}`;try{const i=Q.readFileSync(bt(r),"utf-8");return`${xr(i,t)}
|
|
77
|
+
${It(o,s,n)}`}catch{return`${Ps(t)}
|
|
78
|
+
${It(o,s,n)}`}},oe=t=>{const{codeReviewPromptPath:e,locale:r}=t,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:
|
|
79
79
|
|
|
80
80
|
1. Language: ${r}
|
|
81
81
|
2. Code quality and best practices
|
|
@@ -83,7 +83,7 @@ ${kt(o,s,n)}`}},se=t=>{const{codeReviewPromptPath:e,locale:r}=t,o=`I'll give you
|
|
|
83
83
|
4. Performance improvements
|
|
84
84
|
5. Readability and maintainability
|
|
85
85
|
|
|
86
|
-
Please structure your response with appropriate Markdown headings, code blocks, and bullet points.`;if(!e)return o;try{const s=
|
|
86
|
+
Please structure your response with appropriate Markdown headings, code blocks, and bullet points.`;if(!e)return o;try{const s=Q.readFileSync(bt(e),"utf-8");return`${xr(s,t)}`}catch{return o}},As=async t=>{if(t.systemPromptPath)try{Q.readFileSync(bt(t.systemPromptPath),"utf-8")}catch(e){throw new v(`Error reading system prompt file: ${t.systemPromptPath}, ${e}`)}if(t.codeReview&&t.codeReviewPromptPath)try{Q.readFileSync(bt(t.codeReviewPromptPath),"utf-8")}catch(e){throw new v(`Error reading code review prompt file: ${t.codeReviewPromptPath}, ${e}`)}},Ee=(t,e="commit")=>e==="review"?`Please analyze the following diff and provide a comprehensive code review:
|
|
87
87
|
|
|
88
88
|
\`\`\`diff
|
|
89
89
|
${t}
|
|
@@ -95,16 +95,16 @@ Focus on code quality, potential issues, and improvement suggestions.`:`Please a
|
|
|
95
95
|
${t}
|
|
96
96
|
\`\`\`
|
|
97
97
|
|
|
98
|
-
Focus on understanding the purpose and impact of these changes to create meaningful commit message(s).`,
|
|
98
|
+
Focus on understanding the purpose and impact of these changes to create meaningful commit message(s).`,tl=async(t,e,r,o,s,n,i)=>new Promise((a,l)=>{const d=JSON.stringify(o),u=(t.protocol.includes("https")?no:ln).request({port:i||void 0,hostname:t.hostname,path:e,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(d),...r},timeout:s,agent:n?Xc(n):void 0},m=>{const f=[];m.on("data",h=>f.push(h)),m.on("end",()=>{a({request:u,response:m,data:Buffer.concat(f).toString()})})});u.on("error",l),u.on("timeout",()=>{u.destroy(),l(new v(`Time out error: request took over ${s}ms. Try increasing the \`timeout\` config`))}),u.write(d),u.end()}),rl=async(t,e,r,o,s,n)=>{const i=new URL(t),{response:a,data:l}=await tl(i,e,{Authorization:`Bearer ${r}`},o,s,n);if(!a.statusCode||a.statusCode<200||a.statusCode>299){let d=`API Error: ${a.statusCode} - ${a.statusMessage}`;throw l&&(d+=`
|
|
99
99
|
|
|
100
|
-
${
|
|
100
|
+
${l}`),a.statusCode===500&&(d+=`
|
|
101
101
|
|
|
102
|
-
Check the API status: ${t}`),new v(d)}return JSON.parse(c)},As=t=>t.trim(),el=["gpt-5","gpt-5-mini","gpt-5-nano","gpt-5-codex","o1","o1-mini","o1-pro","o3","o3-mini","o3-pro","o4-mini"],xr=t=>{const e=t.toLowerCase();return el.some(r=>e===r||e.startsWith(`${r}-`)||e.startsWith(`${r}.`))},tl=async(t,e,r,o,s,n,i,a,c,d,l,u,p,f)=>{try{const h=Ee(n,p),y=xr(s),w={model:s,messages:[{role:"system",content:l},{role:"user",content:h}],stream:!1,n:1,frequency_penalty:0,presence_penalty:0,...y?{max_completion_tokens:a,temperature:1}:{max_tokens:a,top_p:d,temperature:c}},C=new URL(e),b=`${C.protocol}//${C.host}${r}`,E={Authorization:`Bearer ${o}`,"Content-Type":"application/json"};ee(n,p,t,s,b,E,u),te(n,p,t,l,h,u),ne(n,p,t,w,u);const k=Date.now(),$=await Zc(e,r,o,w,i,f),P=Date.now()-k;V(n,p,t,$,u);const O=$.choices.filter(S=>S.message?.content).map(S=>As(S.message.content)).join();return q(n,p,t,P,O,u),$.choices.filter(S=>S.message?.content).map(S=>As(S.message.content))}catch(h){G(n,p,t,h,u);const y=h;throw y.code==="ENOTFOUND"?new v(`Error connecting to ${y.hostname} (${y.syscall})`):y}};class rl extends re{constructor(e){super(e),this.params=e;const r=this.params.keyName||"OPENAI_COMPATIBLE";this.colors=Za(r),this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${yt(r)}]`),this.errorPrefix=g.red.bold(`[${yt(r)}]`),this.openAI=new ro({apiKey:this.params.config.key,baseURL:`${this.params.config.url}${this.params.config.path}`})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your OpenAI-compatible API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or check your service limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the model name is correct":r.includes("network")||r.includes("connection")?"Network error. Check your internet connection and API endpoint":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your usage limits":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your API configuration":r.includes("500")||r.includes("Internal Server Error")?"Server error. Try again later":r.includes("overloaded")||r.includes("capacity")?"Service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,temperature:c,generate:d,type:l,maxLength:u,timeout:p,stream:f=!1}=this.params.config,h=this.params.config.maxTokens,y={...J,locale:a,maxLength:u,type:l,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?se(y):oe(y),C=`Here is the diff: ${r}`,b=this.params.keyName||"OpenAI-Compatible",E=`${this.params.config.url}${this.params.config.path}`,k={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};ee(r,e,b,this.params.config.model,E,k,i),te(r,e,b,w,C,i);const $=xr(this.params.config.model),P={messages:[{role:"system",content:w},{role:"user",content:C}],model:this.params.config.model,stream:f,...$?{max_completion_tokens:h,temperature:1}:{max_tokens:h,top_p:this.params.config.topP,temperature:c}};ne(r,e,b,P,i);const O=Date.now();try{const S=await this.openAI.chat.completions.create(P,{timeout:p});let U="";if(f&&S){const fe=S;for await(const Q of fe){const Lt=Q.choices?.[0]?.delta?.content||"",he=Q.choices?.[0]?.delta?.reasoning_content||"",Ft=`${Lt}${he}`;U+=Ft}}else U=S.choices?.[0]?.message.content||"";const _=Date.now()-O;return V(r,e,b,S,i),q(r,e,b,_,U,i),e==="review"?this.sanitizeResponse(U):this.parseMessage(U,l,d)}catch(S){throw G(r,e,b,S,i),S}}}const ol=["claude-4","claude-haiku-4","claude-sonnet-4","claude-opus-4"],sl=t=>{const e=t.toLowerCase();return ol.some(r=>e===r||e.startsWith(`${r}-`)||e.startsWith(`${r}.`))},nl=10*60*1e3;class il extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=g.red.bold("[Anthropic]"),this.anthropic=new mn({apiKey:this.params.config.key,...this.params.config.timeout>nl&&{timeout:this.params.config.timeout}})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Anthropic API key in configuration":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your Anthropic usage limits":r.includes("model_not_found")||r.includes("Model not found")||/model.*does not exist/i.test(r)?"Model not found or not accessible. Check if the Claude model name is correct":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Claude model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Claude model configuration":r.includes("500")||r.includes("Internal Server Error")?"Anthropic server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:a,locale:c,generate:d,type:l,maxLength:u,maxTokens:p,topP:f,model:h}=this.params.config,y={...J,locale:c,maxLength:u,type:l,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?se(y):oe(y),C=Ee(r,e),E=`${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"};ee(r,e,"Anthropic",h,E,k,i),te(r,e,"Anthropic",w,C,i);const $=sl(h),P={max_tokens:p,temperature:a,system:w,messages:[{role:"user",content:C}],model:h,...$?{}:{top_p:f}};ne(r,e,"Anthropic",P,i);const O=Date.now();try{const S=await this.anthropic.messages.create(P),U=Date.now()-O;V(r,e,"Anthropic",S,i);const _=S.content.map(({text:fe})=>fe).join("");return q(r,e,"Anthropic",U,_,i),e==="review"?this.sanitizeResponse(_):this.parseMessage(_,l,d)}catch(S){throw G(r,e,"Anthropic",S,i),S}}}const ae="Bedrock",ye={MISSING_DEPENDENCY:"MissingDependencyError",MISSING_REGION:"MissingRegionError",MISSING_MODEL_ID:"MissingModelIdError",MISSING_API_KEY:"MissingApiKeyError",MISSING_APPLICATION_KEY:"MissingApplicationKeyError",INVALID_RESPONSE:"InvalidResponseError",EMPTY_RESPONSE:"EmptyResponseError"},W=t=>typeof t=="string"&&t.length>0;let Ze=null,et=null;const Ss=t=>{const e=new Error('Amazon Bedrock support requires "@aws-sdk/client-bedrock-runtime" and "@aws-sdk/credential-providers". Install them with `pnpm add @aws-sdk/client-bedrock-runtime @aws-sdk/credential-providers`.');return e.name=ye.MISSING_DEPENDENCY,e.originalError=t,e},al=async()=>{if(Ze)return Ze;try{return Ze=await import("@aws-sdk/client-bedrock-runtime"),Ze}catch(t){throw Ze=null,Ss(t)}},ks=async()=>{if(et)return et;try{return et=await import("@aws-sdk/credential-providers"),et}catch(t){throw et=null,Ss(t)}};class cl extends re{constructor(e){super(e),this.params=e,this.credentialCache=void 0,this.credentialCacheTimestamp=0,this.CREDENTIAL_CACHE_TTL=5*60*1e3,this.bedrockConfig=this.params.config,this.colors={primary:"#232F3E",secondary:"#FF9900"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${ae}]`),this.errorPrefix=g.red.bold(`[${ae}]`),this.validateConfiguration()}validateConfiguration(){const e=this.bedrockConfig;if(!W(e.model)){const s=new Error("Model ID or inference profile ARN is required.");throw s.name=ye.MISSING_MODEL_ID,s}if(!this.getRegion()){const s=new Error("AWS region is required. Configure BEDROCK.region or set AWS_REGION/AWS_DEFAULT_REGION.");throw s.name=ye.MISSING_REGION,s}const r=W(e.key),o=this.canUseAwsSdk();if(!r&&!o){const s=new Error("Authentication required: Configure AWS credentials (profile, access keys, IAM role) or API key (BEDROCK.key).");throw s.name=ye.MISSING_API_KEY,s}if(r&&!o&&!this.getRegion()&&!W(e.applicationBaseUrl)){const s=new Error("Bearer token authentication requires region or applicationBaseUrl to construct endpoint.");throw s.name=ye.MISSING_REGION,s}}canUseAwsSdk(){const e=this.bedrockConfig,r=W(e.profile)||W(process.env.AWS_PROFILE),o=W(e.accessKeyId)&&W(e.secretAccessKey)||W(process.env.AWS_ACCESS_KEY_ID)&&W(process.env.AWS_SECRET_ACCESS_KEY);return r||o}determineAuthMethod(){const e=W(this.bedrockConfig.key);if(this.canUseAwsSdk())return"aws-sdk";if(e)return"bearer-token";throw new Error("No authentication method configured")}getServiceSpecificErrorMessage(e){const r=e?.name||e.code,o=e.message||"";switch(r){case"UnrecognizedClientException":case"InvalidSignatureException":return"Authentication with AWS failed. Check your IAM credentials or Bedrock API key settings.";case"AccessDeniedException":return"Access denied. Ensure the IAM principal or application key has permission to invoke the Bedrock resource.";case"ValidationException":return"Invalid request for the selected Bedrock model. Verify the model ID and payload.";case"ResourceNotFoundException":return"The specified Bedrock model, endpoint, or inference profile could not be found.";case"ThrottlingException":return"Request throttled by Bedrock. Reduce request rate or check service quotas."}return o.includes("Region")?"AWS region is required for Bedrock. Configure BEDROCK.region or set AWS_REGION/AWS_DEFAULT_REGION.":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,o=this.bedrockConfig,s=o.model,{logging:n,inferenceParameters:i}=o,a={...J,locale:o.locale,maxLength:o.maxLength,type:o.type,generate:o.generate,systemPrompt:o.systemPrompt,systemPromptPath:o.systemPromptPath,codeReviewPromptPath:o.codeReviewPromptPath},c=e==="review"?se(a):oe(a),d=Ee(r,e),l={region:this.getRegion(),profile:o.profile,modelId:s},u=`https://bedrock-runtime.${this.getRegion()||"unknown"}.amazonaws.com/model/${encodeURIComponent(s)}/converse`;ee(r,e,ae,s,u,l,n),te(r,e,ae,c,d,n);const p={modelId:s,systemPrompt:c,userPrompt:d,...i&&Object.keys(i).length>0&&{inferenceConfig:i}};ne(r,e,ae,p,n);const f=Date.now();try{const h=this.determineAuthMethod();At()&&(console.log(g.cyan(`[Bedrock] Authentication method: ${h}`)),console.log(g.cyan(`[Bedrock] Model ID: ${s}`)),console.log(g.cyan(`[Bedrock] Region: ${this.getRegion()}`)),console.log(g.cyan(`[Bedrock] Has AWS credentials: ${this.canUseAwsSdk()}`)),console.log(g.cyan(`[Bedrock] Has API key: ${W(o.key)}`)));const y=h==="bearer-token"?await this.invokeWithBearerToken({model:s,systemPrompt:c,userPrompt:d,logging:n,requestType:e,diff:r,inferenceConfig:i}):await this.invokeWithAwsSdk({model:s,systemPrompt:c,userPrompt:d,logging:n,requestType:e,diff:r,inferenceConfig:i}),w=Date.now()-f;return q(r,e,ae,w,y,n),e==="review"?this.sanitizeResponse(y):this.parseMessage(y,o.type,o.generate)}catch(h){throw G(r,e,ae,h,n),h instanceof Error&&(h.status=h?.status||h?.$metadata?.httpStatusCode),h}}async invokeWithAwsSdk(e){const r=this.getRegion(),{model:o,systemPrompt:s,userPrompt:n,inferenceConfig:i,logging:a,requestType:c,diff:d}=e,{BedrockRuntimeClient:l,ConverseCommand:u}=await al(),p=this.bedrockConfig,f={region:r,requestHandler:{requestTimeout:p.timeout||12e4}},h=await this.resolveCredentials();h&&(f.credentials=h);const y=new l(f),w=new u({modelId:o,messages:[{role:"user",content:[{text:n}]}],...s?{system:[{text:s}]}:{},...i&&Object.keys(i).length>0&&{inferenceConfig:i}});At()&&console.log(g.cyan(`[Bedrock] Sending ConverseCommand with modelId: ${o}`));let C;try{C=await y.send(w),V(d,c,ae,C,a)}catch(E){throw At()&&(console.error(g.red(`[Bedrock] AWS SDK Error: ${E.name}`)),console.error(g.red(`[Bedrock] Error message: ${E.message}`)),E.$metadata&&(console.error(g.red(`[Bedrock] Request ID: ${E.$metadata.requestId}`)),console.error(g.red(`[Bedrock] HTTP Status: ${E.$metadata.httpStatusCode}`))),E.$fault&&console.error(g.red(`[Bedrock] Fault: ${E.$fault}`))),E}const b=C.output?.message?.content?.[0]?.text||"";if(!b){const E=new Error("No text content found in Bedrock response.");throw E.name=ye.EMPTY_RESPONSE,E.content=C,E}return b}invokeWithBearerToken(e){const{model:r,systemPrompt:o,userPrompt:s,inferenceConfig:n,logging:i,requestType:a,diff:c}=e,d=this.bedrockConfig,l=this.getRegion(),u=encodeURIComponent(r),p=d.applicationBaseUrl||`https://bedrock-runtime.${l}.amazonaws.com/model/${u}/converse`,f=new URL(p),h={modelId:r,messages:[{role:"user",content:[{text:s}]}],...n&&Object.keys(n).length>0&&{inferenceConfig:n}};o&&(h.system=[{text:o}]);const y=JSON.stringify(h),w={"Content-Type":"application/json","Content-Length":Buffer.byteLength(y).toString()};return W(d.key)&&(w.Authorization=`Bearer ${d.key}`),W(d.applicationInferenceProfileArn)&&(w["x-amzn-bedrock-inference-profile-arn"]=d.applicationInferenceProfileArn),W(d.applicationEndpointId)&&(w["x-amzn-bedrock-endpoint-id"]=d.applicationEndpointId),new Promise((C,b)=>{const E=so.request({method:"POST",protocol:f.protocol,hostname:f.hostname,port:f.port,path:f.pathname+f.search,headers:w,timeout:d.timeout},k=>{const $=[];k.on("data",P=>$.push(P)),k.on("end",()=>{const P=Buffer.concat($).toString("utf8");if(k.statusCode&&k.statusCode>=400){const _=new Error(`Bedrock application endpoint responded with status ${k.statusCode}.`);return _.status=k.statusCode,_.content=P,G(c,a,ae,_,i),b(_)}const O=ns(P);if(!O.ok){const _=new Error("Failed to parse Bedrock application response as JSON. The Bedrock Converse API should always return valid JSON.");return _.name=ye.INVALID_RESPONSE,_.content=P,G(c,a,ae,_,i),b(_)}const S=O.data;V(c,a,ae,S,i);const U=S.output?.message?.content?.[0]?.text||"";if(!U){const _=new Error("No text content found in Bedrock response.");return _.name=ye.EMPTY_RESPONSE,_.content=S,G(c,a,ae,_,i),b(_)}C(U)})});E.on("error",k=>{const $=k;G(c,a,ae,$,i),b($)}),E.write(y),E.end()})}getRegion(){return this.bedrockConfig.region||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||""}async resolveCredentials(){const e=Date.now();if(this.credentialCache&&e-this.credentialCacheTimestamp<this.CREDENTIAL_CACHE_TTL)return this.credentialCache;const r=this.bedrockConfig,o=r.profile,s=r.accessKeyId,n=r.secretAccessKey,i=r.sessionToken;let a;if(W(o)){const{fromIni:c}=await ks();a=c({profile:o})}else if(W(s)&&W(n))a=async()=>({accessKeyId:s,secretAccessKey:n,sessionToken:i||process.env.AWS_SESSION_TOKEN||void 0});else if(process.env.AWS_PROFILE){const{fromIni:c}=await ks();a=c({profile:process.env.AWS_PROFILE})}return a&&(this.credentialCache=a,this.credentialCacheTimestamp=e),a}}class Ne{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=pn.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 ll extends re{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#e28c58",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Codestral]"),this.errorPrefix=g.red.bold("[Codestral]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Codestral API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Codestral plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Codestral model name is correct":r.includes("Invalid model type")?"Invalid model type. Use supported models: codestral-latest, codestral-2501":r.includes("overloaded")||r.includes("capacity")?"Codestral service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Codestral model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Codestral model configuration":r.includes("500")||r.includes("Internal Server Error")?"Codestral server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l}=this.params.config,u={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},p=e==="review"?se(u):oe(u);this.checkAvailableModels();const f=Ee(r,e),y=`${this.params.config.url||"https://codestral.mistral.ai"}/v1/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};ee(r,e,"Codestral",this.params.config.model,y,w,i),te(r,e,"Codestral",p,f,i);const C=await this.createChatCompletions(p,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,c)}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,r){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,r)}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:wt(10,1e3)};r==="commit"&&(i.response_format={type:"json_object"}),ne(o,r,"Codestral",i,s);const a=Date.now();try{const d=await new Ne({method:"POST",baseURL:`${n}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),l=Date.now()-a,u=d.data;if(V(o,r,"Codestral",u,s),!u.choices||u.choices.length===0||!u.choices[0].message?.content)throw G(o,r,"Codestral",{message:"No Content on response",result:u},s),new Error("No Content on response. Please open a Bug report");const f=u.choices[0].message.content;return q(o,r,"Codestral",l,f,s),f}catch(c){throw G(o,r,"Codestral",c,s),c}}}class ul extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#D18EE2",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Cohere]"),this.errorPrefix=g.red.bold("[Cohere]"),this.cohere=new fn({token:this.params.config.key})}isValidCohereV2Response(e){const r=e;return r?.message?.content!==void 0&&Array.isArray(r.message.content)&&r.message.content.length>0&&typeof r.message.content[0]?.text=="string"}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Cohere API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Cohere plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Cohere model name is correct":r.includes("overloaded")||r.includes("capacity")?"Cohere service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Cohere model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Cohere model configuration":r.includes("500")||r.includes("Internal Server Error")?"Cohere server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:a,locale:c,generate:d,type:l,maxLength:u,maxTokens:p}=this.params.config,f={...J,locale:c,maxLength:u,type:l,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},h=e==="review"?se(f):oe(f),y=`Here is the diff: ${r}`,w=[...h?[{role:"system",content:h}]:[],{role:"user",content:y}],b=`${this.params.config.url}/v2/chat`;ee(r,e,"Cohere",this.params.config.model,b,{},i),te(r,e,"Cohere",h,y,i);const E={model:this.params.config.model,messages:w,max_tokens:p,temperature:a,seed:wt(10,1e3),p:this.params.config.topP};ne(r,e,"Cohere",E,i);const k=Date.now();try{const $=await this.cohere.chat(E,{timeoutInSeconds:Math.floor(this.params.config.timeout/1e3)}),P=Date.now()-k;if(!this.isValidCohereV2Response($))throw new Error("Invalid response structure from Cohere v2 API");const O=$.message.content[0].text;return V(r,e,"Cohere",$,i),q(r,e,"Cohere",P,O,i),e==="review"?this.sanitizeResponse(O):this.parseMessage(O,l,d)}catch($){throw G(r,e,"Cohere",$,i),$}}}class dl extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#53a3f9",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[DeepSeek]"),this.errorPrefix=g.red.bold("[DeepSeek]");const r=this.params.config.url||"https://api.deepseek.com";this.deepSeek=new ro({baseURL:r,apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your DeepSeek API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your DeepSeek plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the DeepSeek model name is correct":r.includes("Invalid model type")?"Invalid model type. Use supported models: deepseek-reasoner, deepseek-chat":r.includes("overloaded")||r.includes("capacity")?"DeepSeek service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this DeepSeek model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your DeepSeek model configuration":r.includes("500")||r.includes("Internal Server Error")?"DeepSeek server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l}=this.params.config,u={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},p=e==="review"?se(u):oe(u);this.checkAvailableModels();const f=Ee(r,e),y=`${this.params.config.url||"https://api.deepseek.com"}/chat/completions`,w={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};ee(r,e,"DeepSeek",this.params.config.model,y,w,i),te(r,e,"DeepSeek",p,f,i);const C=await this.createChatCompletions(p,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,c)}checkAvailableModels(){if(["deepseek-reasoner","deepseek-chat"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of DeepSeek")}async createChatCompletions(e,r,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={messages:[{role:"system",content:e},{role:"user",content:r}],model:this.params.config.model,max_tokens:this.params.config.maxTokens,top_p:this.params.config.topP,temperature:this.params.config.temperature};ne(s,o,"DeepSeek",i,n);const a=Date.now();try{const c=await this.deepSeek.chat.completions.create(i,{timeout:this.params.config.timeout}),d=Date.now()-a,l=c.choices?.[0];if(!l?.message)throw new Error("DeepSeek API returned invalid response structure");const u=l.message.content||l.message.reasoning_content||"";if(!u)throw new Error("DeepSeek API returned empty response");return V(s,o,"DeepSeek",c,n),q(s,o,"DeepSeek",d,u,n),u}catch(c){throw G(s,o,"DeepSeek",c,n),c}}}class ml extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=g.red.bold("[Gemini]"),this.genAI=new hn(this.params.config.key)}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Google AI Studio API key in configuration":r.includes("quota")||r.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your Google AI Studio usage limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Gemini model name is correct":r.includes("SAFETY")||r.includes("safety")?"Content blocked by safety filters. Try rephrasing your request":r.includes("RECITATION")||r.includes("recitation")?"Content blocked due to recitation concerns. Try a different approach":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Gemini model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Gemini model configuration":r.includes("500")||r.includes("Internal Server Error")?"Google AI service error. Try again later":r.includes("MAX_TOKENS")||r.includes("truncated")||r.includes("maxOutputTokens")?"Response truncated due to token limit. Gemini 2.5+ models use thinking tokens. Try increasing maxTokens (recommended: 8192+)":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,logging:n,locale:i,codeReviewPromptPath:a,generate:c,type:d,maxLength:l}=this.params.config,u=this.params.config.maxTokens,p={...J,locale:i,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:a,vcs_branch:this.params.branchName||""},f=e==="review"?se(p):oe(p),h={maxOutputTokens:u,temperature:this.params.config.temperature,topP:this.params.config.topP},y=this.genAI.getGenerativeModel({model:this.params.config.model,systemInstruction:f,generationConfig:h,safetySettings:[{category:st.HARM_CATEGORY_HATE_SPEECH,threshold:nt.BLOCK_LOW_AND_ABOVE},{category:st.HARM_CATEGORY_SEXUALLY_EXPLICIT,threshold:nt.BLOCK_LOW_AND_ABOVE},{category:st.HARM_CATEGORY_HARASSMENT,threshold:nt.BLOCK_LOW_AND_ABOVE},{category:st.HARM_CATEGORY_DANGEROUS_CONTENT,threshold:nt.BLOCK_LOW_AND_ABOVE}]}),w=Ee(r,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};ee(r,e,"Gemini",this.params.config.model,b,E,n),te(r,e,"Gemini",f,w,n),ne(r,e,"Gemini",{systemInstruction:{parts:[{text:f}]},contents:[{parts:[{text:w}]}],generationConfig:h},n);const $=Date.now();try{const P=this.params.config.timeout>1e4?{request:{timeout:this.params.config.timeout}}:void 0,O=await y.generateContent(w,P),S=O.response;if(S.candidates?.[0]?.finishReason==="MAX_TOKENS"){const Q=S.usageMetadata;throw new Error(`Response truncated: maxOutputTokens exceeded. Thinking tokens: ${Q?.thoughtsTokenCount??"N/A"}, Output tokens: ${Q?.candidatesTokenCount??"N/A"}. Increase maxTokens config for Gemini 2.5+ thinking models.`)}const _=S.text(),fe=Date.now()-$;return V(r,e,"Gemini",{response:_,candidates:O.response.candidates,usageMetadata:O.response.usageMetadata},n),q(r,e,"Gemini",fe,_,n),e==="review"?this.sanitizeResponse(_):this.parseMessage(_,d,c)}catch(P){throw G(r,e,"Gemini",P,n),P}}}class pl extends re{constructor(e){super(e),this.params=e,this.baseURL="https://models.github.ai",this.colors={primary:"#24292e",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[GitHub Models]"),this.errorPrefix=g.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 j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){if(!this.params.config.key){const f=new Error("GitHub token is required for GitHub Models. Use: aicommit2 github-login");throw f.code="MISSING_TOKEN",f}const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,locale:i,generate:a,type:c,maxLength:d}=this.params.config,l={...J,locale:i,maxLength:d,type:c,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},u=e==="review"?se(l):oe(l),p=await this.makeRequest(u,r,e);return e==="review"?this.sanitizeResponse(p):this.parseMessage(p,c,a)}async makeRequest(e,r,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"?r:`Here's the diff:
|
|
102
|
+
Check the API status: ${t}`),new v(d)}return JSON.parse(l)},Ss=t=>t.trim(),ol=["gpt-5","gpt-5-mini","gpt-5-nano","gpt-5-codex","o1","o1-mini","o1-pro","o3","o3-mini","o3-pro","o4-mini"],Rr=t=>{const e=t.toLowerCase();return ol.some(r=>e===r||e.startsWith(`${r}-`)||e.startsWith(`${r}.`))},sl=async(t,e,r,o,s,n,i,a,l,d,c,u,m,f)=>{try{const h=Ee(n,m),y=Rr(s),w={model:s,messages:[{role:"system",content:c},{role:"user",content:h}],stream:!1,n:1,frequency_penalty:0,presence_penalty:0,...y?{max_completion_tokens:a,temperature:1}:{max_tokens:a,top_p:d,temperature:l}},C=new URL(e),b=`${C.protocol}//${C.host}${r}`,E={Authorization:`Bearer ${o}`,"Content-Type":"application/json"};Z(n,m,t,s,b,E,u),ee(n,m,t,c,h,u),se(n,m,t,w,u);const k=Date.now(),$=await rl(e,r,o,w,i,f),P=Date.now()-k;V(n,m,t,$,u);const O=$.choices.filter(S=>S.message?.content).map(S=>Ss(S.message.content)).join();return q(n,m,t,P,O,u),$.choices.filter(S=>S.message?.content).map(S=>Ss(S.message.content))}catch(h){G(n,m,t,h,u);const y=h;throw y.code==="ENOTFOUND"?new v(`Error connecting to ${y.hostname} (${y.syscall})`):y}};class nl extends te{constructor(e){super(e),this.params=e;const r=this.params.keyName||"OPENAI_COMPATIBLE";this.colors=rc(r),this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${wt(r)}]`),this.errorPrefix=g.red.bold(`[${wt(r)}]`),this.openAI=new oo({apiKey:this.params.config.key,baseURL:`${this.params.config.url}${this.params.config.path}`})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your OpenAI-compatible API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or check your service limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the model name is correct":r.includes("network")||r.includes("connection")?"Network error. Check your internet connection and API endpoint":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your usage limits":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your API configuration":r.includes("500")||r.includes("Internal Server Error")?"Server error. Try again later":r.includes("overloaded")||r.includes("capacity")?"Service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,temperature:l,generate:d,type:c,maxLength:u,timeout:m,stream:f=!1}=this.params.config,h=this.params.config.maxTokens,y={...J,locale:a,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?oe(y):re(y),C=`Here is the diff: ${r}`,b=this.params.keyName||"OpenAI-Compatible",E=`${this.params.config.url}${this.params.config.path}`,k={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};Z(r,e,b,this.params.config.model,E,k,i),ee(r,e,b,w,C,i);const $=Rr(this.params.config.model),P={messages:[{role:"system",content:w},{role:"user",content:C}],model:this.params.config.model,stream:f,...$?{max_completion_tokens:h,temperature:1}:{max_tokens:h,top_p:this.params.config.topP,temperature:l}};se(r,e,b,P,i);const O=Date.now();try{const S=await this.openAI.chat.completions.create(P,{timeout:m});let U="";if(f&&S){const he=S;for await(const fe of he){const me=fe.choices?.[0]?.delta?.content||"",Kr=fe.choices?.[0]?.delta?.reasoning_content||"",jt=`${me}${Kr}`;U+=jt}}else U=S.choices?.[0]?.message.content||"";const _=Date.now()-O;return V(r,e,b,S,i),q(r,e,b,_,U,i),e==="review"?this.sanitizeResponse(U):this.parseMessage(U,c,d)}catch(S){throw G(r,e,b,S,i),S}}}const il=["claude-4","claude-haiku-4","claude-sonnet-4","claude-opus-4"],al=t=>{const e=t.toLowerCase();return il.some(r=>e===r||e.startsWith(`${r}-`)||e.startsWith(`${r}.`))},cl=10*60*1e3;class ll extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#AE5630",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Anthropic]"),this.errorPrefix=g.red.bold("[Anthropic]"),this.anthropic=new hn({apiKey:this.params.config.key,...this.params.config.timeout>cl&&{timeout:this.params.config.timeout}})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Anthropic API key in configuration":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your Anthropic usage limits":r.includes("model_not_found")||r.includes("Model not found")||/model.*does not exist/i.test(r)?"Model not found or not accessible. Check if the Claude model name is correct":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Claude model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Claude model configuration":r.includes("500")||r.includes("Internal Server Error")?"Anthropic server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:a,locale:l,generate:d,type:c,maxLength:u,maxTokens:m,topP:f,model:h}=this.params.config,y={...J,locale:l,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?oe(y):re(y),C=Ee(r,e),E=`${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"};Z(r,e,"Anthropic",h,E,k,i),ee(r,e,"Anthropic",w,C,i);const $=al(h),P={max_tokens:m,temperature:a,system:w,messages:[{role:"user",content:C}],model:h,...$?{}:{top_p:f}};se(r,e,"Anthropic",P,i);const O=Date.now();try{const S=await this.anthropic.messages.create(P),U=Date.now()-O;V(r,e,"Anthropic",S,i);const _=S.content.map(({text:he})=>he).join("");return q(r,e,"Anthropic",U,_,i),e==="review"?this.sanitizeResponse(_):this.parseMessage(_,c,d)}catch(S){throw G(r,e,"Anthropic",S,i),S}}}const ie="Bedrock",ye={MISSING_DEPENDENCY:"MissingDependencyError",MISSING_REGION:"MissingRegionError",MISSING_MODEL_ID:"MissingModelIdError",MISSING_API_KEY:"MissingApiKeyError",MISSING_APPLICATION_KEY:"MissingApplicationKeyError",INVALID_RESPONSE:"InvalidResponseError",EMPTY_RESPONSE:"EmptyResponseError"},W=t=>typeof t=="string"&&t.length>0;let et=null,tt=null;const ks=t=>{const e=new Error('Amazon Bedrock support requires "@aws-sdk/client-bedrock-runtime" and "@aws-sdk/credential-providers". Install them with `pnpm add @aws-sdk/client-bedrock-runtime @aws-sdk/credential-providers`.');return e.name=ye.MISSING_DEPENDENCY,e.originalError=t,e},ul=async()=>{if(et)return et;try{return et=await import("@aws-sdk/client-bedrock-runtime"),et}catch(t){throw et=null,ks(t)}},Is=async()=>{if(tt)return tt;try{return tt=await import("@aws-sdk/credential-providers"),tt}catch(t){throw tt=null,ks(t)}};class dl extends te{constructor(e){super(e),this.params=e,this.credentialCache=void 0,this.credentialCacheTimestamp=0,this.CREDENTIAL_CACHE_TTL=5*60*1e3,this.bedrockConfig=this.params.config,this.colors={primary:"#232F3E",secondary:"#FF9900"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${ie}]`),this.errorPrefix=g.red.bold(`[${ie}]`),this.validateConfiguration()}validateConfiguration(){const e=this.bedrockConfig;if(!W(e.model)){const s=new Error("Model ID or inference profile ARN is required.");throw s.name=ye.MISSING_MODEL_ID,s}if(!this.getRegion()){const s=new Error("AWS region is required. Configure BEDROCK.region or set AWS_REGION/AWS_DEFAULT_REGION.");throw s.name=ye.MISSING_REGION,s}const r=W(e.key),o=this.canUseAwsSdk();if(!r&&!o){const s=new Error("Authentication required: Configure AWS credentials (profile, access keys, IAM role) or API key (BEDROCK.key).");throw s.name=ye.MISSING_API_KEY,s}if(r&&!o&&!this.getRegion()&&!W(e.applicationBaseUrl)){const s=new Error("Bearer token authentication requires region or applicationBaseUrl to construct endpoint.");throw s.name=ye.MISSING_REGION,s}}canUseAwsSdk(){const e=this.bedrockConfig,r=W(e.profile)||W(process.env.AWS_PROFILE),o=W(e.accessKeyId)&&W(e.secretAccessKey)||W(process.env.AWS_ACCESS_KEY_ID)&&W(process.env.AWS_SECRET_ACCESS_KEY);return r||o}determineAuthMethod(){const e=W(this.bedrockConfig.key);if(this.canUseAwsSdk())return"aws-sdk";if(e)return"bearer-token";throw new Error("No authentication method configured")}getServiceSpecificErrorMessage(e){const r=e?.name||e.code,o=e.message||"";switch(r){case"UnrecognizedClientException":case"InvalidSignatureException":return"Authentication with AWS failed. Check your IAM credentials or Bedrock API key settings.";case"AccessDeniedException":return"Access denied. Ensure the IAM principal or application key has permission to invoke the Bedrock resource.";case"ValidationException":return"Invalid request for the selected Bedrock model. Verify the model ID and payload.";case"ResourceNotFoundException":return"The specified Bedrock model, endpoint, or inference profile could not be found.";case"ThrottlingException":return"Request throttled by Bedrock. Reduce request rate or check service quotas."}return o.includes("Region")?"AWS region is required for Bedrock. Configure BEDROCK.region or set AWS_REGION/AWS_DEFAULT_REGION.":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,o=this.bedrockConfig,s=o.model,{logging:n,inferenceParameters:i}=o,a={...J,locale:o.locale,maxLength:o.maxLength,type:o.type,generate:o.generate,systemPrompt:o.systemPrompt,systemPromptPath:o.systemPromptPath,codeReviewPromptPath:o.codeReviewPromptPath},l=e==="review"?oe(a):re(a),d=Ee(r,e),c={region:this.getRegion(),profile:o.profile,modelId:s},u=`https://bedrock-runtime.${this.getRegion()||"unknown"}.amazonaws.com/model/${encodeURIComponent(s)}/converse`;Z(r,e,ie,s,u,c,n),ee(r,e,ie,l,d,n);const m={modelId:s,systemPrompt:l,userPrompt:d,...i&&Object.keys(i).length>0&&{inferenceConfig:i}};se(r,e,ie,m,n);const f=Date.now();try{const h=this.determineAuthMethod();St()&&(console.log(g.cyan(`[Bedrock] Authentication method: ${h}`)),console.log(g.cyan(`[Bedrock] Model ID: ${s}`)),console.log(g.cyan(`[Bedrock] Region: ${this.getRegion()}`)),console.log(g.cyan(`[Bedrock] Has AWS credentials: ${this.canUseAwsSdk()}`)),console.log(g.cyan(`[Bedrock] Has API key: ${W(o.key)}`)));const y=h==="bearer-token"?await this.invokeWithBearerToken({model:s,systemPrompt:l,userPrompt:d,logging:n,requestType:e,diff:r,inferenceConfig:i}):await this.invokeWithAwsSdk({model:s,systemPrompt:l,userPrompt:d,logging:n,requestType:e,diff:r,inferenceConfig:i}),w=Date.now()-f;return q(r,e,ie,w,y,n),e==="review"?this.sanitizeResponse(y):this.parseMessage(y,o.type,o.generate)}catch(h){throw G(r,e,ie,h,n),h instanceof Error&&(h.status=h?.status||h?.$metadata?.httpStatusCode),h}}async invokeWithAwsSdk(e){const r=this.getRegion(),{model:o,systemPrompt:s,userPrompt:n,inferenceConfig:i,logging:a,requestType:l,diff:d}=e,{BedrockRuntimeClient:c,ConverseCommand:u}=await ul(),m=this.bedrockConfig,f={region:r,requestHandler:{requestTimeout:m.timeout||12e4}},h=await this.resolveCredentials();h&&(f.credentials=h);const y=new c(f),w=new u({modelId:o,messages:[{role:"user",content:[{text:n}]}],...s?{system:[{text:s}]}:{},...i&&Object.keys(i).length>0&&{inferenceConfig:i}});St()&&console.log(g.cyan(`[Bedrock] Sending ConverseCommand with modelId: ${o}`));let C;try{C=await y.send(w),V(d,l,ie,C,a)}catch(E){throw St()&&(console.error(g.red(`[Bedrock] AWS SDK Error: ${E.name}`)),console.error(g.red(`[Bedrock] Error message: ${E.message}`)),E.$metadata&&(console.error(g.red(`[Bedrock] Request ID: ${E.$metadata.requestId}`)),console.error(g.red(`[Bedrock] HTTP Status: ${E.$metadata.httpStatusCode}`))),E.$fault&&console.error(g.red(`[Bedrock] Fault: ${E.$fault}`))),E}const b=C.output?.message?.content?.[0]?.text||"";if(!b){const E=new Error("No text content found in Bedrock response.");throw E.name=ye.EMPTY_RESPONSE,E.content=C,E}return b}invokeWithBearerToken(e){const{model:r,systemPrompt:o,userPrompt:s,inferenceConfig:n,logging:i,requestType:a,diff:l}=e,d=this.bedrockConfig,c=this.getRegion(),u=encodeURIComponent(r),m=d.applicationBaseUrl||`https://bedrock-runtime.${c}.amazonaws.com/model/${u}/converse`,f=new URL(m),h={modelId:r,messages:[{role:"user",content:[{text:s}]}],...n&&Object.keys(n).length>0&&{inferenceConfig:n}};o&&(h.system=[{text:o}]);const y=JSON.stringify(h),w={"Content-Type":"application/json","Content-Length":Buffer.byteLength(y).toString()};return W(d.key)&&(w.Authorization=`Bearer ${d.key}`),W(d.applicationInferenceProfileArn)&&(w["x-amzn-bedrock-inference-profile-arn"]=d.applicationInferenceProfileArn),W(d.applicationEndpointId)&&(w["x-amzn-bedrock-endpoint-id"]=d.applicationEndpointId),new Promise((C,b)=>{const E=no.request({method:"POST",protocol:f.protocol,hostname:f.hostname,port:f.port,path:f.pathname+f.search,headers:w,timeout:d.timeout},k=>{const $=[];k.on("data",P=>$.push(P)),k.on("end",()=>{const P=Buffer.concat($).toString("utf8");if(k.statusCode&&k.statusCode>=400){const _=new Error(`Bedrock application endpoint responded with status ${k.statusCode}.`);return _.status=k.statusCode,_.content=P,G(l,a,ie,_,i),b(_)}const O=is(P);if(!O.ok){const _=new Error("Failed to parse Bedrock application response as JSON. The Bedrock Converse API should always return valid JSON.");return _.name=ye.INVALID_RESPONSE,_.content=P,G(l,a,ie,_,i),b(_)}const S=O.data;V(l,a,ie,S,i);const U=S.output?.message?.content?.[0]?.text||"";if(!U){const _=new Error("No text content found in Bedrock response.");return _.name=ye.EMPTY_RESPONSE,_.content=S,G(l,a,ie,_,i),b(_)}C(U)})});E.on("error",k=>{const $=k;G(l,a,ie,$,i),b($)}),E.write(y),E.end()})}getRegion(){return this.bedrockConfig.region||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||""}async resolveCredentials(){const e=Date.now();if(this.credentialCache&&e-this.credentialCacheTimestamp<this.CREDENTIAL_CACHE_TTL)return this.credentialCache;const r=this.bedrockConfig,o=r.profile,s=r.accessKeyId,n=r.secretAccessKey,i=r.sessionToken;let a;if(W(o)){const{fromIni:l}=await Is();a=l({profile:o})}else if(W(s)&&W(n))a=async()=>({accessKeyId:s,secretAccessKey:n,sessionToken:i||process.env.AWS_SESSION_TOKEN||void 0});else if(process.env.AWS_PROFILE){const{fromIni:l}=await Is();a=l({profile:process.env.AWS_PROFILE})}return a&&(this.credentialCache=a,this.credentialCacheTimestamp=e),a}}class Te{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=gn.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 ml extends te{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#e28c58",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Codestral]"),this.errorPrefix=g.red.bold("[Codestral]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Codestral API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Codestral plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Codestral model name is correct":r.includes("Invalid model type")?"Invalid model type. Use supported models: codestral-latest, codestral-2501":r.includes("overloaded")||r.includes("capacity")?"Codestral service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Codestral model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Codestral model configuration":r.includes("500")||r.includes("Internal Server Error")?"Codestral server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c}=this.params.config,u={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},m=e==="review"?oe(u):re(u);this.checkAvailableModels();const f=Ee(r,e),y=`${this.params.config.url||"https://codestral.mistral.ai"}/v1/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};Z(r,e,"Codestral",this.params.config.model,y,w,i),ee(r,e,"Codestral",m,f,i);const C=await this.createChatCompletions(m,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,l)}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,r){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,r)}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:vt(10,1e3)};r==="commit"&&(i.response_format={type:"json_object"}),se(o,r,"Codestral",i,s);const a=Date.now();try{const d=await new Te({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()-a,u=d.data;if(V(o,r,"Codestral",u,s),!u.choices||u.choices.length===0||!u.choices[0].message?.content)throw G(o,r,"Codestral",{message:"No Content on response",result:u},s),new Error("No Content on response. Please open a Bug report");const f=u.choices[0].message.content;return q(o,r,"Codestral",c,f,s),f}catch(l){throw G(o,r,"Codestral",l,s),l}}}class pl extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#D18EE2",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Cohere]"),this.errorPrefix=g.red.bold("[Cohere]"),this.cohere=new yn({token:this.params.config.key})}isValidCohereV2Response(e){const r=e;return r?.message?.content!==void 0&&Array.isArray(r.message.content)&&r.message.content.length>0&&typeof r.message.content[0]?.text=="string"}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Cohere API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Cohere plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Cohere model name is correct":r.includes("overloaded")||r.includes("capacity")?"Cohere service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Cohere model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Cohere model configuration":r.includes("500")||r.includes("Internal Server Error")?"Cohere server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,temperature:a,locale:l,generate:d,type:c,maxLength:u,maxTokens:m}=this.params.config,f={...J,locale:l,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},h=e==="review"?oe(f):re(f),y=`Here is the diff: ${r}`,w=[...h?[{role:"system",content:h}]:[],{role:"user",content:y}],b=`${this.params.config.url}/v2/chat`;Z(r,e,"Cohere",this.params.config.model,b,{},i),ee(r,e,"Cohere",h,y,i);const E={model:this.params.config.model,messages:w,max_tokens:m,temperature:a,seed:vt(10,1e3),p:this.params.config.topP};se(r,e,"Cohere",E,i);const k=Date.now();try{const $=await this.cohere.chat(E,{timeoutInSeconds:Math.floor(this.params.config.timeout/1e3)}),P=Date.now()-k;if(!this.isValidCohereV2Response($))throw new Error("Invalid response structure from Cohere v2 API");const O=$.message.content[0].text;return V(r,e,"Cohere",$,i),q(r,e,"Cohere",P,O,i),e==="review"?this.sanitizeResponse(O):this.parseMessage(O,c,d)}catch($){throw G(r,e,"Cohere",$,i),$}}}class fl extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#53a3f9",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[DeepSeek]"),this.errorPrefix=g.red.bold("[DeepSeek]");const r=this.params.config.url||"https://api.deepseek.com";this.deepSeek=new oo({baseURL:r,apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your DeepSeek API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your DeepSeek plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the DeepSeek model name is correct":r.includes("Invalid model type")?"Invalid model type. Use supported models: deepseek-reasoner, deepseek-chat":r.includes("overloaded")||r.includes("capacity")?"DeepSeek service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this DeepSeek model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your DeepSeek model configuration":r.includes("500")||r.includes("Internal Server Error")?"DeepSeek server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c}=this.params.config,u={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},m=e==="review"?oe(u):re(u);this.checkAvailableModels();const f=Ee(r,e),y=`${this.params.config.url||"https://api.deepseek.com"}/chat/completions`,w={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};Z(r,e,"DeepSeek",this.params.config.model,y,w,i),ee(r,e,"DeepSeek",m,f,i);const C=await this.createChatCompletions(m,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,l)}checkAvailableModels(){if(["deepseek-reasoner","deepseek-chat"].includes(this.params.config.model))return!0;throw new Error("Invalid model type of DeepSeek")}async createChatCompletions(e,r,o){const s=this.params.stagedDiff.diff,{logging:n}=this.params.config,i={messages:[{role:"system",content:e},{role:"user",content:r}],model:this.params.config.model,max_tokens:this.params.config.maxTokens,top_p:this.params.config.topP,temperature:this.params.config.temperature};se(s,o,"DeepSeek",i,n);const a=Date.now();try{const l=await this.deepSeek.chat.completions.create(i,{timeout:this.params.config.timeout}),d=Date.now()-a,c=l.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 V(s,o,"DeepSeek",l,n),q(s,o,"DeepSeek",d,u,n),u}catch(l){throw G(s,o,"DeepSeek",l,n),l}}}class hl extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#0077FF",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Gemini]"),this.errorPrefix=g.red.bold("[Gemini]"),this.genAI=new wn(this.params.config.key)}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Google AI Studio API key in configuration":r.includes("quota")||r.includes("QUOTA_EXCEEDED")?"API quota exceeded. Check your Google AI Studio usage limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Gemini model name is correct":r.includes("SAFETY")||r.includes("safety")?"Content blocked by safety filters. Try rephrasing your request":r.includes("RECITATION")||r.includes("recitation")?"Content blocked due to recitation concerns. Try a different approach":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Gemini model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Gemini model configuration":r.includes("500")||r.includes("Internal Server Error")?"Google AI service error. Try again later":r.includes("MAX_TOKENS")||r.includes("truncated")||r.includes("maxOutputTokens")?"Response truncated due to token limit. Gemini 2.5+ models use thinking tokens. Try increasing maxTokens (recommended: 8192+)":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,logging:n,locale:i,codeReviewPromptPath:a,generate:l,type:d,maxLength:c}=this.params.config,u=this.params.config.maxTokens,m={...J,locale:i,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:a,vcs_branch:this.params.branchName||""},f=e==="review"?oe(m):re(m),h={maxOutputTokens:u,temperature:this.params.config.temperature,topP:this.params.config.topP},y=this.genAI.getGenerativeModel({model:this.params.config.model,systemInstruction:f,generationConfig:h,safetySettings:[{category:nt.HARM_CATEGORY_HATE_SPEECH,threshold:it.BLOCK_LOW_AND_ABOVE},{category:nt.HARM_CATEGORY_SEXUALLY_EXPLICIT,threshold:it.BLOCK_LOW_AND_ABOVE},{category:nt.HARM_CATEGORY_HARASSMENT,threshold:it.BLOCK_LOW_AND_ABOVE},{category:nt.HARM_CATEGORY_DANGEROUS_CONTENT,threshold:it.BLOCK_LOW_AND_ABOVE}]}),w=Ee(r,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};Z(r,e,"Gemini",this.params.config.model,b,E,n),ee(r,e,"Gemini",f,w,n),se(r,e,"Gemini",{systemInstruction:{parts:[{text:f}]},contents:[{parts:[{text:w}]}],generationConfig:h},n);const $=Date.now();try{const P=this.params.config.timeout>1e4?{request:{timeout:this.params.config.timeout}}:void 0,O=await y.generateContent(w,P),S=O.response;if(S.candidates?.[0]?.finishReason==="MAX_TOKENS"){const fe=S.usageMetadata;throw new Error(`Response truncated: maxOutputTokens exceeded. Thinking tokens: ${fe?.thoughtsTokenCount??"N/A"}, Output tokens: ${fe?.candidatesTokenCount??"N/A"}. Increase maxTokens config for Gemini 2.5+ thinking models.`)}const _=S.text(),he=Date.now()-$;return V(r,e,"Gemini",{response:_,candidates:O.response.candidates,usageMetadata:O.response.usageMetadata},n),q(r,e,"Gemini",he,_,n),e==="review"?this.sanitizeResponse(_):this.parseMessage(_,d,l)}catch(P){throw G(r,e,"Gemini",P,n),P}}}class gl extends te{constructor(e){super(e),this.params=e,this.baseURL="https://models.github.ai",this.colors={primary:"#24292e",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[GitHub Models]"),this.errorPrefix=g.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 j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){if(!this.params.config.key){const f=new Error("GitHub token is required for GitHub Models. Use: aicommit2 github-login");throw f.code="MISSING_TOKEN",f}const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,locale:i,generate:a,type:l,maxLength:d}=this.params.config,c={...J,locale:i,maxLength:d,type:l,generate:a,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},u=e==="review"?oe(c):re(c),m=await this.makeRequest(u,r,e);return e==="review"?this.sanitizeResponse(m):this.parseMessage(m,l,a)}async makeRequest(e,r,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"?r:`Here's the diff:
|
|
103
103
|
|
|
104
|
-
${r}`}],i=
|
|
104
|
+
${r}`}],i=Rr(s),a={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}},l=`${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;Z(r,o,"GitHub Models",s,l,d,c),ee(r,o,"GitHub Models",e,o==="review"?r:`Here's the diff:
|
|
105
105
|
|
|
106
|
-
${r}`,l),ne(r,o,"GitHub Models",a,l);const u=new AbortController,p=setTimeout(()=>u.abort(),this.params.config.timeout);try{const f=Date.now(),h=await fetch(c,{method:"POST",headers:d,body:JSON.stringify(a),signal:u.signal});if(clearTimeout(p),!h.ok){const b=await h.text(),E={status:h.status,statusText:h.statusText,url:c,headers:Object.fromEntries(h.headers),body:b};G(r,o,"GitHub Models",E,l);let k=`GitHub API request failed: ${h.status} ${h.statusText}`;try{const P=JSON.parse(b);P.error?.message?k+=` - ${P.error.message}`:P.message&&(k+=` - ${P.message}`)}catch{b&&(k+=` - ${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 $=new Error(k);throw $.status=h.status,$.code="API_ERROR",$.content=b,$}const y=await h.json(),w=Date.now()-f;V(r,o,"GitHub Models",y,l);const C=y.choices?.[0]?.message?.content?.trim();if(!C){G(r,o,"GitHub Models",{message:"No content found in GitHub Models response",result:y},l);const E=new Error("No response content received from GitHub Models");throw E.code="NO_CONTENT",E.content=JSON.stringify(y,null,2),E}return q(r,o,"GitHub Models",w,C,l),C}catch(f){if(clearTimeout(p),f instanceof Error&&f.name==="AbortError"){const w={message:`GitHub Models request timeout after ${this.params.config.timeout}ms`,error:f};G(r,o,"GitHub Models",w,l);const C=new Error(`GitHub Models request timed out after ${this.params.config.timeout}ms`);throw C.code="REQUEST_TIMEOUT",C.originalError=f,C}if(f.code)throw f;G(r,o,"GitHub Models",{message:"GitHub Models request failed",error:f},l);const y=new Error(`GitHub Models request failed: ${f instanceof Error?f.message:String(f)}`);throw y.code="REQUEST_FAILED",y.originalError=f,y}}}class fl extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#f55036",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Groq]"),this.errorPrefix=g.red.bold("[Groq]"),this.groq=new gn({apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Groq API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Groq plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Groq model name is correct":r.includes("overloaded")||r.includes("capacity")?"Groq service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Groq model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Groq model configuration":r.includes("500")||r.includes("Internal Server Error")?"Groq server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,temperature:c,generate:d,type:l,maxLength:u}=this.params.config,p=this.params.config.maxTokens,f={...J,locale:a,maxLength:u,type:l,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},h=e==="review"?se(f):oe(f),y=`Here is the diff: ${r}`,C=`${this.params.config.url||"https://api.groq.com"}/openai/v1/chat/completions`,b={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};ee(r,e,"Groq",this.params.config.model,C,b,i),te(r,e,"Groq",h,y,i);const E={messages:[{role:"system",content:h},{role:"user",content:y}],model:this.params.config.model,max_tokens:p,top_p:this.params.config.topP,temperature:c};ne(r,e,"Groq",E,i);const k=Date.now();try{const $=await this.groq.chat.completions.create(E,{timeout:this.params.config.timeout}),P=Date.now()-k,O=$.choices[0].message.content||"";return V(r,e,"Groq",$,i),q(r,e,"Groq",P,O,i),e==="review"?this.sanitizeResponse(O):this.parseMessage(O,l,d)}catch($){throw G(r,e,"Groq",$,i),$}}}class hl extends re{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=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=g.red.bold("[HuggingFace]"),this.cookie=this.params.config.cookie;const r=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:r,"Referrer-Policy":"strict-origin-when-cross-origin"}}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("cookie")||r.includes("Cookie")?"Invalid cookie. Check your Hugging Face session cookie in configuration":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Hugging Face model name is correct":r.includes("conversation")||r.includes("conversion")?"Failed to create conversation. Try again or check your session":r.includes("401")||r.includes("Unauthorized")?"Authentication failed. Your Hugging Face session may have expired":r.includes("403")||r.includes("Forbidden")?"Access denied. You may not have permission to access this model":r.includes("404")||r.includes("Not Found")?"Model not found. Check your Hugging Face model configuration":r.includes("500")||r.includes("Internal Server Error")?"Hugging Face server error. Try again later":r.includes("overloaded")||r.includes("capacity")?"Hugging Face service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){await this.initialize();const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l,temperature:u,maxTokens:p,topP:f,timeout:h}=this.params.config,y={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?se(y):oe(y),C=`Here is the diff: ${r}`,E=`${this.params.config.url||"https://huggingface.co"}/chat/conversation`,k={...this.headers,cookie:this.cookie};ee(r,e,"HuggingFace",this.params.config.model,E,k,i),te(r,e,"HuggingFace",w,C,i);const $=Date.now();try{const P=await this.getNewChat(w),S=await(await this.sendMessage(C,P.id)).completeResponsePromise();await this.deleteConversation(P.id);const U=Date.now()-$;return V(r,e,"HuggingFace",{response:S},i),q(r,e,"HuggingFace",U,S,i),e==="review"?this.sanitizeResponse(S):this.parseMessage(S,d,c)}catch(P){throw G(r,e,"HuggingFace",P,i),P}}async initialize(){const e=await this.getRemoteLlms(),r=e.find(o=>o.name?.toLowerCase()===this.params.config.model.toLowerCase());if(r){this.currentModel=r,this.currentModelId=r.id;return}this.currentModel=e[0],this.currentModelId=e[0].id}async getRemoteLlms(){const e=this.params.config.url||"https://huggingface.co",r=await fetch(`${e}/chat/__data.json`,{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if(r.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${r.status}`);const s=(await r.json()).nodes[0].data,n=s[s[0].models],i=[],a=c=>c===-1?null:s[c];for(const c of n){const d=s[c];if(s[d.unlisted])continue;const l={id:a(d.id),name:a(d.name),displayName:a(d.displayName),preprompt:a(d.preprompt),promptExamples:[],websiteUrl:a(d.websiteUrl),description:a(d.description),datasetName:a(d.datasetName),datasetUrl:a(d.datasetUrl),modelUrl:a(d.modelUrl),parameters:{}},u=a(d.promptExamples);if(u!==null){const h=u.map(y=>a(y));l.promptExamples=h.map(y=>({title:s[y.title],prompt:s[y.prompt]}))}const p=a(d.parameters),f={};for(const[h,y]of Object.entries(p)){if(y===-1){f[h]=null;continue}if(Array.isArray(s[y])){f[h]=s[y].map(w=>s[w]);continue}f[h]=s[y]}l.parameters=f,i.push(l)}return this.models=i,i}async getNewChat(e){const r={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(r),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 r=this.params.config.url||"https://huggingface.co",o=await fetch(`${r}/chat/conversation/${e}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:`${r}/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,r){const o={id:"",model:"",systemPrompt:"",title:"",history:[]},s=e.nodes[1].data,n=s[s[0].model],i=s[s[0].preprompt],a=s[s[0].title],c=s[s[0].messages],d=[];for(const l of c){const u=s[l],p=new Date(s[u.createdAt][1]).getTime()/1e3,f=new Date(s[u.updatedAt][1]).getTime()/1e3;d.push({id:s[u.id],role:s[u.from],content:s[u.content],createdAt:p,updatedAt:f})}return o.id=r,o.model=n,o.systemPrompt=i,o.title=a,o.history=d,this.currentConversation=o,o}async sendMessage(e,r){if(e==="")throw new Error("the prompt can not be empty.");if(!r&&!this.currentConversionID?await this.getNewChat():r?(this.currentConversionID=r,await this.getConversationHistory(r)):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,a=setTimeout(()=>i.abort(),this.params.config.timeout),c=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(a);function d(y){try{const w=y.split(`
|
|
107
|
-
`),C=[];for(const b of w)b.trim()&&C.push(JSON.parse(b));return C}catch{return[{}]}}const l=new TextDecoder;let u="";const p=new TransformStream({async transform(y,w){const C=l.decode(y);try{const b=d(C);for(const E of b)E.type==="finalAnswer"?(u=E?.text||"",w.terminate()):E.type==="stream"&&w.enqueue(E?.token||"")}catch{throw new Error("Error during parsing response")}}}),f=c.body?.pipeThrough(p);async function h(){return new Promise(async(y,w)=>{try{if(!f)w("ModifiedStream undefined");else{const C=f.getReader();for(;;){const{done:b,value:E}=await C.read();if(b){y(u);break}}}}catch(C){w(C)}})}return{id:this.currentConversionID,stream:f,completeResponsePromise:h}}async deleteConversation(e){const r=this.params.config.url||"https://huggingface.co";return(await fetch(`${r}/chat/conversation/${e}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${r}/chat/`},body:null,method:"DELETE"})).json()}}class gl extends re{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#ff7000",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=g.red.bold("[MistralAI]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Mistral AI API key in configuration":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your Mistral AI usage limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Mistral model name is correct":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Mistral model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Mistral model configuration":r.includes("500")||r.includes("Internal Server Error")?"Mistral AI server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l}=this.params.config,u={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},p=e==="review"?se(u):oe(u);await this.checkAvailableModels();const f=`Here is the diff: ${r}`,y=`${this.params.config.url||"https://api.mistral.ai"}/v1/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};ee(r,e,"MistralAI",this.params.config.model,y,w,i),te(r,e,"MistralAI",p,f,i);const C=await this.createChatCompletions(p,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,c)}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 Ne({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,r,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:r}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:wt(10,1e3)};ne(s,o,"MistralAI",i,n);const a=Date.now();try{const c=this.params.config.url||"https://api.mistral.ai",d=await new Ne({method:"POST",baseURL:`${c}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),l=Date.now()-a,u=d.data;if(V(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 f=u.choices[0].message.content;return q(s,o,"MistralAI",l,f,n),f}catch(c){throw G(s,o,"MistralAI",c,n),c}}}class yl extends re{constructor(e){super(e),this.params=e,this.host=bt,this.model="",this.key="",this.auth="",this.setupFetch=(r,o={})=>wn(r,{...o,dispatcher:new vn({headersTimeout:this.params.config.timeout})}),this.colors={primary:"#FFF",secondary:"#000"},this.model=this.params.keyName,this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${yt(this.model)}]`),this.errorPrefix=g.red.bold(`[${yt(this.model)}]`),this.host=this.params.config.host||bt,this.auth=this.params.config.auth||"Bearer",this.key=this.params.config.key||"",this.ollama=new yn({host:this.host,fetch:this.setupFetch,...this.key&&{headers:{Authorization:`${this.auth} ${this.key}`}}})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("ECONNREFUSED")||r.includes("connection refused")?ie.ollamaNotRunning():r.includes("model")&&(r.includes("not found")||r.includes("404"))?ie.ollamaModelNotPulled(this.model):null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l}=this.params.config,u={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},p=e==="review"?se(u):oe(u);await this.checkIsAvailableOllama();const f=`Here is the diff: ${r}`,h=`Ollama_${this.model}`,y=`${this.host}/api/chat`,w=this.key?{Authorization:`${this.auth} ${this.key}`}:{};ee(r,e,h,this.model,y,w,i),te(r,e,h,p,f,i);const C=await this.createChatCompletions(p,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,c)}async checkIsAvailableOllama(){const e=new Ne({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,r,o){const{stream:s,numCtx:n,temperature:i,topP:a,timeout:c,maxTokens:d,logging:l}=this.params.config,u=s||!1,p=this.params.stagedDiff.diff,f=`Ollama_${this.model}`,h={model:this.model,messages:[{role:"system",content:e},{role:"user",content:r}],stream:u,keep_alive:c,options:{num_ctx:n,temperature:i,top_p:a,seed:wt(10,1e3),num_predict:d??-1}};ne(p,o,f,h,l);const y=Date.now();try{const w=await this.ollama.chat(h),C=Date.now()-y;let b="";if(u){if(w)for await(const E of w)b+=E.message.content}else b=w.message.content;return V(p,o,f,{response:b,fullResponse:w},l),q(p,o,f,C,b,l),b}catch(w){throw G(p,o,f,w,l),w}}}class wl extends re{constructor(e){super(e),this.params=e,this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=g.red.bold("[ChatGPT]")}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")?"Invalid API key. Check your OpenAI API key in configuration":r.includes("quota")?"API quota exceeded. Check your OpenAI usage limits":r.includes("500")?"OpenAI server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}extractJSONFromError(e){const r=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(r);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,temperature:i,logging:a,locale:c,generate:d,type:l,maxLength:u,proxy:p,maxTokens:f,timeout:h}=this.params.config,y={...J,locale:c,maxLength:u,type:l,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?se(y):oe(y),C=await tl("ChatGPT",this.params.config.url,this.params.config.path,this.params.config.key,this.params.config.model,r,h,f,i,this.params.config.topP,w,a,e,p);return vt(e==="review"?C.map(b=>this.sanitizeResponse(b)):C.map(b=>this.parseMessage(b,l,d)))}}class vl extends re{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#20808D",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Perplexity]"),this.errorPrefix=g.red.bold("[Perplexity]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Perplexity API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Perplexity plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Perplexity model name is correct":r.includes("overloaded")||r.includes("capacity")?"Perplexity service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Perplexity model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Perplexity model configuration":r.includes("500")||r.includes("Internal Server Error")?"Perplexity server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}extractJSONFromError(e){const r=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(r);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:c,type:d,maxLength:l}=this.params.config,u={...J,locale:a,maxLength:l,type:d,generate:c,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},p=e==="review"?se(u):oe(u),f=`Here is the diff: ${r}`,y=`${this.params.config.url||"https://api.perplexity.ai"}/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};ee(r,e,"Perplexity",this.params.config.model,y,w,i),te(r,e,"Perplexity",p,f,i);const C=await this.createChatCompletions(p,f,e);return this.parseMessage(C,d,c)}async createChatCompletions(e,r,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:r}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1};ne(s,o,"Perplexity",i,n);const a=Date.now();try{const c=this.params.config.url||"https://api.perplexity.ai",d=await new Ne({method:"POST",baseURL:`${c}/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),l=Date.now()-a,u=d.data;if(V(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 f=u.choices[0].message.content;return q(s,o,"Perplexity",l,f,n),f}catch(c){throw G(s,o,"Perplexity",c,n),c}}}const Cl="stats.json",It=1,bl=30,Rr=()=>M.join(as,Cl),Or=async()=>{const t=Rr();if(!await gt(t))return{version:It,metrics:[]};try{const e=await D.readFile(t,"utf-8"),r=JSON.parse(e);return!r.version||r.version<It?{version:It,metrics:r.metrics||[]}:r}catch{return{version:It,metrics:[]}}},El=async t=>{const e=Rr(),r=M.dirname(e);await D.mkdir(r,{recursive:!0}),await D.writeFile(e,JSON.stringify(t,null,2),"utf-8")},Is=async t=>{const e={timestamp:Date.now(),provider:t.provider,model:t.model,responseTimeMs:t.responseTimeMs,success:t.success,errorCode:t.errorCode,tokensUsed:t.tokensUsed},r=await Or();r.metrics.push(e),await El(r)},$l=(t,e)=>{const r=e.filter(n=>n.provider===t);if(r.length===0)return{provider:t,totalRequests:0,successCount:0,failureCount:0,avgResponseTimeMs:0,minResponseTimeMs:0,maxResponseTimeMs:0};const o=r.filter(n=>n.success),s=r.map(n=>n.responseTimeMs);return{provider:t,totalRequests:r.length,successCount:o.length,failureCount:r.length-o.length,avgResponseTimeMs:Math.round(s.reduce((n,i)=>n+i,0)/s.length),minResponseTimeMs:Math.min(...s),maxResponseTimeMs:Math.max(...s)}},Pl=async(t=bl)=>{const e=await Or(),r=Date.now()-t*24*60*60*1e3,o=e.metrics.filter(c=>c.timestamp>=r);if(o.length===0)return{totalRequests:0,successRate:0,avgResponseTimeMs:0,providerStats:[],periodStart:r,periodEnd:Date.now()};const n=[...new Set(o.map(c=>c.provider))].map(c=>$l(c,o)).sort((c,d)=>d.totalRequests-c.totalRequests),i=o.filter(c=>c.success).length,a=o.reduce((c,d)=>c+d.responseTimeMs,0);return{totalRequests:o.length,successRate:Math.round(i/o.length*1e3)/10,avgResponseTimeMs:Math.round(a/o.length),providerStats:n,periodStart:Math.min(...o.map(c=>c.timestamp)),periodEnd:Math.max(...o.map(c=>c.timestamp))}},Al=async()=>{const t=Rr();await gt(t)&&await D.unlink(t)},Sl=async()=>(await Or()).metrics.length>0,Ms=(t,e)=>{const r=g.red.bold(`[${t}]`);return Xr({name:`${r} ${e}`,value:e,isError:!0,disabled:!0})};class kl{constructor(){this.providers=new Map,this.register=(e,r)=>{this.providers.set(e,r)},this.has=e=>this.providers.has(e),this.createService=(e,r)=>{const o=this.providers.get(e);return o?new o(r):null},this.createRequest$=(e,r,o)=>{const s=this.createService(e,r);if(!s)return Ms(e,"Invalid AI type");const n=Date.now(),i=Array.isArray(r.config.model)?r.config.model[0]:r.config.model;let a=!1;return(o==="commit"?s.generateCommitMessage$():s.generateCodeReview$()).pipe(Qr({next:d=>{if(a)return;a=!0;const l=d.isError===!0;Is({provider:e,model:i||"unknown",responseTimeMs:Date.now()-n,success:!l,errorCode:l?"REQUEST_ERROR":void 0}).catch(()=>{})}}))},this.getRegisteredProviders=()=>Array.from(this.providers.keys()),this.registerBuiltinProviders=()=>{this.register("OPENAI",wl),this.register("GEMINI",ml),this.register("ANTHROPIC",il),this.register("HUGGINGFACE",hl),this.register("MISTRAL",gl),this.register("CODESTRAL",ll),this.register("OLLAMA",yl),this.register("COHERE",ul),this.register("GROQ",fl),this.register("PERPLEXITY",vl),this.register("BEDROCK",cl),this.register("GITHUB_MODELS",pl),this.register("DEEPSEEK",dl)},this.registerBuiltinProviders()}}const Il=new kl;class Mt{constructor(e,r,o=""){this.config=e,this.stagedDiff=r,this.branchName=o,this.extractProviderName=s=>{if(!s)return"compatible";try{return new URL(s).hostname}catch{return"compatible"}},this.createCommitMsgRequests$=s=>this.createServiceRequests$(s,"commit"),this.createCodeReviewRequests$=s=>this.createServiceRequests$(s,"review"),this.createServiceRequests$=(s,n)=>N(s).pipe(Zr(i=>this.createProviderRequests$(i,n)),L(i=>Ms("UNKNOWN",i.message||"Unknown error"))),this.createProviderRequests$=(s,n)=>{const i=this.config[s],a=Array.isArray(i.model)?i.model:[i.model];return N(a).pipe(Zr(c=>this.createModelRequest$(s,c,n)))},this.createModelRequest$=(s,n,i)=>{const a=this.config[s];return a.compatible?this.createCompatibleServiceRequest$(a,n,i):Il.createRequest$(s,{config:{...a,model:n},stagedDiff:this.stagedDiff,keyName:n,branchName:this.branchName},i)},this.createCompatibleServiceRequest$=(s,n,i)=>{const a=mc.create(rl,{config:{...s,url:s.url||"",path:s.path||"",model:n},stagedDiff:this.stagedDiff,keyName:n,branchName:this.branchName}),c=Date.now(),d=this.extractProviderName(s.url);let l=!1;return(i==="commit"?a.generateCommitMessage$():a.generateCodeReview$()).pipe(Qr({next:p=>{if(l)return;l=!0;const f=p.isError===!0;Is({provider:d,model:n,responseTimeMs:Date.now()-c,success:!f,errorCode:f?"REQUEST_ERROR":void 0}).catch(()=>{})}}))}}}class Dr{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 xt extends Dr{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 I("git",["rev-parse","--show-toplevel"],{reject:!0});return e.trim()}catch(e){const r=e;if(r.code==="ENOENT")throw new v(`Git command not found!
|
|
106
|
+
${r}`,c),se(r,o,"GitHub Models",a,c);const u=new AbortController,m=setTimeout(()=>u.abort(),this.params.config.timeout);try{const f=Date.now(),h=await fetch(l,{method:"POST",headers:d,body:JSON.stringify(a),signal:u.signal});if(clearTimeout(m),!h.ok){const b=await h.text(),E={status:h.status,statusText:h.statusText,url:l,headers:Object.fromEntries(h.headers),body:b};G(r,o,"GitHub Models",E,c);let k=`GitHub API request failed: ${h.status} ${h.statusText}`;try{const P=JSON.parse(b);P.error?.message?k+=` - ${P.error.message}`:P.message&&(k+=` - ${P.message}`)}catch{b&&(k+=` - ${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 $=new Error(k);throw $.status=h.status,$.code="API_ERROR",$.content=b,$}const y=await h.json(),w=Date.now()-f;V(r,o,"GitHub Models",y,c);const C=y.choices?.[0]?.message?.content?.trim();if(!C){G(r,o,"GitHub Models",{message:"No content found in GitHub Models response",result:y},c);const E=new Error("No response content received from GitHub Models");throw E.code="NO_CONTENT",E.content=JSON.stringify(y,null,2),E}return q(r,o,"GitHub Models",w,C,c),C}catch(f){if(clearTimeout(m),f instanceof Error&&f.name==="AbortError"){const w={message:`GitHub Models request timeout after ${this.params.config.timeout}ms`,error:f};G(r,o,"GitHub Models",w,c);const C=new Error(`GitHub Models request timed out after ${this.params.config.timeout}ms`);throw C.code="REQUEST_TIMEOUT",C.originalError=f,C}if(f.code)throw f;G(r,o,"GitHub Models",{message:"GitHub Models request failed",error:f},c);const y=new Error(`GitHub Models request failed: ${f instanceof Error?f.message:String(f)}`);throw y.code="REQUEST_FAILED",y.originalError=f,y}}}class yl extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#f55036",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Groq]"),this.errorPrefix=g.red.bold("[Groq]"),this.groq=new vn({apiKey:this.params.config.key})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Groq API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Groq plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Groq model name is correct":r.includes("overloaded")||r.includes("capacity")?"Groq service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Groq model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Groq model configuration":r.includes("500")||r.includes("Internal Server Error")?"Groq server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,temperature:l,generate:d,type:c,maxLength:u}=this.params.config,m=this.params.config.maxTokens,f={...J,locale:a,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},h=e==="review"?oe(f):re(f),y=`Here is the diff: ${r}`,C=`${this.params.config.url||"https://api.groq.com"}/openai/v1/chat/completions`,b={Authorization:`Bearer ${this.params.config.key}`,"Content-Type":"application/json"};Z(r,e,"Groq",this.params.config.model,C,b,i),ee(r,e,"Groq",h,y,i);const E={messages:[{role:"system",content:h},{role:"user",content:y}],model:this.params.config.model,max_tokens:m,top_p:this.params.config.topP,temperature:l};se(r,e,"Groq",E,i);const k=Date.now();try{const $=await this.groq.chat.completions.create(E,{timeout:this.params.config.timeout}),P=Date.now()-k,O=$.choices[0].message.content||"";return V(r,e,"Groq",$,i),q(r,e,"Groq",P,O,i),e==="review"?this.sanitizeResponse(O):this.parseMessage(O,c,d)}catch($){throw G(r,e,"Groq",$,i),$}}}class wl extends te{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=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[HuggingFace]"),this.errorPrefix=g.red.bold("[HuggingFace]"),this.cookie=this.params.config.cookie;const r=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:r,"Referrer-Policy":"strict-origin-when-cross-origin"}}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("cookie")||r.includes("Cookie")?"Invalid cookie. Check your Hugging Face session cookie in configuration":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Hugging Face model name is correct":r.includes("conversation")||r.includes("conversion")?"Failed to create conversation. Try again or check your session":r.includes("401")||r.includes("Unauthorized")?"Authentication failed. Your Hugging Face session may have expired":r.includes("403")||r.includes("Forbidden")?"Access denied. You may not have permission to access this model":r.includes("404")||r.includes("Not Found")?"Model not found. Check your Hugging Face model configuration":r.includes("500")||r.includes("Internal Server Error")?"Hugging Face server error. Try again later":r.includes("overloaded")||r.includes("capacity")?"Hugging Face service is overloaded. Try again in a few minutes":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){await this.initialize();const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c,temperature:u,maxTokens:m,topP:f,timeout:h}=this.params.config,y={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?oe(y):re(y),C=`Here is the diff: ${r}`,E=`${this.params.config.url||"https://huggingface.co"}/chat/conversation`,k={...this.headers,cookie:this.cookie};Z(r,e,"HuggingFace",this.params.config.model,E,k,i),ee(r,e,"HuggingFace",w,C,i);const $=Date.now();try{const P=await this.getNewChat(w),S=await(await this.sendMessage(C,P.id)).completeResponsePromise();await this.deleteConversation(P.id);const U=Date.now()-$;return V(r,e,"HuggingFace",{response:S},i),q(r,e,"HuggingFace",U,S,i),e==="review"?this.sanitizeResponse(S):this.parseMessage(S,d,l)}catch(P){throw G(r,e,"HuggingFace",P,i),P}}async initialize(){const e=await this.getRemoteLlms(),r=e.find(o=>o.name?.toLowerCase()===this.params.config.model.toLowerCase());if(r){this.currentModel=r,this.currentModelId=r.id;return}this.currentModel=e[0],this.currentModelId=e[0].id}async getRemoteLlms(){const e=this.params.config.url||"https://huggingface.co",r=await fetch(`${e}/chat/__data.json`,{headers:{...this.headers,cookie:this.cookie},body:null,method:"GET"});if(r.status!==200)throw new Error(`Failed to get remote LLMs with status code: ${r.status}`);const s=(await r.json()).nodes[0].data,n=s[s[0].models],i=[],a=l=>l===-1?null:s[l];for(const l of n){const d=s[l];if(s[d.unlisted])continue;const c={id:a(d.id),name:a(d.name),displayName:a(d.displayName),preprompt:a(d.preprompt),promptExamples:[],websiteUrl:a(d.websiteUrl),description:a(d.description),datasetName:a(d.datasetName),datasetUrl:a(d.datasetUrl),modelUrl:a(d.modelUrl),parameters:{}},u=a(d.promptExamples);if(u!==null){const h=u.map(y=>a(y));c.promptExamples=h.map(y=>({title:s[y.title],prompt:s[y.prompt]}))}const m=a(d.parameters),f={};for(const[h,y]of Object.entries(m)){if(y===-1){f[h]=null;continue}if(Array.isArray(s[y])){f[h]=s[y].map(w=>s[w]);continue}f[h]=s[y]}c.parameters=f,i.push(c)}return this.models=i,i}async getNewChat(e){const r={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(r),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 r=this.params.config.url||"https://huggingface.co",o=await fetch(`${r}/chat/conversation/${e}/__data.json`,{headers:{...this.headers,cookie:this.cookie,Referer:`${r}/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,r){const o={id:"",model:"",systemPrompt:"",title:"",history:[]},s=e.nodes[1].data,n=s[s[0].model],i=s[s[0].preprompt],a=s[s[0].title],l=s[s[0].messages],d=[];for(const c of l){const u=s[c],m=new Date(s[u.createdAt][1]).getTime()/1e3,f=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:f})}return o.id=r,o.model=n,o.systemPrompt=i,o.title=a,o.history=d,this.currentConversation=o,o}async sendMessage(e,r){if(e==="")throw new Error("the prompt can not be empty.");if(!r&&!this.currentConversionID?await this.getNewChat():r?(this.currentConversionID=r,await this.getConversationHistory(r)):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,a=setTimeout(()=>i.abort(),this.params.config.timeout),l=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(a);function d(y){try{const w=y.split(`
|
|
107
|
+
`),C=[];for(const b of w)b.trim()&&C.push(JSON.parse(b));return C}catch{return[{}]}}const c=new TextDecoder;let u="";const m=new TransformStream({async transform(y,w){const C=c.decode(y);try{const b=d(C);for(const E of b)E.type==="finalAnswer"?(u=E?.text||"",w.terminate()):E.type==="stream"&&w.enqueue(E?.token||"")}catch{throw new Error("Error during parsing response")}}}),f=l.body?.pipeThrough(m);async function h(){return new Promise(async(y,w)=>{try{if(!f)w("ModifiedStream undefined");else{const C=f.getReader();for(;;){const{done:b,value:E}=await C.read();if(b){y(u);break}}}}catch(C){w(C)}})}return{id:this.currentConversionID,stream:f,completeResponsePromise:h}}async deleteConversation(e){const r=this.params.config.url||"https://huggingface.co";return(await fetch(`${r}/chat/conversation/${e}`,{headers:{...this.headers,cookie:this.cookie,Referer:`${r}/chat/`},body:null,method:"DELETE"})).json()}}class vl extends te{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#ff7000",secondary:"#fff"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[MistralAI]"),this.errorPrefix=g.red.bold("[MistralAI]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Mistral AI API key in configuration":r.includes("quota")||r.includes("usage")?"API quota exceeded. Check your Mistral AI usage limits":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Mistral model name is correct":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Mistral model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Mistral model configuration":r.includes("500")||r.includes("Internal Server Error")?"Mistral AI server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c}=this.params.config,u={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},m=e==="review"?oe(u):re(u);await this.checkAvailableModels();const f=`Here is the diff: ${r}`,y=`${this.params.config.url||"https://api.mistral.ai"}/v1/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};Z(r,e,"MistralAI",this.params.config.model,y,w,i),ee(r,e,"MistralAI",m,f,i);const C=await this.createChatCompletions(m,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,l)}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 Te({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,r,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:r}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1,safe_prompt:!1,random_seed:vt(10,1e3)};se(s,o,"MistralAI",i,n);const a=Date.now();try{const l=this.params.config.url||"https://api.mistral.ai",d=await new Te({method:"POST",baseURL:`${l}/v1/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),c=Date.now()-a,u=d.data;if(V(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 f=u.choices[0].message.content;return q(s,o,"MistralAI",c,f,n),f}catch(l){throw G(s,o,"MistralAI",l,n),l}}}class Cl extends te{constructor(e){super(e),this.params=e,this.host=Et,this.model="",this.key="",this.auth="",this.setupFetch=(r,o={})=>bn(r,{...o,dispatcher:new En({headersTimeout:this.params.config.timeout})}),this.colors={primary:"#FFF",secondary:"#000"},this.model=this.params.keyName,this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold(`[${wt(this.model)}]`),this.errorPrefix=g.red.bold(`[${wt(this.model)}]`),this.host=this.params.config.host||Et,this.auth=this.params.config.auth||"Bearer",this.key=this.params.config.key||"",this.ollama=new Cn({host:this.host,fetch:this.setupFetch,...this.key&&{headers:{Authorization:`${this.auth} ${this.key}`}}})}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("ECONNREFUSED")||r.includes("connection refused")?ne.ollamaNotRunning():r.includes("model")&&(r.includes("not found")||r.includes("404"))?ne.ollamaModelNotPulled(this.model):null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c}=this.params.config,u={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},m=e==="review"?oe(u):re(u);await this.checkIsAvailableOllama();const f=`Here is the diff: ${r}`,h=`Ollama_${this.model}`,y=`${this.host}/api/chat`,w=this.key?{Authorization:`${this.auth} ${this.key}`}:{};Z(r,e,h,this.model,y,w,i),ee(r,e,h,m,f,i);const C=await this.createChatCompletions(m,f,e);return e==="review"?this.sanitizeResponse(C):this.parseMessage(C,d,l)}async checkIsAvailableOllama(){const e=new Te({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,r,o){const{stream:s,numCtx:n,temperature:i,topP:a,timeout:l,maxTokens:d,logging:c}=this.params.config,u=s||!1,m=this.params.stagedDiff.diff,f=`Ollama_${this.model}`,h={model:this.model,messages:[{role:"system",content:e},{role:"user",content:r}],stream:u,keep_alive:l,options:{num_ctx:n,temperature:i,top_p:a,seed:vt(10,1e3),num_predict:d??-1}};se(m,o,f,h,c);const y=Date.now();try{const w=await this.ollama.chat(h),C=Date.now()-y;let b="";if(u){if(w)for await(const E of w)b+=E.message.content}else b=w.message.content;return V(m,o,f,{response:b,fullResponse:w},c),q(m,o,f,C,b,c),b}catch(w){throw G(m,o,f,w,c),w}}}class bl extends te{constructor(e){super(e),this.params=e,this.colors={primary:"#74AA9C",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[ChatGPT]"),this.errorPrefix=g.red.bold("[ChatGPT]")}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")?"Invalid API key. Check your OpenAI API key in configuration":r.includes("quota")?"API quota exceeded. Check your OpenAI usage limits":r.includes("500")?"OpenAI server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}extractJSONFromError(e){const r=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(r);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,temperature:i,logging:a,locale:l,generate:d,type:c,maxLength:u,proxy:m,maxTokens:f,timeout:h}=this.params.config,y={...J,locale:l,maxLength:u,type:c,generate:d,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},w=e==="review"?oe(y):re(y),C=await sl("ChatGPT",this.params.config.url,this.params.config.path,this.params.config.key,this.params.config.model,r,h,f,i,this.params.config.topP,w,a,e,m);return Ct(e==="review"?C.map(b=>this.sanitizeResponse(b)):C.map(b=>this.parseMessage(b,c,d)))}}class El extends te{constructor(e){super(e),this.params=e,this.apiKey="",this.colors={primary:"#20808D",secondary:"#FFF"},this.serviceName=g.bgHex(this.colors.primary).hex(this.colors.secondary).bold("[Perplexity]"),this.errorPrefix=g.red.bold("[Perplexity]"),this.apiKey=this.params.config.key}getServiceSpecificErrorMessage(e){const r=e.message||"";return r.includes("API key")||r.includes("api_key")?"Invalid API key. Check your Perplexity API key in configuration":r.includes("rate_limit")||r.includes("Rate limit")?"Rate limit exceeded. Wait a moment and try again, or upgrade your Perplexity plan":r.includes("model")||r.includes("Model")?"Model not found or not accessible. Check if the Perplexity model name is correct":r.includes("overloaded")||r.includes("capacity")?"Perplexity service is overloaded. Try again in a few minutes":r.includes("403")||r.includes("Forbidden")?"Access denied. Your API key may not have permission for this Perplexity model":r.includes("404")||r.includes("Not Found")?"Model or endpoint not found. Check your Perplexity model configuration":r.includes("500")||r.includes("Internal Server Error")?"Perplexity server error. Try again later":null}generateCommitMessage$(){return j(this.generateMessage("commit")).pipe(F(e=>N(e)),T(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})),L(this.handleError$))}generateCodeReview$(){return j(this.generateMessage("review")).pipe(F(e=>N(e)),T(e=>({name:`${this.serviceName} ${e.title}`,short:e.title,value:e.value,description:e.value,isError:!1})),L(this.handleError$))}extractJSONFromError(e){const r=/[{[]{1}([,:{}[\]0-9.\-+Eaeflnr-u \n\r\t]|".*?")+[}\]]{1}/gis,o=e.match(r);return o?Object.assign({},...o.map(s=>JSON.parse(s))):{error:{message:"Unknown error"}}}async generateMessage(e){const r=this.params.stagedDiff.diff,{systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,logging:i,locale:a,generate:l,type:d,maxLength:c}=this.params.config,u={...J,locale:a,maxLength:c,type:d,generate:l,systemPrompt:o,systemPromptPath:s,codeReviewPromptPath:n,vcs_branch:this.params.branchName||""},m=e==="review"?oe(u):re(u),f=`Here is the diff: ${r}`,y=`${this.params.config.url||"https://api.perplexity.ai"}/chat/completions`,w={Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"};Z(r,e,"Perplexity",this.params.config.model,y,w,i),ee(r,e,"Perplexity",m,f,i);const C=await this.createChatCompletions(m,f,e);return this.parseMessage(C,d,l)}async createChatCompletions(e,r,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:r}],temperature:this.params.config.temperature,top_p:this.params.config.topP,max_tokens:this.params.config.maxTokens,stream:!1};se(s,o,"Perplexity",i,n);const a=Date.now();try{const l=this.params.config.url||"https://api.perplexity.ai",d=await new Te({method:"POST",baseURL:`${l}/chat/completions`,timeout:this.params.config.timeout}).setHeaders({Authorization:`Bearer ${this.apiKey}`,"content-type":"application/json"}).setBody(i).execute(),c=Date.now()-a,u=d.data;if(V(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 f=u.choices[0].message.content;return q(s,o,"Perplexity",c,f,n),f}catch(l){throw G(s,o,"Perplexity",l,n),l}}}const $l="stats.json",Mt=2,Pl=30,Or=()=>M.join(cs,$l),xt=async()=>{const t=Or();if(!await yt(t))return{version:Mt,metrics:[],selections:[]};try{const e=await D.readFile(t,"utf-8"),r=JSON.parse(e);return!r.version||r.version<Mt?{version:Mt,metrics:r.metrics||[],selections:r.selections||[]}:r}catch{return{version:Mt,metrics:[],selections:[]}}},Al=(t,e)=>{const r=Date.now()-e*24*60*60*1e3;return{version:t.version,metrics:t.metrics.filter(o=>o.timestamp>=r),selections:t.selections.filter(o=>o.timestamp>=r)}},Ms=async(t,e)=>{const r=Or(),o=M.dirname(r),s=e?Al(t,e):t;await D.mkdir(o,{recursive:!0}),await D.writeFile(r,JSON.stringify(s,null,2),"utf-8")},xs=async t=>{const e={timestamp:Date.now(),provider:t.provider,model:t.model,responseTimeMs:t.responseTimeMs,success:t.success,errorCode:t.errorCode,tokensUsed:t.tokensUsed},r=await xt();r.metrics.push(e),await Ms(r,t.statsDays)},Sl=async t=>{const e={timestamp:Date.now(),provider:t.provider,model:t.model},r=await xt();r.selections.push(e),await Ms(r,t.statsDays)},kl=(t,e,r)=>{const o=e.filter(d=>d.provider===t),s=r.filter(d=>d.provider===t);if(o.length===0)return{provider:t,totalRequests:0,successCount:0,failureCount:0,selectedCount:s.length,selectionRate:0,avgResponseTimeMs:0,minResponseTimeMs:0,maxResponseTimeMs:0};const n=o.filter(d=>d.success),i=o.map(d=>d.responseTimeMs),a=s.length,l=n.length>0?Math.min(100,Math.round(a/n.length*1e3)/10):0;return{provider:t,totalRequests:o.length,successCount:n.length,failureCount:o.length-n.length,selectedCount:a,selectionRate:l,avgResponseTimeMs:Math.round(i.reduce((d,c)=>d+c,0)/i.length),minResponseTimeMs:Math.min(...i),maxResponseTimeMs:Math.max(...i)}},Il=async(t=Pl)=>{const e=await xt(),r=Date.now()-t*24*60*60*1e3,o=e.metrics.filter(d=>d.timestamp>=r),s=e.selections.filter(d=>d.timestamp>=r);if(o.length===0)return{totalRequests:0,successRate:0,avgResponseTimeMs:0,providerStats:[],periodStart:r,periodEnd:Date.now()};const i=[...new Set(o.map(d=>d.provider))].map(d=>kl(d,o,s)).sort((d,c)=>c.totalRequests-d.totalRequests),a=o.filter(d=>d.success).length,l=o.reduce((d,c)=>d+c.responseTimeMs,0);return{totalRequests:o.length,successRate:Math.round(a/o.length*1e3)/10,avgResponseTimeMs:Math.round(l/o.length),providerStats:i,periodStart:Math.min(...o.map(d=>d.timestamp)),periodEnd:Math.max(...o.map(d=>d.timestamp))}},Ml=async()=>{const t=Or();await yt(t)&&await D.unlink(t)},xl=async()=>(await xt()).metrics.length>0,Rs=(t,e)=>{const r=g.red.bold(`[${t}]`);return Qr({name:`${r} ${e}`,value:e,isError:!0,disabled:!0})};class Rl{constructor(){this.providers=new Map,this.register=(e,r)=>{this.providers.set(e,r)},this.has=e=>this.providers.has(e),this.createService=(e,r)=>{const o=this.providers.get(e);return o?new o(r):null},this.createRequest$=(e,r,o)=>{const s=this.createService(e,r);if(!s)return Rs(e,"Invalid AI type");const n=Date.now(),i=Array.isArray(r.config.model)?r.config.model[0]:r.config.model;let a=!1;return(o==="commit"?s.generateCommitMessage$():s.generateCodeReview$()).pipe(Zr({next:d=>{if(Object.assign(d,{provider:e,model:i||"unknown"}),r.statsEnabled===!1||a)return;a=!0;const c=d.isError===!0;xs({provider:e,model:i||"unknown",responseTimeMs:Date.now()-n,success:!c,errorCode:c?"REQUEST_ERROR":void 0,statsDays:r.statsDays}).catch(()=>{})}}))},this.getRegisteredProviders=()=>Array.from(this.providers.keys()),this.registerBuiltinProviders=()=>{this.register("OPENAI",bl),this.register("GEMINI",hl),this.register("ANTHROPIC",ll),this.register("HUGGINGFACE",wl),this.register("MISTRAL",vl),this.register("CODESTRAL",ml),this.register("OLLAMA",Cl),this.register("COHERE",pl),this.register("GROQ",yl),this.register("PERPLEXITY",El),this.register("BEDROCK",dl),this.register("GITHUB_MODELS",gl),this.register("DEEPSEEK",fl)},this.registerBuiltinProviders()}}const Ol=new Rl;class Rt{constructor(e,r,o=""){this.config=e,this.stagedDiff=r,this.branchName=o,this.extractProviderName=s=>{if(!s)return"compatible";try{return new URL(s).hostname}catch{return"compatible"}},this.createCommitMsgRequests$=s=>this.createServiceRequests$(s,"commit"),this.createCodeReviewRequests$=s=>this.createServiceRequests$(s,"review"),this.createServiceRequests$=(s,n)=>N(s).pipe(eo(i=>this.createProviderRequests$(i,n)),L(i=>Rs("UNKNOWN",i.message||"Unknown error"))),this.createProviderRequests$=(s,n)=>{const i=this.config[s],a=Array.isArray(i.model)?i.model:[i.model];return N(a).pipe(eo(l=>this.createModelRequest$(s,l,n)))},this.createModelRequest$=(s,n,i)=>{const a=this.config[s];return a.compatible?this.createCompatibleServiceRequest$(a,n,i):Ol.createRequest$(s,{config:{...a,model:n},stagedDiff:this.stagedDiff,keyName:n,branchName:this.branchName,statsEnabled:this.config.useStats,statsDays:this.config.statsDays},i)},this.createCompatibleServiceRequest$=(s,n,i)=>{const a=hc.create(nl,{config:{...s,url:s.url||"",path:s.path||"",model:n},stagedDiff:this.stagedDiff,keyName:n,branchName:this.branchName}),l=Date.now(),d=this.extractProviderName(s.url);let c=!1;return(i==="commit"?a.generateCommitMessage$():a.generateCodeReview$()).pipe(Zr({next:m=>{if(Object.assign(m,{provider:d,model:n}),this.config.useStats===!1||c)return;c=!0;const f=m.isError===!0;xs({provider:d,model:n,responseTimeMs:Date.now()-l,success:!f,errorCode:f?"REQUEST_ERROR":void 0,statsDays:this.config.statsDays}).catch(()=>{})}}))}}}class Dr{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 Ot extends Dr{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 I("git",["rev-parse","--show-toplevel"],{reject:!0});return e.trim()}catch(e){const r=e;if(r.code==="ENOENT")throw new v(`Git command not found!
|
|
108
108
|
|
|
109
109
|
Please install Git first: https://git-scm.com/downloads`);if(r.stderr){if(r.stderr.includes("not a git repository"))throw new v(`Not in a Git repository!
|
|
110
110
|
|
|
@@ -112,18 +112,18 @@ Initialize with: git init
|
|
|
112
112
|
Or navigate to an existing Git repository.`);if(r.stderr.includes("permission denied"))throw new v(`Git permission denied: ${r.stderr.trim()}
|
|
113
113
|
|
|
114
114
|
Check file permissions and repository access.`)}throw new v(`Failed to verify Git repository: ${r.message||"Unknown error"}`)}}async getStagedDiff(e,r){const o=["diff","--cached","--diff-algorithm=minimal"],{stdout:s}=await I("git",[...o,"--name-only",...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]);if(!s)return null;const{stdout:n}=await I("git",[...o,...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),i=s.split(`
|
|
115
|
-
`).filter(Boolean),{stdout:a}=await I("git",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),
|
|
116
|
-
`).filter(Boolean);for(const
|
|
115
|
+
`).filter(Boolean),{stdout:a}=await I("git",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),l=[],d=a.split(`
|
|
116
|
+
`).filter(Boolean);for(const m of d){const f=m.split(" ");f[0]==="-"&&f[1]==="-"&&f[2]&&l.push(f[2])}let c=n;if(l.length>0){n.trim()||(c=""),c+=`
|
|
117
117
|
|
|
118
118
|
--- Binary Files Changed ---
|
|
119
|
-
`;for(const
|
|
120
|
-
`}}const u=[...new Set([...i,...
|
|
121
|
-
`).filter(Boolean);for(const
|
|
119
|
+
`;for(const m of l){const{stdout:f}=await I("git",["status","--porcelain",m]),h=f.substring(0,2).trim();c+=`Binary file ${m} ${h==="A"?"added":h==="M"?"modified":h==="D"?"deleted":"changed"}
|
|
120
|
+
`}}const u=[...new Set([...i,...l])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async getCommitDiff(e,r,o){const s=["diff-tree","-r","--no-commit-id","--name-only",e],{stdout:n}=await I("git",[...s,...this.filesToExclude,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]);if(!n)return null;const{stdout:i}=await I("git",["show",e,"--",...this.filesToExclude,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),{stdout:a}=await I("git",["diff-tree","-r","--numstat",e,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),l=[],d=a.split(`
|
|
121
|
+
`).filter(Boolean);for(const m of d){const f=m.split(" ");f[0]==="-"&&f[1]==="-"&&f[2]&&l.push(f[2])}let c=i;if(l.length>0){i.trim()||(c=""),c+=`
|
|
122
122
|
|
|
123
123
|
--- Binary Files Changed ---
|
|
124
|
-
`;for(const
|
|
124
|
+
`;for(const m of l)c+=`Binary file ${m} changed
|
|
125
125
|
`}const u=[...new Set([...n.split(`
|
|
126
|
-
`).filter(Boolean),...
|
|
126
|
+
`).filter(Boolean),...l])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async commit(e,r=[],o={}){try{await I("git",["commit","-m",e,...r],{stdio:"inherit"})}catch(s){const n=s;throw n.stderr?n.stderr.includes("nothing to commit")?new v(`Nothing to commit.
|
|
127
127
|
|
|
128
128
|
Stage your changes with: git add <files>
|
|
129
129
|
Or use the --all flag to stage all changes.`):n.stderr.includes("Please enter the commit message")?new v(`Commit message cannot be empty.
|
|
@@ -140,15 +140,15 @@ Please install Jujutsu:
|
|
|
140
140
|
- macOS: brew install jj
|
|
141
141
|
- Linux: cargo install jj-cli
|
|
142
142
|
- Windows: cargo install jj-cli
|
|
143
|
-
- See: https://github.com/jj-vcs/jj#installation`):new v(`Failed to execute jj command: ${r.message}`)}try{const{stdout:e,stderr:r}=await I("jj",["workspace","root"],{reject:!0}),o=e.trim();if(!o)throw new v("jj workspace root returned empty path");const s=M.join(o,".jj");if(!
|
|
143
|
+
- See: https://github.com/jj-vcs/jj#installation`):new v(`Failed to execute jj command: ${r.message}`)}try{const{stdout:e,stderr:r}=await I("jj",["workspace","root"],{reject:!0}),o=e.trim();if(!o)throw new v("jj workspace root returned empty path");const s=M.join(o,".jj");if(!Q.existsSync(s))throw new v(`Jujutsu repository directory not found at ${s}
|
|
144
144
|
|
|
145
145
|
Initialize a jj repository with: jj init`);return o}catch(e){if(e instanceof v)throw e;const r=e;throw r.stderr?r.stderr.includes("not in a jj repo")?new v(`Not in a Jujutsu repository!
|
|
146
146
|
|
|
147
147
|
Initialize with: jj init
|
|
148
148
|
Or navigate to an existing jj repository.`):r.stderr.includes("No workspace found")?new v(`No Jujutsu workspace found!
|
|
149
149
|
|
|
150
|
-
This may be a bare repository. Navigate to a workspace directory.`):new v(`Jujutsu error: ${r.stderr.trim()}`):new v(`Failed to verify Jujutsu repository: ${r.message||"Unknown error"}`)}}async getStagedDiff(e,r){try{const{stdout:o}=await I("jj",["status","--no-pager"]);if(process.env.DEBUG&&(console.log("jj status output:",JSON.stringify(o)),console.log("excludeFiles:",e),console.log("exclude:",r)),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):[],...r?r.map(this.excludeFromDiff):[]],i=[...s,...n];let a="all()";i.length>0&&(a=`all() & ${i.join(" & ")}`);const
|
|
151
|
-
`).filter(Boolean),h=[],y=
|
|
150
|
+
This may be a bare repository. Navigate to a workspace directory.`):new v(`Jujutsu error: ${r.stderr.trim()}`):new v(`Failed to verify Jujutsu repository: ${r.message||"Unknown error"}`)}}async getStagedDiff(e,r){try{const{stdout:o}=await I("jj",["status","--no-pager"]);if(process.env.DEBUG&&(console.log("jj status output:",JSON.stringify(o)),console.log("excludeFiles:",e),console.log("exclude:",r)),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):[],...r?r.map(this.excludeFromDiff):[]],i=[...s,...n];let a="all()";i.length>0&&(a=`all() & ${i.join(" & ")}`);const l=["diff","--name-only"],d=["diff","--git"];i.length>0&&(l.push(a),d.push(a)),process.env.DEBUG&&(console.log("jj diff command with fileset:",l),console.log("fileset expression:",a));const{stdout:c}=await I("jj",l);if(process.env.DEBUG&&console.log("jj diff --name-only output:",JSON.stringify(c)),!c.trim())return null;const{stdout:u}=await I("jj",d),{stdout:m}=await I("jj",["status","--no-pager"]),f=c.split(`
|
|
151
|
+
`).filter(Boolean),h=[],y=m.split(`
|
|
152
152
|
`);for(const b of y)if(b.includes("(binary)")||b.includes("Binary file")){const E=b.match(/([^\s]+)\s*\(binary\)/);E&&E[1]&&h.push(E[1])}let w=u;if(h.length>0){w+=`
|
|
153
153
|
|
|
154
154
|
--- Binary Files Changed ---
|
|
@@ -159,8 +159,8 @@ Try: jj status --no-pager`);if(s.stderr.includes("Invalid revision"))throw new v
|
|
|
159
159
|
|
|
160
160
|
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}
|
|
161
161
|
stderr: ${s.stderr}
|
|
162
|
-
exitCode: ${s.exitCode}`);return null}}async getCommitDiff(e,r,o){const s=[...r?r.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
|
|
163
|
-
`).filter(Boolean);return{files:d,diff:
|
|
162
|
+
exitCode: ${s.exitCode}`);return null}}async getCommitDiff(e,r,o){const s=[...r?r.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:a}=await I("jj",n);if(!a.trim())return null;const{stdout:l}=await I("jj",i),d=a.split(`
|
|
163
|
+
`).filter(Boolean);return{files:d,diff:l||`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,r=[],o={}){try{await I("jj",["describe","-m",e,...r],{stdio:"inherit"}),o.autoNew&&await I("jj",["new"],{stdio:"inherit"})}catch(s){const n=s;throw n.stderr?n.stderr.includes("Empty commit message")?new v(`Commit message cannot be empty.
|
|
164
164
|
|
|
165
165
|
Provide a meaningful commit message.`):n.stderr.includes("No changes to commit")?new v(`No changes to commit.
|
|
166
166
|
|
|
@@ -174,9 +174,9 @@ Check repository state with: jj status`):new v(`Jujutsu describe failed: ${n.std
|
|
|
174
174
|
YADM work tree: ${n}
|
|
175
175
|
Expected: ${i}
|
|
176
176
|
|
|
177
|
-
This appears to be a regular Git repository.`);const{stdout:a}=await I("yadm",["rev-parse","--git-dir"],{reject:!0}),
|
|
177
|
+
This appears to be a regular Git repository.`);const{stdout:a}=await I("yadm",["rev-parse","--git-dir"],{reject:!0}),l=a.trim();if(!l.includes("yadm"))throw new v(`Not a YADM repository (git-dir does not contain "yadm").
|
|
178
178
|
|
|
179
|
-
Git directory: ${
|
|
179
|
+
Git directory: ${l}
|
|
180
180
|
|
|
181
181
|
This appears to be a regular Git repository.`);return r}catch(e){if(e instanceof v)throw e;const r=e;if(r.code==="ENOENT")throw new v(`YADM command not found!
|
|
182
182
|
|
|
@@ -186,18 +186,18 @@ Initialize with: yadm init
|
|
|
186
186
|
Or clone your dotfiles: yadm clone <url>`);if(r.stderr.includes("permission denied"))throw new v(`YADM permission denied: ${r.stderr.trim()}
|
|
187
187
|
|
|
188
188
|
Check file permissions and repository access.`)}throw new v(`Failed to verify YADM repository: ${r.message||"Unknown error"}`)}}async getStagedDiff(e,r){const o=["diff","--cached","--diff-algorithm=minimal"],{stdout:s}=await I("yadm",[...o,"--name-only",...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]);if(!s)return null;const{stdout:n}=await I("yadm",[...o,...this.filesToExclude,...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),i=s.split(`
|
|
189
|
-
`).filter(Boolean),{stdout:a}=await I("yadm",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),
|
|
190
|
-
`).filter(Boolean);for(const
|
|
189
|
+
`).filter(Boolean),{stdout:a}=await I("yadm",[...o,"--numstat",...e?e.map(this.excludeFromDiff):[],...r?r.map(this.excludeFromDiff):[]]),l=[],d=a.split(`
|
|
190
|
+
`).filter(Boolean);for(const m of d){const f=m.split(" ");f[0]==="-"&&f[1]==="-"&&f[2]&&l.push(f[2])}let c=n;if(l.length>0){n.trim()||(c=""),c+=`
|
|
191
191
|
|
|
192
192
|
--- Binary Files Changed ---
|
|
193
|
-
`;for(const
|
|
194
|
-
`}}const u=[...new Set([...i,...
|
|
195
|
-
`).filter(Boolean);for(const
|
|
193
|
+
`;for(const m of l){const{stdout:f}=await I("yadm",["status","--porcelain",m]),h=f.substring(0,2).trim();c+=`Binary file ${m} ${h==="A"?"added":h==="M"?"modified":h==="D"?"deleted":"changed"}
|
|
194
|
+
`}}const u=[...new Set([...i,...l])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async getCommitDiff(e,r,o){const s=["diff-tree","-r","--no-commit-id","--name-only",e],{stdout:n}=await I("yadm",[...s,...this.filesToExclude,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]);if(!n)return null;const{stdout:i}=await I("yadm",["show",e,"--",...this.filesToExclude,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),{stdout:a}=await I("yadm",["diff-tree","-r","--numstat",e,...r?r.map(this.excludeFromDiff):[],...o?o.map(this.excludeFromDiff):[]]),l=[],d=a.split(`
|
|
195
|
+
`).filter(Boolean);for(const m of d){const f=m.split(" ");f[0]==="-"&&f[1]==="-"&&f[2]&&l.push(f[2])}let c=i;if(l.length>0){i.trim()||(c=""),c+=`
|
|
196
196
|
|
|
197
197
|
--- Binary Files Changed ---
|
|
198
|
-
`;for(const
|
|
198
|
+
`;for(const m of l)c+=`Binary file ${m} changed
|
|
199
199
|
`}const u=[...new Set([...n.split(`
|
|
200
|
-
`).filter(Boolean),...
|
|
200
|
+
`).filter(Boolean),...l])];return{files:u,diff:c||`Files changed: ${u.join(", ")}`}}async commit(e,r=[],o={}){try{await I("yadm",["commit","-m",e,...r],{stdio:"inherit"})}catch(s){const n=s;throw n.stderr?n.stderr.includes("nothing to commit")?new v(`Nothing to commit.
|
|
201
201
|
|
|
202
202
|
Stage your changes with: yadm add <file>
|
|
203
203
|
Or stage tracked file modifications: aicommit2 --all
|
|
@@ -210,23 +210,23 @@ Configure with:
|
|
|
210
210
|
yadm config --global user.name "Your Name"
|
|
211
211
|
yadm config --global user.email "your.email@example.com"`):n.stderr.includes("Permission denied")?new v(`YADM permission error: ${n.stderr.trim()}
|
|
212
212
|
|
|
213
|
-
Check repository permissions and file access.`):new v(`YADM commit failed: ${n.stderr.trim()}`):n.exitCode===1?new v("YADM commit failed. Check your staged changes and try again."):new v(`Failed to commit with YADM: ${n.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await I("yadm",["config","--get","core.commentChar"]);return e}catch{return"#"}}async getBranchName(){try{const{stdout:e}=await I("yadm",["branch","--show-current"]),r=e.trim();if(!r){const{stdout:o}=await I("yadm",["rev-parse","--short","HEAD"]);return`HEAD@${o.trim()}`}return r}catch{return"HEAD"}}}let Tr=null;async function
|
|
214
|
-
${
|
|
215
|
-
${
|
|
216
|
-
${
|
|
217
|
-
${
|
|
218
|
-
${
|
|
219
|
-
${
|
|
220
|
-
${
|
|
213
|
+
Check repository permissions and file access.`):new v(`YADM commit failed: ${n.stderr.trim()}`):n.exitCode===1?new v("YADM commit failed. Check your staged changes and try again."):new v(`Failed to commit with YADM: ${n.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:e}=await I("yadm",["config","--get","core.commentChar"]);return e}catch{return"#"}}async getBranchName(){try{const{stdout:e}=await I("yadm",["branch","--show-current"]),r=e.trim();if(!r){const{stdout:o}=await I("yadm",["rev-parse","--short","HEAD"]);return`HEAD@${o.trim()}`}return r}catch{return"HEAD"}}}let Tr=null;async function Dl(){const t=process.argv.includes("--git"),e=process.argv.includes("--yadm"),r=process.argv.includes("--jj");if(t)try{const c=new Ot;return await c.assertRepo(),c}catch(c){throw new v(`--git flag is set, but Git is not available or not in a git repository.
|
|
214
|
+
${c instanceof Error?c.message:String(c)}`)}if(e)try{const c=new Nr;return await c.assertRepo(),c}catch(c){throw new v(`--yadm flag is set, but YADM is not available or not in a YADM repository.
|
|
215
|
+
${c instanceof Error?c.message:String(c)}`)}if(r)try{const c=new _r;return await c.assertRepo(),c}catch(c){throw new v(`--jj flag is set, but Jujutsu is not available or not in a jj repository.
|
|
216
|
+
${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 Ot;return await c.assertRepo(),c}catch(c){throw new v(`FORCE_GIT="true" environment variable is set, but Git is not available or not in a git repository.
|
|
217
|
+
${c instanceof Error?c.message:String(c)}`)}if(s)try{const c=new Nr;return await c.assertRepo(),c}catch(c){throw new v(`FORCE_YADM="true" environment variable is set, but YADM is not available or not in a YADM repository.
|
|
218
|
+
${c instanceof Error?c.message:String(c)}`)}if(n)try{const c=new _r;return await c.assertRepo(),c}catch(c){throw new v(`FORCE_JJ="true" environment variable is set, but Jujutsu is not available or not in a jj repository.
|
|
219
|
+
${c instanceof Error?c.message:String(c)}`)}let i=!1;try{i=(await ge({})).forceGit===!0}catch{i=!1}if(i)try{const c=new Ot;return await c.assertRepo(),c}catch(c){throw new v(`forceGit=true is set in config, but Git is not available or not in a git repository.
|
|
220
|
+
${c instanceof Error?c.message:String(c)}`)}let a=null,l=null,d=null;try{const c=new _r;return await c.assertRepo(),c}catch(c){a=c instanceof Error?c:new Error(String(c))}try{const c=new Ot;return await c.assertRepo(),c}catch(c){l=c instanceof Error?c:new Error(String(c))}try{const c=new Nr;return await c.assertRepo(),c}catch(c){d=c instanceof Error?c:new Error(String(c))}if(a&&l&&d){const c=a.message.replace("KnownError: ","").trim(),u=l.message.replace("KnownError: ","").trim(),m=d.message.replace("KnownError: ","").trim();throw new v(`No supported VCS repository found.
|
|
221
221
|
|
|
222
222
|
Jujutsu Error:
|
|
223
|
-
${
|
|
223
|
+
${c}
|
|
224
224
|
|
|
225
225
|
Git Error:
|
|
226
226
|
${u}
|
|
227
227
|
|
|
228
228
|
YADM Error:
|
|
229
|
-
${
|
|
229
|
+
${m}
|
|
230
230
|
|
|
231
231
|
Solutions:
|
|
232
232
|
\u2022 Initialize a Jujutsu repository: jj init
|
|
@@ -234,7 +234,7 @@ Solutions:
|
|
|
234
234
|
\u2022 Initialize a YADM repository: yadm init (or yadm clone <url>)
|
|
235
235
|
\u2022 Navigate to an existing Jujutsu, Git, or YADM repository
|
|
236
236
|
\u2022 Set FORCE_GIT="true" environment variable to force Git detection
|
|
237
|
-
\u2022 Set forceGit=true in config file to prefer Git detection`)}throw new v("Unexpected error during VCS detection")}async function $e(){return Tr||(Tr=await
|
|
237
|
+
\u2022 Set forceGit=true in config file to prefer Git detection`)}throw new v("Unexpected error during VCS detection")}async function $e(){return Tr||(Tr=await Dl()),Tr}const Lr=async()=>(await $e()).assertRepo(),Fr=async(t,e)=>(await $e()).getStagedDiff(t,e),_l=async(t,e,r)=>{const o=await $e();if(!o.getCommitDiff)throw new v(`Commit diff not supported for ${o.name}`);return o.getCommitDiff(t,e,r)},Nl=async()=>(await $e()).getCommentChar(),Tl=t=>`Detected ${t.files.length.toLocaleString()} changed file${t.files.length>1?"s":""} (${t.diff.length.toLocaleString()} characters)`,Dt=async()=>(await $e()).name,Ll=async(t,e,r)=>{await(await $e()).commit(t,e||[],r)},_t=async()=>(await $e()).getBranchName();class de{constructor(){this.title="aicommit2"}printTitle(){try{const e=ao.textSync(this.title,{font:"Small Slant"}),r=$n(["#8B5CF6","#A020F0","#D946EF"]);console.log(g.bold(r.multiline(e)))}catch{console.log(g.bold(ao.textSync(this.title,{font:"Small Slant"})))}}showLoader(e){if(this.loader){this.loader.text=e;return}this.loader=co(e).start()}stopLoader(){this.loader?.stop(),this.loader=void 0}displaySpinner(e){return co(e).start()}stopSpinner(e){e.stop(),e.clear()}printStagedFiles(e){console.log(g.bold.green("\u2714 ")+g.bold(`${Tl(e)}:`)),console.log(`${e.files.map(r=>` ${r}`).join(`
|
|
238
238
|
`)}
|
|
239
239
|
`)}printAnalyzed(){console.log(`
|
|
240
240
|
${g.bold.green("\u2714")} ${g.bold("Changes analyzed")}`)}printCommitted(){console.log(`
|
|
@@ -246,35 +246,35 @@ ${g.bold.red("\u2716")} ${g.red(`${e}`)}`)}printWarning(e){console.log(`
|
|
|
246
246
|
${g.bold.yellow("\u26A0")} ${g.red(`${e}`)}`)}printSuccess(e){console.log(`
|
|
247
247
|
${g.bold.green("\u2714")} ${g.green(`${e}`)}`)}printInfo(e){console.log(`
|
|
248
248
|
${g.bold.blue("\u2139")} ${g.blue(`${e}`)}`)}printSetupGitEvent(e){console.log(`
|
|
249
|
-
${g.bold.green("\u2714")} ${g.bold(`Git ${e} hook has been set up`)}`)}moveCursorUp(){const e=
|
|
250
|
-
${g.bold.yellow("\u26A0")} ${g.yellow(`${jr}`)}`)}get currentChoices(){return this.choices$.getValue().map(e=>e)}}const X=new de;var
|
|
251
|
-
`)}),process.exit(0));const
|
|
252
|
-
${
|
|
253
|
-
`)}i&&(
|
|
254
|
-
`),process.exit()),(n||d&&S.length===1)&&(await
|
|
255
|
-
`),process.exit(1)}X.printError(C.message),
|
|
256
|
-
${
|
|
257
|
-
`),
|
|
249
|
+
${g.bold.green("\u2714")} ${g.bold(`Git ${e} hook has been set up`)}`)}moveCursorUp(){const e=at.createInterface({input:process.stdin,output:process.stdout});at.moveCursor(process.stdout,0,-1),e.close()}moveCursorDown(){const e=at.createInterface({input:process.stdin,output:process.stdout});at.moveCursor(process.stdout,0,2),e.close()}print(e){console.log(e)}}const Fl={isLoading:!1,startOption:{text:"AI is analyzing your changes"}},Os={isLoading:!1,startOption:{text:"AI is performing a code review"}},jr="No commit messages were generated",Ds="No code reviews were generated",Br={type:"reactiveListPrompt",name:"aicommit2Prompt",message:"Pick a commit message to use: ",emptyMessage:`\u26A0 ${jr}`,loop:!1,descPageSize:15,showDescription:!0,pickKey:"short",isDescriptionDim:!0,stopMessage:"Changes analyzed"};class Gr{constructor(e){this.choices$=new to([]),this.destroyed$=new cn(1),this.stopMessage="Changes analyzed",this.isDestroyed=!1,this.subscriptions=new Ut,this.inquirerInstance=null,this.loader$=new to(e)}addSubscription(e){if(this.isDestroyed){e.unsubscribe();return}this.subscriptions.add(e)}initPrompt(e=Br){return this.stopMessage=e.stopMessage,st.registerPrompt("reactiveListPrompt",Pn),this.inquirerInstance=st.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(Qa))}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){St()&&console.warn("Error during ReactivePromptManager destruction:",e)}finally{this.inquirerInstance=null}}}alertNoGeneratedMessage(){this.loader$.next({isLoading:!1,message:jr,stopOption:{doneFrame:"\u26A0",color:"yellow"}})}stopLoaderOnSuccess(){this.loader$.next({isLoading:!1,message:this.stopMessage})}logEmptyCommitMessage(){console.log(`
|
|
250
|
+
${g.bold.yellow("\u26A0")} ${g.yellow(`${jr}`)}`)}get currentChoices(){return this.choices$.getValue().map(e=>e)}}const X=new de;var jl=async(t,e,r,o,s,n,i,a,l,d,c,u,m,f,h,y,w)=>(async()=>{const C=y==="json";if(C||X.printTitle(),await Lr(),o){const Pe=await Dt();Pe==="git"?await I("git",["add","."]):Pe==="yadm"&&await I("yadm",["add","--update"])}const b={locale:t?.toString(),generate:e?.toString(),type:s?.toString(),systemPrompt:a?.toString(),...l===!0&&{includeBody:"true"},...u===!0&&{disableLowerCase:"true"}};m&&(b.logLevel="verbose");const E=await ge(b,w);(l===!0||E.includeBody===!0)&&ac(E),u&&cc(E),await As(E);const $={autoNew:h||E.jjAutoNew},P=C?null:X.displaySpinner("Detecting staged files"),O=await Fr(r,E.exclude);if(P?.stop(),!O){const Pe=await Dt();throw new v(yr.noStagedChanges(Pe),{code:R.NO_STAGED_CHANGES})}C||X.printStagedFiles(O);const S=De(E,"commit");if(S.length===0)throw new v(yr.noApiKeysConfigured(),{code:R.MISSING_API_KEY});const U=await _t(),_=new Rt(E,O,U);C&&((await Hl(_,S)).forEach(Ws=>{process.stdout.write(JSON.stringify(Ws)+`
|
|
251
|
+
`)}),process.exit(0));const he=De(E,"review");he.length>0&&await Bl(_,he);const fe=await Gl(_,S,d);E.useStats!==!1&&Sl({provider:fe.provider,model:fe.model,statsDays:E.statsDays}).catch(()=>{});let me=fe.value;if(c){if(X.printInfo("Opening editor to modify commit message..."),me=await Ul(me),!me.trim())throw new v(yr.emptyCommitMessage(),{code:R.EMPTY_COMMIT_MESSAGE});X.printSuccess("Commit message edited successfully!"),X.print(`
|
|
252
|
+
${me}
|
|
253
|
+
`)}(i||E.autoCopy)&&(Hn("copy-paste").copy(me),i&&X.printCopied()),i&&!f&&process.exit(),f&&(process.stdout.write(me+`
|
|
254
|
+
`),process.exit()),(n||d&&S.length===1)&&(await _s(me,w,$),process.exit());const{confirmationPrompt:jt}=await st.prompt([{type:"confirm",name:"confirmationPrompt",message:"Use selected message?",default:!0}]);jt?await _s(me,w,$):X.printCancelledCommit(),process.exit()})().catch(C=>{if(y==="json"){const b={error:C.message||"Unknown error occurred"};process.stderr.write(JSON.stringify(b)+`
|
|
255
|
+
`),process.exit(1)}X.printError(C.message),pe(C),process.exit(1)});async function Bl(t,e){const r=new Gr(Os);let o=null;try{const s=r.initPrompt({...Br,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Ds}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20});if(r.startLoader(),o=t.createCodeReviewRequests$(e).subscribe({next:l=>r.refreshChoices(l),error:l=>{console.error("Code review request error:",l),r.checkErrorOnChoices()},complete:()=>r.checkErrorOnChoices()}),!(await s).codeReviewPrompt?.value)throw new v("An error occurred! No selected code review");X.moveCursorUp();const{continuePrompt:a}=await st.prompt([{type:"confirm",name:"continuePrompt",message:"Will you continue without changing the code?",default:!0}]);a||(X.printCancelledCommit(),process.exit())}finally{o&&o.unsubscribe(),r.destroy()}}const Gl=async(t,e,r)=>{const o=new Gr(Fl);let s=null;try{if(r&&e.length===1){const c=[];o.startLoader(),s=t.createCommitMsgRequests$(e).subscribe({next:m=>{c.push(m),o.refreshChoices(m)},error:m=>{console.error("Commit message generation error:",m),o.checkErrorOnChoices(!1)},complete:()=>o.checkErrorOnChoices(!1)}),await new Promise(m=>{s?.add(()=>m())}),o.clearLoader(),X.moveCursorUp();const u=c.find(m=>m.value&&!m.isError&&!m.disabled);if(!u||!u.value)throw new v("No valid commit message was generated");return X.print(`
|
|
256
|
+
${u.name}
|
|
257
|
+
`),{value:u.value,provider:u.provider||"unknown",model:u.model||"unknown"}}const n=new Map,i=o.initPrompt();o.startLoader(),s=t.createCommitMsgRequests$(e).subscribe({next:c=>{const u=c;u.value&&n.set(u.value,u),o.refreshChoices(c)},error:c=>{console.error("Commit message generation error:",c),o.checkErrorOnChoices()},complete:()=>o.checkErrorOnChoices()});const a=await i;X.moveCursorUp();const l=a.aicommit2Prompt?.value;if(!l)throw new v("An error occurred! No selected message");const d=n.get(l);return{value:l,provider:d?.provider||"unknown",model:d?.model||"unknown"}}finally{s&&s.unsubscribe(),o.destroy()}};async function Ul(t){const e=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),r=M.join(Fe.tmpdir(),`aicommit2-${Date.now()}-${qs.randomBytes(4).toString("hex")}.txt`);try{Q.writeFileSync(r,t,"utf8");const o=e.split(" "),[s,...n]=o;await I(s,[...n,r],{stdio:"inherit"});const i=Q.readFileSync(r,"utf8").trim();if(Q.unlinkSync(r),!i)throw new v("Commit cancelled - empty message");return i}catch(o){throw Q.existsSync(r)&&Q.unlinkSync(r),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:
|
|
258
258
|
- Editor binary exists in PATH
|
|
259
259
|
- Editor flags are correct
|
|
260
|
-
- 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.`)}}const
|
|
260
|
+
- 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.`)}}const _s=async(t,e,r)=>{await Ll(t,e,r),X.printCommitted()},Hl=async(t,e)=>{const o=(await Ht(t.createCommitMsgRequests$(e).pipe(Kt()),{defaultValue:[]})).filter(s=>s.value&&!s.isError&&!s.disabled);if(o.length===0)throw new v("No valid commit messages were generated");return o.map(({value:s=""})=>{const[n="",...i]=s.split(`
|
|
261
261
|
`);return{subject:n,body:i.join(`
|
|
262
|
-
`).trim()}})};var
|
|
262
|
+
`).trim()}})};var Kl=ae({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:[ae({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"]}}),ae({name:"get",parameters:["[<key>","[<key> ...]]"],help:{description:"Retrieve configuration values for specified AI provider.",examples:["aic2 config get OPENAI","aic2 config get ANTHROPIC"]}}),ae({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"']}}),ae({name:"list",parameters:[],help:{description:"Display all configuration keys and their values.",examples:["aic2 config list"]}}),ae({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"]}}),ae({name:"path",parameters:[],help:{description:"Display the path of the loaded configuration file.",examples:["aic2 config path"]}})]},t=>{(async()=>{const{mode:e,keyValue:r}=t._,o=t._[1];if(e==="get"){const s=await ge({},[]);if(r.length===0){console.log(s);return}for(const n of r){const i=n.split(".");let a=s,l=!0;for(const d of i)if(fr(a,d))a=a[d];else{l=!1;break}l?console.log(n,a):console.log(`${n} not found`)}return}if(e==="set"){await hr(r.map(s=>{const n=s.indexOf("=");if(n===-1)throw new v("Invalid format. Use: key=value");const i=s.slice(0,n),a=s.slice(n+1);return[i,a]}));return}if(e==="add"){await mc(r.map(s=>{const n=s.indexOf("=");if(n===-1)throw new v("Invalid format. Use: key=value");const i=s.slice(0,n),a=s.slice(n+1);return[i,a]}));return}if(e==="list"){await pc();return}if(e==="del"){if(!o)throw new v("Please provide the config name to delete.");const s=await Ye(),n=o.split(".");if(n.length===2){const[i,a]=n;if(s[i]&&typeof s[i]=="object"&&fr(s[i],a)){delete s[i][a],Object.keys(s[i]).length===0&&delete s[i];const l=await Oe();await D.writeFile(l,Re.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const d=await D.readFile(l,"utf8");console.log("--- Updated Config Content ---"),console.log(d),console.log("----------------------------")}else throw new v(`Config not found: ${o}`)}else if(n.length===1){const i=n[0];if(fr(s,i)){delete s[i];const a=await Oe();await D.writeFile(a,Re.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const l=await D.readFile(a,"utf8");console.log("--- Updated Config Content ---"),console.log(l),console.log("----------------------------")}else throw new v(`Config not found: ${o}`)}else throw new v(`Invalid config name format: ${o}`);return}if(e==="path"){await fc();return}throw new v(`Invalid mode: ${e}`)})().catch(e=>{new de().printError(e.message),pe(e),process.exit(1)})});const zl={healthy:g.green("\u2705"),error:g.red("\u274C"),warning:g.yellow("\u26A0\uFE0F"),skipped:g.gray("\u23ED\uFE0F")},Wl={healthy:g.green,error:g.red,warning:g.yellow,skipped:g.gray},Yl=t=>typeof t.key=="string"&&t.key.trim().length>0,Vl=async(t,e)=>{try{return await new Te({method:"GET",baseURL:t,timeout:e}).execute(),{ok:!0}}catch(r){const o=r instanceof Error?r.message:String(r);return o.includes("ECONNREFUSED")?{ok:!1,error:"Not running"}:{ok:!1,error:o}}},ql=async(t,e,r)=>{if(t==="OLLAMA"){if(!Ce(e))return{provider:t,status:"skipped",message:"No models configured"};const o=typeof e.host=="string"&&e.host.trim()?e.host:Et,s=await Vl(o,r);return s.ok?{provider:t,status:"healthy",message:"Running",details:`Host: ${o}`}:{provider:t,status:"warning",message:s.error||"Connection failed",details:`Host: ${o}`}}return t==="HUGGINGFACE"?e.cookie?{provider:t,status:"healthy",message:"Cookie configured"}:{provider:t,status:"skipped",message:"No cookie configured"}:t==="BEDROCK"?Pt(e)?{provider:t,status:"healthy",message:"Credentials configured"}:{provider:t,status:"skipped",message:"Not configured"}:Yl(e)?{provider:t,status:"healthy",message:"API key configured"}:{provider:t,status:"skipped",message:"Not configured"}},Jl=async t=>{const e=[],r=t.timeout||1e4;for(const o of Ke){const s=t[o];if(!s||typeof s!="object"){e.push({provider:o,status:"skipped",message:"Not configured"});continue}if(s.disabled){e.push({provider:o,status:"skipped",message:"Disabled"});continue}const n=await ql(o,s,r);e.push(n)}return e},Xl=Math.max(...Ke.map(t=>t.length)),Ql=t=>t.padEnd(Xl),Zl=t=>{console.log(""),console.log(g.bold("\u{1FA7A} aicommit2 Health Check")),console.log(""),console.log(g.bold("Providers:"));for(const r of t){const o=zl[r.status],s=Ql(r.provider),n=Wl[r.status](r.message),i=r.details?g.gray(` (${r.details})`):"";console.log(` ${o} ${s} ${n}${i}`)}const e={healthy:t.filter(r=>r.status==="healthy").length,error:t.filter(r=>r.status==="error").length,warning:t.filter(r=>r.status==="warning").length,skipped:t.filter(r=>r.status==="skipped").length};console.log(""),console.log(g.bold("Summary: ")+g.green(`${e.healthy} healthy`)+", "+g.red(`${e.error} error`)+", "+g.yellow(`${e.warning} warning`)+", "+g.gray(`${e.skipped} skipped`)),console.log(""),e.error>0&&(process.exitCode=1)},eu=ae({name:"doctor",parameters:[],help:{description:"Check health status of configured AI providers",examples:["aicommit2 doctor"]}},()=>{(async()=>{const t=await ge({},[]),e=await Jl(t);Zl(e)})().catch(t=>{console.error(g.red(t.message)),pe(t),process.exit(1)})});var tu=ae({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"]}},t=>{(async()=>{const e=new de;if(t.flags.token){try{await ru(t.flags.token,e)}catch(r){throw new v(`Token authentication failed: ${r.message}`)}return}try{await ou(e)}catch(r){throw new v(`Browser authentication failed: ${r.message}`)}})().catch(e=>{new de().printError(e.message),pe(e),process.exit(1)})});async function ru(t,e){if(e.printWarning("Authenticating with provided token..."),!t.startsWith("ghp_")&&!t.startsWith("gho_")&&!t.startsWith("ghu_"))throw new Error("Invalid token format. GitHub tokens should start with ghp_, gho_, or ghu_");try{const r=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${t}`,Accept:"application/vnd.github.v3+json","User-Agent":"aicommit2-github-models"}});if(!r.ok)throw new Error(`GitHub API request failed: ${r.status} ${r.statusText}`);const o=await r.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 ${t}`,"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 hr([["GITHUB_MODELS.key",t]]),e.printSuccess(`Successfully authenticated as ${o.login}`)}catch(r){throw new Error(`Token validation failed: ${r.message}`)}}async function ou(t){t.printInfo("Starting GitHub browser authentication for GitHub Models...");try{try{ot("gh --version",{stdio:"ignore"})}catch{throw new Error("GitHub CLI (gh) is not installed. Please install it first: https://cli.github.com/")}try{ot("gh auth status",{encoding:"utf8",stdio:"pipe"}).includes("Logged in to github.com")&&t.printInfo("Already authenticated with GitHub CLI")}catch{t.printInfo("Authenticating with GitHub CLI..."),t.printInfo("Please follow the instructions in your browser to complete authentication.");try{ot("gh auth login --web -h github.com",{stdio:"inherit"})}catch{throw new Error("GitHub CLI authentication failed")}}t.printInfo("Verifying GitHub Models access...");try{const e=ot("gh auth token",{encoding:"utf8"}).trim();e&&(await hr([["GITHUB_MODELS.key",e]]),t.printSuccess("GitHub token stored for GitHub Models access"))}catch{t.printWarning("Could not extract token from GitHub CLI, but authentication completed")}t.printSuccess("GitHub authentication completed and GitHub Models access verified!"),t.printInfo("See usage guide: https://github.com/tak-bro/aicommit2/blob/main/docs/providers/github-models.md"),t.printInfo("Available models: gpt-4o-mini, gpt-4o, meta-llama-3.1-405b-instruct, etc."),t.printInfo("Using GitHub Models API: https://models.github.ai")}catch(e){throw e}}const Le="prepare-commit-msg",su=async()=>{const t=await Dt();if(t==="git")return`.git/hooks/${Le}`;if(t==="yadm"){const e=process.env.HOME||process.env.USERPROFILE;if(!e)throw new v("HOME environment variable not set. Cannot determine YADM hook path.");try{const{execa:s}=await Promise.resolve().then(function(){return Ja}),{stdout:n}=await s("yadm",["introspect","repo"]),i=n.trim();if(i)return M.join(i,"hooks",Le)}catch{}const r=M.join(e,".config/yadm/hooks"),o=M.join(e,".yadm/hooks");try{return await D.access(r),M.join(r,Le)}catch{return M.join(o,Le)}}throw t==="jujutsu"?new v("Hooks are not supported for Jujutsu repositories."):new v(`Hooks are not supported for ${t} repositories.`)},Nt=pn(new URL("cli.mjs",import.meta.url)),nu=process.argv[1].replace(/\\/g,"/").includes(`/hooks/${Le}`),Ns=process.platform==="win32",Ts=`
|
|
263
263
|
#!/usr/bin/env node
|
|
264
|
-
import(${JSON.stringify(
|
|
265
|
-
`.trim();var
|
|
266
|
-
`);const r=await Promise.all(e.map(async o=>{const s=we.join(
|
|
267
|
-
${g.green("Total:")} ${e.length} file${e.length!==1?"s":""}`)}catch(e){if(e.code==="ENOENT")console.log(`${g.yellow("Logs directory does not exist yet.")}`);else throw e}},
|
|
264
|
+
import(${JSON.stringify(fn(Nt))})
|
|
265
|
+
`.trim();var iu=ae({name:"hook",parameters:["<install/uninstall>"],help:{description:"Install or uninstall the Git prepare-commit-msg hook",examples:["aic2 hook install","aic2 hook uninstall"]}},t=>{(async()=>{const e=await Lr(),{installUninstall:r}=t._,o=await su(),s=M.isAbsolute(o)?o:M.join(e,o),n=await yt(s);if(r==="install"){if(n){if(await D.realpath(s).catch(()=>{})===Nt){console.warn("The hook is already installed");return}throw new v(`A different ${Le} hook seems to be installed. Please remove it before installing aicommit2.`)}await D.mkdir(M.dirname(s),{recursive:!0}),Ns?await D.writeFile(s,Ts):(await D.symlink(Nt,s,"file"),await D.chmod(s,493)),console.log(`${g.green("\u2714")} Hook installed`);return}if(r==="uninstall"){if(!n){console.warn("Hook is not installed");return}if(Ns){if(await D.readFile(s,"utf8")!==Ts){console.warn("Hook is not installed");return}}else if(await D.realpath(s)!==Nt){console.warn("Hook is not installed");return}await D.rm(s),console.log(`${g.green("\u2714")} Hook uninstalled`);return}throw new v(`Invalid mode: ${r}`)})().catch(e=>{console.error(`${g.red("\u2716")} ${e.message}`),pe(e),process.exit(1)})});const au=an(Js),cu=t=>{const e=["B","KB","MB","GB"];if(t===0)return"0 B";const r=Math.floor(Math.log(t)/Math.log(1024));return Math.round(t/Math.pow(1024,r)*100)/100+" "+e[r]},lu=t=>t.toLocaleDateString()+" "+t.toLocaleTimeString(),uu=async t=>{try{const e=await lo(le);if(e.length===0){console.log(`${g.yellow("No log files found.")}`);return}console.log(`${g.blue("Log files in")} ${le}:
|
|
266
|
+
`);const r=await Promise.all(e.map(async o=>{const s=we.join(le,o),n=await An(s);return{name:o,size:cu(n.size),modified:lu(n.mtime)}}));r.sort((o,s)=>new Date(s.modified).getTime()-new Date(o.modified).getTime()),r.forEach((o,s)=>{console.log(`${s===0?"\u{1F4C4}":" "} ${g.cyan(o.name)} ${g.gray(`(${o.size}, ${o.modified})`)}`)}),console.log(`
|
|
267
|
+
${g.green("Total:")} ${e.length} file${e.length!==1?"s":""}`)}catch(e){if(e.code==="ENOENT")console.log(`${g.yellow("Logs directory does not exist yet.")}`);else throw e}},du=async t=>{try{await lo(le);const e=process.platform;let r;switch(e){case"darwin":r=`open "${le}"`;break;case"win32":r=`start "" "${le}"`;break;default:r=`xdg-open "${le}"`;break}await au(r),console.log(`${g.green("\u2714")} Opened logs directory in file manager`)}catch(e){e.code==="ENOENT"?console.log(`${g.yellow("Logs directory does not exist yet.")}`):t.printError(`Failed to open logs directory: ${e.message}`)}},mu=async t=>{try{await Sn(le,{recursive:!0,force:!0}),console.log(`${g.green("\u2714")} All log files removed!`)}catch(e){t.printError(`Failed to remove log files: ${e.message}`)}};var pu=ae({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"]}},t=>{(async()=>{const{action:e}=t._,r=new de;switch(e){case"list":await uu();break;case"path":console.log(`${g.blue("Logs directory:")} ${le}`);break;case"open":await du(r);break;case"removeAll":await mu(r);break;default:throw new v(`Invalid action: ${e}. Use 'list', 'path', 'open', or 'removeAll'`)}})().catch(e=>{new de().printError(e.message),pe(e),process.exit(1)})});const fu=process.argv.slice(2).filter(t=>!t.startsWith("--pre-commit")),[Tt,Ls]=fu;var hu=(t=!1)=>(async()=>{if(!Tt)throw new v('Commit message file path is missing. This file should be called from the "pre-commit framework"');if(Ls){console.log(`Skipping aicommit2 message generation for ${Ls} commit`);return}const e=await Fr();if(!e)return;const r=new de;r.printTitle();const o={};t&&(o.logLevel="verbose");const s=await ge(o);if(s.systemPromptPath)try{await D.readFile(M.resolve(s.systemPromptPath),"utf-8")}catch{throw new v(`Error reading system prompt file: ${s.systemPromptPath}`)}const n=De(s,"commit");if(n.length===0)throw new v("Please set at least one API key via the `aicommit2 config set` command");const a=await _t(),l=new Rt(s,e,a);let d;try{d=await Ht(l.createCommitMsgRequests$(n).pipe(ro(w=>!w.isError),T(w=>w.value),Kt()))}finally{r.printAnalyzed()}const u=await D.readFile(Tt,"utf8")!=="",m=d.length>1;let f="";u&&(f=`# \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
|
|
268
268
|
`,f+=`# ----------------------------------------
|
|
269
269
|
`,f+=`# How to use:
|
|
270
|
-
`,
|
|
270
|
+
`,m?(f+=`# 1. Remove the "#" from your chosen message
|
|
271
271
|
`,f+=`# 2. Edit the message if needed
|
|
272
272
|
`,f+=`# 3. Save and close the editor
|
|
273
273
|
`):(f+=`# 1. The message below will be used
|
|
274
274
|
`,f+=`# 2. Edit the message if needed
|
|
275
275
|
`,f+=`# 3. Save and close the editor
|
|
276
276
|
`),f+=`# ----------------------------------------
|
|
277
|
-
`),
|
|
277
|
+
`),m?(u&&(f+=`
|
|
278
278
|
# \u{1F4DD} Choose one of these messages:
|
|
279
279
|
`),f+=`
|
|
280
280
|
${d.map(w=>`# ${w}`).join(`
|
|
@@ -282,8 +282,8 @@ ${d.map(w=>`# ${w}`).join(`
|
|
|
282
282
|
# \u{1F4DD} Generated commit message:
|
|
283
283
|
`),f+=`
|
|
284
284
|
${d[0]}
|
|
285
|
-
`);const h=await D.readFile(
|
|
286
|
-
`+h;await D.writeFile(
|
|
285
|
+
`);const h=await D.readFile(Tt,"utf8"),y=f+`
|
|
286
|
+
`+h;await D.writeFile(Tt,y),r.printSavedCommitMessage()})().catch(e=>{new de().printError(e.message),pe(e),process.exit(1)});const Ur=process.argv.slice(2),Fs=[];let Hr=!1;for(let t=0;t<Ur.length;t++){const e=Ur[t];if(Hr){Hr=!1;continue}if(e!=="--hook-mode"){if(e.startsWith("-")){const r=Ur[t+1];r&&!r.startsWith("-")&&(Hr=!0);continue}Fs.push(e)}}const[Lt,js]=Fs;var gu=(t,e,r,o,s,n,i)=>(async()=>{if(!Lt)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(js){console.log(`Skipping aicommit2 message generation for ${js} commit`);return}const a=await Fr();if(!a)return;const l=new de;l.printTitle();const d={locale:t?.toString(),generate:e?.toString(),type:o?.toString(),systemPrompt:s?.toString(),...n===!0&&{includeBody:"true"}};i&&(d.logLevel="verbose");const c=await ge(d,r);if(c.systemPromptPath)try{await D.readFile(M.resolve(c.systemPromptPath),"utf-8")}catch{throw new v(`Error reading system prompt file: ${c.systemPromptPath}`)}const u=De(c,"commit");if(u.length===0)throw new v("Please set at least one API key via the `aicommit2 config set` command");const f=await _t(),h=new Rt(c,a,f),y=l.displaySpinner("The AI is analyzing your changes");let w;try{w=await Ht(h.createCommitMsgRequests$(u).pipe(ro(S=>!S.isError),T(S=>S.value),Kt()))}finally{y.stop(),y.clear(),l.printAnalyzed()}const b=await D.readFile(Lt,"utf8")!=="",E=w.length>1,k=await Nl();let $="";b&&($=`${k} \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
|
|
287
287
|
`,$+=`${k} ----------------------------------------
|
|
288
288
|
`,$+=`${k} How to use:
|
|
289
289
|
`,E?($+=`${k} 1. Remove the "${k}" from your chosen message
|
|
@@ -301,17 +301,17 @@ ${w.map(S=>`${k} ${S}`).join(`
|
|
|
301
301
|
${k} \u{1F4DD} Generated commit message:
|
|
302
302
|
`),$+=`
|
|
303
303
|
${w[0]}
|
|
304
|
-
`);const P=await D.readFile(
|
|
305
|
-
`+P;await D.writeFile(
|
|
304
|
+
`);const P=await D.readFile(Lt,"utf8"),O=$+`
|
|
305
|
+
`+P;await D.writeFile(Lt,O),l.printSavedCommitMessage()})().catch(a=>{new de().printError(a.message),pe(a),process.exit(1)});const Bs=20,Gs=t=>t<1e3?`${t}ms`:`${(t/1e3).toFixed(1)}s`,Us=t=>new Date(t).toLocaleDateString(),yu=t=>{const e=Math.round(t/100*Bs),r=Bs-e;return(t>=80?g.green:t>=50?g.yellow:g.red)("\u2588".repeat(e))+g.gray("\u2591".repeat(r))},wu=t=>{const e=t.totalRequests>0?Math.round(t.successCount/t.totalRequests*100):0,r=yu(e),o=t.provider.padEnd(14),s=`${e}%`.padStart(4),n=`${t.totalRequests}`.padStart(4),i=`${t.selectedCount}`.padStart(4),a=t.selectionRate>0?`(${t.selectionRate}%)`.padStart(7):"".padStart(7),l=Gs(t.avgResponseTimeMs).padStart(6);console.log(` ${g.bold(o)} ${s} ${r} ${n} ${g.cyan(i)} ${g.gray(a)} ${l}`)},vu=async t=>{if(!await xl()){console.log(g.yellow(`
|
|
306
306
|
No statistics recorded yet.`)),console.log(g.gray(`Statistics will be collected as you generate commit messages.
|
|
307
|
-
`));return}const r=await
|
|
307
|
+
`));return}const r=await Il(t);if(r.totalRequests===0){console.log(g.yellow(`
|
|
308
308
|
No statistics in the last ${t} days.
|
|
309
|
-
`));return}if(console.log(""),console.log(g.bold("\u{1F4CA}
|
|
309
|
+
`));return}if(console.log(""),console.log(g.bold("\u{1F4CA} aicommit2 Statistics")),console.log(g.gray(` Period: ${Us(r.periodStart)} - ${Us(r.periodEnd)}`)),console.log(""),console.log(g.bold("Overview:")),console.log(` Total requests: ${g.cyan(r.totalRequests)}`),console.log(` Success rate: ${g.green(r.successRate+"%")}`),console.log(` Avg response time: ${g.yellow(Gs(r.avgResponseTimeMs))}`),console.log(""),r.providerStats.length>0){console.log(g.bold("Provider Usage:")),console.log(g.gray(" Provider Rate Bar Cnt Selected Time"));for(const o of r.providerStats)wu(o);console.log("")}},Cu=async()=>{await Ml(),console.log(g.green(`
|
|
310
310
|
Statistics cleared successfully.
|
|
311
|
-
`))},
|
|
311
|
+
`))},bu=ae({name:"stats",parameters:["[action]"],flags:{days:{type:Number,description:"Number of days to include in statistics (default: 30)",alias:"d",default:30}},help:{description:"View AI request statistics and performance metrics",examples:["aicommit2 stats Show statistics for last 30 days","aicommit2 stats -d 7 Show statistics for last 7 days","aicommit2 stats clear Clear all statistics"]}},t=>{(async()=>{const e=t._[0],{days:r}=t.flags;switch(e){case"clear":await Cu();break;default:await vu(r);break}})().catch(e=>{console.error(g.red(e.message)),pe(e),process.exit(1)})});class Hs{constructor(e="SubscriptionManager"){this.destroyed$=new zt,this.subscriptions=new Ut,this.isDestroyed=!1,this.name=e}add(e,r){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`);const s=new Ut;return s.unsubscribe(),s}const o=e.pipe(uo(this.destroyed$),mo(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Observable finalized`)})).subscribe({next:r?.next,error:s=>{console.error(`${this.name}: Observable error:`,s),r?.error?.(s)},complete:r?.complete});return this.subscriptions.add(o),o}pipe(e){return this.isDestroyed?(console.warn(`${this.name}: Cannot pipe - manager is destroyed`),e):e.pipe(uo(this.destroyed$),mo(()=>{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 Eu=new Hs("Global"),rt=()=>{Eu.destroy()};process.on("exit",rt),process.on("SIGINT",rt),process.on("SIGTERM",rt),process.on("uncaughtException",t=>{console.error("Uncaught exception:",t),rt(),process.exit(1)}),process.on("unhandledRejection",(t,e)=>{console.error("Unhandled rejection at:",e,"reason:",t),rt(),process.exit(1)});class $u{constructor(){this.destroyed$=new zt,this.consoleManager=new de,this.subscriptionManager=new Hs,this.currentCodeReviewSubscription=null,this.currentCodeReviewPromptManager=null,this.watcher=null,this.lastCommitHash=null,this.isProcessingCommit=!1,this.REPO_PATH=process.cwd(),this.GIT_PATH=M.join(this.REPO_PATH,".git"),this.HEAD_PATH=M.join(this.GIT_PATH,"HEAD"),this.REFS_PATH=M.join(this.GIT_PATH,"refs","heads"),this.COMMIT_MSG_PATH=M.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,r,o,s,n,i){this.consoleManager.printTitle(),await Lr();const a=await Dt();if(a!=="git")throw new v(`Watch mode is only supported for Git repositories. Current VCS: ${a}`);const l=await this.initializeConfig(e,r,s,n,i);await this.initializeCurrentCommit();try{await this.watchGitEvents(l)}catch(d){return await this.handleWatchGitError(d),this.watch(e,r,o,s,n,i)}}async initializeConfig(e,r,o,s,n){const i={locale:e?.toString(),generate:r?.toString(),systemPrompt:o?.toString()};s&&(i.logLevel="verbose");const a=await ge(i,n);return await As(a),De(a,"watch").length===0&&(this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
|
|
312
312
|
aicommit2 config set [MODEL].key="YOUR_API_KEY"
|
|
313
|
-
aicommit2 config set [MODEL].watchMode="true"`),process.exit()),a}async handleWatchGitError(e){this.consoleManager.printError(`An error occurred: ${e.message}`),
|
|
313
|
+
aicommit2 config set [MODEL].watchMode="true"`),process.exit()),a}async handleWatchGitError(e){this.consoleManager.printError(`An error occurred: ${e.message}`),pe(e),await new Promise(r=>setTimeout(r,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 r=sn(Qs),{stdout:o}=await r(e,{cwd:this.REPO_PATH});return o}clearTerminal(){process.stdout.write("\x1Bc")}async handleCommitEvent(e,r){try{const o=await _l(r);if(!o){this.consoleManager.printWarning("No changes found in this commit");return}this.consoleManager.stopLoader(),this.consoleManager.printStagedFiles(o);const s=De(e,"watch");if(s.length===0){this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
|
|
314
314
|
aicommit2 config set [MODEL].key="YOUR_API_KEY"
|
|
315
|
-
aicommit2 config set [MODEL].watchMode="true"`),process.exit();return}await this.performCodeReview(e,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${r}: ${o.message}`)}}async performCodeReview(e,r,o){this.cleanupPreviousCodeReview();const s=await
|
|
315
|
+
aicommit2 config set [MODEL].watchMode="true"`),process.exit();return}await this.performCodeReview(e,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${r}: ${o.message}`)}}async performCodeReview(e,r,o){this.cleanupPreviousCodeReview();const s=await _t(),n=new Rt(e,r,s);this.currentCodeReviewPromptManager=new Gr(Os);try{const i=this.initializeCodeReviewInquirer();this.currentCodeReviewPromptManager.startLoader(),this.currentCodeReviewSubscription=this.subscribeToCodeReviewRequests(n,o),await i}finally{this.cleanupCodeReview()}}cleanupPreviousCodeReview(){this.cleanupCurrentReviewResources(),this.destroyed$.closed||(this.destroyed$.next(),this.destroyed$.complete()),this.destroyed$=new zt}initializeCodeReviewInquirer(){return this.currentCodeReviewPromptManager.initPrompt({...Br,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Ds}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20})}subscribeToCodeReviewRequests(e,r){return this.subscriptionManager.add(e.createCodeReviewRequests$(r),{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 r=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,M.join(this.GIT_PATH,"logs","HEAD")].filter(s=>{try{return Q.accessSync(s),!0}catch{return!1}});this.watcher=kn.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,r){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(`
|
|
316
316
|
\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(`
|
|
317
|
-
\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
|
|
317
|
+
\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 Pu=new $u,Au=async(t,e,r,o,s,n)=>Pu.watch(t,e,r,o,s,n),Ks={"Message Options":["locale","generate","type","prompt","include-body"],Behavior:["all","confirm","auto-select","edit","clipboard","dry-run","output"],"VCS Selection":["git","yadm","jj","jj-auto-new"],"Hook Integration":["hook-mode","pre-commit","watch-commit"],Formatting:["disable-lowercase","exclude"],Debug:["verbose"]},Su=t=>{if(!t||typeof t!="object")return!1;const e=t;return e.data?.name!==void 0&&typeof e.data.name=="string"},ku=t=>Su(t)?t.data.name:null,Iu=t=>{for(const[e,r]of Object.entries(Ks))if(r.includes(t))return e;return null},Mu=t=>t.type==="section"&&t.data?.title==="Flags:",xu=t=>t.data?.body?.data?.tableData!==void 0,Ru=t=>{const e=new Map;for(const r of Object.keys(Ks))e.set(r,[]);if(e.set("Other",[]),!Array.isArray(t))return e;for(const r of t){if(!Array.isArray(r))continue;const o=ku(r[0]),s=o&&Iu(o)||"Other";e.get(s)?.push(r)}return e},Ou=(t,e,r,o,s)=>({type:"section",data:{title:s?`Flags - ${t}:`:` ${t}:`,body:{type:"table",data:{tableData:e,tableOptions:r,tableBreakpoints:o}}}}),Du=(t,e)=>{const r=[];for(const o of t){if(!Mu(o)||!xu(o)){r.push(o);continue}const{tableData:s,tableOptions:n,tableBreakpoints:i}=o.data.body.data;[...Ru(s).entries()].filter(([,d])=>d.length>0).forEach(([d,c],u)=>{r.push(Ou(d,c,n,i,u===0))})}return e.render(r)},Ft=process.argv.slice(2),{version:zs,description:_u}=Un;Ys({name:"aicommit2",version:zs,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},"jj-auto-new":{type:Boolean,description:"Run jj new after jj describe (default: false, only describe)",default:!1},"dry-run":{type:Boolean,description:"Generate commit message without committing (output only)",alias:"d",default:!1},output:{type:String,description:"Output format for non-interactive mode (json). For LazyGit integration",alias:"o"}},commands:[Kl,eu,tu,iu,pu,bu],help:{description:_u,render:Du},ignoreArgv:t=>t==="unknown-flag"||t==="argument"},async t=>{const e={};t.flags.verbose&&(e.logLevel="verbose");const r=await ge(e,Ft);if(await $c(r),_e.info(`aicommit2 version: ${zs}`),t.flags["pre-commit"]){hu(t.flags.verbose);return}if(t.flags["hook-mode"]||nu){gu(t.flags.locale,t.flags.generate,t.flags.exclude,t.flags.type,t.flags.prompt,t.flags["include-body"],t.flags.verbose);return}if(t.flags["watch-commit"]){Au(t.flags.locale,t.flags.generate,t.flags.exclude,t.flags.prompt,t.flags.verbose,Ft);return}jl(t.flags.locale,t.flags.generate,t.flags.exclude,t.flags.all,t.flags.type,t.flags.confirm,t.flags.clipboard,t.flags.prompt,t.flags["include-body"],t.flags["auto-select"],t.flags.edit,t.flags["disable-lowercase"],t.flags.verbose,t.flags["dry-run"],t.flags["jj-auto-new"],t.flags.output,Ft)},Ft);
|