aicommit2 2.6.0 → 2.6.1
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/dist/{ai.service-287ccdb0.mjs → ai.service-75d813be.mjs} +1 -1
- package/dist/{anthropic.service-57ee01e3.mjs → anthropic.service-5cdbdbb2.mjs} +1 -1
- package/dist/{bedrock.service-931a6a6f.mjs → bedrock.service-77f90b1d.mjs} +1 -1
- package/dist/{cli-a99cbd35.mjs → cli-fab3b4d7.mjs} +57 -57
- package/dist/cli.mjs +1 -1
- package/dist/{codestral.service-e6db6c08.mjs → codestral.service-e699d247.mjs} +1 -1
- package/dist/{cohere.service-6346af97.mjs → cohere.service-116c0ff2.mjs} +1 -1
- package/dist/{copilot-sdk.service-d2f51cb1.mjs → copilot-sdk.service-e79100de.mjs} +3 -3
- package/dist/{deep-seek.service-c4c223bd.mjs → deep-seek.service-55a7cae5.mjs} +1 -1
- package/dist/{gemini.service-f3781142.mjs → gemini.service-8229964f.mjs} +1 -1
- package/dist/{github-models.service-62c81303.mjs → github-models.service-2363c869.mjs} +1 -1
- package/dist/{groq.service-26ba8602.mjs → groq.service-91a40955.mjs} +1 -1
- package/dist/{hugging-face.service-041332a3.mjs → hugging-face.service-29dee38b.mjs} +1 -1
- package/dist/{mistral.service-af265922.mjs → mistral.service-97bbd45d.mjs} +1 -1
- package/dist/{ollama.service-205b1bf7.mjs → ollama.service-39fbf468.mjs} +1 -1
- package/dist/{openai-0090fa38.mjs → openai-9f0569a3.mjs} +1 -1
- package/dist/{openai-compatible.service-09ec26c2.mjs → openai-compatible.service-edf430e1.mjs} +1 -1
- package/dist/{openai.service-e424ef44.mjs → openai.service-0f4c84d2.mjs} +1 -1
- package/dist/{openrouter.service-54e19166.mjs → openrouter.service-4c0e10cf.mjs} +1 -1
- package/dist/{perplexity.service-1b9eaf27.mjs → perplexity.service-55a372f0.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import{command as G,cli as gs}from"cleye";import{createRequire as ys}from"module";import yt from"crypto";import O from"fs";import ue from"os";import A from"path";import{Buffer as fn}from"node:buffer";import ae from"node:path";import wt,{ChildProcess as pn,exec as ws}from"node:child_process";import U from"node:process";import Cs,{execSync as Ae,exec as Es}from"child_process";import{fileURLToPath as hn}from"node:url";import bs,{constants as gn}from"node:os";import vs from"assert";import As from"events";import{createWriteStream as Ps,createReadStream as xs,readFileSync as $s}from"node:fs";import Ss from"buffer";import Ct from"stream";import ks,{promisify as Rs}from"util";import{debuglog as Is,promisify as Ls}from"node:util";import T from"inquirer";import{from as Be,switchMap as yn,of as Ms,tap as Os,mergeMap as wn,catchError as Ts,BehaviorSubject as Cn,ReplaySubject as Ds,Subscription as Et,lastValueFrom as bt,toArray as vt,filter as En,map as bn,Subject as Ns}from"rxjs";import R from"fs/promises";import h from"chalk";import He from"readline";import vn from"figlet";import _s from"gradient-string";import An from"ora";import js from"inquirer-reactive-list-prompt";import K from"winston";import"winston-daily-rotate-file";import Fs from"axios";import{fileURLToPath as Gs,pathToFileURL as Bs}from"url";import{readdir as Pn,stat as Hs,rm as Us}from"node:fs/promises";import Ks from"chokidar";import{takeUntil as xn,finalize as $n}from"rxjs/operators";var Ws="aicommit2",Sn="2.6.0",qs="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",zs=["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"],Ys="MIT",Vs="tak-bro/aicommit2",Js="Hyungtak Jin(@tak-bro)",Xs="module",Qs=["dist"],Zs={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},er={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},tr={"@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.1.0",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"},nr={"@github/copilot-sdk":"0.2.0"},or={"@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"},sr={extends:["@pvtnbr","prettier"],rules:{"unicorn/no-process-exit":"off"},overrides:[{files:"./src/commands/prepare-commit-msg-hook.ts",rules:{"unicorn/prevent-abbreviations":"off"}}]},rr={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"},{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"]},ir={name:Ws,version:Sn,description:qs,keywords:zs,license:Ys,repository:Vs,author:Js,type:Xs,files:Qs,bin:Zs,scripts:er,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:tr,optionalDependencies:nr,devDependencies:or,eslintConfig:sr,release:rr},At=ys(import.meta.url),oe=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function de(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var me={exports:{}},Pt,kn;function ar(){if(kn)return Pt;kn=1,Pt=o,o.sync=s;var e=O;function t(r,a){var c=a.pathExt!==void 0?a.pathExt:process.env.PATHEXT;if(!c||(c=c.split(";"),c.indexOf("")!==-1))return!0;for(var l=0;l<c.length;l++){var u=c[l].toLowerCase();if(u&&r.substr(-u.length).toLowerCase()===u)return!0}return!1}function n(r,a,c){return!r.isSymbolicLink()&&!r.isFile()?!1:t(a,c)}function o(r,a,c){e.stat(r,function(l,u){c(l,l?!1:n(u,r,a))})}function s(r,a){return n(e.statSync(r),r,a)}return Pt}var xt,Rn;function cr(){if(Rn)return xt;Rn=1,xt=t,t.sync=n;var e=O;function t(r,a,c){e.stat(r,function(l,u){c(l,l?!1:o(u,a))})}function n(r,a){return o(e.statSync(r),a)}function o(r,a){return r.isFile()&&s(r,a)}function s(r,a){var c=r.mode,l=r.uid,u=r.gid,d=a.uid!==void 0?a.uid:process.getuid&&process.getuid(),p=a.gid!==void 0?a.gid:process.getgid&&process.getgid(),g=parseInt("100",8),y=parseInt("010",8),f=parseInt("001",8),$=g|y,S=c&f||c&y&&u===p||c&g&&l===d||c&$&&d===0;return S}return xt}var Ue;process.platform==="win32"||oe.TESTING_WINDOWS?Ue=ar():Ue=cr();var lr=$t;$t.sync=ur;function $t(e,t,n){if(typeof t=="function"&&(n=t,t={}),!n){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){$t(e,t||{},function(r,a){r?s(r):o(a)})})}Ue(e,t||{},function(o,s){o&&(o.code==="EACCES"||t&&t.ignoreErrors)&&(o=null,s=!1),n(o,s)})}function ur(e,t){try{return Ue.sync(e,t||{})}catch(n){if(t&&t.ignoreErrors||n.code==="EACCES")return!1;throw n}}const fe=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",In=A,dr=fe?";":":",Ln=lr,Mn=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),On=(e,t)=>{const n=t.colon||dr,o=e.match(/\//)||fe&&e.match(/\\/)?[""]:[...fe?[process.cwd()]:[],...(t.path||process.env.PATH||"").split(n)],s=fe?t.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",r=fe?s.split(n):[""];return fe&&e.indexOf(".")!==-1&&r[0]!==""&&r.unshift(""),{pathEnv:o,pathExt:r,pathExtExe:s}},Tn=(e,t,n)=>{typeof t=="function"&&(n=t,t={}),t||(t={});const{pathEnv:o,pathExt:s,pathExtExe:r}=On(e,t),a=[],c=u=>new Promise((d,p)=>{if(u===o.length)return t.all&&a.length?d(a):p(Mn(e));const g=o[u],y=/^".*"$/.test(g)?g.slice(1,-1):g,f=In.join(y,e),$=!y&&/^\.[\\\/]/.test(e)?e.slice(0,2)+f:f;d(l($,u,0))}),l=(u,d,p)=>new Promise((g,y)=>{if(p===s.length)return g(c(d+1));const f=s[p];Ln(u+f,{pathExt:r},($,S)=>{if(!$&&S)if(t.all)a.push(u+f);else return g(u+f);return g(l(u,d,p+1))})});return n?c(0).then(u=>n(null,u),n):c(0)},mr=(e,t)=>{t=t||{};const{pathEnv:n,pathExt:o,pathExtExe:s}=On(e,t),r=[];for(let a=0;a<n.length;a++){const c=n[a],l=/^".*"$/.test(c)?c.slice(1,-1):c,u=In.join(l,e),d=!l&&/^\.[\\\/]/.test(e)?e.slice(0,2)+u:u;for(let p=0;p<o.length;p++){const g=d+o[p];try{if(Ln.sync(g,{pathExt:s}))if(t.all)r.push(g);else return g}catch{}}}if(t.all&&r.length)return r;if(t.nothrow)return null;throw Mn(e)};var fr=Tn;Tn.sync=mr;var St={exports:{}};const Dn=(e={})=>{const t=e.env||process.env;return(e.platform||process.platform)!=="win32"?"PATH":Object.keys(t).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};St.exports=Dn,St.exports.default=Dn;var pr=St.exports;const Nn=A,hr=fr,gr=pr;function _n(e,t){const n=e.options.env||process.env,o=process.cwd(),s=e.options.cwd!=null,r=s&&process.chdir!==void 0&&!process.chdir.disabled;if(r)try{process.chdir(e.options.cwd)}catch{}let a;try{a=hr.sync(e.command,{path:n[gr({env:n})],pathExt:t?Nn.delimiter:void 0})}catch{}finally{r&&process.chdir(o)}return a&&(a=Nn.resolve(s?e.options.cwd:"",a)),a}function yr(e){return _n(e)||_n(e,!0)}var wr=yr,kt={};const Rt=/([()\][%!^"`<>&|;, *?])/g;function Cr(e){return e=e.replace(Rt,"^$1"),e}function Er(e,t){return e=`${e}`,e=e.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),e=e.replace(/(?=(\\+?)?)\1$/,"$1$1"),e=`"${e}"`,e=e.replace(Rt,"^$1"),t&&(e=e.replace(Rt,"^$1")),e}kt.command=Cr,kt.argument=Er;var br=/^#!(.*)/;const vr=br;var Ar=(e="")=>{const t=e.match(vr);if(!t)return null;const[n,o]=t[0].replace(/#! ?/,"").split(" "),s=n.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const It=O,Pr=Ar;function xr(e){const n=Buffer.alloc(150);let o;try{o=It.openSync(e,"r"),It.readSync(o,n,0,150,0),It.closeSync(o)}catch{}return Pr(n.toString())}var $r=xr;const Sr=A,jn=wr,Fn=kt,kr=$r,Rr=process.platform==="win32",Ir=/\.(?:com|exe)$/i,Lr=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Mr(e){e.file=jn(e);const t=e.file&&kr(e.file);return t?(e.args.unshift(e.file),e.command=t,jn(e)):e.file}function Or(e){if(!Rr)return e;const t=Mr(e),n=!Ir.test(t);if(e.options.forceShell||n){const o=Lr.test(t);e.command=Sr.normalize(e.command),e.command=Fn.command(e.command),e.args=e.args.map(r=>Fn.argument(r,o));const s=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${s}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}function Tr(e,t,n){t&&!Array.isArray(t)&&(n=t,t=null),t=t?t.slice(0):[],n=Object.assign({},n);const o={command:e,args:t,options:n,file:void 0,original:{command:e,args:t}};return n.shell?o:Or(o)}var Dr=Tr;const Lt=process.platform==="win32";function Mt(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function Nr(e,t){if(!Lt)return;const n=e.emit;e.emit=function(o,s){if(o==="exit"){const r=Gn(s,t);if(r)return n.call(e,"error",r)}return n.apply(e,arguments)}}function Gn(e,t){return Lt&&e===1&&!t.file?Mt(t.original,"spawn"):null}function _r(e,t){return Lt&&e===1&&!t.file?Mt(t.original,"spawnSync"):null}var jr={hookChildProcess:Nr,verifyENOENT:Gn,verifyENOENTSync:_r,notFoundError:Mt};const Bn=Cs,Ot=Dr,Tt=jr;function Hn(e,t,n){const o=Ot(e,t,n),s=Bn.spawn(o.command,o.args,o.options);return Tt.hookChildProcess(s,o),s}function Fr(e,t,n){const o=Ot(e,t,n),s=Bn.spawnSync(o.command,o.args,o.options);return s.error=s.error||Tt.verifyENOENTSync(s.status,o),s}me.exports=Hn,me.exports.spawn=Hn,me.exports.sync=Fr,me.exports._parse=Ot,me.exports._enoent=Tt;var Gr=me.exports,Br=de(Gr);function Hr(e){const t=typeof e=="string"?`
|
|
1
|
+
import{command as G,cli as ys}from"cleye";import{createRequire as ws}from"module";import yt from"crypto";import O from"fs";import ue from"os";import A from"path";import{Buffer as pn}from"node:buffer";import ae from"node:path";import wt,{ChildProcess as hn,exec as Cs}from"node:child_process";import U from"node:process";import Es,{execSync as Ae,exec as bs}from"child_process";import{fileURLToPath as gn}from"node:url";import vs,{constants as yn}from"node:os";import As from"assert";import Ps from"events";import{createWriteStream as xs,createReadStream as $s,readFileSync as Ss}from"node:fs";import ks from"buffer";import Ct from"stream";import Rs,{promisify as Is}from"util";import{debuglog as Ls,promisify as Ms}from"node:util";import T from"inquirer";import{from as Be,switchMap as wn,of as Os,tap as Ts,mergeMap as Cn,catchError as Ds,BehaviorSubject as En,ReplaySubject as Ns,Subscription as Et,lastValueFrom as bt,toArray as vt,filter as bn,map as vn,Subject as _s}from"rxjs";import R from"fs/promises";import h from"chalk";import He from"readline";import An from"figlet";import js from"gradient-string";import Pn from"ora";import Fs from"inquirer-reactive-list-prompt";import K from"winston";import"winston-daily-rotate-file";import Gs from"axios";import{fileURLToPath as Bs,pathToFileURL as Hs}from"url";import{readdir as xn,stat as Us,rm as Ks}from"node:fs/promises";import Ws from"chokidar";import{takeUntil as $n,finalize as Sn}from"rxjs/operators";var qs="aicommit2",kn="2.6.1",zs="A Reactive CLI that generates commit messages for Git and Jujutsu with various AI",Ys=["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"],Vs="MIT",Js="tak-bro/aicommit2",Xs="Hyungtak Jin(@tak-bro)",Qs="module",Zs=["dist"],er={aicommit2:"./dist/cli.mjs",aic2:"./dist/cli.mjs"},tr={prepare:"simple-git-hooks",build:"pkgroll --minify",lint:"eslint --cache .","type-check":"tsc",test:"tsx tests",prepack:"pnpm build && clean-pkg-json",prettier:"prettier"},nr={"@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.1.0",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"},or={"@github/copilot-sdk":"0.2.0"},sr={"@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"},rr={extends:["@pvtnbr","prettier"],rules:{"unicorn/no-process-exit":"off"},overrides:[{files:"./src/commands/prepare-commit-msg-hook.ts",rules:{"unicorn/prevent-abbreviations":"off"}}]},ir={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"},{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"]},ar={name:qs,version:kn,description:zs,keywords:Ys,license:Vs,repository:Js,author:Xs,type:Qs,files:Zs,bin:er,scripts:tr,"simple-git-hooks":{"pre-commit":"pnpm lint-staged"},"lint-staged":{"*.ts":["prettier --config ./.prettierrc --write","eslint --fix"]},dependencies:nr,optionalDependencies:or,devDependencies:sr,eslintConfig:rr,release:ir},At=ws(import.meta.url),ne=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function de(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var me={exports:{}},Pt,Rn;function cr(){if(Rn)return Pt;Rn=1,Pt=o,o.sync=s;var e=O;function t(r,a){var c=a.pathExt!==void 0?a.pathExt:process.env.PATHEXT;if(!c||(c=c.split(";"),c.indexOf("")!==-1))return!0;for(var l=0;l<c.length;l++){var u=c[l].toLowerCase();if(u&&r.substr(-u.length).toLowerCase()===u)return!0}return!1}function n(r,a,c){return!r.isSymbolicLink()&&!r.isFile()?!1:t(a,c)}function o(r,a,c){e.stat(r,function(l,u){c(l,l?!1:n(u,r,a))})}function s(r,a){return n(e.statSync(r),r,a)}return Pt}var xt,In;function lr(){if(In)return xt;In=1,xt=t,t.sync=n;var e=O;function t(r,a,c){e.stat(r,function(l,u){c(l,l?!1:o(u,a))})}function n(r,a){return o(e.statSync(r),a)}function o(r,a){return r.isFile()&&s(r,a)}function s(r,a){var c=r.mode,l=r.uid,u=r.gid,d=a.uid!==void 0?a.uid:process.getuid&&process.getuid(),p=a.gid!==void 0?a.gid:process.getgid&&process.getgid(),g=parseInt("100",8),y=parseInt("010",8),f=parseInt("001",8),$=g|y,S=c&f||c&y&&u===p||c&g&&l===d||c&$&&d===0;return S}return xt}var Ue;process.platform==="win32"||ne.TESTING_WINDOWS?Ue=cr():Ue=lr();var ur=$t;$t.sync=dr;function $t(e,t,n){if(typeof t=="function"&&(n=t,t={}),!n){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(o,s){$t(e,t||{},function(r,a){r?s(r):o(a)})})}Ue(e,t||{},function(o,s){o&&(o.code==="EACCES"||t&&t.ignoreErrors)&&(o=null,s=!1),n(o,s)})}function dr(e,t){try{return Ue.sync(e,t||{})}catch(n){if(t&&t.ignoreErrors||n.code==="EACCES")return!1;throw n}}const fe=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",Ln=A,mr=fe?";":":",Mn=ur,On=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),Tn=(e,t)=>{const n=t.colon||mr,o=e.match(/\//)||fe&&e.match(/\\/)?[""]:[...fe?[process.cwd()]:[],...(t.path||process.env.PATH||"").split(n)],s=fe?t.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",r=fe?s.split(n):[""];return fe&&e.indexOf(".")!==-1&&r[0]!==""&&r.unshift(""),{pathEnv:o,pathExt:r,pathExtExe:s}},Dn=(e,t,n)=>{typeof t=="function"&&(n=t,t={}),t||(t={});const{pathEnv:o,pathExt:s,pathExtExe:r}=Tn(e,t),a=[],c=u=>new Promise((d,p)=>{if(u===o.length)return t.all&&a.length?d(a):p(On(e));const g=o[u],y=/^".*"$/.test(g)?g.slice(1,-1):g,f=Ln.join(y,e),$=!y&&/^\.[\\\/]/.test(e)?e.slice(0,2)+f:f;d(l($,u,0))}),l=(u,d,p)=>new Promise((g,y)=>{if(p===s.length)return g(c(d+1));const f=s[p];Mn(u+f,{pathExt:r},($,S)=>{if(!$&&S)if(t.all)a.push(u+f);else return g(u+f);return g(l(u,d,p+1))})});return n?c(0).then(u=>n(null,u),n):c(0)},fr=(e,t)=>{t=t||{};const{pathEnv:n,pathExt:o,pathExtExe:s}=Tn(e,t),r=[];for(let a=0;a<n.length;a++){const c=n[a],l=/^".*"$/.test(c)?c.slice(1,-1):c,u=Ln.join(l,e),d=!l&&/^\.[\\\/]/.test(e)?e.slice(0,2)+u:u;for(let p=0;p<o.length;p++){const g=d+o[p];try{if(Mn.sync(g,{pathExt:s}))if(t.all)r.push(g);else return g}catch{}}}if(t.all&&r.length)return r;if(t.nothrow)return null;throw On(e)};var pr=Dn;Dn.sync=fr;var St={exports:{}};const Nn=(e={})=>{const t=e.env||process.env;return(e.platform||process.platform)!=="win32"?"PATH":Object.keys(t).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"};St.exports=Nn,St.exports.default=Nn;var hr=St.exports;const _n=A,gr=pr,yr=hr;function jn(e,t){const n=e.options.env||process.env,o=process.cwd(),s=e.options.cwd!=null,r=s&&process.chdir!==void 0&&!process.chdir.disabled;if(r)try{process.chdir(e.options.cwd)}catch{}let a;try{a=gr.sync(e.command,{path:n[yr({env:n})],pathExt:t?_n.delimiter:void 0})}catch{}finally{r&&process.chdir(o)}return a&&(a=_n.resolve(s?e.options.cwd:"",a)),a}function wr(e){return jn(e)||jn(e,!0)}var Cr=wr,kt={};const Rt=/([()\][%!^"`<>&|;, *?])/g;function Er(e){return e=e.replace(Rt,"^$1"),e}function br(e,t){return e=`${e}`,e=e.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'),e=e.replace(/(?=(\\+?)?)\1$/,"$1$1"),e=`"${e}"`,e=e.replace(Rt,"^$1"),t&&(e=e.replace(Rt,"^$1")),e}kt.command=Er,kt.argument=br;var vr=/^#!(.*)/;const Ar=vr;var Pr=(e="")=>{const t=e.match(Ar);if(!t)return null;const[n,o]=t[0].replace(/#! ?/,"").split(" "),s=n.split("/").pop();return s==="env"?o:o?`${s} ${o}`:s};const It=O,xr=Pr;function $r(e){const n=Buffer.alloc(150);let o;try{o=It.openSync(e,"r"),It.readSync(o,n,0,150,0),It.closeSync(o)}catch{}return xr(n.toString())}var Sr=$r;const kr=A,Fn=Cr,Gn=kt,Rr=Sr,Ir=process.platform==="win32",Lr=/\.(?:com|exe)$/i,Mr=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function Or(e){e.file=Fn(e);const t=e.file&&Rr(e.file);return t?(e.args.unshift(e.file),e.command=t,Fn(e)):e.file}function Tr(e){if(!Ir)return e;const t=Or(e),n=!Lr.test(t);if(e.options.forceShell||n){const o=Mr.test(t);e.command=kr.normalize(e.command),e.command=Gn.command(e.command),e.args=e.args.map(r=>Gn.argument(r,o));const s=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${s}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}function Dr(e,t,n){t&&!Array.isArray(t)&&(n=t,t=null),t=t?t.slice(0):[],n=Object.assign({},n);const o={command:e,args:t,options:n,file:void 0,original:{command:e,args:t}};return n.shell?o:Tr(o)}var Nr=Dr;const Lt=process.platform==="win32";function Mt(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function _r(e,t){if(!Lt)return;const n=e.emit;e.emit=function(o,s){if(o==="exit"){const r=Bn(s,t);if(r)return n.call(e,"error",r)}return n.apply(e,arguments)}}function Bn(e,t){return Lt&&e===1&&!t.file?Mt(t.original,"spawn"):null}function jr(e,t){return Lt&&e===1&&!t.file?Mt(t.original,"spawnSync"):null}var Fr={hookChildProcess:_r,verifyENOENT:Bn,verifyENOENTSync:jr,notFoundError:Mt};const Hn=Es,Ot=Nr,Tt=Fr;function Un(e,t,n){const o=Ot(e,t,n),s=Hn.spawn(o.command,o.args,o.options);return Tt.hookChildProcess(s,o),s}function Gr(e,t,n){const o=Ot(e,t,n),s=Hn.spawnSync(o.command,o.args,o.options);return s.error=s.error||Tt.verifyENOENTSync(s.status,o),s}me.exports=Un,me.exports.spawn=Un,me.exports.sync=Gr,me.exports._parse=Ot,me.exports._enoent=Tt;var Br=me.exports,Hr=de(Br);function Ur(e){const t=typeof e=="string"?`
|
|
2
2
|
`:`
|
|
3
|
-
`.charCodeAt(),n=typeof e=="string"?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,-1)),e[e.length-1]===n&&(e=e.slice(0,-1)),e}function
|
|
4
|
-
${t}`,
|
|
3
|
+
`.charCodeAt(),n=typeof e=="string"?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,-1)),e[e.length-1]===n&&(e=e.slice(0,-1)),e}function Kn(e={}){const{env:t=process.env,platform:n=process.platform}=e;return n!=="win32"?"PATH":Object.keys(t).reverse().find(o=>o.toUpperCase()==="PATH")||"Path"}const Kr=({cwd:e=U.cwd(),path:t=U.env[Kn()],preferLocal:n=!0,execPath:o=U.execPath,addExecPath:s=!0}={})=>{const r=e instanceof URL?gn(e):e,a=ae.resolve(r),c=[];return n&&Wr(c,a),s&&qr(c,o,a),[...c,t].join(ae.delimiter)},Wr=(e,t)=>{let n;for(;n!==t;)e.push(ae.join(t,"node_modules/.bin")),n=t,t=ae.resolve(t,"..")},qr=(e,t,n)=>{const o=t instanceof URL?gn(t):t;e.push(ae.resolve(n,o,".."))},zr=({env:e=U.env,...t}={})=>{e={...e};const n=Kn({env:e});return t.path=e[n],e[n]=Kr(t),e},Yr=(e,t,n,o)=>{if(n==="length"||n==="prototype"||n==="arguments"||n==="caller")return;const s=Object.getOwnPropertyDescriptor(e,n),r=Object.getOwnPropertyDescriptor(t,n);!Vr(s,r)&&o||Object.defineProperty(e,n,r)},Vr=function(e,t){return e===void 0||e.configurable||e.writable===t.writable&&e.enumerable===t.enumerable&&e.configurable===t.configurable&&(e.writable||e.value===t.value)},Jr=(e,t)=>{const n=Object.getPrototypeOf(t);n!==Object.getPrototypeOf(e)&&Object.setPrototypeOf(e,n)},Xr=(e,t)=>`/* Wrapped ${e}*/
|
|
4
|
+
${t}`,Qr=Object.getOwnPropertyDescriptor(Function.prototype,"toString"),Zr=Object.getOwnPropertyDescriptor(Function.prototype.toString,"name"),ei=(e,t,n)=>{const o=n===""?"":`with ${n.trim()}() `,s=Xr.bind(null,o,t.toString());Object.defineProperty(s,"name",Zr),Object.defineProperty(e,"toString",{...Qr,value:s})};function ti(e,t,{ignoreNonConfigurable:n=!1}={}){const{name:o}=e;for(const s of Reflect.ownKeys(t))Yr(e,t,s,n);return Jr(e,t),ei(e,t,o),e}const Ke=new WeakMap,Wn=(e,t={})=>{if(typeof e!="function")throw new TypeError("Expected a function");let n,o=0;const s=e.displayName||e.name||"<anonymous>",r=function(...a){if(Ke.set(r,++o),o===1)n=e.apply(this,a),e=null;else if(t.throw===!0)throw new Error(`Function \`${s}\` can only be called once`);return n};return ti(r,e),Ke.set(r,o),r};Wn.callCount=e=>{if(!Ke.has(e))throw new Error(`The given function \`${e.name}\` is not wrapped by the \`onetime\` package`);return Ke.get(e)};const ni=()=>{const e=zn-qn+1;return Array.from({length:e},oi)},oi=(e,t)=>({name:`SIGRT${t+1}`,number:qn+t,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),qn=34,zn=64,si=[{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"}],Yn=()=>{const e=ni();return[...si,...e].map(ri)},ri=({name:e,number:t,description:n,action:o,forced:s=!1,standard:r})=>{const{signals:{[e]:a}}=yn,c=a!==void 0;return{name:e,number:c?a:t,description:n,supported:c,action:o,forced:s,standard:r}},ii=()=>{const e=Yn();return Object.fromEntries(e.map(ai))},ai=({name:e,number:t,description:n,supported:o,action:s,forced:r,standard:a})=>[e,{name:e,number:t,description:n,supported:o,action:s,forced:r,standard:a}],ci=ii(),li=()=>{const e=Yn(),t=zn+1,n=Array.from({length:t},(o,s)=>ui(s,e));return Object.assign({},...n)},ui=(e,t)=>{const n=di(e,t);if(n===void 0)return{};const{name:o,description:s,supported:r,action:a,forced:c,standard:l}=n;return{[e]:{name:o,number:e,description:s,supported:r,action:a,forced:c,standard:l}}},di=(e,t)=>{const n=t.find(({name:o})=>yn.signals[o]===e);return n!==void 0?n:t.find(o=>o.number===e)};li();const mi=({timedOut:e,timeout:t,errorCode:n,signal:o,signalDescription:s,exitCode:r,isCanceled:a})=>e?`timed out after ${t} milliseconds`:a?"was canceled":n!==void 0?`failed with ${n}`:o!==void 0?`was killed with ${o} (${s})`:r!==void 0?`failed with exit code ${r}`:"failed",We=({stdout:e,stderr:t,all:n,error:o,signal:s,exitCode:r,command:a,escapedCommand:c,timedOut:l,isCanceled:u,killed:d,parsed:{options:{timeout:p,cwd:g=U.cwd()}}})=>{r=r===null?void 0:r,s=s===null?void 0:s;const y=s===void 0?void 0:ci[s].description,f=o&&o.code,S=`Command ${mi({timedOut:l,timeout:p,errorCode:f,signal:s,signalDescription:y,exitCode:r,isCanceled:u})}: ${a}`,x=Object.prototype.toString.call(o)==="[object Error]",P=x?`${S}
|
|
5
5
|
${o.message}`:S,v=[P,t,e].filter(Boolean).join(`
|
|
6
|
-
`);return x?(o.originalMessage=o.message,o.message=v):o=new Error(v),o.shortMessage=P,o.command=a,o.escapedCommand=c,o.exitCode=r,o.signal=s,o.signalDescription=y,o.stdout=e,o.stderr=t,o.cwd=g,n!==void 0&&(o.all=n),"bufferedData"in o&&delete o.bufferedData,o.failed=!0,o.timedOut=!!l,o.isCanceled=u,o.killed=d&&!l,o},qe=["stdin","stdout","stderr"],
|
|
7
|
-
`)},
|
|
6
|
+
`);return x?(o.originalMessage=o.message,o.message=v):o=new Error(v),o.shortMessage=P,o.command=a,o.escapedCommand=c,o.exitCode=r,o.signal=s,o.signalDescription=y,o.stdout=e,o.stderr=t,o.cwd=g,n!==void 0&&(o.all=n),"bufferedData"in o&&delete o.bufferedData,o.failed=!0,o.timedOut=!!l,o.isCanceled=u,o.killed=d&&!l,o},qe=["stdin","stdout","stderr"],fi=e=>qe.some(t=>e[t]!==void 0),Vn=e=>{if(!e)return;const{stdio:t}=e;if(t===void 0)return qe.map(o=>e[o]);if(fi(e))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${qe.map(o=>`\`${o}\``).join(", ")}`);if(typeof t=="string")return t;if(!Array.isArray(t))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof t}\``);const n=Math.max(t.length,qe.length);return Array.from({length:n},(o,s)=>t[s])},pi=e=>{const t=Vn(e);return t==="ipc"?"ipc":t===void 0||typeof t=="string"?[t,t,t,"ipc"]:t.includes("ipc")?t:[...t,"ipc"]};var pe={exports:{}},ze={exports:{}};ze.exports;var Jn;function hi(){return Jn||(Jn=1,function(e){e.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],process.platform!=="win32"&&e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),process.platform==="linux"&&e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}(ze)),ze.exports}var M=ne.process;const ce=function(e){return e&&typeof e=="object"&&typeof e.removeListener=="function"&&typeof e.emit=="function"&&typeof e.reallyExit=="function"&&typeof e.listeners=="function"&&typeof e.kill=="function"&&typeof e.pid=="number"&&typeof e.on=="function"};if(!ce(M))pe.exports=function(){return function(){}};else{var gi=As,Pe=hi(),yi=/^win/i.test(M.platform),Ye=Ps;typeof Ye!="function"&&(Ye=Ye.EventEmitter);var _;M.__signal_exit_emitter__?_=M.__signal_exit_emitter__:(_=M.__signal_exit_emitter__=new Ye,_.count=0,_.emitted={}),_.infinite||(_.setMaxListeners(1/0),_.infinite=!0),pe.exports=function(e,t){if(!ce(ne.process))return function(){};gi.equal(typeof e,"function","a callback must be provided for exit handler"),xe===!1&&Xn();var n="exit";t&&t.alwaysLast&&(n="afterexit");var o=function(){_.removeListener(n,e),_.listeners("exit").length===0&&_.listeners("afterexit").length===0&&Dt()};return _.on(n,e),o};var Dt=function(){!xe||!ce(ne.process)||(xe=!1,Pe.forEach(function(t){try{M.removeListener(t,Nt[t])}catch{}}),M.emit=_t,M.reallyExit=Qn,_.count-=1)};pe.exports.unload=Dt;var he=function(t,n,o){_.emitted[t]||(_.emitted[t]=!0,_.emit(t,n,o))},Nt={};Pe.forEach(function(e){Nt[e]=function(){if(ce(ne.process)){var n=M.listeners(e);n.length===_.count&&(Dt(),he("exit",null,e),he("afterexit",null,e),yi&&e==="SIGHUP"&&(e="SIGINT"),M.kill(M.pid,e))}}}),pe.exports.signals=function(){return Pe};var xe=!1,Xn=function(){xe||!ce(ne.process)||(xe=!0,_.count+=1,Pe=Pe.filter(function(t){try{return M.on(t,Nt[t]),!0}catch{return!1}}),M.emit=Ci,M.reallyExit=wi)};pe.exports.load=Xn;var Qn=M.reallyExit,wi=function(t){ce(ne.process)&&(M.exitCode=t||0,he("exit",M.exitCode,null),he("afterexit",M.exitCode,null),Qn.call(M,M.exitCode))},_t=M.emit,Ci=function(t,n){if(t==="exit"&&ce(ne.process)){n!==void 0&&(M.exitCode=n);var o=_t.apply(this,arguments);return he("exit",M.exitCode,null),he("afterexit",M.exitCode,null),o}else return _t.apply(this,arguments)}}var Ei=pe.exports,bi=de(Ei);const vi=1e3*5,Ai=(e,t="SIGTERM",n={})=>{const o=e(t);return Pi(e,t,n,o),o},Pi=(e,t,n,o)=>{if(!xi(t,n,o))return;const s=Si(n),r=setTimeout(()=>{e("SIGKILL")},s);r.unref&&r.unref()},xi=(e,{forceKillAfterTimeout:t},n)=>$i(e)&&t!==!1&&n,$i=e=>e===vs.constants.signals.SIGTERM||typeof e=="string"&&e.toUpperCase()==="SIGTERM",Si=({forceKillAfterTimeout:e=!0})=>{if(e===!0)return vi;if(!Number.isFinite(e)||e<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`);return e},ki=(e,t)=>{e.kill()&&(t.isCanceled=!0)},Ri=(e,t,n)=>{e.kill(t),n(Object.assign(new Error("Timed out"),{timedOut:!0,signal:t}))},Ii=(e,{timeout:t,killSignal:n="SIGTERM"},o)=>{if(t===0||t===void 0)return o;let s;const r=new Promise((c,l)=>{s=setTimeout(()=>{Ri(e,n,l)},t)}),a=o.finally(()=>{clearTimeout(s)});return Promise.race([r,a])},Li=({timeout:e})=>{if(e!==void 0&&(!Number.isFinite(e)||e<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`)},Mi=async(e,{cleanup:t,detached:n},o)=>{if(!t||n)return o;const s=bi(()=>{e.kill()});return o.finally(()=>{s()})};function jt(e){return e!==null&&typeof e=="object"&&typeof e.pipe=="function"}function Zn(e){return jt(e)&&e.writable!==!1&&typeof e._write=="function"&&typeof e._writableState=="object"}const Oi=e=>e instanceof hn&&typeof e.then=="function",Ft=(e,t,n)=>{if(typeof n=="string")return e[t].pipe(xs(n)),e;if(Zn(n))return e[t].pipe(n),e;if(!Oi(n))throw new TypeError("The second argument must be a string, a stream or an Execa child process.");if(!Zn(n.stdin))throw new TypeError("The target child process's stdin must be available.");return e[t].pipe(n.stdin),n},Ti=e=>{e.stdout!==null&&(e.pipeStdout=Ft.bind(void 0,e,"stdout")),e.stderr!==null&&(e.pipeStderr=Ft.bind(void 0,e,"stderr")),e.all!==void 0&&(e.pipeAll=Ft.bind(void 0,e,"all"))};var $e={exports:{}};const{PassThrough:Di}=Ct;var Ni=e=>{e={...e};const{array:t}=e;let{encoding:n}=e;const o=n==="buffer";let s=!1;t?s=!(n||o):n=n||"utf8",o&&(n=null);const r=new Di({objectMode:s});n&&r.setEncoding(n);let a=0;const c=[];return r.on("data",l=>{c.push(l),s?a=c.length:a+=l.length}),r.getBufferedValue=()=>t?c:o?Buffer.concat(c,a):c.join(""),r.getBufferedLength=()=>a,r};const{constants:_i}=ks,ji=Ct,{promisify:Fi}=Rs,Gi=Ni,Bi=Fi(ji.pipeline);class eo extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function Gt(e,t){if(!e)throw new Error("Expected a stream");t={maxBuffer:1/0,...t};const{maxBuffer:n}=t,o=Gi(t);return await new Promise((s,r)=>{const a=c=>{c&&o.getBufferedLength()<=_i.MAX_LENGTH&&(c.bufferedData=o.getBufferedValue()),r(c)};(async()=>{try{await Bi(e,o),s()}catch(c){a(c)}})(),o.on("data",()=>{o.getBufferedLength()>n&&a(new eo)})}),o.getBufferedValue()}$e.exports=Gt,$e.exports.buffer=(e,t)=>Gt(e,{...t,encoding:"buffer"}),$e.exports.array=(e,t)=>Gt(e,{...t,array:!0}),$e.exports.MaxBufferError=eo;var Hi=$e.exports,to=de(Hi);const{PassThrough:Ui}=Ct;var Ki=function(){var e=[],t=new Ui({objectMode:!0});return t.setMaxListeners(0),t.add=n,t.isEmpty=o,t.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(n),t;function n(r){return Array.isArray(r)?(r.forEach(n),this):(e.push(r),r.once("end",s.bind(null,r)),r.once("error",t.emit.bind(t,"error")),r.pipe(t,{end:!1}),this)}function o(){return e.length==0}function s(r){e=e.filter(function(a){return a!==r}),!e.length&&t.readable&&t.end()}},Wi=de(Ki);const no=e=>{if(e!==void 0)throw new TypeError("The `input` and `inputFile` options cannot be both set.")},qi=({input:e,inputFile:t})=>typeof t!="string"?e:(no(e),Ss(t)),zi=e=>{const t=qi(e);if(jt(t))throw new TypeError("The `input` option cannot be a stream in sync mode");return t},Yi=({input:e,inputFile:t})=>typeof t!="string"?e:(no(e),$s(t)),Vi=(e,t)=>{const n=Yi(t);n!==void 0&&(jt(n)?n.pipe(e.stdin):e.stdin.end(n))},Ji=(e,{all:t})=>{if(!t||!e.stdout&&!e.stderr)return;const n=Wi();return e.stdout&&n.add(e.stdout),e.stderr&&n.add(e.stderr),n},Bt=async(e,t)=>{if(!(!e||t===void 0)){e.destroy();try{return await t}catch(n){return n.bufferedData}}},Ht=(e,{encoding:t,buffer:n,maxBuffer:o})=>{if(!(!e||!n))return t?to(e,{encoding:t,maxBuffer:o}):to.buffer(e,{maxBuffer:o})},Xi=async({stdout:e,stderr:t,all:n},{encoding:o,buffer:s,maxBuffer:r},a)=>{const c=Ht(e,{encoding:o,buffer:s,maxBuffer:r}),l=Ht(t,{encoding:o,buffer:s,maxBuffer:r}),u=Ht(n,{encoding:o,buffer:s,maxBuffer:r*2});try{return await Promise.all([a,c,l,u])}catch(d){return Promise.all([{error:d,signal:d.signal,timedOut:d.timedOut},Bt(e,c),Bt(t,l),Bt(n,u)])}},Qi=(async()=>{})().constructor.prototype,Zi=["then","catch","finally"].map(e=>[e,Reflect.getOwnPropertyDescriptor(Qi,e)]),oo=(e,t)=>{for(const[n,o]of Zi){const s=typeof t=="function"?(...r)=>Reflect.apply(o.value,t(),r):o.value.bind(t);Reflect.defineProperty(e,n,{...o,value:s})}},ea=e=>new Promise((t,n)=>{e.on("exit",(o,s)=>{t({exitCode:o,signal:s})}),e.on("error",o=>{n(o)}),e.stdin&&e.stdin.on("error",o=>{n(o)})}),so=(e,t=[])=>Array.isArray(t)?[e,...t]:[e],ta=/^[\w.-]+$/,na=/"/g,oa=e=>typeof e!="string"||ta.test(e)?e:`"${e.replace(na,'\\"')}"`,ro=(e,t)=>so(e,t).join(" "),io=(e,t)=>so(e,t).map(n=>oa(n)).join(" "),ao=/ +/g,co=e=>{const t=[];for(const n of e.trim().split(ao)){const o=t[t.length-1];o&&o.endsWith("\\")?t[t.length-1]=`${o.slice(0,-1)} ${n}`:t.push(n)}return t},lo=e=>{const t=typeof e;if(t==="string")return e;if(t==="number")return String(e);if(t==="object"&&e!==null&&!(e instanceof hn)&&"stdout"in e){const n=typeof e.stdout;if(n==="string")return e.stdout;if(pn.isBuffer(e.stdout))return e.stdout.toString();throw new TypeError(`Unexpected "${n}" stdout in template expression`)}throw new TypeError(`Unexpected "${t}" in template expression`)},uo=(e,t,n)=>n||e.length===0||t.length===0?[...e,...t]:[...e.slice(0,-1),`${e[e.length-1]}${t[0]}`,...t.slice(1)],sa=({templates:e,expressions:t,tokens:n,index:o,template:s})=>{const r=s??e.raw[o],a=r.split(ao).filter(Boolean),c=uo(n,a,r.startsWith(" "));if(o===t.length)return c;const l=t[o],u=Array.isArray(l)?l.map(d=>lo(d)):[lo(l)];return uo(c,u,r.endsWith(" "))},mo=(e,t)=>{let n=[];for(const[o,s]of e.entries())n=sa({templates:e,expressions:t,tokens:n,index:o,template:s});return n},ra=Ls("execa").enabled,Ve=(e,t)=>String(e).padStart(t,"0"),ia=()=>{const e=new Date;return`${Ve(e.getHours(),2)}:${Ve(e.getMinutes(),2)}:${Ve(e.getSeconds(),2)}.${Ve(e.getMilliseconds(),3)}`},fo=(e,{verbose:t})=>{t&&U.stderr.write(`[${ia()}] ${e}
|
|
7
|
+
`)},aa=1e3*1e3*100,ca=({env:e,extendEnv:t,preferLocal:n,localDir:o,execPath:s})=>{const r=t?{...U.env,...e}:e;return n?zr({env:r,cwd:o,execPath:s}):r},po=(e,t,n={})=>{const o=Hr._parse(e,t,n);return e=o.command,t=o.args,n=o.options,n={maxBuffer:aa,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:n.cwd||U.cwd(),execPath:U.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:ra,...n},n.env=ca(n),n.stdio=Vn(n),U.platform==="win32"&&ae.basename(e,".exe")==="cmd"&&t.unshift("/q"),{file:e,args:t,options:n,parsed:o}},Se=(e,t,n)=>typeof t!="string"&&!pn.isBuffer(t)?n===void 0?void 0:"":e.stripFinalNewline?Ur(t):t;function C(e,t,n){const o=po(e,t,n),s=ro(e,t),r=io(e,t);fo(r,o.options),Li(o.options);let a;try{a=wt.spawn(o.file,o.args,o.options)}catch(y){const f=new wt.ChildProcess,$=Promise.reject(We({error:y,stdout:"",stderr:"",all:"",command:s,escapedCommand:r,parsed:o,timedOut:!1,isCanceled:!1,killed:!1}));return oo(f,$),f}const c=ea(a),l=Ii(a,o.options,c),u=Mi(a,o.options,l),d={isCanceled:!1};a.kill=Ai.bind(null,a.kill.bind(a)),a.cancel=ki.bind(null,a,d);const g=Wn(async()=>{const[{error:y,exitCode:f,signal:$,timedOut:S},x,P,v]=await Xi(a,o.options,u),w=Se(o.options,x),I=Se(o.options,P),L=Se(o.options,v);if(y||f!==0||$!==null){const N=We({error:y,exitCode:f,signal:$,stdout:w,stderr:I,all:L,command:s,escapedCommand:r,parsed:o,timedOut:S,isCanceled:d.isCanceled||(o.options.signal?o.options.signal.aborted:!1),killed:a.killed});if(!o.options.reject)return N;throw N}return{command:s,escapedCommand:r,exitCode:0,stdout:w,stderr:I,all:L,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return Vi(a,o.options),a.all=Ji(a,o.options),Ti(a),oo(a,g),a}function Ut(e,t,n){const o=po(e,t,n),s=ro(e,t),r=io(e,t);fo(r,o.options);const a=zi(o.options);let c;try{c=wt.spawnSync(o.file,o.args,{...o.options,input:a})}catch(d){throw We({error:d,stdout:"",stderr:"",all:"",command:s,escapedCommand:r,parsed:o,timedOut:!1,isCanceled:!1,killed:!1})}const l=Se(o.options,c.stdout,c.error),u=Se(o.options,c.stderr,c.error);if(c.error||c.status!==0||c.signal!==null){const d=We({stdout:l,stderr:u,error:c.error,signal:c.signal,exitCode:c.status,command:s,escapedCommand:r,parsed:o,timedOut:c.error&&c.error.code==="ETIMEDOUT",isCanceled:!1,killed:c.signal!==null});if(!o.options.reject)return d;throw d}return{command:s,escapedCommand:r,exitCode:0,stdout:l,stderr:u,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}}const la=({input:e,inputFile:t,stdio:n})=>e===void 0&&t===void 0&&n===void 0?{stdin:"inherit"}:{},ho=(e={})=>({preferLocal:!0,...la(e),...e});function go(e){function t(n,...o){if(!Array.isArray(n))return go({...e,...n});const[s,...r]=mo(n,o);return C(s,r,ho(e))}return t.sync=(n,...o)=>{if(!Array.isArray(n))throw new TypeError("Please use $(options).sync`command` instead of $.sync(options)`command`.");const[s,...r]=mo(n,o);return Ut(s,r,ho(e))},t}const ua=go();function da(e,t){const[n,...o]=co(e);return C(n,o,t)}function ma(e,t){const[n,...o]=co(e);return Ut(n,o,t)}function fa(e,t,n={}){t&&!Array.isArray(t)&&typeof t=="object"&&(n=t,t=[]);const o=pi(n),s=U.execArgv.filter(c=>!c.startsWith("--inspect")),{nodePath:r=U.execPath,nodeOptions:a=s}=n;return C(r,[...a,e,...Array.isArray(t)?t:[]],{...n,stdin:void 0,stdout:void 0,stderr:void 0,stdio:o,shell:!1})}var pa=Object.freeze({__proto__:null,execa:C,execaSync:Ut,$:ua,execaCommand:da,execaCommandSync:ma,execaNode:fa});const{hasOwnProperty:Kt}=Object.prototype,Je=typeof process<"u"&&process.platform==="win32"?`\r
|
|
8
8
|
`:`
|
|
9
|
-
`,Wt=(e,t)=>{const n=[];let o="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const s=t.whitespace?" = ":"=";for(const r of Object.keys(e)){const a=e[r];if(a&&Array.isArray(a))for(const c of a)o+=ge(r+"[]")+s+ge(c)+Je;else a&&typeof a=="object"?n.push(r):o+=ge(r)+s+ge(a)+Je}t.section&&o.length&&(o="["+ge(t.section)+"]"+Je+o);for(const r of n){const a=
|
|
10
|
-
`).length;return n.mode==="none"||!e.trim()?{diff:e,stats:{originalLines:o,compressedLines:o,originalChars:e.length,compressedChars:e.length,truncatedHunks:0,truncatedFiles:0}}:
|
|
11
|
-
`);return{diff:d,stats:{originalLines:n,compressedLines:s.length,originalChars:e.length,compressedChars:d.length,truncatedHunks:r,truncatedFiles:a}}},
|
|
12
|
-
`),n=[];let o=[];for(const s of t)s.startsWith("diff --git ")?(o.length>0&&n.push(o),o=[s]):o.push(s);return o.length>0&&n.push(o),n},
|
|
9
|
+
`,Wt=(e,t)=>{const n=[];let o="";typeof t=="string"?t={section:t,whitespace:!1}:(t=t||Object.create(null),t.whitespace=t.whitespace===!0);const s=t.whitespace?" = ":"=";for(const r of Object.keys(e)){const a=e[r];if(a&&Array.isArray(a))for(const c of a)o+=ge(r+"[]")+s+ge(c)+Je;else a&&typeof a=="object"?n.push(r):o+=ge(r)+s+ge(a)+Je}t.section&&o.length&&(o="["+ge(t.section)+"]"+Je+o);for(const r of n){const a=yo(r).join("\\."),c=(t.section?t.section+".":"")+a,{whitespace:l}=t,u=Wt(e[r],{section:c,whitespace:l});o.length&&u.length&&(o+=Je),o+=u}return o},yo=e=>e.replace(/\1/g,"LITERAL\\1LITERAL").replace(/\\\./g,"").split(/\./).map(t=>t.replace(/\1/g,"\\.").replace(/\2LITERAL\\1LITERAL\2/g,"")),wo=e=>{const t=Object.create(null);let n=t,o=null;const s=/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i,r=e.split(/[\r\n]+/g);for(const c of r){if(!c||c.match(/^\s*[;#]/))continue;const l=c.match(s);if(!l)continue;if(l[1]!==void 0){if(o=Xe(l[1]),o==="__proto__"){n=Object.create(null);continue}n=t[o]=t[o]||Object.create(null);continue}const u=Xe(l[2]),d=u.length>2&&u.slice(-2)==="[]",p=d?u.slice(0,-2):u;if(p==="__proto__")continue;const g=l[3]?Xe(l[4]):!0,y=g==="true"||g==="false"||g==="null"?JSON.parse(g):g;d&&(Kt.call(n,p)?Array.isArray(n[p])||(n[p]=[n[p]]):n[p]=[]),Array.isArray(n[p])?n[p].push(y):n[p]=y}const a=[];for(const c of Object.keys(t)){if(!Kt.call(t,c)||typeof t[c]!="object"||Array.isArray(t[c]))continue;const l=yo(c);n=t;const u=l.pop(),d=u.replace(/\\\./g,".");for(const p of l)p!=="__proto__"&&((!Kt.call(n,p)||typeof n[p]!="object")&&(n[p]=Object.create(null)),n=n[p]);n===t&&d===u||(n[d]=t[c],a.push(c))}for(const c of a)delete t[c];return t},Co=e=>e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"),ge=e=>typeof e!="string"||e.match(/[=\r\n]/)||e.match(/^\[/)||e.length>1&&Co(e)||e!==e.trim()?JSON.stringify(e):e.split(";").join("\\;").split("#").join("\\#"),Xe=(e,t)=>{if(e=(e||"").trim(),Co(e)){e.charAt(0)==="'"&&(e=e.slice(1,-1));try{e=JSON.parse(e)}catch{}}else{let n=!1,o="";for(let s=0,r=e.length;s<r;s++){const a=e.charAt(s);if(n)"\\;#".indexOf(a)!==-1?o+=a:o+="\\"+a,n=!1;else{if(";#".indexOf(a)!==-1)break;a==="\\"?n=!0:o+=a}}return n&&(o+="\\"),o.trim()}return e};var ha={parse:wo,decode:wo,stringify:Wt,encode:Wt,safe:ge,unsafe:Xe},ye=de(ha);const we=3,ga=3,Eo={mode:"none",maxHunkLines:0,maxDiffLines:0},ya=(e,t={})=>{const n={...Eo,...t},o=e.split(`
|
|
10
|
+
`).length;return n.mode==="none"||!e.trim()?{diff:e,stats:{originalLines:o,compressedLines:o,originalChars:e.length,compressedChars:e.length,truncatedHunks:0,truncatedFiles:0}}:wa(e,n,o)},wa=(e,t,n)=>{const o=Ca(e),s=[];let r=0,a=0;const c=t.maxDiffLines>0?t.maxDiffLines:1/0,l=t.maxHunkLines>0?t.maxHunkLines:1/0;for(let p=0;p<o.length;p++){if(s.length>=c){a+=o.length-p;break}const{lines:g,hunksTruncated:y}=Ea(o[p],l);r+=y;const f=c-s.length;if(g.length>f){s.push(...g.slice(0,f)),a+=o.length-p-1;break}s.push(...g)}if(r>0||a>0){const p=[];r>0&&p.push(`${r} hunk${r>1?"s":""} truncated`),a>0&&p.push(`${a} file${a>1?"s":""} omitted`),s.push("",`[diff compressed \u2014 ${p.join(", ")}]`)}const d=s.join(`
|
|
11
|
+
`);return{diff:d,stats:{originalLines:n,compressedLines:s.length,originalChars:e.length,compressedChars:d.length,truncatedHunks:r,truncatedFiles:a}}},Ca=e=>{const t=e.split(`
|
|
12
|
+
`),n=[];let o=[];for(const s of t)s.startsWith("diff --git ")?(o.length>0&&n.push(o),o=[s]):o.push(s);return o.length>0&&n.push(o),n},Ea=(e,t)=>{const o=[`=== ${va(e)} ===`];let s=0;const r=[];let a=null;for(const c of e)if(!Aa(c)){if(c.startsWith("@@")){a&&r.push(a),a={header:c,lines:[]};continue}a&&a.lines.push(c)}a&&r.push(a);for(const c of r){o.push(c.header);const l=ba(c.lines);if(t>0&&l.length>t){const u=l.length-t;o.push(...l.slice(0,t)),o.push(`[... ${u} lines truncated]`),s++}else o.push(...l)}return{lines:o,hunksTruncated:s}},ba=e=>{if(e.length===0)return[];const t=e.map(r=>r.startsWith("+")||r.startsWith("-")),n=new Array(e.length).fill(!1);for(let r=0;r<e.length;r++)if(t[r]){n[r]=!0;for(let a=1;a<=ga;a++)r-a>=0&&(n[r-a]=!0),r+a<e.length&&(n[r+a]=!0);continue}const o=[];let s=!1;for(let r=0;r<e.length;r++)n[r]?(s&&(o.push(" ..."),s=!1),o.push(e[r])):s=!0;return o},va=e=>{const n=(e[0]||"").match(/^diff --git a\/(.+?) b\/(.+)$/);if(!n)return"unknown";const[,o,s]=n;return o!==s?`${o} \u2192 ${s}`:s},Aa=e=>e.startsWith("diff --git ")||e.startsWith("index ")||e.startsWith("--- a/")||e.startsWith("--- /dev/null")||e.startsWith("+++ b/")||e.startsWith("+++ /dev/null")||e.startsWith("old mode ")||e.startsWith("new mode ")||e.startsWith("new file mode ")||e.startsWith("deleted file mode ")||e.startsWith("similarity index ")||e.startsWith("rename from ")||e.startsWith("rename to ")||e.startsWith("Binary files ");class m extends Error{constructor(t,n={}){super(t,{cause:n.cause}),this.name="KnownError",this.code=n.code,this.suggestions=n.suggestions||[]}}const ke=" ",W=e=>{if(e instanceof Error){if(e instanceof m){e.suggestions.length>0&&(console.error(""),console.error(`${ke}${h.yellow("Suggestions:")}`),e.suggestions.forEach(t=>{console.error(`${ke} ${h.dim("\u2022")} ${t}`)}));return}e.stack&&console.error(h.dim(e.stack.split(`
|
|
13
13
|
`).slice(1).join(`
|
|
14
14
|
`))),console.error(`
|
|
15
|
-
${ke}${h.dim(`aicommit2 v${
|
|
16
|
-
${ke}Please open a Bug report with the information above:`),console.error(`${ke}https://github.com/tak-bro/aicommit2/issues/new/choose`)}},Qe=e=>R.lstat(e).then(()=>!0,()=>!1),Eo=async e=>{try{await R.mkdir(e,{recursive:!0})}catch(t){if(t.code!=="EEXIST")throw t}},Aa=e=>e&&`${e[0].toUpperCase()}${e.slice(1)}`,Pa=(e,t)=>{const n=Math.ceil(e),o=Math.floor(t);return Math.floor(Math.random()*(o-n+1))+n},bo=(e,t)=>e.disabled&&!t.disabled?1:!e.disabled&&t.disabled?-1:0,qt=e=>e.reduce((t,n)=>Array.isArray(n)?t.concat(qt(n)):t.concat(n),[]),xa=(e,t=5)=>e.replace(/[\n\r]/g,"").split(" ").slice(0,t).join(" "),$a=e=>{let t=0;for(let n=0;n<e.length;n++){const o=e.charCodeAt(n);t=(t<<5)-t+o,t=t&t}return Math.abs(t)},Sa=e=>{const t=e%360,n=65+e%15,o=45+e%10;return`hsl(${t}, ${n}%, ${o}%)`},ka=e=>{const[t,n,o]=e.match(/\d+/g).map((p,g)=>g===0?Number(p):Number(p)/100),s=(1-Math.abs(2*o-1))*n,r=s*(1-Math.abs(t/60%2-1)),a=o-s/2;let c,l,u;t<60?[c,l,u]=[s,r,0]:t<120?[c,l,u]=[r,s,0]:t<180?[c,l,u]=[0,s,r]:t<240?[c,l,u]=[0,r,s]:t<300?[c,l,u]=[r,0,s]:[c,l,u]=[s,0,r];const d=p=>{const g=Math.round((p+a)*255).toString(16);return g.length===1?"0"+g:g};return`#${d(c)}${d(l)}${d(u)}`},Ra=e=>{const t=$a(e),n=Sa(t);return{primary:ka(n),secondary:"#FFFFFF"}},Ia=e=>{try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,error:t}}},Ze=e=>{if(!e||typeof e!="string")return"";if(A.isAbsolute(e))return A.resolve(e);if(Le){const t=A.dirname(Le),n=A.join(t,e);return A.resolve(n)}else return""},La=["","conventional","gitmoji"],Re="http://localhost:11434",{hasOwnProperty:Ma}=Object.prototype,zt=(e,t)=>Ma.call(e,t),Ce=["OPENAI","COPILOT_SDK","OPENROUTER","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS","BEDROCK"],vo=e=>{const t=ue.platform(),n=ue.homedir();let o,s;switch(e){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(t==="darwin")e==="cache"?s=A.join(n,"Library","Caches"):s=A.join(n,"Library","Application Support");else if(t==="win32")s=process.env.LOCALAPPDATA||n;else switch(e){case"config":s=A.join(n,".config");break;case"data":s=A.join(n,".local","share");break;case"cache":s=A.join(n,".cache");break;case"state":s=A.join(n,".local","state");break;default:s=n}return o||s},Ao=A.join(vo("config"),"aicommit2"),q=A.join(vo("state"),"aicommit2","logs"),Po=A.join(Ao,"config.ini"),xo=A.join(q,"aicommit2-%DATE%.log"),$o=A.join(q,"exceptions-%DATE%.log"),Oa=e=>{const t=Object.keys(e),n=new Set([...Ce,...t.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(n)},b=(e,t,n)=>{if(!t)throw new m(`Invalid config property ${e}: ${n}`)},j=(e,t=!1)=>n=>typeof n=="boolean"?n:n==null?t:(b(e,/^(?:true|false)$/.test(n),"Must be a boolean(true or false)"),n==="true"),et=e=>t=>{if(!t)return{};if(typeof t=="object")return b(e,!Array.isArray(t),"Must be a JSON object"),t;try{const n=JSON.parse(t);return b(e,typeof n=="object"&&n!==null&&!Array.isArray(n),"Must be a valid JSON object"),n}catch(n){throw new m(`Invalid ${e}: Must be valid JSON. Error: ${n.message}`)}},i={systemPrompt(e){return e||""},systemPromptPath(e){return e||""},codeReviewPromptPath(e){return e||""},timeout(e){if(!e)return 6e4;b("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;b("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return b("temperature",t>0,"Must be greater than 0"),b("temperature",t<=2,"Must be less than or equal to 2"),t},maxTokens(e){return e?(b("maxTokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):8192},logLevel(e){return e?(b("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(e),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),e):"info"},logFilePath(e){return e||xo},exceptionLogFilePath(e){return e||$o},locale(e){return e?(b("locale",e,"Cannot be empty"),b("locale",/^[a-z-]+$/i.test(e),"Must be a valid locale (letters and dashes/underscores). You can consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes"),e):"en"},generate(e){if(!e)return 1;b("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("generate",t>0,"Must be greater than 0"),b("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(b("type",La.includes(e),"Invalid commit type"),e):"conventional"},maxLength(e){if(!e)return 50;b("maxLength",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("maxLength",t>=20,"Must be greater than 20 characters"),t},exclude:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):[],topP:e=>{if(!e)return .9;b("topP",/^(1|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 1");const t=Number(e);return b("topP",t>0,"Must be greater than 0"),b("topP",t<=1,"Must be less than or equal to 1"),t},logging:j("logging",!0),includeBody:j("includeBody"),codeReview:j("codeReview"),disabled:j("disabled"),watchMode:j("watchMode"),forceGit:j("forceGit"),stream:j("stream"),disableLowerCase:j("disableLowerCase"),ticketExtraction:j("ticketExtraction",!0),learnConventions:j("learnConventions",!0),jjAutoNew:j("jjAutoNew"),autoCopy:j("autoCopy"),modelNameDisplay:e=>e?(b("modelNameDisplay",/^(?:none|short|full)$/.test(e),"Must be none, short, or full"),e):"short",diffCompression:e=>e?(b("diffCompression",/^(?:none|compact)$/.test(e),"Must be none or compact"),e):Co.mode,maxHunkLines:e=>e?(b("maxHunkLines",/^\d+$/.test(e),"Must be an integer"),Number(e)):0,maxDiffLines:e=>e?(b("maxDiffLines",/^\d+$/.test(e),"Must be an integer"),Number(e)):0,diffContext:e=>{if(!e)return we;b("diffContext",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("diffContext",t>=0&&t<=10,"Must be between 0 and 10"),t},useStats:j("useStats",!0),statsDays:e=>{if(!e)return 30;b("statsDays",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("statsDays",t>0,"Must be greater than 0"),t}},Ie={OPENAI:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["gpt-4o-mini"],url:e=>e?(b("OPENAI.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.openai.com",path:e=>e||"/v1/chat/completions",proxy:e=>e||"",topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},OPENROUTER:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["openrouter/auto"],url:e=>e?(b("OPENROUTER.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://openrouter.ai",path:e=>e||"/api/v1/chat/completions",responseFormat:et("OPENROUTER.responseFormat"),provider:et("OPENROUTER.provider"),reasoning:et("OPENROUTER.reasoning"),topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},HUGGINGFACE:{cookie:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,topP:i.topP,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GEMINI:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["gemini-3-flash-preview"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},ANTHROPIC:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["claude-sonnet-4-20250514"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},MISTRAL:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["mistral-small-latest"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},CODESTRAL:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["codestral-latest"],topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},OLLAMA:{model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):[],host:e=>e?(b("OLLAMA.host",/^https?:\/\//.test(e),"Must be a valid URL"),e):Re,timeout:e=>{if(!e)return 1e5;b("OLLAMA.timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("OLLAMA.timeout",t>=500,"Must be greater than 500ms"),t},auth:e=>e||"",key:e=>e||"",envKey:e=>e||"",numCtx:e=>{if(!e)return 2048;b("OLLAMA.numCtx",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("OLLAMA.numCtx",t>=2048,"Must be greater than 2048"),t},systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},COHERE:{key:e=>e||"",envKey:e=>e||"",url:e=>e?(b("COHERE.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.cohere.ai",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["command-a-03-2025"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,timeout:i.timeout,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GROQ:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["llama-3.3-70b-versatile"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},PERPLEXITY:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["sonar"],topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},DEEPSEEK:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["deepseek-v4-flash"],thinking:e=>{if(!(e==null||e===""))return typeof e=="boolean"?e:(b("DEEPSEEK.thinking",/^(?:true|false)$/.test(e),"Must be a boolean(true or false)"),e==="true")},reasoningEffort:e=>{if(!e||e.trim()==="")return;const t=e.trim().toLowerCase();return b("DEEPSEEK.reasoningEffort",t==="high"||t==="max","Must be high or max"),t},topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GITHUB_MODELS:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["openai/gpt-4o-mini"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},COPILOT_SDK:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["gpt-4.1"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},BEDROCK:{key:e=>e||"",envKey:e=>e&&e.length>0?e:"BEDROCK_API_KEY",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>{const o=n.trim();return o&&!o.includes(".")&&!o.includes(":")&&console.warn(`[Bedrock] Model ID "${o}" may be invalid.
|
|
15
|
+
${ke}${h.dim(`aicommit2 v${kn}`)}`),console.error(`
|
|
16
|
+
${ke}Please open a Bug report with the information above:`),console.error(`${ke}https://github.com/tak-bro/aicommit2/issues/new/choose`)}},Qe=e=>R.lstat(e).then(()=>!0,()=>!1),bo=async e=>{try{await R.mkdir(e,{recursive:!0})}catch(t){if(t.code!=="EEXIST")throw t}},Pa=e=>e&&`${e[0].toUpperCase()}${e.slice(1)}`,xa=(e,t)=>{const n=Math.ceil(e),o=Math.floor(t);return Math.floor(Math.random()*(o-n+1))+n},vo=(e,t)=>e.disabled&&!t.disabled?1:!e.disabled&&t.disabled?-1:0,qt=e=>e.reduce((t,n)=>Array.isArray(n)?t.concat(qt(n)):t.concat(n),[]),$a=(e,t=5)=>e.replace(/[\n\r]/g,"").split(" ").slice(0,t).join(" "),Sa=e=>{let t=0;for(let n=0;n<e.length;n++){const o=e.charCodeAt(n);t=(t<<5)-t+o,t=t&t}return Math.abs(t)},ka=e=>{const t=e%360,n=65+e%15,o=45+e%10;return`hsl(${t}, ${n}%, ${o}%)`},Ra=e=>{const[t,n,o]=e.match(/\d+/g).map((p,g)=>g===0?Number(p):Number(p)/100),s=(1-Math.abs(2*o-1))*n,r=s*(1-Math.abs(t/60%2-1)),a=o-s/2;let c,l,u;t<60?[c,l,u]=[s,r,0]:t<120?[c,l,u]=[r,s,0]:t<180?[c,l,u]=[0,s,r]:t<240?[c,l,u]=[0,r,s]:t<300?[c,l,u]=[r,0,s]:[c,l,u]=[s,0,r];const d=p=>{const g=Math.round((p+a)*255).toString(16);return g.length===1?"0"+g:g};return`#${d(c)}${d(l)}${d(u)}`},Ia=e=>{const t=Sa(e),n=ka(t);return{primary:Ra(n),secondary:"#FFFFFF"}},La=e=>{try{return{ok:!0,data:JSON.parse(e)}}catch(t){return{ok:!1,error:t}}},Ze=e=>{if(!e||typeof e!="string")return"";if(A.isAbsolute(e))return A.resolve(e);if(Le){const t=A.dirname(Le),n=A.join(t,e);return A.resolve(n)}else return""},Ma=["","conventional","gitmoji"],Re="http://localhost:11434",{hasOwnProperty:Oa}=Object.prototype,zt=(e,t)=>Oa.call(e,t),Ce=["OPENAI","COPILOT_SDK","OPENROUTER","OLLAMA","HUGGINGFACE","GEMINI","ANTHROPIC","MISTRAL","CODESTRAL","COHERE","GROQ","PERPLEXITY","DEEPSEEK","GITHUB_MODELS","BEDROCK"],Ao=e=>{const t=ue.platform(),n=ue.homedir();let o,s;switch(e){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(t==="darwin")e==="cache"?s=A.join(n,"Library","Caches"):s=A.join(n,"Library","Application Support");else if(t==="win32")s=process.env.LOCALAPPDATA||n;else switch(e){case"config":s=A.join(n,".config");break;case"data":s=A.join(n,".local","share");break;case"cache":s=A.join(n,".cache");break;case"state":s=A.join(n,".local","state");break;default:s=n}return o||s},Po=A.join(Ao("config"),"aicommit2"),q=A.join(Ao("state"),"aicommit2","logs"),xo=A.join(Po,"config.ini"),$o=A.join(q,"aicommit2-%DATE%.log"),So=A.join(q,"exceptions-%DATE%.log"),Ta=e=>{const t=Object.keys(e),n=new Set([...Ce,...t.filter(o=>/^[A-Z][A-Z0-9_]*$/.test(o))]);return Array.from(n)},b=(e,t,n)=>{if(!t)throw new m(`Invalid config property ${e}: ${n}`)},j=(e,t=!1)=>n=>typeof n=="boolean"?n:n==null?t:(b(e,/^(?:true|false)$/.test(n),"Must be a boolean(true or false)"),n==="true"),et=e=>t=>{if(!t)return{};if(typeof t=="object")return b(e,!Array.isArray(t),"Must be a JSON object"),t;try{const n=JSON.parse(t);return b(e,typeof n=="object"&&n!==null&&!Array.isArray(n),"Must be a valid JSON object"),n}catch(n){throw new m(`Invalid ${e}: Must be valid JSON. Error: ${n.message}`)}},i={systemPrompt(e){return e||""},systemPromptPath(e){return e||""},codeReviewPromptPath(e){return e||""},timeout(e){if(!e)return 6e4;b("timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("timeout",t>=500,"Must be greater than 500ms"),t},temperature(e){if(!e)return .7;b("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return b("temperature",t>0,"Must be greater than 0"),b("temperature",t<=2,"Must be less than or equal to 2"),t},maxTokens(e){return e?(b("maxTokens",/^\d+$/.test(e),"Must be an integer"),Number(e)):8192},logLevel(e){return e?(b("logLevel",/^(?:error|warn|info|http|verbose|debug|silly)$/.test(e),"Must be a valid log level (error, warn, info, http, verbose, debug, silly)"),e):"info"},logFilePath(e){return e||$o},exceptionLogFilePath(e){return e||So},locale(e){return e?(b("locale",e,"Cannot be empty"),b("locale",/^[a-z-]+$/i.test(e),"Must be a valid locale (letters and dashes/underscores). You can consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes"),e):"en"},generate(e){if(!e)return 1;b("generate",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("generate",t>0,"Must be greater than 0"),b("generate",t<=5,"Must be less or equal to 5"),t},type(e){return e?(b("type",Ma.includes(e),"Invalid commit type"),e):"conventional"},maxLength(e){if(!e)return 50;b("maxLength",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("maxLength",t>=20,"Must be greater than 20 characters"),t},exclude:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):[],topP:e=>{if(!e)return .9;b("topP",/^(1|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 1");const t=Number(e);return b("topP",t>0,"Must be greater than 0"),b("topP",t<=1,"Must be less than or equal to 1"),t},logging:j("logging",!0),includeBody:j("includeBody"),codeReview:j("codeReview"),disabled:j("disabled"),watchMode:j("watchMode"),forceGit:j("forceGit"),stream:j("stream"),disableLowerCase:j("disableLowerCase"),ticketExtraction:j("ticketExtraction",!0),learnConventions:j("learnConventions",!0),jjAutoNew:j("jjAutoNew"),autoCopy:j("autoCopy"),modelNameDisplay:e=>e?(b("modelNameDisplay",/^(?:none|short|full)$/.test(e),"Must be none, short, or full"),e):"short",diffCompression:e=>e?(b("diffCompression",/^(?:none|compact)$/.test(e),"Must be none or compact"),e):Eo.mode,maxHunkLines:e=>e?(b("maxHunkLines",/^\d+$/.test(e),"Must be an integer"),Number(e)):0,maxDiffLines:e=>e?(b("maxDiffLines",/^\d+$/.test(e),"Must be an integer"),Number(e)):0,diffContext:e=>{if(!e)return we;b("diffContext",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("diffContext",t>=0&&t<=10,"Must be between 0 and 10"),t},useStats:j("useStats",!0),statsDays:e=>{if(!e)return 30;b("statsDays",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("statsDays",t>0,"Must be greater than 0"),t}},Ie={OPENAI:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["gpt-4o-mini"],url:e=>e?(b("OPENAI.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.openai.com",path:e=>e||"/v1/chat/completions",proxy:e=>e||"",topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},OPENROUTER:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["openrouter/auto"],url:e=>e?(b("OPENROUTER.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://openrouter.ai",path:e=>e||"/api/v1/chat/completions",responseFormat:et("OPENROUTER.responseFormat"),provider:et("OPENROUTER.provider"),reasoning:et("OPENROUTER.reasoning"),topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},HUGGINGFACE:{cookie:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["CohereForAI/c4ai-command-r-plus"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,topP:i.topP,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GEMINI:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["gemini-3-flash-preview"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},ANTHROPIC:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["claude-sonnet-4-20250514"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},MISTRAL:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["mistral-small-latest"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},CODESTRAL:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["codestral-latest"],topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},OLLAMA:{model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):[],host:e=>e?(b("OLLAMA.host",/^https?:\/\//.test(e),"Must be a valid URL"),e):Re,timeout:e=>{if(!e)return 1e5;b("OLLAMA.timeout",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("OLLAMA.timeout",t>=500,"Must be greater than 500ms"),t},auth:e=>e||"",key:e=>e||"",envKey:e=>e||"",numCtx:e=>{if(!e)return 2048;b("OLLAMA.numCtx",/^\d+$/.test(e),"Must be an integer");const t=Number(e);return b("OLLAMA.numCtx",t>=2048,"Must be greater than 2048"),t},systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},COHERE:{key:e=>e||"",envKey:e=>e||"",url:e=>e?(b("COHERE.url",/^https?:\/\//.test(e),"Must be a valid URL"),e):"https://api.cohere.ai",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["command-a-03-2025"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,timeout:i.timeout,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GROQ:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["llama-3.3-70b-versatile"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},PERPLEXITY:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["sonar"],topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},DEEPSEEK:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["deepseek-v4-flash"],thinking:e=>{if(!(e==null||e===""))return typeof e=="boolean"?e:(b("DEEPSEEK.thinking",/^(?:true|false)$/.test(e),"Must be a boolean(true or false)"),e==="true")},reasoningEffort:e=>{if(!e||e.trim()==="")return;const t=e.trim().toLowerCase();return b("DEEPSEEK.reasoningEffort",t==="high"||t==="max","Must be high or max"),t},topP:i.topP,systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},GITHUB_MODELS:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):["openai/gpt-4o-mini"],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},COPILOT_SDK:{key:e=>e||"",envKey:e=>e||"",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>n.trim()).filter(n=>!!n&&n.length>0):[],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext},BEDROCK:{key:e=>e||"",envKey:e=>e&&e.length>0?e:"BEDROCK_API_KEY",model:e=>e?(typeof e=="string"?e?.split(","):e).map(n=>{const o=n.trim();return o&&!o.includes(".")&&!o.includes(":")&&console.warn(`[Bedrock] Model ID "${o}" may be invalid.
|
|
17
17
|
Expected formats:
|
|
18
18
|
- Foundation model: "provider.model-name-version" (e.g., "anthropic.claude-haiku-4-5-20251001-v1:0")
|
|
19
19
|
- Inference profile: "prefix.provider.model-name-version" (e.g., "us.anthropic.claude-haiku-4-5-20251001-v1:0")
|
|
20
20
|
- ARN: Full Amazon Resource Name
|
|
21
|
-
See https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html`),o}).filter(n=>!!n&&n.length>0):["anthropic.claude-haiku-4-5-20251001-v1:0"],runtimeMode:e=>{e&&console.warn("[Bedrock] DEPRECATION: runtimeMode is no longer used. Authentication method is now auto-detected from configured credentials.")},region:e=>e||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"",profile:e=>e||process.env.AWS_PROFILE||"",accessKeyId:e=>e||process.env.AWS_ACCESS_KEY_ID||"",secretAccessKey:e=>e||process.env.AWS_SECRET_ACCESS_KEY||"",sessionToken:e=>e||process.env.AWS_SESSION_TOKEN||"",applicationEndpointId:e=>e||process.env.BEDROCK_APPLICATION_ENDPOINT_ID||"",applicationInferenceProfileArn:e=>e||process.env.BEDROCK_APPLICATION_INFERENCE_PROFILE_ARN||process.env.BEDROCK_INFERENCE_PROFILE_ARN||"",applicationBaseUrl:e=>e||process.env.BEDROCK_APPLICATION_BASE_URL||"",systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:e=>{if(!e)return;b("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return b("temperature",t>0,"Must be greater than 0"),b("temperature",t<=2,"Must be less than or equal to 2"),t},maxTokens:e=>{if(e)return b("maxTokens",/^\d+$/.test(e),"Must be an integer"),Number(e)},logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:e=>{if(!e)return;b("topP",/^(1|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 1");const t=Number(e);return b("topP",t>0,"Must be greater than 0"),b("topP",t<=1,"Must be less than or equal to 1"),t},codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,inferenceParameters:et("BEDROCK.inferenceParameters"),diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext}},Ta=e=>typeof e=="object"&&e!==null,So=(e,t)=>{Object.keys(e).forEach(n=>{const o=e[n];Ta(o)&&t in o&&(o[t]=!0)})},Da=e=>{So(e,"includeBody")},ko=e=>{So(e,"disableLowerCase")};let Le,Me=null,Yt=null;const Na=(e=[])=>{const t={};for(const n of e)if(n.startsWith("--")){const[o,s]=n.slice(2).split("="),[r,a]=o.split(".");r&&a&&r in Ie?(t[r]||(t[r]={}),t[r][a]=s):t[o]=s}return t},_a=()=>{const e=ue.homedir(),t=process.env.AICOMMIT_CONFIG_PATH,n=Po,o=A.join(e,".aicommit2");return[t,n,o].filter(s=>!!s)},Ee=async()=>{const e=_a();for(const t of e)if(await Qe(t))return t;return Po},ja=e=>e.replace(/\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}|\$([a-zA-Z_][a-zA-Z0-9_]*)/g,(t,n,o)=>{const s=n||o;return process.env[s]??""}),Ro=e=>{if(Array.isArray(e)||e===null||typeof e!="object")return e;const t={};for(const[n,o]of Object.entries(e)){const s=Ro(o);if(!n.includes(".")){t[n]=s;continue}const r=n.split(".");let a=t;for(const c of r.slice(0,-1)){const l=a[c];(!l||typeof l!="object"||Array.isArray(l))&&(a[c]={}),a=a[c]}a[r[r.length-1]]=s}return t},Oe=async()=>{const e=await Ee();if(Me&&Yt===e)return Me;Le=e;try{const t=await R.readFile(e,"utf8"),n=ja(t);return Me=Ro(ye.parse(n)),Yt=e,Me}catch(t){return t.code==="ENOENT"?(Le=void 0,{}):(console.error(`Error reading config file ${e}:`,t),Le=void 0,{})}},Io=()=>{Me=null,Yt=null},Z=async(e,t=[])=>{const n=await Oe(),o=Na(t),s={...e,...o},r={},a=Oa(n),c={};for(const u of a){const d=n[u]?.envKey;let p;d?(p=[d],u==="BEDROCK"&&d!=="BEDROCK_APPLICATION_API_KEY"&&p.push("BEDROCK_APPLICATION_API_KEY")):u==="BEDROCK"?p=["BEDROCK_API_KEY","BEDROCK_APPLICATION_API_KEY"]:p=[`${u}_API_KEY`];const g=p.map(y=>y?process.env[y]:void 0).find(y=>typeof y=="string"&&y.length>0);g&&(c[u]={key:g})}const l=(u,d)=>{const p=s[`${u}.${d}`]??s[u]?.[d],g=c[u]?.[d],y=n[u]?.[d],f=s[d]??n[d];return p!==void 0?p:g!==void 0?g:y!==void 0?y:f};for(const[u,d]of Object.entries(i)){const p=s[u]??n[u];r[u]=d(p)}for(const u of a){r[u]={};const d=Ie[u]||nt(u);for(const[p,g]of Object.entries(d)){const y=l(u,p);r[u][p]=g(y)}}return r},tt=async e=>{const t=await Oe();for(const[s,r]of e){const[a,c]=s.split(".");if(!c){const d=i[s];if(!d)throw new m(`Invalid config property: ${s}`);t[s]=d(r);continue}if(t[a]||(t[a]={}),Ce.includes(a)){const d=Ie[a][c];if(!d)throw new m(`Invalid config property: ${s}`);t[a][c]=d(r);continue}if(!/^[A-Z][A-Z0-9_]*$/.test(a))throw new m(`Invalid service name: ${a}. Service names must be uppercase letters, numbers, and underscores.`);const u=nt(a);if(!u[c])throw new m(`Invalid config property for custom service: ${s}`);try{t[a][c]=u[c](r)}catch(d){throw d instanceof m?d:new m(`Invalid value for ${s}: ${d.message}`)}}const n=await Ee(),o=A.dirname(n);await R.mkdir(o,{recursive:!0}),await R.writeFile(n,ye.stringify(t),"utf8"),Io()},Fa=async e=>{const t=await Oe();for(const[s,r]of e){const[a,c]=s.split("."),l=t[a];if(c==="model"){l||(t[a]={});const d=t[a][c]||[],p=typeof r=="string"?r.split(",").map(g=>g.trim()).filter(g=>!!g):r;t[a][c]=qt([...d,...p]);continue}if(l&&l.compatible===!0){l||(t[a]={});const d=nt(a);if(!d[c])throw new m(`Invalid config property: ${s}`);try{t[a][c]=d[c](r)}catch(p){throw p instanceof m?p:new m(`Invalid value for ${s}: ${p.message}`)}continue}if(a in Ie){l||(t[a]={});const d=Ie[a][c];if(!d)throw new m(`Invalid config property: ${s}`);t[a][c]=d(r)}else{const d=nt(a);if(!d[c])throw new m(`Invalid config property: ${s}`);t[a]||(t[a]={}),t[a][c]=d[c](r)}}const n=await Ee(),o=A.dirname(n);await R.mkdir(o,{recursive:!0}),await R.writeFile(n,ye.stringify(t),"utf8"),Io()},Ga=async()=>{const e=await Oe();console.log(ye.stringify(e))},Ba=async()=>{console.log(await Ee())},nt=e=>({compatible:j("compatible"),stream:j("stream"),url:t=>t?(b(`${e}.url`,/^https?:\/\//.test(t),"Must be a valid URL"),t):"",path:t=>t||"",key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(o=>o.trim()).filter(o=>!!o&&o.length>0):[],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,autoCopy:i.autoCopy,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext}),_=e=>typeof e=="string"&&e.trim().length>0,Ha=()=>{try{const e=typeof At<"u"?At.resolve:void 0;return e?(e("@github/copilot-sdk"),!0):typeof import.meta.resolve=="function"?(import.meta.resolve("@github/copilot-sdk"),!0):!1}catch{return!1}};let Vt;const Ua=e=>ee(e)?(Vt===void 0&&(Vt=Ha()),Vt):!1,ee=e=>(Array.isArray(e.model)?e.model:_(e.model)?[e.model.trim()]:[]).length>0,ot=e=>{const t=_(e.key),n=_(e.region)||_(process.env.AWS_REGION)||_(process.env.AWS_DEFAULT_REGION),o=_(e.profile)||_(process.env.AWS_PROFILE),s=_(e.accessKeyId)&&_(e.secretAccessKey)||_(process.env.AWS_ACCESS_KEY_ID)&&_(process.env.AWS_SECRET_ACCESS_KEY),r=_(e.applicationBaseUrl)||_(process.env.BEDROCK_APPLICATION_BASE_URL),a=_(e.applicationEndpointId)||_(process.env.BEDROCK_APPLICATION_ENDPOINT_ID),c=_(process.env.BEDROCK_APPLICATION_API_KEY);return n&&(t||o||s)||(r&&t||a&&c)},le=(e,t)=>Object.entries(e).map(([n,o])=>[n,o]).filter(([n,o])=>!o.disabled).filter(([n,o])=>Ce.includes(n)||o.compatible===!0).filter(([n,o])=>{switch(t){case"commit":return n==="OLLAMA"?!!o&&ee(o):n==="COPILOT_SDK"?!!o&&Ua(o):n==="HUGGINGFACE"?!!o&&!!o.cookie:n==="BEDROCK"?ee(o)&&ot(o):!!o.key&&o.key.length>0;case"review":const s=e.codeReview||o.codeReview;return n==="OLLAMA"||n==="COPILOT_SDK"?!!o&&ee(o)&&s:n==="HUGGINGFACE"?!!o&&!!o.cookie&&s:n==="BEDROCK"?ee(o)&&ot(o)&&s:!!o.key&&o.key.length>0&&s;case"watch":const r=e.watchMode||o.watchMode;return n==="OLLAMA"||n==="COPILOT_SDK"?!!o&&ee(o)&&r:n==="HUGGINGFACE"?!!o&&!!o.cookie&&r:n==="BEDROCK"?ee(o)&&ot(o)&&r:o.compatible?!!o.url&&!!o.key&&r:!!o.key&&o.key.length>0&&r}}).map(([n])=>n);class Ka{static create(t,n){return new t(n)}}const Wa="stats.json",st=2,qa=30,Jt=()=>A.join(Ao,Wa),rt=async()=>{const e=Jt();if(!await Qe(e))return{version:st,metrics:[],selections:[]};try{const t=await R.readFile(e,"utf-8"),n=JSON.parse(t);return!n.version||n.version<st?{version:st,metrics:n.metrics||[],selections:n.selections||[]}:n}catch{return{version:st,metrics:[],selections:[]}}},za=(e,t)=>{const n=Date.now()-t*24*60*60*1e3;return{version:e.version,metrics:e.metrics.filter(o=>o.timestamp>=n),selections:e.selections.filter(o=>o.timestamp>=n)}},Lo=async(e,t)=>{const n=Jt(),o=A.dirname(n),s=t?za(e,t):e;await R.mkdir(o,{recursive:!0}),await R.writeFile(n,JSON.stringify(s,null,2),"utf-8")},Ya=async e=>{const t={timestamp:Date.now(),provider:e.provider,model:e.model,responseTimeMs:e.responseTimeMs,success:e.success,errorCode:e.errorCode,tokensUsed:e.tokensUsed},n=await rt();n.metrics.push(t),await Lo(n,e.statsDays)},Va=async e=>{const t={timestamp:Date.now(),provider:e.provider,model:e.model},n=await rt();n.selections.push(t),await Lo(n,e.statsDays)},Ja=(e,t,n)=>{const o=t.filter(u=>u.provider===e),s=n.filter(u=>u.provider===e);if(o.length===0)return{provider:e,totalRequests:0,successCount:0,failureCount:0,selectedCount:s.length,selectionRate:0,avgResponseTimeMs:0,minResponseTimeMs:0,maxResponseTimeMs:0};const r=o.filter(u=>u.success),a=o.map(u=>u.responseTimeMs),c=s.length,l=r.length>0?Math.min(100,Math.round(c/r.length*1e3)/10):0;return{provider:e,totalRequests:o.length,successCount:r.length,failureCount:o.length-r.length,selectedCount:c,selectionRate:l,avgResponseTimeMs:Math.round(a.reduce((u,d)=>u+d,0)/a.length),minResponseTimeMs:Math.min(...a),maxResponseTimeMs:Math.max(...a)}},Xa=async(e=qa)=>{const t=await rt(),n=Date.now()-e*24*60*60*1e3,o=t.metrics.filter(u=>u.timestamp>=n),s=t.selections.filter(u=>u.timestamp>=n);if(o.length===0)return{totalRequests:0,successRate:0,avgResponseTimeMs:0,providerStats:[],periodStart:n,periodEnd:Date.now()};const a=[...new Set(o.map(u=>u.provider))].map(u=>Ja(u,o,s)).sort((u,d)=>d.totalRequests-u.totalRequests),c=o.filter(u=>u.success).length,l=o.reduce((u,d)=>u+d.responseTimeMs,0);return{totalRequests:o.length,successRate:Math.round(c/o.length*1e3)/10,avgResponseTimeMs:Math.round(l/o.length),providerStats:a,periodStart:Math.min(...o.map(u=>u.timestamp)),periodEnd:Math.max(...o.map(u=>u.timestamp))}},Qa=async()=>{const e=Jt();await Qe(e)&&await R.unlink(e)},Za=async()=>(await rt()).metrics.length>0,Mo=(e,t)=>{const n=h.red.bold(`[${e}]`);return Ms({name:`${n} ${t}`,value:t,isError:!0,disabled:!0})},Oo=e=>{let t=!1;return Os({next:n=>{if(Object.assign(n,{provider:e.provider,model:e.model}),e.statsEnabled===!1||t)return;t=!0;const o=n.isError===!0,s={provider:e.provider,model:e.model,responseTimeMs:Date.now()-e.startTime,success:!o,errorCode:o?"REQUEST_ERROR":void 0,statsDays:e.statsDays};Ya(s).catch(()=>{})}})};class ec{constructor(){this.loaders=new Map,this.cache=new Map,this.loadService=async t=>{const n=this.cache.get(t);if(n)return n;const o=this.loaders.get(t);if(!o)return null;const s=await o();return this.cache.set(t,s),s},this.createService=async(t,n)=>{const o=await this.loadService(t);return o?new o(n):null},this.createRequest$=(t,n,o)=>{const s=Date.now(),r=Array.isArray(n.config.model)?n.config.model[0]:n.config.model;return Be(this.createService(t,n)).pipe(yn(a=>a?(o==="commit"?a.generateCommitMessage$():a.generateCodeReview$()).pipe(Oo({provider:t,model:r||"unknown",startTime:s,statsEnabled:n.statsEnabled,statsDays:n.statsDays})):Mo(t,"Invalid AI type")))},this.registerBuiltinProviders=()=>{this.loaders.set("OPENAI",()=>import("./openai.service-e424ef44.mjs").then(t=>t.OpenAIService)),this.loaders.set("COPILOT_SDK",()=>import("./copilot-sdk.service-d2f51cb1.mjs").then(t=>t.CopilotSdkService)),this.loaders.set("OPENROUTER",()=>import("./openrouter.service-54e19166.mjs").then(t=>t.OpenRouterService)),this.loaders.set("GEMINI",()=>import("./gemini.service-f3781142.mjs").then(t=>t.GeminiService)),this.loaders.set("ANTHROPIC",()=>import("./anthropic.service-57ee01e3.mjs").then(t=>t.AnthropicService)),this.loaders.set("HUGGINGFACE",()=>import("./hugging-face.service-041332a3.mjs").then(t=>t.HuggingFaceService)),this.loaders.set("MISTRAL",()=>import("./mistral.service-af265922.mjs").then(t=>t.MistralService)),this.loaders.set("CODESTRAL",()=>import("./codestral.service-e6db6c08.mjs").then(t=>t.CodestralService)),this.loaders.set("OLLAMA",()=>import("./ollama.service-205b1bf7.mjs").then(t=>t.OllamaService)),this.loaders.set("COHERE",()=>import("./cohere.service-6346af97.mjs").then(t=>t.CohereService)),this.loaders.set("GROQ",()=>import("./groq.service-26ba8602.mjs").then(t=>t.GroqService)),this.loaders.set("PERPLEXITY",()=>import("./perplexity.service-1b9eaf27.mjs").then(t=>t.PerplexityService)),this.loaders.set("BEDROCK",()=>import("./bedrock.service-931a6a6f.mjs").then(t=>t.BedrockService)),this.loaders.set("GITHUB_MODELS",()=>import("./github-models.service-62c81303.mjs").then(t=>t.GitHubModelsService)),this.loaders.set("DEEPSEEK",()=>import("./deep-seek.service-c4c223bd.mjs").then(t=>t.DeepSeekService))},this.registerBuiltinProviders()}}const tc=new ec;class Xt{getDetectedMessage(t){return`Detected ${t.files.length.toLocaleString()} changed file${t.files.length>1?"s":""} (${t.diff.length.toLocaleString()} characters)`}getDetectedFiles(t){return`Detected ${t.length.toLocaleString()} changed file${t.length>1?"s":""}`}}const To="AICOMMIT2_MSG_FILE";class it extends Xt{constructor(){super(...arguments),this.name="git",this.excludeFromDiff=t=>`:(exclude)${t}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:t}=await C("git",["rev-parse","--show-toplevel"],{reject:!0});return t.trim()}catch(t){const n=t;if(n.code==="ENOENT")throw new m(`Git command not found!
|
|
21
|
+
See https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html`),o}).filter(n=>!!n&&n.length>0):["anthropic.claude-haiku-4-5-20251001-v1:0"],runtimeMode:e=>{e&&console.warn("[Bedrock] DEPRECATION: runtimeMode is no longer used. Authentication method is now auto-detected from configured credentials.")},region:e=>e||process.env.AWS_REGION||process.env.AWS_DEFAULT_REGION||"",profile:e=>e||process.env.AWS_PROFILE||"",accessKeyId:e=>e||process.env.AWS_ACCESS_KEY_ID||"",secretAccessKey:e=>e||process.env.AWS_SECRET_ACCESS_KEY||"",sessionToken:e=>e||process.env.AWS_SESSION_TOKEN||"",applicationEndpointId:e=>e||process.env.BEDROCK_APPLICATION_ENDPOINT_ID||"",applicationInferenceProfileArn:e=>e||process.env.BEDROCK_APPLICATION_INFERENCE_PROFILE_ARN||process.env.BEDROCK_INFERENCE_PROFILE_ARN||"",applicationBaseUrl:e=>e||process.env.BEDROCK_APPLICATION_BASE_URL||"",systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:e=>{if(!e)return;b("temperature",/^(2|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 2");const t=Number(e);return b("temperature",t>0,"Must be greater than 0"),b("temperature",t<=2,"Must be less than or equal to 2"),t},maxTokens:e=>{if(e)return b("maxTokens",/^\d+$/.test(e),"Must be an integer"),Number(e)},logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:e=>{if(!e)return;b("topP",/^(1|\d)(\.\d{1,2})?$/.test(e),"Must be decimal between 0 and 1");const t=Number(e);return b("topP",t>0,"Must be greater than 0"),b("topP",t<=1,"Must be less than or equal to 1"),t},codeReview:i.codeReview,disabled:i.disabled,stream:i.stream,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,inferenceParameters:et("BEDROCK.inferenceParameters"),diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext}},Da=e=>typeof e=="object"&&e!==null,ko=(e,t)=>{Object.keys(e).forEach(n=>{const o=e[n];Da(o)&&t in o&&(o[t]=!0)})},Na=e=>{ko(e,"includeBody")},Ro=e=>{ko(e,"disableLowerCase")};let Le,Me=null,Yt=null;const _a=(e=[])=>{const t={};for(const n of e)if(n.startsWith("--")){const[o,s]=n.slice(2).split("="),[r,a]=o.split(".");r&&a&&r in Ie?(t[r]||(t[r]={}),t[r][a]=s):t[o]=s}return t},ja=()=>{const e=ue.homedir(),t=process.env.AICOMMIT_CONFIG_PATH,n=xo,o=A.join(e,".aicommit2");return[t,n,o].filter(s=>!!s)},Ee=async()=>{const e=ja();for(const t of e)if(await Qe(t))return t;return xo},Fa=e=>e.replace(/\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}|\$([a-zA-Z_][a-zA-Z0-9_]*)/g,(t,n,o)=>{const s=n||o;return process.env[s]??""}),Io=e=>{if(Array.isArray(e)||e===null||typeof e!="object")return e;const t={};for(const[n,o]of Object.entries(e)){const s=Io(o);if(!n.includes(".")){t[n]=s;continue}const r=n.split(".");let a=t;for(const c of r.slice(0,-1)){const l=a[c];(!l||typeof l!="object"||Array.isArray(l))&&(a[c]={}),a=a[c]}a[r[r.length-1]]=s}return t},Oe=async()=>{const e=await Ee();if(Me&&Yt===e)return Me;Le=e;try{const t=await R.readFile(e,"utf8"),n=Fa(t);return Me=Io(ye.parse(n)),Yt=e,Me}catch(t){return t.code==="ENOENT"?(Le=void 0,{}):(console.error(`Error reading config file ${e}:`,t),Le=void 0,{})}},Lo=()=>{Me=null,Yt=null},Z=async(e,t=[])=>{const n=await Oe(),o=_a(t),s={...e,...o},r={},a=Ta(n),c={};for(const u of a){const d=n[u]?.envKey;let p;d?(p=[d],u==="BEDROCK"&&d!=="BEDROCK_APPLICATION_API_KEY"&&p.push("BEDROCK_APPLICATION_API_KEY")):u==="BEDROCK"?p=["BEDROCK_API_KEY","BEDROCK_APPLICATION_API_KEY"]:p=[`${u}_API_KEY`];const g=p.map(y=>y?process.env[y]:void 0).find(y=>typeof y=="string"&&y.length>0);g&&(c[u]={key:g})}const l=(u,d)=>{const p=s[`${u}.${d}`]??s[u]?.[d],g=c[u]?.[d],y=n[u]?.[d],f=s[d]??n[d];return p!==void 0?p:g!==void 0?g:y!==void 0?y:f};for(const[u,d]of Object.entries(i)){const p=s[u]??n[u];r[u]=d(p)}for(const u of a){r[u]={};const d=Ie[u]||nt(u);for(const[p,g]of Object.entries(d)){const y=l(u,p);r[u][p]=g(y)}}return r},tt=async e=>{const t=await Oe();for(const[s,r]of e){const[a,c]=s.split(".");if(!c){const d=i[s];if(!d)throw new m(`Invalid config property: ${s}`);t[s]=d(r);continue}if(t[a]||(t[a]={}),Ce.includes(a)){const d=Ie[a][c];if(!d)throw new m(`Invalid config property: ${s}`);t[a][c]=d(r);continue}if(!/^[A-Z][A-Z0-9_]*$/.test(a))throw new m(`Invalid service name: ${a}. Service names must be uppercase letters, numbers, and underscores.`);const u=nt(a);if(!u[c])throw new m(`Invalid config property for custom service: ${s}`);try{t[a][c]=u[c](r)}catch(d){throw d instanceof m?d:new m(`Invalid value for ${s}: ${d.message}`)}}const n=await Ee(),o=A.dirname(n);await R.mkdir(o,{recursive:!0}),await R.writeFile(n,ye.stringify(t),"utf8"),Lo()},Ga=async e=>{const t=await Oe();for(const[s,r]of e){const[a,c]=s.split("."),l=t[a];if(c==="model"){l||(t[a]={});const d=t[a][c]||[],p=typeof r=="string"?r.split(",").map(g=>g.trim()).filter(g=>!!g):r;t[a][c]=qt([...d,...p]);continue}if(l&&l.compatible===!0){l||(t[a]={});const d=nt(a);if(!d[c])throw new m(`Invalid config property: ${s}`);try{t[a][c]=d[c](r)}catch(p){throw p instanceof m?p:new m(`Invalid value for ${s}: ${p.message}`)}continue}if(a in Ie){l||(t[a]={});const d=Ie[a][c];if(!d)throw new m(`Invalid config property: ${s}`);t[a][c]=d(r)}else{const d=nt(a);if(!d[c])throw new m(`Invalid config property: ${s}`);t[a]||(t[a]={}),t[a][c]=d[c](r)}}const n=await Ee(),o=A.dirname(n);await R.mkdir(o,{recursive:!0}),await R.writeFile(n,ye.stringify(t),"utf8"),Lo()},Ba=async()=>{const e=await Oe();console.log(ye.stringify(e))},Ha=async()=>{console.log(await Ee())},nt=e=>({compatible:j("compatible"),stream:j("stream"),url:t=>t?(b(`${e}.url`,/^https?:\/\//.test(t),"Must be a valid URL"),t):"",path:t=>t||"",key:t=>t||"",envKey:t=>t||"",model:t=>t?(typeof t=="string"?t?.split(","):t).map(o=>o.trim()).filter(o=>!!o&&o.length>0):[],systemPrompt:i.systemPrompt,systemPromptPath:i.systemPromptPath,codeReviewPromptPath:i.codeReviewPromptPath,timeout:i.timeout,temperature:i.temperature,maxTokens:i.maxTokens,logging:i.logging,locale:i.locale,generate:i.generate,type:i.type,maxLength:i.maxLength,includeBody:i.includeBody,topP:i.topP,codeReview:i.codeReview,disabled:i.disabled,watchMode:i.watchMode,disableLowerCase:i.disableLowerCase,ticketExtraction:i.ticketExtraction,learnConventions:i.learnConventions,autoCopy:i.autoCopy,diffCompression:i.diffCompression,maxHunkLines:i.maxHunkLines,maxDiffLines:i.maxDiffLines,diffContext:i.diffContext}),D=e=>typeof e=="string"&&e.trim().length>0,Ua=()=>{try{const e=typeof At<"u"?At.resolve:void 0;return e?(e("@github/copilot-sdk"),!0):typeof import.meta.resolve=="function"?(import.meta.resolve("@github/copilot-sdk"),!0):!1}catch{return!1}};let Vt;const Jt=e=>se(e)||D(e.key)||D(process.env.COPILOT_GITHUB_TOKEN)?(Vt===void 0&&(Vt=Ua()),Vt):!1,se=e=>(Array.isArray(e.model)?e.model:D(e.model)?[e.model.trim()]:[]).length>0,ot=e=>{const t=D(e.key),n=D(e.region)||D(process.env.AWS_REGION)||D(process.env.AWS_DEFAULT_REGION),o=D(e.profile)||D(process.env.AWS_PROFILE),s=D(e.accessKeyId)&&D(e.secretAccessKey)||D(process.env.AWS_ACCESS_KEY_ID)&&D(process.env.AWS_SECRET_ACCESS_KEY),r=D(e.applicationBaseUrl)||D(process.env.BEDROCK_APPLICATION_BASE_URL),a=D(e.applicationEndpointId)||D(process.env.BEDROCK_APPLICATION_ENDPOINT_ID),c=D(process.env.BEDROCK_APPLICATION_API_KEY);return n&&(t||o||s)||(r&&t||a&&c)},le=(e,t)=>Object.entries(e).map(([n,o])=>[n,o]).filter(([n,o])=>!o.disabled).filter(([n,o])=>Ce.includes(n)||o.compatible===!0).filter(([n,o])=>{switch(t){case"commit":return n==="OLLAMA"?!!o&&se(o):n==="COPILOT_SDK"?!!o&&Jt(o):n==="HUGGINGFACE"?!!o&&!!o.cookie:n==="BEDROCK"?se(o)&&ot(o):!!o.key&&o.key.length>0;case"review":const s=e.codeReview||o.codeReview;return n==="OLLAMA"?!!o&&se(o)&&s:n==="COPILOT_SDK"?!!o&&Jt(o)&&s:n==="HUGGINGFACE"?!!o&&!!o.cookie&&s:n==="BEDROCK"?se(o)&&ot(o)&&s:!!o.key&&o.key.length>0&&s;case"watch":const r=e.watchMode||o.watchMode;return n==="OLLAMA"?!!o&&se(o)&&r:n==="COPILOT_SDK"?!!o&&Jt(o)&&r:n==="HUGGINGFACE"?!!o&&!!o.cookie&&r:n==="BEDROCK"?se(o)&&ot(o)&&r:o.compatible?!!o.url&&!!o.key&&r:!!o.key&&o.key.length>0&&r}}).map(([n])=>n);class Ka{static create(t,n){return new t(n)}}const Wa="stats.json",st=2,qa=30,Xt=()=>A.join(Po,Wa),rt=async()=>{const e=Xt();if(!await Qe(e))return{version:st,metrics:[],selections:[]};try{const t=await R.readFile(e,"utf-8"),n=JSON.parse(t);return!n.version||n.version<st?{version:st,metrics:n.metrics||[],selections:n.selections||[]}:n}catch{return{version:st,metrics:[],selections:[]}}},za=(e,t)=>{const n=Date.now()-t*24*60*60*1e3;return{version:e.version,metrics:e.metrics.filter(o=>o.timestamp>=n),selections:e.selections.filter(o=>o.timestamp>=n)}},Mo=async(e,t)=>{const n=Xt(),o=A.dirname(n),s=t?za(e,t):e;await R.mkdir(o,{recursive:!0}),await R.writeFile(n,JSON.stringify(s,null,2),"utf-8")},Ya=async e=>{const t={timestamp:Date.now(),provider:e.provider,model:e.model,responseTimeMs:e.responseTimeMs,success:e.success,errorCode:e.errorCode,tokensUsed:e.tokensUsed},n=await rt();n.metrics.push(t),await Mo(n,e.statsDays)},Va=async e=>{const t={timestamp:Date.now(),provider:e.provider,model:e.model},n=await rt();n.selections.push(t),await Mo(n,e.statsDays)},Ja=(e,t,n)=>{const o=t.filter(u=>u.provider===e),s=n.filter(u=>u.provider===e);if(o.length===0)return{provider:e,totalRequests:0,successCount:0,failureCount:0,selectedCount:s.length,selectionRate:0,avgResponseTimeMs:0,minResponseTimeMs:0,maxResponseTimeMs:0};const r=o.filter(u=>u.success),a=o.map(u=>u.responseTimeMs),c=s.length,l=r.length>0?Math.min(100,Math.round(c/r.length*1e3)/10):0;return{provider:e,totalRequests:o.length,successCount:r.length,failureCount:o.length-r.length,selectedCount:c,selectionRate:l,avgResponseTimeMs:Math.round(a.reduce((u,d)=>u+d,0)/a.length),minResponseTimeMs:Math.min(...a),maxResponseTimeMs:Math.max(...a)}},Xa=async(e=qa)=>{const t=await rt(),n=Date.now()-e*24*60*60*1e3,o=t.metrics.filter(u=>u.timestamp>=n),s=t.selections.filter(u=>u.timestamp>=n);if(o.length===0)return{totalRequests:0,successRate:0,avgResponseTimeMs:0,providerStats:[],periodStart:n,periodEnd:Date.now()};const a=[...new Set(o.map(u=>u.provider))].map(u=>Ja(u,o,s)).sort((u,d)=>d.totalRequests-u.totalRequests),c=o.filter(u=>u.success).length,l=o.reduce((u,d)=>u+d.responseTimeMs,0);return{totalRequests:o.length,successRate:Math.round(c/o.length*1e3)/10,avgResponseTimeMs:Math.round(l/o.length),providerStats:a,periodStart:Math.min(...o.map(u=>u.timestamp)),periodEnd:Math.max(...o.map(u=>u.timestamp))}},Qa=async()=>{const e=Xt();await Qe(e)&&await R.unlink(e)},Za=async()=>(await rt()).metrics.length>0,Oo=(e,t)=>{const n=h.red.bold(`[${e}]`);return Os({name:`${n} ${t}`,value:t,isError:!0,disabled:!0})},To=e=>{let t=!1;return Ts({next:n=>{if(Object.assign(n,{provider:e.provider,model:e.model}),e.statsEnabled===!1||t)return;t=!0;const o=n.isError===!0,s={provider:e.provider,model:e.model,responseTimeMs:Date.now()-e.startTime,success:!o,errorCode:o?"REQUEST_ERROR":void 0,statsDays:e.statsDays};Ya(s).catch(()=>{})}})};class ec{constructor(){this.loaders=new Map,this.cache=new Map,this.loadService=async t=>{const n=this.cache.get(t);if(n)return n;const o=this.loaders.get(t);if(!o)return null;const s=await o();return this.cache.set(t,s),s},this.createService=async(t,n)=>{const o=await this.loadService(t);return o?new o(n):null},this.createRequest$=(t,n,o)=>{const s=Date.now(),r=Array.isArray(n.config.model)?n.config.model[0]:n.config.model;return Be(this.createService(t,n)).pipe(wn(a=>a?(o==="commit"?a.generateCommitMessage$():a.generateCodeReview$()).pipe(To({provider:t,model:r||"unknown",startTime:s,statsEnabled:n.statsEnabled,statsDays:n.statsDays})):Oo(t,"Invalid AI type")))},this.registerBuiltinProviders=()=>{this.loaders.set("OPENAI",()=>import("./openai.service-0f4c84d2.mjs").then(t=>t.OpenAIService)),this.loaders.set("COPILOT_SDK",()=>import("./copilot-sdk.service-e79100de.mjs").then(t=>t.CopilotSdkService)),this.loaders.set("OPENROUTER",()=>import("./openrouter.service-4c0e10cf.mjs").then(t=>t.OpenRouterService)),this.loaders.set("GEMINI",()=>import("./gemini.service-8229964f.mjs").then(t=>t.GeminiService)),this.loaders.set("ANTHROPIC",()=>import("./anthropic.service-5cdbdbb2.mjs").then(t=>t.AnthropicService)),this.loaders.set("HUGGINGFACE",()=>import("./hugging-face.service-29dee38b.mjs").then(t=>t.HuggingFaceService)),this.loaders.set("MISTRAL",()=>import("./mistral.service-97bbd45d.mjs").then(t=>t.MistralService)),this.loaders.set("CODESTRAL",()=>import("./codestral.service-e699d247.mjs").then(t=>t.CodestralService)),this.loaders.set("OLLAMA",()=>import("./ollama.service-39fbf468.mjs").then(t=>t.OllamaService)),this.loaders.set("COHERE",()=>import("./cohere.service-116c0ff2.mjs").then(t=>t.CohereService)),this.loaders.set("GROQ",()=>import("./groq.service-91a40955.mjs").then(t=>t.GroqService)),this.loaders.set("PERPLEXITY",()=>import("./perplexity.service-55a372f0.mjs").then(t=>t.PerplexityService)),this.loaders.set("BEDROCK",()=>import("./bedrock.service-77f90b1d.mjs").then(t=>t.BedrockService)),this.loaders.set("GITHUB_MODELS",()=>import("./github-models.service-2363c869.mjs").then(t=>t.GitHubModelsService)),this.loaders.set("DEEPSEEK",()=>import("./deep-seek.service-55a7cae5.mjs").then(t=>t.DeepSeekService))},this.registerBuiltinProviders()}}const tc=new ec;class Qt{getDetectedMessage(t){return`Detected ${t.files.length.toLocaleString()} changed file${t.files.length>1?"s":""} (${t.diff.length.toLocaleString()} characters)`}getDetectedFiles(t){return`Detected ${t.length.toLocaleString()} changed file${t.length>1?"s":""}`}}const Do="AICOMMIT2_MSG_FILE";class it extends Qt{constructor(){super(...arguments),this.name="git",this.excludeFromDiff=t=>`:(exclude)${t}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:t}=await C("git",["rev-parse","--show-toplevel"],{reject:!0});return t.trim()}catch(t){const n=t;if(n.code==="ENOENT")throw new m(`Git command not found!
|
|
22
22
|
|
|
23
23
|
Please install Git first: https://git-scm.com/downloads`);if(n.stderr){if(n.stderr.includes("not a git repository"))throw new m(`Not in a Git repository!
|
|
24
24
|
|
|
@@ -62,13 +62,13 @@ Stash or commit them before rewriting a non-HEAD commit:
|
|
|
62
62
|
|
|
63
63
|
Rewriting via \`git rebase -i\` would linearize history and drop the merges.
|
|
64
64
|
Reword the merge commit directly with \`git commit --amend\` (if HEAD) or
|
|
65
|
-
use \`git rebase -i --rebase-merges\` manually.`);const{stdout:s}=await C("git",["rev-parse","--short",n]),r=s.trim(),a=A.join(ue.tmpdir(),`aicommit2-rewrite-msg-${yt.randomBytes(8).toString("hex")}.txt`);O.writeFileSync(a,t,"utf8");const c=process.platform==="darwin"?"sed -i ''":"sed -i";try{await C("git",["rebase","-i",`${n}^`,"--keep-empty"],{env:{...process.env,[
|
|
65
|
+
use \`git rebase -i --rebase-merges\` manually.`);const{stdout:s}=await C("git",["rev-parse","--short",n]),r=s.trim(),a=A.join(ue.tmpdir(),`aicommit2-rewrite-msg-${yt.randomBytes(8).toString("hex")}.txt`);O.writeFileSync(a,t,"utf8");const c=process.platform==="darwin"?"sed -i ''":"sed -i";try{await C("git",["rebase","-i",`${n}^`,"--keep-empty"],{env:{...process.env,[Do]:a,GIT_SEQUENCE_EDITOR:`${c} 's/^pick ${r}/reword ${r}/'`,GIT_EDITOR:`sh -c 'cp "$${Do}" "$1"' --`},stdio:"inherit"})}finally{try{O.unlinkSync(a)}catch{}}}}catch(o){const s=o;throw s.stderr?s.stderr.includes("Author identity unknown")?new m(`Git author identity not configured.
|
|
66
66
|
|
|
67
67
|
Configure with:
|
|
68
68
|
git config --global user.name "Your Name"
|
|
69
69
|
git config --global user.email "your.email@example.com"`):s.stderr.includes("nothing to amend")?new m("Nothing to amend. The specified commit has no changes to modify."):s.stderr.includes("fatal: invalid upstream")?new m(`Invalid commit reference: ${n}.
|
|
70
70
|
|
|
71
|
-
Make sure the commit hash is correct and the commit exists in this repository.`):new m(`Git rewrite failed: ${s.stderr.trim()}`):new m(`Failed to rewrite commit: ${s.message||"Unknown error"}`)}}async isCommitPushed(t="HEAD"){try{const{stdout:n}=await C("git",["branch","-r","--contains",t]);return n.trim().length>0}catch{return!1}}}class
|
|
71
|
+
Make sure the commit hash is correct and the commit exists in this repository.`):new m(`Git rewrite failed: ${s.stderr.trim()}`):new m(`Failed to rewrite commit: ${s.message||"Unknown error"}`)}}async isCommitPushed(t="HEAD"){try{const{stdout:n}=await C("git",["branch","-r","--contains",t]);return n.trim().length>0}catch{return!1}}}class Zt extends Qt{constructor(){super(...arguments),this.name="jujutsu",this.excludeFromDiff=t=>t.includes("*")||t.includes("?")||t.includes("[")?`~glob:"${t}"`:`~"${t}"`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"]}async assertRepo(){try{const{stdout:t}=await C("jj",["--version"],{reject:!0});process.env.DEBUG&&console.log(`Jujutsu version: ${t}`)}catch(t){const n=t;throw n.code==="ENOENT"?new m(`Jujutsu (jj) command not found!
|
|
72
72
|
|
|
73
73
|
Please install Jujutsu:
|
|
74
74
|
- macOS: brew install jj
|
|
@@ -103,7 +103,7 @@ Make some changes first, then try again.`):r.stderr.includes("Invalid revision")
|
|
|
103
103
|
Ensure you're in a valid workspace with changes.`):r.stderr.includes("Operation not allowed")?new m(`Jujutsu operation not allowed: ${r.stderr.trim()}
|
|
104
104
|
|
|
105
105
|
Check repository state with: jj status`):new m(`Jujutsu describe failed: ${r.stderr.trim()}`):r.exitCode===1?new m("Jujutsu commit failed. Check your changes and repository state."):new m(`Failed to commit with Jujutsu: ${r.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:t}=await C("jj",["config","get","ui.comment-char"]);return t.trim()||"#"}catch{return"#"}}async getRecentCommits(t=5,n){try{const{stdout:o}=await C("jj",["log","--limit",t.toString(),"--no-graph","-T",'description.first_line() ++ "\\n"']);return o.trim()}catch{return""}}async getBranchName(){try{const{stdout:t}=await C("jj",["bookmark","list","--revisions","@"]);if(t.trim()){const s=t.split(`
|
|
106
|
-
`)[0].split(":")[0].trim();if(s)return s}const{stdout:n}=await C("jj",["log","-r","@","--no-graph","-T","change_id.short()"]);return n.trim()||"HEAD"}catch{return"HEAD"}}}class
|
|
106
|
+
`)[0].split(":")[0].trim();if(s)return s}const{stdout:n}=await C("jj",["log","-r","@","--no-graph","-T","change_id.short()"]);return n.trim()||"HEAD"}catch{return"HEAD"}}}class en extends Qt{constructor(){super(...arguments),this.name="yadm",this.excludeFromDiff=t=>`:(exclude)${t}`,this.filesToExclude=["package-lock.json","pnpm-lock.yaml","*.lock","*.lockb"].map(this.excludeFromDiff)}async assertRepo(){try{const{stdout:t}=await C("yadm",["rev-parse","--show-toplevel"],{reject:!0}),n=t.trim(),o=process.env.HOME||process.env.USERPROFILE;if(!o)throw new m("HOME environment variable not set. Cannot determine YADM repository.");const s=await import("path"),r=s.resolve(n),a=s.resolve(o);if(r!==a)throw new m(`Not a YADM repository (work tree is not $HOME).
|
|
107
107
|
|
|
108
108
|
YADM work tree: ${r}
|
|
109
109
|
Expected: ${a}
|
|
@@ -144,14 +144,14 @@ Configure with:
|
|
|
144
144
|
yadm config --global user.name "Your Name"
|
|
145
145
|
yadm config --global user.email "your.email@example.com"`):r.stderr.includes("Permission denied")?new m(`YADM permission error: ${r.stderr.trim()}
|
|
146
146
|
|
|
147
|
-
Check repository permissions and file access.`):new m(`YADM commit failed: ${r.stderr.trim()}`):r.exitCode===1?new m("YADM commit failed. Check your staged changes and try again."):new m(`Failed to commit with YADM: ${r.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:t}=await C("yadm",["config","--get","core.commentChar"]);return t}catch{return"#"}}async getRecentCommits(t=5,n){try{const{stdout:o}=await C("yadm",["log","--format=%s",`-${t}`]);return o.trim()}catch{return""}}async getBranchName(){try{const{stdout:t}=await C("yadm",["branch","--show-current"]),n=t.trim();if(!n){const{stdout:o}=await C("yadm",["rev-parse","--short","HEAD"]);return`HEAD@${o.trim()}`}return n}catch{return"HEAD"}}}let
|
|
148
|
-
${f instanceof Error?f.message:String(f)}`)}if(t)try{const f=new
|
|
149
|
-
${f instanceof Error?f.message:String(f)}`)}if(n)try{const f=new
|
|
147
|
+
Check repository permissions and file access.`):new m(`YADM commit failed: ${r.stderr.trim()}`):r.exitCode===1?new m("YADM commit failed. Check your staged changes and try again."):new m(`Failed to commit with YADM: ${r.message||"Unknown error"}`)}}async getCommentChar(){try{const{stdout:t}=await C("yadm",["config","--get","core.commentChar"]);return t}catch{return"#"}}async getRecentCommits(t=5,n){try{const{stdout:o}=await C("yadm",["log","--format=%s",`-${t}`]);return o.trim()}catch{return""}}async getBranchName(){try{const{stdout:t}=await C("yadm",["branch","--show-current"]),n=t.trim();if(!n){const{stdout:o}=await C("yadm",["rev-parse","--short","HEAD"]);return`HEAD@${o.trim()}`}return n}catch{return"HEAD"}}}let tn=null;const nc=async()=>{const e=process.argv.includes("--git"),t=process.argv.includes("--yadm"),n=process.argv.includes("--jj");if(e)try{const f=new it;return await f.assertRepo(),f}catch(f){throw new m(`--git flag is set, but Git is not available or not in a git repository.
|
|
148
|
+
${f instanceof Error?f.message:String(f)}`)}if(t)try{const f=new en;return await f.assertRepo(),f}catch(f){throw new m(`--yadm flag is set, but YADM is not available or not in a YADM repository.
|
|
149
|
+
${f instanceof Error?f.message:String(f)}`)}if(n)try{const f=new Zt;return await f.assertRepo(),f}catch(f){throw new m(`--jj flag is set, but Jujutsu is not available or not in a jj repository.
|
|
150
150
|
${f instanceof Error?f.message:String(f)}`)}const o=process.env.FORCE_GIT==="true",s=process.env.FORCE_YADM==="true",r=process.env.FORCE_JJ==="true";if(o)try{const f=new it;return await f.assertRepo(),f}catch(f){throw new m(`FORCE_GIT="true" environment variable is set, but Git is not available or not in a git repository.
|
|
151
|
-
${f instanceof Error?f.message:String(f)}`)}if(s)try{const f=new
|
|
152
|
-
${f instanceof Error?f.message:String(f)}`)}if(r)try{const f=new
|
|
151
|
+
${f instanceof Error?f.message:String(f)}`)}if(s)try{const f=new en;return await f.assertRepo(),f}catch(f){throw new m(`FORCE_YADM="true" environment variable is set, but YADM is not available or not in a YADM repository.
|
|
152
|
+
${f instanceof Error?f.message:String(f)}`)}if(r)try{const f=new Zt;return await f.assertRepo(),f}catch(f){throw new m(`FORCE_JJ="true" environment variable is set, but Jujutsu is not available or not in a jj repository.
|
|
153
153
|
${f instanceof Error?f.message:String(f)}`)}let a=!1;try{a=(await Z({})).forceGit===!0}catch{a=!1}if(a)try{const f=new it;return await f.assertRepo(),f}catch(f){throw new m(`forceGit=true is set in config, but Git is not available or not in a git repository.
|
|
154
|
-
${f instanceof Error?f.message:String(f)}`)}const[c,l,u]=await Promise.allSettled([(async()=>{const f=new
|
|
154
|
+
${f instanceof Error?f.message:String(f)}`)}const[c,l,u]=await Promise.allSettled([(async()=>{const f=new Zt;return await f.assertRepo(),f})(),(async()=>{const f=new it;return await f.assertRepo(),f})(),(async()=>{const f=new en;return await f.assertRepo(),f})()]);if(c.status==="fulfilled")return c.value;if(l.status==="fulfilled")return l.value;if(u.status==="fulfilled")return u.value;const d=f=>f.status==="fulfilled"?"unexpected success":String(f.reason?.message??f.reason).replace("KnownError: ","").trim(),p=d(c),g=d(l),y=d(u);throw new m(`No supported VCS repository found.
|
|
155
155
|
|
|
156
156
|
Jujutsu Error:
|
|
157
157
|
${p}
|
|
@@ -168,7 +168,7 @@ Solutions:
|
|
|
168
168
|
\u2022 Initialize a YADM repository: yadm init (or yadm clone <url>)
|
|
169
169
|
\u2022 Navigate to an existing Jujutsu, Git, or YADM repository
|
|
170
170
|
\u2022 Set FORCE_GIT="true" environment variable to force Git detection
|
|
171
|
-
\u2022 Set forceGit=true in config file to prefer Git detection`)},J=async()=>(
|
|
171
|
+
\u2022 Set forceGit=true in config file to prefer Git detection`)},J=async()=>(tn||(tn=await nc()),tn);let Te=null;const No=async()=>{if(Te!==null)return Te;try{Te=(await Z({})).diffContext}catch{Te=we}return Te},nn=(e,t)=>{const{diff:n,stats:o}=ya(e.diff,t);return n===e.diff?e:{...e,diff:n,compression:o}},at=async()=>(await J()).assertRepo(),on=async(e,t)=>{const n=await J(),o=await No(),s=await n.getStagedDiff(e,t,{diffContext:o});return s||null},_o=async(e,t,n)=>{const o=await J();if(!o.getCommitDiff)throw new m(`Commit diff not supported for ${o.name}`);const s=await No(),r=await o.getCommitDiff(e,t,n,{diffContext:s});return r||null},oc=async()=>(await J()).getCommentChar(),sc=e=>{const t=e.files.length.toLocaleString(),n=e.files.length>1?"s":"",o=e.diff.length.toLocaleString();return`Detected ${t} changed file${n} (${o} characters)`},De=async()=>(await J()).name,rc=async(e,t,n)=>{await(await J()).commit(e,t||[],n)},Ne=async()=>(await J()).getBranchName(),_e=async(e=5,t)=>(await J()).getRecentCommits(e,t),ic=async(e,t="HEAD")=>{const n=await J();if(!n.rewriteCommit)throw new m(`Rewrite is not supported for ${n.name} repositories. Only Git is supported.`);await n.rewriteCommit(e,t)},ac=async(e="HEAD")=>{const t=await J();return t.getCommitMessage?t.getCommitMessage(e):""},cc=async(e="HEAD")=>{const t=await J();return t.isCommitPushed?t.isCommitPushed(e):!1};class je{constructor(t,n,o="",s=""){this.config=t,this.stagedDiff=n,this.branchName=o,this.recentCommits=s,this.getDiffForModel=r=>{const a={mode:r.diffCompression||"none",maxHunkLines:r.maxHunkLines||0,maxDiffLines:r.maxDiffLines||0};return nn(this.stagedDiff,a)},this.extractProviderName=r=>{if(!r)return"compatible";try{return new URL(r).hostname}catch{return"compatible"}},this.createCommitMsgRequests$=r=>this.createServiceRequests$(r,"commit"),this.createCodeReviewRequests$=r=>this.createServiceRequests$(r,"review"),this.createServiceRequests$=(r,a)=>Be(r).pipe(Cn(c=>this.createProviderRequests$(c,a)),Ds(c=>Oo("UNKNOWN",c.message||"Unknown error"))),this.createProviderRequests$=(r,a)=>{const c=this.config[r],l=Array.isArray(c.model)?c.model:[c.model];return Be(l).pipe(Cn(u=>this.createModelRequest$(r,u,a)))},this.createModelRequest$=(r,a,c)=>{const l=this.config[r];if(l.compatible)return this.createCompatibleServiceRequest$(l,a,c);const u=this.getDiffForModel(l);return tc.createRequest$(r,{config:{...l,model:a},stagedDiff:u,keyName:a,branchName:this.branchName,recentCommits:this.recentCommits,statsEnabled:this.config.useStats,statsDays:this.config.statsDays,modelNameDisplay:this.config.modelNameDisplay},c)},this.createCompatibleServiceRequest$=(r,a,c)=>{const l=Date.now(),u=this.extractProviderName(r.url),d=this.getDiffForModel(r);return Be(import("./openai-compatible.service-edf430e1.mjs")).pipe(wn(({OpenAICompatibleService:p})=>{const g=Ka.create(p,{config:{...r,url:r.url||"",path:r.path||"",model:a},stagedDiff:d,keyName:a,branchName:this.branchName,recentCommits:this.recentCommits,modelNameDisplay:this.config.modelNameDisplay});return(c==="commit"?g.generateCommitMessage$():g.generateCodeReview$()).pipe(To({provider:u,model:a,startTime:l,statsEnabled:this.config.useStats,statsDays:this.config.statsDays}))}))}}}const lc=1e5;class B{constructor(){this.title="aicommit2",this.formatCompressionStats=t=>{if(!t||t.originalChars===t.compressedChars)return null;const n=Math.round((1-t.compressedChars/t.originalChars)*100);return`[compact: ${t.originalChars.toLocaleString()} \u2192 ${t.compressedChars.toLocaleString()} chars, ${n}% saved]`},this.formatBytes=t=>t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}printTitle(){try{const t=An.textSync(this.title,{font:"Small Slant"}),n=js(["#8B5CF6","#A020F0","#D946EF"]);console.log(h.bold(n.multiline(t)))}catch{console.log(h.bold(An.textSync(this.title,{font:"Small Slant"})))}}showLoader(t){if(this.loader){this.loader.text=t;return}this.loader=Pn(t).start()}stopLoader(){this.loader?.stop(),this.loader=void 0}displaySpinner(t){return Pn(t).start()}stopSpinner(t){t.stop(),t.clear()}printStagedFiles(t,n){const o=Buffer.byteLength(t.diff,"utf8"),s=this.formatBytes(o),r=sc(t),a=this.formatCompressionStats(n);console.log(h.bold.green("\u2714 ")+h.bold(r)+h.dim(` (${s})`)+(a?h.cyan(` ${a}`):"")+h.bold(":")),console.log(`${t.files.map(l=>` ${l}`).join(`
|
|
172
172
|
`)}
|
|
173
173
|
`),o>lc&&!n&&(console.log(h.yellow(`\u26A0 Large diff detected (${s}). This may increase processing time and costs.`)),console.log(h.dim(` Consider using --exclude to filter large files or diffCompression=compact.
|
|
174
174
|
`)))}printAnalyzed(){console.log(`
|
|
@@ -181,8 +181,8 @@ ${h.bold.red("\u2716")} ${h.red(`${t}`)}`)}printWarning(t){console.log(`
|
|
|
181
181
|
${h.bold.yellow("\u26A0")} ${h.yellow(`${t}`)}`)}printSuccess(t){console.log(`
|
|
182
182
|
${h.bold.green("\u2714")} ${h.green(`${t}`)}`)}printInfo(t){console.log(`
|
|
183
183
|
${h.bold.blue("\u2139")} ${h.blue(`${t}`)}`)}printSetupGitEvent(t){console.log(`
|
|
184
|
-
${h.bold.green("\u2714")} ${h.bold(`Git ${t} hook has been set up`)}`)}moveCursorUp(){const t=He.createInterface({input:process.stdin,output:process.stdout});He.moveCursor(process.stdout,0,-1),t.close()}moveCursorDown(){const t=He.createInterface({input:process.stdin,output:process.stdout});He.moveCursor(process.stdout,0,2),t.close()}print(t){console.log(t)}}let ct,
|
|
185
|
-
${h.bold.yellow("\u26A0")} ${h.yellow(`${
|
|
184
|
+
${h.bold.green("\u2714")} ${h.bold(`Git ${t} hook has been set up`)}`)}moveCursorUp(){const t=He.createInterface({input:process.stdin,output:process.stdout});He.moveCursor(process.stdout,0,-1),t.close()}moveCursorDown(){const t=He.createInterface({input:process.stdin,output:process.stdout});He.moveCursor(process.stdout,0,2),t.close()}print(t){console.log(t)}}let ct,jo="info";async function lt(e){if(ct){console.warn("Logger already initialized. Skipping re-initialization.");return}const t=e?.logLevel||"info";jo=t;const n=e?.logFilePath||$o,o=e?.exceptionLogFilePath||So,s=e?.logging??!0;await bo(A.dirname(n)),await bo(A.dirname(o));const r=[];s?r.push(new K.transports.DailyRotateFile({filename:n,datePattern:"YYYY-MM-DD",zippedArchive:!0,maxSize:"20m",maxFiles:"14d",level:t,format:K.format.combine(K.format.timestamp(),K.format.printf(({level:a,message:c,timestamp:l})=>`[${l}] ${a}: ${c}`))})):r.push(new K.transports.Console({silent:!0})),ct=K.createLogger({level:t,format:K.format.json(),transports:r,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 re=new Proxy({},{get:(e,t,n)=>{if(!ct)throw new Error("Logger not initialized. Call initializeLogger() first.");return Reflect.get(ct,t,n)}});function Fo(){const e=K.config.npm.levels;return(e[jo]??e.info)>=e.verbose}const Go={isLoading:!1,startOption:{text:"AI is analyzing your changes"}},Bo={isLoading:!1,startOption:{text:"AI is performing a code review"}},sn="No commit messages were generated",Ho="No code reviews were generated",rn={type:"reactiveListPrompt",name:"aicommit2Prompt",message:"Pick a commit message to use: ",emptyMessage:`\u26A0 ${sn}`,loop:!1,descPageSize:15,showDescription:!0,pickKey:"short",isDescriptionDim:!0,stopMessage:"Changes analyzed"};class ut{constructor(t){this.choices$=new En([]),this.destroyed$=new Ns(1),this.stopMessage="Changes analyzed",this.isDestroyed=!1,this.subscriptions=new Et,this.inquirerInstance=null,this.loader$=new En(t)}addSubscription(t){if(this.isDestroyed){t.unsubscribe();return}this.subscriptions.add(t)}initPrompt(t=rn){return this.stopMessage=t.stopMessage,T.registerPrompt("reactiveListPrompt",Fs),this.inquirerInstance=T.prompt({choices$:this.choices$,loader$:this.loader$,...t}),this.inquirerInstance}startLoader(){this.loader$.next({isLoading:!0})}updateLoaderText(t){this.isDestroyed||this.loader$.next({isLoading:!0,startOption:{text:t}})}clearLoader(){this.inquirerInstance&&this.loader$.next({isLoading:!1,clear:!0})}refreshChoices(t){if(this.isDestroyed||!t)return;const n=t.streamKey;if(n){if(!t.value){this.removeStreamingChoice(n);return}const o=[...this.currentChoices],s=o.findIndex(r=>r.streamKey===n);if(s>=0){o[s]=t,this.choices$.next(o);return}this.choices$.next([...this.currentChoices,t].sort(vo));return}t.value&&this.choices$.next([...this.currentChoices,t].sort(vo))}removeStreamingChoice(t){if(this.isDestroyed)return;const n=this.currentChoices.filter(o=>o.streamKey!==t);this.choices$.next(n)}checkErrorOnChoices(t=!0){if(this.choices$.getValue().map(s=>s).filter(s=>!s.streamKey).every(s=>s?.isError||s?.disabled)){this.alertNoGeneratedMessage(),this.logEmptyCommitMessage(),t&&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(t){console.warn("Error completing subjects:",t)}}closeInquirerInstance(){if(!this.inquirerInstance)return;const t=this.inquirerInstance.ui;t?.rl&&!t.rl.closed&&t.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(t){Fo()&&console.warn("Error during ReactivePromptManager destruction:",t)}finally{this.inquirerInstance=null}}}alertNoGeneratedMessage(){this.loader$.next({isLoading:!1,message:sn,stopOption:{doneFrame:"\u26A0",color:"yellow"}})}stopLoaderOnSuccess(){this.loader$.next({isLoading:!1,message:this.stopMessage})}logEmptyCommitMessage(){console.log(`
|
|
185
|
+
${h.bold.yellow("\u26A0")} ${h.yellow(`${sn}`)}`)}get currentChoices(){return this.choices$.getValue().map(t=>t)}}const E={label:h.bold.green,command:h.bold.white,hint:h.gray,highlight:h.bold.magenta,dim:h.dim},k={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"},Fe={missingApiKey:e=>{const t=e.toUpperCase();return[`Missing API key for ${E.highlight(t)}.`,"",`${E.label("\u2192")} Run: ${E.command(`aicommit2 config set ${t}.key=YOUR_API_KEY`)}`].join(`
|
|
186
186
|
`)},invalidApiKey:e=>{const t=e.toUpperCase();return[`Invalid or expired API key for ${E.highlight(t)}.`,"",`${E.label("\u2192")} Update: ${E.command(`aicommit2 config set ${t}.key=YOUR_NEW_KEY`)}`].join(`
|
|
187
187
|
`)},noApiKeysConfigured:()=>["No AI provider API keys configured.","",`${E.label("\u2192")} Please set at least one API key:`,` ${E.command("aicommit2 config set OPENAI.key=sk-...")}`,` ${E.command("aicommit2 config set ANTHROPIC.key=sk-ant-...")}`,` ${E.command("aicommit2 config set OLLAMA.model=llama3.2")} ${E.dim("(no key needed)")}`,"",`${E.hint("Tip:")} ${E.command("aicommit2 config get")} ${E.hint("to see current config")}`].join(`
|
|
188
188
|
`),rateLimited:e=>[`Rate limit exceeded${e?` for ${E.highlight(e)}`:""}.`,"",`${E.label("\u2192")} Wait a moment and try again`,`${E.label("\u2192")} Or use a different AI provider`].join(`
|
|
@@ -199,7 +199,7 @@ ${h.bold.yellow("\u26A0")} ${h.yellow(`${on}`)}`)}get currentChoices(){return th
|
|
|
199
199
|
`),invalidConfigValue:(e,t)=>[`Invalid value for ${E.highlight(`"${e}"`)}`,"",`${E.label("\u2192")} Expected: ${E.dim(t)}`].join(`
|
|
200
200
|
`),serverError:(e,t)=>{const n=t?` ${E.dim(`(HTTP ${t})`)}`:"";return`${E.highlight(e)} server error${n}. Try again later.`},ollamaNotRunning:()=>[`${E.highlight("Ollama")} is not running or not accessible.`,"",`${E.label("\u2192")} Start: ${E.command("ollama serve")}`].join(`
|
|
201
201
|
`),ollamaModelNotPulled:e=>[`Ollama model ${E.highlight(`"${e}"`)} is not available locally.`,"",`${E.label("\u2192")} Pull: ${E.command(`ollama pull ${e}`)}`].join(`
|
|
202
|
-
`)},uc=e=>({401:k.INVALID_API_KEY,403:k.MODEL_ACCESS_DENIED,404:k.MODEL_NOT_FOUND,429:k.RATE_LIMITED,500:k.SERVER_ERROR,502:k.SERVICE_UNAVAILABLE,503:k.SERVICE_UNAVAILABLE,504:k.TIMEOUT})[e]||k.UNKNOWN,dc=e=>{const t=e.toLowerCase();return t.includes("api key")||t.includes("api_key")||t.includes("apikey")?t.includes("missing")?k.MISSING_API_KEY:k.INVALID_API_KEY:t.includes("401")||t.includes("unauthorized")||t.includes("authentication")?k.AUTH_FAILED:t.includes("rate")||t.includes("429")||t.includes("too many")?k.RATE_LIMITED:t.includes("quota")||t.includes("usage")||t.includes("limit exceeded")?k.QUOTA_EXCEEDED:t.includes("model")&&(t.includes("not found")||t.includes("404"))?k.MODEL_NOT_FOUND:t.includes("403")||t.includes("forbidden")||t.includes("access denied")?k.MODEL_ACCESS_DENIED:t.includes("econnrefused")||t.includes("network")||t.includes("connection")?k.NETWORK_ERROR:t.includes("timeout")||t.includes("timed out")||t.includes("504")?k.TIMEOUT:t.includes("unavailable")||t.includes("overloaded")||t.includes("503")||t.includes("502")?k.SERVICE_UNAVAILABLE:t.includes("500")||t.includes("internal server error")?k.SERVER_ERROR:k.UNKNOWN},z={missingApiKey:e=>`Missing API key for ${e.toUpperCase()}`,invalidApiKey:e=>`Invalid API key for ${e.toUpperCase()}`,rateLimited:e=>`Rate limit exceeded${e?` for ${e}`:""}`,quotaExceeded:e=>`API quota exceeded${e?` for ${e}`:""}`,modelNotFound:(e,t)=>`Model "${e}" not found for ${t.toUpperCase()}`,modelAccessDenied:(e,t)=>`Access denied to model "${e}" on ${t}`,networkError:e=>`Network connection failed${e?` to ${e}`:""}`,timeout:(e,t)=>`Request timed out${t?` from ${t}`:""} after ${e}ms`,serviceUnavailable:e=>`${e} service is temporarily unavailable`,serverError:(e,t)=>`${e} server error${t?` (HTTP ${t})`:""}`,unknown:e=>`An error occurred with ${e}. Please try again.`,ollamaNotRunning:()=>"Ollama is not running. Start with: ollama serve",ollamaModelNotPulled:e=>`Ollama model "${e}" not found. Pull with: ollama pull ${e}`},mc=(e,t={})=>{const{provider:n="AI",model:o,timeout:s}=t;switch(e){case k.MISSING_API_KEY:return z.missingApiKey(n);case k.INVALID_API_KEY:case k.AUTH_FAILED:return z.invalidApiKey(n);case k.RATE_LIMITED:return z.rateLimited(n);case k.QUOTA_EXCEEDED:return z.quotaExceeded(n);case k.MODEL_NOT_FOUND:return z.modelNotFound(o||"unknown",n);case k.MODEL_ACCESS_DENIED:return z.modelAccessDenied(o||"unknown",n);case k.NETWORK_ERROR:return z.networkError(n);case k.TIMEOUT:return z.timeout(s||1e4,n);case k.SERVICE_UNAVAILABLE:return z.serviceUnavailable(n);case k.SERVER_ERROR:return z.serverError(n);default:return z.unknown(n)}},
|
|
202
|
+
`)},uc=e=>({401:k.INVALID_API_KEY,403:k.MODEL_ACCESS_DENIED,404:k.MODEL_NOT_FOUND,429:k.RATE_LIMITED,500:k.SERVER_ERROR,502:k.SERVICE_UNAVAILABLE,503:k.SERVICE_UNAVAILABLE,504:k.TIMEOUT})[e]||k.UNKNOWN,dc=e=>{const t=e.toLowerCase();return t.includes("api key")||t.includes("api_key")||t.includes("apikey")?t.includes("missing")?k.MISSING_API_KEY:k.INVALID_API_KEY:t.includes("401")||t.includes("unauthorized")||t.includes("authentication")?k.AUTH_FAILED:t.includes("rate")||t.includes("429")||t.includes("too many")?k.RATE_LIMITED:t.includes("quota")||t.includes("usage")||t.includes("limit exceeded")?k.QUOTA_EXCEEDED:t.includes("model")&&(t.includes("not found")||t.includes("404"))?k.MODEL_NOT_FOUND:t.includes("403")||t.includes("forbidden")||t.includes("access denied")?k.MODEL_ACCESS_DENIED:t.includes("econnrefused")||t.includes("network")||t.includes("connection")?k.NETWORK_ERROR:t.includes("timeout")||t.includes("timed out")||t.includes("504")?k.TIMEOUT:t.includes("unavailable")||t.includes("overloaded")||t.includes("503")||t.includes("502")?k.SERVICE_UNAVAILABLE:t.includes("500")||t.includes("internal server error")?k.SERVER_ERROR:k.UNKNOWN},z={missingApiKey:e=>`Missing API key for ${e.toUpperCase()}`,invalidApiKey:e=>`Invalid API key for ${e.toUpperCase()}`,rateLimited:e=>`Rate limit exceeded${e?` for ${e}`:""}`,quotaExceeded:e=>`API quota exceeded${e?` for ${e}`:""}`,modelNotFound:(e,t)=>`Model "${e}" not found for ${t.toUpperCase()}`,modelAccessDenied:(e,t)=>`Access denied to model "${e}" on ${t}`,networkError:e=>`Network connection failed${e?` to ${e}`:""}`,timeout:(e,t)=>`Request timed out${t?` from ${t}`:""} after ${e}ms`,serviceUnavailable:e=>`${e} service is temporarily unavailable`,serverError:(e,t)=>`${e} server error${t?` (HTTP ${t})`:""}`,unknown:e=>`An error occurred with ${e}. Please try again.`,ollamaNotRunning:()=>"Ollama is not running. Start with: ollama serve",ollamaModelNotPulled:e=>`Ollama model "${e}" not found. Pull with: ollama pull ${e}`},mc=(e,t={})=>{const{provider:n="AI",model:o,timeout:s}=t;switch(e){case k.MISSING_API_KEY:return z.missingApiKey(n);case k.INVALID_API_KEY:case k.AUTH_FAILED:return z.invalidApiKey(n);case k.RATE_LIMITED:return z.rateLimited(n);case k.QUOTA_EXCEEDED:return z.quotaExceeded(n);case k.MODEL_NOT_FOUND:return z.modelNotFound(o||"unknown",n);case k.MODEL_ACCESS_DENIED:return z.modelAccessDenied(o||"unknown",n);case k.NETWORK_ERROR:return z.networkError(n);case k.TIMEOUT:return z.timeout(s||1e4,n);case k.SERVICE_UNAVAILABLE:return z.serviceUnavailable(n);case k.SERVER_ERROR:return z.serverError(n);default:return z.unknown(n)}},Uo={locale:"en",maxLength:50,type:"conventional",generate:1,systemPrompt:"",systemPromptPath:"",codeReviewPromptPath:"",vcs_branch:"",isReasoning:!1},Ko={"":"<commit message>",conventional:`<type>(<optional scope>): <description>
|
|
203
203
|
|
|
204
204
|
[optional body]
|
|
205
205
|
|
|
@@ -207,12 +207,12 @@ ${h.bold.yellow("\u26A0")} ${h.yellow(`${on}`)}`)}get currentChoices(){return th
|
|
|
207
207
|
|
|
208
208
|
[optional body]
|
|
209
209
|
|
|
210
|
-
[optional footer(s)]`},
|
|
210
|
+
[optional footer(s)]`},Wo={"":"",gitmoji:`
|
|
211
211
|
${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(([e,t])=>` - ${e}: ${t}`).join(`
|
|
212
212
|
`)}`,conventional:`
|
|
213
213
|
${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(([e,t])=>` - ${e}: ${t}`).join(`
|
|
214
|
-
`)}`},
|
|
215
|
-
`)},hc=e=>{const{type:t,maxLength:n,generate:o,locale:s}=e;return[`You are an expert developer writing ${t||""} commit message${o!==1?"s":""} from a git diff.`,"","Analyze the diff to understand:","1. What is the primary intent of these changes? (new feature, bug fix, refactor, etc.)","2. What is the scope? (which module, component, or system is affected?)","3. Are there any breaking changes or side effects?","",`Language: ${s}`,`Subject: max ${n} chars, imperative mood, no period`,t?`Format: ${
|
|
214
|
+
`)}`},an=(e,t)=>e.replace(/{(\w+)}/g,(n,o)=>t[o]?.toString()||Uo[o]?.toString()),fc=(e,t)=>{const n=t.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[e]||o[""];return s[n]||s.en},pc=e=>{const{type:t,maxLength:n,generate:o,locale:s}=e;return[`Generate exactly ${o} ${t} commit message${o!==1?"s":""} from the provided git diff.`,"",`Language: ${s}`,`Subject: max ${n} chars, imperative mood, no period`,"Format:",`${Ko[t]}`,`Allowed types:${Wo[t]}`,"","Rules:","- Extract scope from file paths or logical grouping (e.g., auth, api, ui)","- Focus on WHY the change was made, not just WHAT changed","- Body: only for complex changes (motivation, behavior comparison, breaking changes)","- Footer: issue references or BREAKING CHANGE if applicable"].filter(Boolean).join(`
|
|
215
|
+
`)},hc=e=>{const{type:t,maxLength:n,generate:o,locale:s}=e;return[`You are an expert developer writing ${t||""} commit message${o!==1?"s":""} from a git diff.`,"","Analyze the diff to understand:","1. What is the primary intent of these changes? (new feature, bug fix, refactor, etc.)","2. What is the scope? (which module, component, or system is affected?)","3. Are there any breaking changes or side effects?","",`Language: ${s}`,`Subject: max ${n} chars, imperative mood, no period`,t?`Format: ${Ko[t]}`:"",t?`Allowed types:${Wo[t]}`:"","",`Generate exactly ${o} commit message${o!==1?"s":""}.`,"Prioritize explaining WHY the change was made over describing WHAT changed."].filter(Boolean).join(`
|
|
216
216
|
`)},gc=(e,t,n)=>{const o=fc(e,n),r=e==="conventional"||e==="gitmoji"?`
|
|
217
217
|
[
|
|
218
218
|
{"subject": "${o.subject}", "body": "${o.body}", "footer": ""}
|
|
@@ -220,11 +220,11 @@ ${Object.entries({docs:"Documentation only changes",style:"Changes that do not a
|
|
|
220
220
|
Respond with a JSON array of exactly ${t} object${t!==1?"s":""}:`,`- "subject": ${e} style commit message`,'- "body": detailed explanation (empty string if not needed)','- "footer": BREAKING CHANGE or issue refs (empty string if not needed)',r?`
|
|
221
221
|
Example:${r}`:"",`
|
|
222
222
|
Return valid JSON only.`].filter(Boolean).join(`
|
|
223
|
-
`)},yc=e=>{const{systemPrompt:t,systemPromptPath:n,type:o,generate:s,locale:r,isReasoning:a}=e,c=gc(o,s,r);if(t)return`${
|
|
224
|
-
${c}`;if(n)try{const u=O.readFileSync(Ze(n),"utf-8");return`${
|
|
223
|
+
`)},yc=e=>{const{systemPrompt:t,systemPromptPath:n,type:o,generate:s,locale:r,isReasoning:a}=e,c=gc(o,s,r);if(t)return`${an(t,e)}
|
|
224
|
+
${c}`;if(n)try{const u=O.readFileSync(Ze(n),"utf-8");return`${an(u,e)}
|
|
225
225
|
${c}`}catch{}return`${a?hc(e):pc(e)}
|
|
226
|
-
${c}`},wc=e=>{const{codeReviewPromptPath:t,locale:n}=e;if(t)try{const o=O.readFileSync(Ze(t),"utf-8");return`${
|
|
227
|
-
`),
|
|
226
|
+
${c}`},wc=e=>{const{codeReviewPromptPath:t,locale:n}=e;if(t)try{const o=O.readFileSync(Ze(t),"utf-8");return`${an(o,e)}`}catch{}return Cc(n)},Cc=e=>["Review the git diff and provide structured feedback as JSON.","",`Language: ${e}`,"Severity: critical (must fix) | warning (should fix) | suggestion (nice to have) | praise (good practice)","Category: bug | security | performance | style | maintainability | other","","Rules:","- Reference specific code and file paths from the diff","- Include a concrete suggestion for every issue","- Prioritize: critical > warning > suggestion","","Respond with this JSON structure:",'{"summary": "1-2 sentence assessment", "items": [{"severity": "...", "category": "...", "file": "path (optional)", "line": "number (optional)", "title": "max 80 chars", "description": "why it matters", "suggestion": "how to fix (empty string if N/A)"}]}',"","Return valid JSON only. Empty items array if no issues found."].join(`
|
|
227
|
+
`),cn=async e=>{if(e.systemPromptPath)try{O.readFileSync(Ze(e.systemPromptPath),"utf-8")}catch(t){throw new m(`Error reading system prompt file: ${e.systemPromptPath}, ${t}`)}if(e.codeReview&&e.codeReviewPromptPath)try{O.readFileSync(Ze(e.codeReviewPromptPath),"utf-8")}catch(t){throw new m(`Error reading code review prompt file: ${e.codeReviewPromptPath}, ${t}`)}},Ec=e=>{const t=Object.values(e.typeDistribution).reduce((o,s)=>o+s,0),n=["## Repository Conventions (match these)"];if(e.dominantType&&n.push(`- Predominant style: ${e.dominantType}`),t>0){const o=Object.entries(e.typeDistribution).sort((s,r)=>r[1]-s[1]).map(([s,r])=>`${s} (${Math.round(r/t*100)}%)`).join(", ");n.push(`- Common types: ${o}`)}return e.commonScopes.length>0&&n.push(`- Common scopes: ${e.commonScopes.join(", ")}`),n.push(`- Typical subject length: ~${e.avgSubjectLength} chars`),n.join(`
|
|
228
228
|
`)},bc=e=>{const t=e.map(o=>o.id).join(", "),n=e.map(o=>`"${o.footerHint}"`).join(", ");return`## Ticket Reference
|
|
229
229
|
Branch references ${t}. Add ${n} to the footer if relevant.`},vc=e=>`## Branch Intent
|
|
230
230
|
Branch prefix suggests commit type: ${e.type}`,Ac=(e,t="commit",n)=>{const o=[];return n?.recentCommits&&o.push(`## Recent Commits (for style reference)
|
|
@@ -235,24 +235,24 @@ ${n.branchName}`),`${o.length>0?o.join(`
|
|
|
235
235
|
|
|
236
236
|
`:""}\`\`\`diff
|
|
237
237
|
${e}
|
|
238
|
-
\`\`\``},F=new B;var Pc=async(e,t,n,o,s,r,a,c,l,u,d,p,g,y,f,$,S)=>(async()=>{const x=$==="json";x||F.printTitle();const P=x?null:F.displaySpinner("Detecting repository...");if(await at(),o){P&&(P.text="Staging changes...");const
|
|
239
|
-
`)}),process.exit(0));const Q=le(w,"review");Q.length>0&&await xc(ve,Q);const ie=await $c(ve,H,u);w.useStats!==!1&&Va({provider:ie.provider,model:ie.model,statsDays:w.statsDays}).catch(()=>{});let
|
|
240
|
-
${
|
|
241
|
-
`)}(a||w.autoCopy)&&(At("copy-paste").copy(
|
|
242
|
-
`),process.exit()),(r||u&&H.length===1)&&(await
|
|
243
|
-
`),process.exit(1)}F.printError(x.message),W(x),process.exit(1)});async function xc(e,t){const n=new ut(
|
|
238
|
+
\`\`\``},F=new B;var Pc=async(e,t,n,o,s,r,a,c,l,u,d,p,g,y,f,$,S)=>(async()=>{const x=$==="json";x||F.printTitle();const P=x?null:F.displaySpinner("Detecting repository...");if(await at(),o){P&&(P.text="Staging changes...");const oe=await De();oe==="git"?await C("git",["add","."]):oe==="yadm"&&await C("yadm",["add","--update"])}P&&(P.text="Loading configuration...");const v={locale:e?.toString(),generate:t?.toString(),type:s?.toString(),systemPrompt:c?.toString(),...l===!0&&{includeBody:"true"},...p===!0&&{disableLowerCase:"true"}};g&&(v.logLevel="verbose");const w=await Z(v,S);(l===!0||w.includeBody===!0)&&Na(w),p&&Ro(w),await cn(w);const L={autoNew:f||w.jjAutoNew};P&&(P.text="Detecting staged files...");const N=await on(n,w.exclude);if(P?.stop(),!N){const oe=await De();throw new m(Fe.noStagedChanges(oe),{code:k.NO_STAGED_CHANGES})}if(!x){const oe=nn(N,{mode:w.diffCompression,maxHunkLines:w.maxHunkLines,maxDiffLines:w.maxDiffLines});F.printStagedFiles(N,oe.compression)}const H=le(w,"commit");if(H.length===0)throw new m(Fe.noApiKeysConfigured(),{code:k.MISSING_API_KEY});const ee=await Ne(),V=await _e(),ve=new je(w,N,ee,V);x&&((await kc(ve,H)).forEach(gs=>{process.stdout.write(JSON.stringify(gs)+`
|
|
239
|
+
`)}),process.exit(0));const Q=le(w,"review");Q.length>0&&await xc(ve,Q);const ie=await $c(ve,H,u);w.useStats!==!1&&Va({provider:ie.provider,model:ie.model,statsDays:w.statsDays}).catch(()=>{});let te=ie.value;if(d){if(F.printInfo("Opening editor to modify commit message..."),te=await Sc(te),!te.trim())throw new m(Fe.emptyCommitMessage(),{code:k.EMPTY_COMMIT_MESSAGE});F.printSuccess("Commit message edited successfully!"),F.print(`
|
|
240
|
+
${te}
|
|
241
|
+
`)}(a||w.autoCopy)&&(At("copy-paste").copy(te),a&&F.printCopied()),a&&!y&&process.exit(),y&&(process.stdout.write(te+`
|
|
242
|
+
`),process.exit()),(r||u&&H.length===1)&&(await qo(te,S,L),process.exit());const{confirmationPrompt:hs}=await T.prompt([{type:"confirm",name:"confirmationPrompt",message:"Use selected message?",default:!0}]);hs?await qo(te,S,L):F.printCancelledCommit(),process.exit()})().catch(x=>{if($==="json"){const P={error:x.message||"Unknown error occurred"};process.stderr.write(JSON.stringify(P)+`
|
|
243
|
+
`),process.exit(1)}F.printError(x.message),W(x),process.exit(1)});async function xc(e,t){const n=new ut(Bo);let o=null;try{const s=n.initPrompt({...rn,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Ho}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20});n.startLoader(),o=e.createCodeReviewRequests$(t).subscribe({next:d=>n.refreshChoices(d),error:d=>{console.error("Code review request error:",d),n.checkErrorOnChoices()},complete:()=>n.checkErrorOnChoices()});const a=(await s).codeReviewPrompt?.value;if(!a)throw new m("An error occurred! No selected code review");F.moveCursorUp();const c=a.includes("<!-- HAS_CRITICAL_ISSUES -->"),l=c?"Critical issues found in code review. Continue without fixing?":"Will you continue without changing the code?",{continuePrompt:u}=await T.prompt([{type:"confirm",name:"continuePrompt",message:l,default:!c}]);u||(F.printCancelledCommit(),process.exit())}finally{o&&o.unsubscribe(),n.destroy()}}const $c=async(e,t,n)=>{const o=new ut(Go);let s=null;try{if(n&&t.length===1){const p=[];o.startLoader(),s=e.createCommitMsgRequests$(t).subscribe({next:y=>{"streamKey"in y||p.push(y),o.refreshChoices(y)},error:y=>{console.error("Commit message generation error:",y),o.checkErrorOnChoices(!1)},complete:()=>o.checkErrorOnChoices(!1)}),await new Promise(y=>{s?.add(()=>y())}),o.clearLoader(),F.moveCursorUp();const g=p.find(y=>y.value&&!y.isError&&!y.disabled);if(!g||!g.value)throw new m("No valid commit message was generated");return F.print(`
|
|
244
244
|
${g.name}
|
|
245
245
|
`),{value:g.value,provider:g.provider||"unknown",model:g.model||"unknown"}}const r=new Map,a=o.initPrompt();o.startLoader();let c=0;s=e.createCommitMsgRequests$(t).subscribe({next:p=>{const g=p;g.value&&r.set(g.value,g),p.value&&!p.isError&&!p.disabled&&(c++,o.updateLoaderText(`AI is analyzing your changes (${c} message${c>1?"s":""} generated)`)),o.refreshChoices(p)},error:p=>{console.error("Commit message generation error:",p),o.checkErrorOnChoices()},complete:()=>o.checkErrorOnChoices()});const l=await a;F.moveCursorUp();const u=l.aicommit2Prompt?.value;if(!u)throw new m("An error occurred! No selected message");const d=r.get(u);return{value:u,provider:d?.provider||"unknown",model:d?.model||"unknown"}}finally{s&&s.unsubscribe(),o.destroy()}};async function Sc(e){const t=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),n=A.join(ue.tmpdir(),`aicommit2-${Date.now()}-${yt.randomBytes(4).toString("hex")}.txt`);try{O.writeFileSync(n,e,"utf8");const o=t.split(" "),[s,...r]=o;await C(s,[...r,n],{stdio:"inherit"});const a=O.readFileSync(n,"utf8").trim();if(O.unlinkSync(n),!a)throw new m("Commit cancelled - empty message");return a}catch(o){throw O.existsSync(n)&&O.unlinkSync(n),o instanceof m?o:o&&typeof o=="object"&&"exitCode"in o&&o.exitCode!==0?new m("Commit cancelled"):process.env.VISUAL||process.env.EDITOR?new m(`Failed to open editor "${t}". Please check:
|
|
246
246
|
- Editor binary exists in PATH
|
|
247
247
|
- Editor flags are correct
|
|
248
|
-
- EDITOR/VISUAL is set correctly`):new m(`Failed to open editor "${t}". Please set your EDITOR or VISUAL environment variable to a valid editor command.`)}}const
|
|
248
|
+
- EDITOR/VISUAL is set correctly`):new m(`Failed to open editor "${t}". Please set your EDITOR or VISUAL environment variable to a valid editor command.`)}}const qo=async(e,t,n)=>{await rc(e,t,n),F.printCommitted()},kc=async(e,t)=>{const o=(await bt(e.createCommitMsgRequests$(t).pipe(vt()),{defaultValue:[]})).filter(s=>s.value&&!s.isError&&!s.disabled);if(o.length===0)throw new m("No valid commit messages were generated");return o.map(({value:s=""})=>{const[r="",...a]=s.split(`
|
|
249
249
|
`);return{subject:r,body:a.join(`
|
|
250
|
-
`).trim()}})};var Rc=G({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:[G({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"]}}),G({name:"get",parameters:["[<key>","[<key> ...]]"],help:{description:"Retrieve configuration values for specified AI provider.",examples:["aic2 config get OPENAI","aic2 config get ANTHROPIC"]}}),G({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"']}}),G({name:"list",parameters:[],help:{description:"Display all configuration keys and their values.",examples:["aic2 config list"]}}),G({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"]}}),G({name:"path",parameters:[],help:{description:"Display the path of the loaded configuration file.",examples:["aic2 config path"]}})]},e=>{(async()=>{const{mode:t,keyValue:n}=e._,o=e._[1];if(t==="get"){const s=await Z({},[]);if(n.length===0){console.log(s);return}for(const r of n){const a=r.split(".");let c=s,l=!0;for(const u of a)if(zt(c,u))c=c[u];else{l=!1;break}l?console.log(r,c):console.log(`${r} not found`)}return}if(t==="set"){await tt(n.map(s=>{const r=s.indexOf("=");if(r===-1)throw new m("Invalid format. Use: key=value");const a=s.slice(0,r),c=s.slice(r+1);return[a,c]}));return}if(t==="add"){await Fa(n.map(s=>{const r=s.indexOf("=");if(r===-1)throw new m("Invalid format. Use: key=value");const a=s.slice(0,r),c=s.slice(r+1);return[a,c]}));return}if(t==="list"){await Ga();return}if(t==="del"){if(!o)throw new m("Please provide the config name to delete.");const s=await Oe(),r=o.split(".");if(r.length===2){const[a,c]=r;if(s[a]&&typeof s[a]=="object"&&zt(s[a],c)){delete s[a][c],Object.keys(s[a]).length===0&&delete s[a];const l=await Ee();await R.writeFile(l,ye.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const u=await R.readFile(l,"utf8");console.log("--- Updated Config Content ---"),console.log(u),console.log("----------------------------")}else throw new m(`Config not found: ${o}`)}else if(r.length===1){const a=r[0];if(zt(s,a)){delete s[a];const c=await Ee();await R.writeFile(c,ye.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const l=await R.readFile(c,"utf8");console.log("--- Updated Config Content ---"),console.log(l),console.log("----------------------------")}else throw new m(`Config not found: ${o}`)}else throw new m(`Invalid config name format: ${o}`);return}if(t==="path"){await Ba();return}throw new m(`Invalid mode: ${t}`)})().catch(t=>{new B().printError(t.message),W(t),process.exit(1)})});const qo="gpt-4.1",Ic=["gpt-4.1","gpt-4o","gpt-5-mini"],zo={free:["claude-haiku-4.5","gpt-5-mini","gpt-4.1"],pro:["gpt-5.4","claude-sonnet-4.5","claude-opus-4.5","claude-sonnet-4","gpt-5.3-codex","gpt-5.2-codex","gpt-5.2","gpt-5.1","gpt-5.4-mini"]},Lc=[...zo.free,...zo.pro],Yo={"openai/gpt-4.1":"gpt-4.1","openai/gpt-4o":"gpt-4o","openai/gpt-5-mini":"gpt-5-mini"},Vo=e=>{const t=(e||"").trim().toLowerCase();return t?t in Yo?Yo[t]:t.includes("/")&&t.split("/").pop()||t:qo},Mc=e=>[Vo(e),...Ic].filter((n,o,s)=>s.indexOf(n)===o),Oc=e=>{const t=e.toLowerCase();return t.includes("unknown_model")||t.includes("unknown model")||t.includes("unavailable_model")||t.includes("unavailable model")||t.includes("model not found")||t.includes("not available")||t.includes("not enabled")||t.includes("not allowed")},Tc=e=>{const t=e.toLowerCase();return t.includes("authentication")||t.includes("unauthorized")||t.includes("forbidden")||t.includes("invalid token")||t.includes("token expired")||t.includes("no authentication")||t.includes("copilot cli not found")||t.includes("copilot cli authentication")},Dc=e=>{const t=e.toLowerCase();return t.includes("classic personal access tokens")&&t.includes("ghp_")},Nc=(e=process.env)=>{const t={...e};t.NODE_NO_WARNINGS="1",delete t.GH_TOKEN,delete t.GITHUB_TOKEN;const n=(e.COPILOT_GITHUB_TOKEN||"").trim();return n.length>0?(t.COPILOT_GITHUB_TOKEN=n,{githubToken:n,useLoggedInUser:!1,env:t}):(delete t.COPILOT_GITHUB_TOKEN,{useLoggedInUser:!0,env:t})},dt="https://models.github.ai",cn="/inference/chat/completions",ln="2026-03-10",un="openai/gpt-4o-mini",_c=/^([A-Za-z0-9][A-Za-z0-9._-]*)\/([A-Za-z0-9][A-Za-z0-9._:-]*)$/,Jo=e=>(e||"").trim(),Xo=e=>{const t=Jo(e);return t.length>0&&_c.test(t)},jc=e=>{const t=Jo(e);if(!Xo(t))throw new Error(`Invalid GitHub Models model ID "${t||"(empty)"}". Expected format: "publisher/model" (example: "openai/gpt-4o-mini").`);return t},Fc=e=>{const t=(e||"").trim();return t?["ghp_","gho_","ghu_","ghs_","ghr_","github_pat_"].some(o=>t.startsWith(o)):!1};class mt{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=Fs.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}addBody(t){return this.config.data={...this.config.data,...t},this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}const Gc={healthy:h.green("\u2705"),error:h.red("\u274C"),warning:h.yellow("\u26A0\uFE0F"),skipped:h.gray("\u23ED\uFE0F")},Bc={healthy:h.green,error:h.red,warning:h.yellow,skipped:h.gray},dn=e=>typeof e.key=="string"&&e.key.trim().length>0,Qo=e=>(Array.isArray(e.model)?e.model:typeof e.model=="string"&&e.model.trim().length>0?[e.model.trim()]:[]).length>0,Hc=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length>0,Uc=e=>typeof e=="string"&&e.trim()?e.replace(/\/$/,""):"https://openrouter.ai",Kc=e=>`${Uc(e.url)}/api/v1`,Wc=e=>({Authorization:`Bearer ${e}`,"Content-Type":"application/json","HTTP-Referer":"https://github.com/tak-bro/aicommit2","X-OpenRouter-Title":"aicommit2","X-OpenRouter-Categories":"cli-agent"}),qc=(e,t)=>{const n=e.trim();return t.find(o=>[o.id,o.canonical_slug,o.name].filter(r=>!!r).some(r=>r===n))},zc=(e,t)=>e.supported_parameters?.includes(t)??!1,Yc=[{configKey:"OPENROUTER.responseFormat",configProperty:"responseFormat",parameters:["response_format"]},{configKey:"OPENROUTER.reasoning",configProperty:"reasoning",parameters:["reasoning","include_reasoning"]}],Vc=e=>{const t=e.supported_parameters||[];return t.length>0?`supports: ${t.join(", ")}`:"no supported parameters listed"},Jc=(e,t)=>{const n=[];for(const o of Yc){if(!Hc(e[o.configProperty]))continue;o.parameters.some(r=>zc(t,r))||n.push(o.configKey)}return n},Xc=(e,t,n)=>{const o=n.context_length||n.top_provider?.context_length,s=Vc(n),r=Jc(t,n),a=o?`${o} ctx`:"";if(r.length>0){const u=[`consider removing ${r.join(", ")}`,a,s].filter(Boolean);return`${e}: ${u.join("; ")}`}const c=[a,s].filter(Boolean);return c.length>0?`${e} (${c.join("; ")})`:e},Zo=(e,t)=>{const n=[],o=Array.isArray(e.model)?e.model:typeof e.model=="string"?[e.model]:[];for(const s of o){if(s==="openrouter/auto"){n.push("Auto routing enabled");continue}const r=qc(s,t);if(!r){n.push(`Model not found in catalog: ${s}`);continue}n.push(Xc(s,e,r))}return n},Qc=async(e,t)=>{try{return await new mt({method:"GET",baseURL:e,timeout:t}).execute(),{ok:!0}}catch(n){const o=n instanceof Error?n.message:String(n);return o.includes("ECONNREFUSED")?{ok:!1,error:"Not running"}:{ok:!1,error:o}}},Zc=async(e,t)=>{const n=typeof e.key=="string"?e.key.trim():"";if(!n)return{ok:!1,error:"No API key configured"};try{const o=Kc(e),s=Wc(n),r=["/models/user","/models"];let a,c;for(const y of r)try{a=await new mt({method:"GET",baseURL:`${o}${y}`,timeout:t}).setHeaders(s).execute();break}catch(f){if(c=f,!(f instanceof Error?f.message:String(f)).includes("404"))throw f}if(!a)throw c instanceof Error?c:new Error(String(c));const l=a.data?.data??[],u=Qo(e)?Array.isArray(e.model)?e.model:[e.model]:[];if(u.length===0)return{ok:!0,details:`Catalog reachable (${l.length} models)`};if(u.includes("openrouter/auto")){const y=Zo(e,l);return{ok:!0,details:y.length>0?y.join("; "):`Auto routing enabled (${l.length} models)`}}const p=Zo(e,l);return p.some(y=>y.startsWith("Model not found in catalog:"))?{ok:!1,error:"Selected model not found in OpenRouter catalog",details:p.join("; ")}:{ok:!0,details:p.join("; ")}}catch(o){const s=o instanceof Error?o.message:String(o);return s.includes("401")||s.includes("403")?{ok:!1,error:"Unauthorized or forbidden when reading OpenRouter catalog"}:s.includes("404")?{ok:!1,error:"OpenRouter catalog endpoint not found"}:{ok:!1,error:s}}},el=e=>Array.isArray(e.model)&&e.model.length>0?String(e.model[0]).trim():typeof e.model=="string"&&e.model.trim().length>0?e.model.trim():un,tl=async(e,t)=>{const n=typeof e.key=="string"?e.key.trim():"";if(!n)return{ok:!1,error:"No API key configured"};const o=el(e);if(!Xo(o))return{ok:!1,error:"Invalid model ID format",details:`Expected "publisher/model", got "${o||"(empty)"}"`};try{const s=`${dt}${cn}`;return await new mt({method:"POST",baseURL:s,timeout:t}).setHeaders({"Content-Type":"application/json",Accept:"application/vnd.github+json","X-GitHub-Api-Version":ln,Authorization:`Bearer ${n}`}).setBody({model:o,messages:[{role:"user",content:"health-check"}],max_tokens:1,stream:!1}).execute(),{ok:!0,details:`Model: ${o}`}}catch(s){const r=s instanceof Error?s.message:String(s);return r.includes("401")?{ok:!1,error:"Authentication failed (401)"}:r.includes("403")?{ok:!1,error:"Access denied (403). Check token permission: models: read"}:r.includes("404")?{ok:!1,error:`Model not found (404): ${o}`}:r.includes("422")?{ok:!1,error:`Request validation failed (422) for model: ${o}`}:{ok:!1,error:r}}},nl=e=>{const t=Array.isArray(e.model)?String(e.model[0]||"").trim():String(e.model||"").trim();if(!t)return{ok:!1,error:"No model configured"};try{if((process.env.COPILOT_GITHUB_TOKEN||"").trim().startsWith("ghp_"))return{ok:!1,error:"Unsupported classic PAT in COPILOT_GITHUB_TOKEN",details:"Copilot CLI requires Fine-Grained PAT (github_pat_...) or Copilot login flow"};const o=process.versions.node,s=Number(o.split(".")[0]||"0");if(Number.isFinite(s)&&s<22)return{ok:!1,error:`Node.js ${o} is too old for Copilot SDK`,details:"Copilot SDK v0.2.0 requires node:sqlite support (Node.js 22+ recommended)"};const r=Ae("copilot --version",{stdio:["ignore","pipe","pipe"]}).toString().trim(),a=Vo(t),l=Lc.includes(a)?void 0:`Model '${t}' is not in the known working models list and may not work`;return{ok:!0,details:r?`CLI: ${r}; Model: ${t}; Node: ${o}`:`Model: ${t}; Node: ${o}`,modelWarning:l}}catch{return{ok:!1,error:"Copilot CLI not found",details:"Install and authenticate Copilot CLI before using COPILOT_SDK provider"}}},ol=async(e,t,n)=>{if(e==="OLLAMA"){if(!ee(t))return{provider:e,status:"skipped",message:"No models configured"};const o=typeof t.host=="string"&&t.host.trim()?t.host:Re,s=await Qc(o,n);return s.ok?{provider:e,status:"healthy",message:"Running",details:`Host: ${o}`}:{provider:e,status:"warning",message:s.error||"Connection failed",details:`Host: ${o}`}}if(e==="HUGGINGFACE")return t.cookie?{provider:e,status:"healthy",message:"Cookie configured"}:{provider:e,status:"skipped",message:"No cookie configured"};if(e==="BEDROCK")return ot(t)?{provider:e,status:"healthy",message:"Credentials configured"}:{provider:e,status:"skipped",message:"Not configured"};if(e==="OPENROUTER"){if(!dn(t))return{provider:e,status:"skipped",message:"Not configured"};const o=await Zc(t,n);return o.ok?{provider:e,status:"healthy",message:"Catalog reachable",details:o.details}:{provider:e,status:"warning",message:o.error||"Catalog check failed",details:o.details}}if(e==="GITHUB_MODELS"){if(!dn(t))return{provider:e,status:"skipped",message:"Not configured"};const o=await tl(t,n);return o.ok?{provider:e,status:"healthy",message:"Models API reachable",details:o.details}:{provider:e,status:"warning",message:o.error||"Connection check failed",details:o.details}}if(e==="COPILOT_SDK"){if(!Qo(t))return{provider:e,status:"skipped",message:"No models configured"};const o=nl(t);return o.ok?o.modelWarning?{provider:e,status:"warning",message:o.modelWarning,details:o.details}:{provider:e,status:"healthy",message:"SDK environment ready",details:o.details}:{provider:e,status:"warning",message:o.error||"Environment check failed",details:o.details}}return dn(t)?{provider:e,status:"healthy",message:"API key configured"}:{provider:e,status:"skipped",message:"Not configured"}},sl=async e=>{const t=[],n=e.timeout||1e4;for(const o of Ce){const s=e[o];if(!s||typeof s!="object"){t.push({provider:o,status:"skipped",message:"Not configured"});continue}if(s.disabled){t.push({provider:o,status:"skipped",message:"Disabled"});continue}const r=await ol(o,s,n);t.push(r)}return t},rl=Math.max(...Ce.map(e=>e.length)),il=e=>e.padEnd(rl),al=e=>{console.log(""),console.log(h.bold("\u{1FA7A} aicommit2 Health Check")),console.log(""),console.log(h.bold("Providers:"));for(const n of e){const o=Gc[n.status],s=il(n.provider),r=Bc[n.status](n.message),a=n.details?h.gray(` (${n.details})`):"";console.log(` ${o} ${s} ${r}${a}`)}const t={healthy:e.filter(n=>n.status==="healthy").length,error:e.filter(n=>n.status==="error").length,warning:e.filter(n=>n.status==="warning").length,skipped:e.filter(n=>n.status==="skipped").length};console.log(""),console.log(h.bold("Summary: ")+h.green(`${t.healthy} healthy`)+", "+h.red(`${t.error} error`)+", "+h.yellow(`${t.warning} warning`)+", "+h.gray(`${t.skipped} skipped`)),console.log(""),t.error>0&&(process.exitCode=1)},cl=G({name:"doctor",parameters:[],help:{description:"Check health status of configured AI providers",examples:["aicommit2 doctor"]}},()=>{(async()=>{const e=await Z({},[]),t=await sl(e);al(t)})().catch(e=>{console.error(h.red(e.message)),W(e),process.exit(1)})});var ll=G({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 github_pat_xxxxxxxxxxxxxxxxxxxx"]}},e=>{(async()=>{const t=new B;if(e.flags.token){try{await ul(e.flags.token,t)}catch(n){throw new m(`Token authentication failed: ${n.message}`)}return}try{await dl(t)}catch(n){throw new m(`Browser authentication failed: ${n.message}`)}})().catch(t=>{new B().printError(t.message),W(t),process.exit(1)})});async function ul(e,t){if(t.printWarning("Authenticating with provided token..."),!Fc(e))throw new Error("Invalid token format. Expected GitHub token prefix like ghp_, gho_, ghu_, ghs_, ghr_, or github_pat_");try{const n=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${e}`,Accept:"application/vnd.github.v3+json","User-Agent":"aicommit2-github-models"}});if(!n.ok)throw new Error(`GitHub API request failed: ${n.status} ${n.statusText}`);const o=await n.json();try{(await fetch(`${dt}${cn}`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/vnd.github+json","X-GitHub-Api-Version":ln,Authorization:`Bearer ${e}`,"User-Agent":"aicommit2-github-models"},body:JSON.stringify({messages:[{role:"user",content:"test"}],model:un,max_tokens:1})})).ok?t.printSuccess("GitHub Models access verified!"):t.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}catch{t.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}await tt([["GITHUB_MODELS.key",e]]),t.printSuccess(`Successfully authenticated as ${o.login}`)}catch(n){throw new Error(`Token validation failed: ${n.message}`)}}async function dl(e){e.printInfo("Starting GitHub browser authentication for GitHub Models...");try{try{Ae("gh --version",{stdio:"ignore"})}catch{throw new Error("GitHub CLI (gh) is not installed. Please install it first: https://cli.github.com/")}try{Ae("gh auth status",{encoding:"utf8",stdio:"pipe"}).includes("Logged in to github.com")&&e.printInfo("Already authenticated with GitHub CLI")}catch{e.printInfo("Authenticating with GitHub CLI..."),e.printInfo("Please follow the instructions in your browser to complete authentication.");try{Ae("gh auth login --web -h github.com",{stdio:"inherit"})}catch{throw new Error("GitHub CLI authentication failed")}}e.printInfo("Verifying GitHub Models access...");try{const t=Ae("gh auth token",{encoding:"utf8"}).trim();t&&(await tt([["GITHUB_MODELS.key",t]]),e.printSuccess("GitHub token stored for GitHub Models access"))}catch{e.printWarning("Could not extract token from GitHub CLI, but authentication completed")}e.printSuccess("GitHub authentication completed and GitHub Models access verified!"),e.printInfo("See usage guide: https://github.com/tak-bro/aicommit2/blob/main/docs/providers/github-models.md"),e.printInfo("Use `gh models list` to view the latest available models."),e.printInfo(`Using GitHub Models API: ${dt}`)}catch(t){throw t}}const be="prepare-commit-msg",ml=async()=>{const e=await De();if(e==="git")return`.git/hooks/${be}`;if(e==="yadm"){const t=process.env.HOME||process.env.USERPROFILE;if(!t)throw new m("HOME environment variable not set. Cannot determine YADM hook path.");try{const{execa:s}=await Promise.resolve().then(function(){return fa}),{stdout:r}=await s("yadm",["introspect","repo"]),a=r.trim();if(a)return A.join(a,"hooks",be)}catch{}const n=A.join(t,".config/yadm/hooks"),o=A.join(t,".yadm/hooks");try{return await R.access(n),A.join(n,be)}catch{return A.join(o,be)}}throw e==="jujutsu"?new m("Hooks are not supported for Jujutsu repositories."):new m(`Hooks are not supported for ${e} repositories.`)},ft=Gs(new URL("cli.mjs",import.meta.url)),fl=process.argv[1].replace(/\\/g,"/").includes(`/hooks/${be}`),es=process.platform==="win32",ts=`
|
|
250
|
+
`).trim()}})};var Rc=G({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:[G({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"]}}),G({name:"get",parameters:["[<key>","[<key> ...]]"],help:{description:"Retrieve configuration values for specified AI provider.",examples:["aic2 config get OPENAI","aic2 config get ANTHROPIC"]}}),G({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"']}}),G({name:"list",parameters:[],help:{description:"Display all configuration keys and their values.",examples:["aic2 config list"]}}),G({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"]}}),G({name:"path",parameters:[],help:{description:"Display the path of the loaded configuration file.",examples:["aic2 config path"]}})]},e=>{(async()=>{const{mode:t,keyValue:n}=e._,o=e._[1];if(t==="get"){const s=await Z({},[]);if(n.length===0){console.log(s);return}for(const r of n){const a=r.split(".");let c=s,l=!0;for(const u of a)if(zt(c,u))c=c[u];else{l=!1;break}l?console.log(r,c):console.log(`${r} not found`)}return}if(t==="set"){await tt(n.map(s=>{const r=s.indexOf("=");if(r===-1)throw new m("Invalid format. Use: key=value");const a=s.slice(0,r),c=s.slice(r+1);return[a,c]}));return}if(t==="add"){await Ga(n.map(s=>{const r=s.indexOf("=");if(r===-1)throw new m("Invalid format. Use: key=value");const a=s.slice(0,r),c=s.slice(r+1);return[a,c]}));return}if(t==="list"){await Ba();return}if(t==="del"){if(!o)throw new m("Please provide the config name to delete.");const s=await Oe(),r=o.split(".");if(r.length===2){const[a,c]=r;if(s[a]&&typeof s[a]=="object"&&zt(s[a],c)){delete s[a][c],Object.keys(s[a]).length===0&&delete s[a];const l=await Ee();await R.writeFile(l,ye.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const u=await R.readFile(l,"utf8");console.log("--- Updated Config Content ---"),console.log(u),console.log("----------------------------")}else throw new m(`Config not found: ${o}`)}else if(r.length===1){const a=r[0];if(zt(s,a)){delete s[a];const c=await Ee();await R.writeFile(c,ye.stringify(s),"utf8"),console.log(`Successfully deleted config: ${o}`);const l=await R.readFile(c,"utf8");console.log("--- Updated Config Content ---"),console.log(l),console.log("----------------------------")}else throw new m(`Config not found: ${o}`)}else throw new m(`Invalid config name format: ${o}`);return}if(t==="path"){await Ha();return}throw new m(`Invalid mode: ${t}`)})().catch(t=>{new B().printError(t.message),W(t),process.exit(1)})});const zo="gpt-4.1",Ic=["gpt-4.1","gpt-4o","gpt-5-mini"],Yo={free:["claude-haiku-4.5","gpt-5-mini","gpt-4.1"],pro:["gpt-5.4","claude-sonnet-4.5","claude-opus-4.5","claude-sonnet-4","gpt-5.3-codex","gpt-5.2-codex","gpt-5.2","gpt-5.1","gpt-5.4-mini"]},Lc=[...Yo.free,...Yo.pro],Vo={"openai/gpt-4.1":"gpt-4.1","openai/gpt-4o":"gpt-4o","openai/gpt-5-mini":"gpt-5-mini"},Jo=e=>{const t=(e||"").trim().toLowerCase();return t?t in Vo?Vo[t]:t.includes("/")&&t.split("/").pop()||t:zo},Mc=e=>[Jo(e),...Ic].filter((n,o,s)=>s.indexOf(n)===o),Oc=e=>{const t=e.toLowerCase();return t.includes("unknown_model")||t.includes("unknown model")||t.includes("unavailable_model")||t.includes("unavailable model")||t.includes("model not found")||t.includes("not available")||t.includes("not enabled")||t.includes("not allowed")},Tc=e=>{const t=e.toLowerCase();return t.includes("authentication")||t.includes("unauthorized")||t.includes("forbidden")||t.includes("invalid token")||t.includes("token expired")||t.includes("no authentication")||t.includes("copilot cli not found")||t.includes("copilot cli authentication")},Dc=e=>{const t=e.toLowerCase();return t.includes("classic personal access tokens")&&t.includes("ghp_")},Nc=(e=process.env)=>{const t={...e};t.NODE_NO_WARNINGS="1",delete t.GH_TOKEN,delete t.GITHUB_TOKEN;const n=(e.COPILOT_GITHUB_TOKEN||"").trim();return n.length>0?(t.COPILOT_GITHUB_TOKEN=n,{githubToken:n,useLoggedInUser:!1,env:t}):(delete t.COPILOT_GITHUB_TOKEN,{useLoggedInUser:!0,env:t})},dt="https://models.github.ai",ln="/inference/chat/completions",un="2026-03-10",dn="openai/gpt-4o-mini",_c=/^([A-Za-z0-9][A-Za-z0-9._-]*)\/([A-Za-z0-9][A-Za-z0-9._:-]*)$/,Xo=e=>(e||"").trim(),Qo=e=>{const t=Xo(e);return t.length>0&&_c.test(t)},jc=e=>{const t=Xo(e);if(!Qo(t))throw new Error(`Invalid GitHub Models model ID "${t||"(empty)"}". Expected format: "publisher/model" (example: "openai/gpt-4o-mini").`);return t},Fc=e=>{const t=(e||"").trim();return t?["ghp_","gho_","ghu_","ghs_","ghr_","github_pat_"].some(o=>t.startsWith(o)):!1};class mt{constructor(t={}){if(!t.method)throw new Error("method should be defined!");if(!t.baseURL)throw new Error("baseURL should be defined!");this.config={...t},this.axiosInstance=Gs.create(this.config)}setHeaders(t){return this.config.headers=t,this}setParams(t){return this.config.params=t,this}setBody(t){return this.config.data=t,this}addBody(t){return this.config.data={...this.config.data,...t},this}setMethod(t){return this.config.method=t,this}async execute(){try{return await this.axiosInstance.request(this.config)}catch(t){throw t}}}const Gc={healthy:h.green("\u2705"),error:h.red("\u274C"),warning:h.yellow("\u26A0\uFE0F"),skipped:h.gray("\u23ED\uFE0F")},Bc={healthy:h.green,error:h.red,warning:h.yellow,skipped:h.gray},mn=e=>typeof e.key=="string"&&e.key.trim().length>0,Zo=e=>(Array.isArray(e.model)?e.model:typeof e.model=="string"&&e.model.trim().length>0?[e.model.trim()]:[]).length>0,Hc=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.keys(e).length>0,Uc=e=>typeof e=="string"&&e.trim()?e.replace(/\/$/,""):"https://openrouter.ai",Kc=e=>`${Uc(e.url)}/api/v1`,Wc=e=>({Authorization:`Bearer ${e}`,"Content-Type":"application/json","HTTP-Referer":"https://github.com/tak-bro/aicommit2","X-OpenRouter-Title":"aicommit2","X-OpenRouter-Categories":"cli-agent"}),qc=(e,t)=>{const n=e.trim();return t.find(o=>[o.id,o.canonical_slug,o.name].filter(r=>!!r).some(r=>r===n))},zc=(e,t)=>e.supported_parameters?.includes(t)??!1,Yc=[{configKey:"OPENROUTER.responseFormat",configProperty:"responseFormat",parameters:["response_format"]},{configKey:"OPENROUTER.reasoning",configProperty:"reasoning",parameters:["reasoning","include_reasoning"]}],Vc=e=>{const t=e.supported_parameters||[];return t.length>0?`supports: ${t.join(", ")}`:"no supported parameters listed"},Jc=(e,t)=>{const n=[];for(const o of Yc){if(!Hc(e[o.configProperty]))continue;o.parameters.some(r=>zc(t,r))||n.push(o.configKey)}return n},Xc=(e,t,n)=>{const o=n.context_length||n.top_provider?.context_length,s=Vc(n),r=Jc(t,n),a=o?`${o} ctx`:"";if(r.length>0){const u=[`consider removing ${r.join(", ")}`,a,s].filter(Boolean);return`${e}: ${u.join("; ")}`}const c=[a,s].filter(Boolean);return c.length>0?`${e} (${c.join("; ")})`:e},es=(e,t)=>{const n=[],o=Array.isArray(e.model)?e.model:typeof e.model=="string"?[e.model]:[];for(const s of o){if(s==="openrouter/auto"){n.push("Auto routing enabled");continue}const r=qc(s,t);if(!r){n.push(`Model not found in catalog: ${s}`);continue}n.push(Xc(s,e,r))}return n},Qc=async(e,t)=>{try{return await new mt({method:"GET",baseURL:e,timeout:t}).execute(),{ok:!0}}catch(n){const o=n instanceof Error?n.message:String(n);return o.includes("ECONNREFUSED")?{ok:!1,error:"Not running"}:{ok:!1,error:o}}},Zc=async(e,t)=>{const n=typeof e.key=="string"?e.key.trim():"";if(!n)return{ok:!1,error:"No API key configured"};try{const o=Kc(e),s=Wc(n),r=["/models/user","/models"];let a,c;for(const y of r)try{a=await new mt({method:"GET",baseURL:`${o}${y}`,timeout:t}).setHeaders(s).execute();break}catch(f){if(c=f,!(f instanceof Error?f.message:String(f)).includes("404"))throw f}if(!a)throw c instanceof Error?c:new Error(String(c));const l=a.data?.data??[],u=Zo(e)?Array.isArray(e.model)?e.model:[e.model]:[];if(u.length===0)return{ok:!0,details:`Catalog reachable (${l.length} models)`};if(u.includes("openrouter/auto")){const y=es(e,l);return{ok:!0,details:y.length>0?y.join("; "):`Auto routing enabled (${l.length} models)`}}const p=es(e,l);return p.some(y=>y.startsWith("Model not found in catalog:"))?{ok:!1,error:"Selected model not found in OpenRouter catalog",details:p.join("; ")}:{ok:!0,details:p.join("; ")}}catch(o){const s=o instanceof Error?o.message:String(o);return s.includes("401")||s.includes("403")?{ok:!1,error:"Unauthorized or forbidden when reading OpenRouter catalog"}:s.includes("404")?{ok:!1,error:"OpenRouter catalog endpoint not found"}:{ok:!1,error:s}}},el=e=>Array.isArray(e.model)&&e.model.length>0?String(e.model[0]).trim():typeof e.model=="string"&&e.model.trim().length>0?e.model.trim():dn,tl=async(e,t)=>{const n=typeof e.key=="string"?e.key.trim():"";if(!n)return{ok:!1,error:"No API key configured"};const o=el(e);if(!Qo(o))return{ok:!1,error:"Invalid model ID format",details:`Expected "publisher/model", got "${o||"(empty)"}"`};try{const s=`${dt}${ln}`;return await new mt({method:"POST",baseURL:s,timeout:t}).setHeaders({"Content-Type":"application/json",Accept:"application/vnd.github+json","X-GitHub-Api-Version":un,Authorization:`Bearer ${n}`}).setBody({model:o,messages:[{role:"user",content:"health-check"}],max_tokens:1,stream:!1}).execute(),{ok:!0,details:`Model: ${o}`}}catch(s){const r=s instanceof Error?s.message:String(s);return r.includes("401")?{ok:!1,error:"Authentication failed (401)"}:r.includes("403")?{ok:!1,error:"Access denied (403). Check token permission: models: read"}:r.includes("404")?{ok:!1,error:`Model not found (404): ${o}`}:r.includes("422")?{ok:!1,error:`Request validation failed (422) for model: ${o}`}:{ok:!1,error:r}}},nl=e=>{const t=Array.isArray(e.model)?String(e.model[0]||"").trim():String(e.model||"").trim();if(!t)return{ok:!1,error:"No model configured"};try{if((process.env.COPILOT_GITHUB_TOKEN||"").trim().startsWith("ghp_"))return{ok:!1,error:"Unsupported classic PAT in COPILOT_GITHUB_TOKEN",details:"Copilot CLI requires Fine-Grained PAT (github_pat_...) or Copilot login flow"};const o=process.versions.node,s=Number(o.split(".")[0]||"0");if(Number.isFinite(s)&&s<22)return{ok:!1,error:`Node.js ${o} is too old for Copilot SDK`,details:"Copilot SDK v0.2.0 requires node:sqlite support (Node.js 22+ recommended)"};const r=Ae("copilot --version",{stdio:["ignore","pipe","pipe"]}).toString().trim(),a=Jo(t),l=Lc.includes(a)?void 0:`Model '${t}' is not in the known working models list and may not work`;return{ok:!0,details:r?`CLI: ${r}; Model: ${t}; Node: ${o}`:`Model: ${t}; Node: ${o}`,modelWarning:l}}catch{return{ok:!1,error:"Copilot CLI not found",details:"Install and authenticate Copilot CLI before using COPILOT_SDK provider"}}},ol=async(e,t,n)=>{if(e==="OLLAMA"){if(!se(t))return{provider:e,status:"skipped",message:"No models configured"};const o=typeof t.host=="string"&&t.host.trim()?t.host:Re,s=await Qc(o,n);return s.ok?{provider:e,status:"healthy",message:"Running",details:`Host: ${o}`}:{provider:e,status:"warning",message:s.error||"Connection failed",details:`Host: ${o}`}}if(e==="HUGGINGFACE")return t.cookie?{provider:e,status:"healthy",message:"Cookie configured"}:{provider:e,status:"skipped",message:"No cookie configured"};if(e==="BEDROCK")return ot(t)?{provider:e,status:"healthy",message:"Credentials configured"}:{provider:e,status:"skipped",message:"Not configured"};if(e==="OPENROUTER"){if(!mn(t))return{provider:e,status:"skipped",message:"Not configured"};const o=await Zc(t,n);return o.ok?{provider:e,status:"healthy",message:"Catalog reachable",details:o.details}:{provider:e,status:"warning",message:o.error||"Catalog check failed",details:o.details}}if(e==="GITHUB_MODELS"){if(!mn(t))return{provider:e,status:"skipped",message:"Not configured"};const o=await tl(t,n);return o.ok?{provider:e,status:"healthy",message:"Models API reachable",details:o.details}:{provider:e,status:"warning",message:o.error||"Connection check failed",details:o.details}}if(e==="COPILOT_SDK"){if(!Zo(t))return{provider:e,status:"skipped",message:"No models configured"};const o=nl(t);return o.ok?o.modelWarning?{provider:e,status:"warning",message:o.modelWarning,details:o.details}:{provider:e,status:"healthy",message:"SDK environment ready",details:o.details}:{provider:e,status:"warning",message:o.error||"Environment check failed",details:o.details}}return mn(t)?{provider:e,status:"healthy",message:"API key configured"}:{provider:e,status:"skipped",message:"Not configured"}},sl=async e=>{const t=[],n=e.timeout||1e4;for(const o of Ce){const s=e[o];if(!s||typeof s!="object"){t.push({provider:o,status:"skipped",message:"Not configured"});continue}if(s.disabled){t.push({provider:o,status:"skipped",message:"Disabled"});continue}const r=await ol(o,s,n);t.push(r)}return t},rl=Math.max(...Ce.map(e=>e.length)),il=e=>e.padEnd(rl),al=e=>{console.log(""),console.log(h.bold("\u{1FA7A} aicommit2 Health Check")),console.log(""),console.log(h.bold("Providers:"));for(const n of e){const o=Gc[n.status],s=il(n.provider),r=Bc[n.status](n.message),a=n.details?h.gray(` (${n.details})`):"";console.log(` ${o} ${s} ${r}${a}`)}const t={healthy:e.filter(n=>n.status==="healthy").length,error:e.filter(n=>n.status==="error").length,warning:e.filter(n=>n.status==="warning").length,skipped:e.filter(n=>n.status==="skipped").length};console.log(""),console.log(h.bold("Summary: ")+h.green(`${t.healthy} healthy`)+", "+h.red(`${t.error} error`)+", "+h.yellow(`${t.warning} warning`)+", "+h.gray(`${t.skipped} skipped`)),console.log(""),t.error>0&&(process.exitCode=1)},cl=G({name:"doctor",parameters:[],help:{description:"Check health status of configured AI providers",examples:["aicommit2 doctor"]}},()=>{(async()=>{const e=await Z({},[]),t=await sl(e);al(t)})().catch(e=>{console.error(h.red(e.message)),W(e),process.exit(1)})});var ll=G({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 github_pat_xxxxxxxxxxxxxxxxxxxx"]}},e=>{(async()=>{const t=new B;if(e.flags.token){try{await ul(e.flags.token,t)}catch(n){throw new m(`Token authentication failed: ${n.message}`)}return}try{await dl(t)}catch(n){throw new m(`Browser authentication failed: ${n.message}`)}})().catch(t=>{new B().printError(t.message),W(t),process.exit(1)})});async function ul(e,t){if(t.printWarning("Authenticating with provided token..."),!Fc(e))throw new Error("Invalid token format. Expected GitHub token prefix like ghp_, gho_, ghu_, ghs_, ghr_, or github_pat_");try{const n=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${e}`,Accept:"application/vnd.github.v3+json","User-Agent":"aicommit2-github-models"}});if(!n.ok)throw new Error(`GitHub API request failed: ${n.status} ${n.statusText}`);const o=await n.json();try{(await fetch(`${dt}${ln}`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/vnd.github+json","X-GitHub-Api-Version":un,Authorization:`Bearer ${e}`,"User-Agent":"aicommit2-github-models"},body:JSON.stringify({messages:[{role:"user",content:"test"}],model:dn,max_tokens:1})})).ok?t.printSuccess("GitHub Models access verified!"):t.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}catch{t.printWarning("Could not verify GitHub Models access, but proceeding with authentication...")}await tt([["GITHUB_MODELS.key",e]]),t.printSuccess(`Successfully authenticated as ${o.login}`)}catch(n){throw new Error(`Token validation failed: ${n.message}`)}}async function dl(e){e.printInfo("Starting GitHub browser authentication for GitHub Models...");try{try{Ae("gh --version",{stdio:"ignore"})}catch{throw new Error("GitHub CLI (gh) is not installed. Please install it first: https://cli.github.com/")}try{Ae("gh auth status",{encoding:"utf8",stdio:"pipe"}).includes("Logged in to github.com")&&e.printInfo("Already authenticated with GitHub CLI")}catch{e.printInfo("Authenticating with GitHub CLI..."),e.printInfo("Please follow the instructions in your browser to complete authentication.");try{Ae("gh auth login --web -h github.com",{stdio:"inherit"})}catch{throw new Error("GitHub CLI authentication failed")}}e.printInfo("Verifying GitHub Models access...");try{const t=Ae("gh auth token",{encoding:"utf8"}).trim();t&&(await tt([["GITHUB_MODELS.key",t]]),e.printSuccess("GitHub token stored for GitHub Models access"))}catch{e.printWarning("Could not extract token from GitHub CLI, but authentication completed")}e.printSuccess("GitHub authentication completed and GitHub Models access verified!"),e.printInfo("See usage guide: https://github.com/tak-bro/aicommit2/blob/main/docs/providers/github-models.md"),e.printInfo("Use `gh models list` to view the latest available models."),e.printInfo(`Using GitHub Models API: ${dt}`)}catch(t){throw t}}const be="prepare-commit-msg",ml=async()=>{const e=await De();if(e==="git")return`.git/hooks/${be}`;if(e==="yadm"){const t=process.env.HOME||process.env.USERPROFILE;if(!t)throw new m("HOME environment variable not set. Cannot determine YADM hook path.");try{const{execa:s}=await Promise.resolve().then(function(){return pa}),{stdout:r}=await s("yadm",["introspect","repo"]),a=r.trim();if(a)return A.join(a,"hooks",be)}catch{}const n=A.join(t,".config/yadm/hooks"),o=A.join(t,".yadm/hooks");try{return await R.access(n),A.join(n,be)}catch{return A.join(o,be)}}throw e==="jujutsu"?new m("Hooks are not supported for Jujutsu repositories."):new m(`Hooks are not supported for ${e} repositories.`)},ft=Bs(new URL("cli.mjs",import.meta.url)),fl=process.argv[1].replace(/\\/g,"/").includes(`/hooks/${be}`),ts=process.platform==="win32",ns=`
|
|
251
251
|
#!/usr/bin/env node
|
|
252
|
-
import(${JSON.stringify(
|
|
253
|
-
`.trim();var pl=G({name:"hook",parameters:["<install/uninstall>"],help:{description:"Install or uninstall the Git prepare-commit-msg hook",examples:["aic2 hook install","aic2 hook uninstall"]}},e=>{(async()=>{const t=await at(),{installUninstall:n}=e._,o=await ml(),s=A.isAbsolute(o)?o:A.join(t,o),r=await Qe(s);if(n==="install"){if(r){if(await R.realpath(s).catch(()=>{})===ft){console.warn("The hook is already installed");return}throw new m(`A different ${be} hook seems to be installed. Please remove it before installing aicommit2.`)}await R.mkdir(A.dirname(s),{recursive:!0}),
|
|
254
|
-
`);const n=await Promise.all(t.map(async o=>{const s=ae.join(q,o),r=await
|
|
255
|
-
${h.green("Total:")} ${t.length} file${t.length!==1?"s":""}`)}catch(t){if(t.code==="ENOENT")console.log(`${h.yellow("Logs directory does not exist yet.")}`);else throw t}},Cl=async e=>{try{await
|
|
252
|
+
import(${JSON.stringify(Hs(ft))})
|
|
253
|
+
`.trim();var pl=G({name:"hook",parameters:["<install/uninstall>"],help:{description:"Install or uninstall the Git prepare-commit-msg hook",examples:["aic2 hook install","aic2 hook uninstall"]}},e=>{(async()=>{const t=await at(),{installUninstall:n}=e._,o=await ml(),s=A.isAbsolute(o)?o:A.join(t,o),r=await Qe(s);if(n==="install"){if(r){if(await R.realpath(s).catch(()=>{})===ft){console.warn("The hook is already installed");return}throw new m(`A different ${be} hook seems to be installed. Please remove it before installing aicommit2.`)}await R.mkdir(A.dirname(s),{recursive:!0}),ts?await R.writeFile(s,ns):(await R.symlink(ft,s,"file"),await R.chmod(s,493)),console.log(`${h.green("\u2714")} Hook installed`);return}if(n==="uninstall"){if(!r){console.warn("Hook is not installed");return}if(ts){if(await R.readFile(s,"utf8")!==ns){console.warn("Hook is not installed");return}}else if(await R.realpath(s)!==ft){console.warn("Hook is not installed");return}await R.rm(s),console.log(`${h.green("\u2714")} Hook uninstalled`);return}throw new m(`Invalid mode: ${n}`)})().catch(t=>{console.error(`${h.red("\u2716")} ${t.message}`),W(t),process.exit(1)})});const hl=Ms(Cs),gl=e=>{const t=["B","KB","MB","GB"];if(e===0)return"0 B";const n=Math.floor(Math.log(e)/Math.log(1024));return Math.round(e/Math.pow(1024,n)*100)/100+" "+t[n]},yl=e=>e.toLocaleDateString()+" "+e.toLocaleTimeString(),wl=async e=>{try{const t=await xn(q);if(t.length===0){console.log(`${h.yellow("No log files found.")}`);return}console.log(`${h.blue("Log files in")} ${q}:
|
|
254
|
+
`);const n=await Promise.all(t.map(async o=>{const s=ae.join(q,o),r=await Us(s);return{name:o,size:gl(r.size),modified:yl(r.mtime)}}));n.sort((o,s)=>new Date(s.modified).getTime()-new Date(o.modified).getTime()),n.forEach((o,s)=>{console.log(`${s===0?"\u{1F4C4}":" "} ${h.cyan(o.name)} ${h.gray(`(${o.size}, ${o.modified})`)}`)}),console.log(`
|
|
255
|
+
${h.green("Total:")} ${t.length} file${t.length!==1?"s":""}`)}catch(t){if(t.code==="ENOENT")console.log(`${h.yellow("Logs directory does not exist yet.")}`);else throw t}},Cl=async e=>{try{await xn(q);const t=process.platform;let n;switch(t){case"darwin":n=`open "${q}"`;break;case"win32":n=`start "" "${q}"`;break;default:n=`xdg-open "${q}"`;break}await hl(n),console.log(`${h.green("\u2714")} Opened logs directory in file manager`)}catch(t){t.code==="ENOENT"?console.log(`${h.yellow("Logs directory does not exist yet.")}`):e.printError(`Failed to open logs directory: ${t.message}`)}},El=async e=>{try{await Ks(q,{recursive:!0,force:!0}),console.log(`${h.green("\u2714")} All log files removed!`)}catch(t){e.printError(`Failed to remove log files: ${t.message}`)}};var bl=G({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"]}},e=>{(async()=>{const{action:t}=e._,n=new B;switch(t){case"list":await wl();break;case"path":console.log(`${h.blue("Logs directory:")} ${q}`);break;case"open":await Cl(n);break;case"removeAll":await El(n);break;default:throw new m(`Invalid action: ${t}. Use 'list', 'path', 'open', or 'removeAll'`)}})().catch(t=>{new B().printError(t.message),W(t),process.exit(1)})});const vl=new Set(["--locale","-l","--generate","-g","--type","-t","--prompt","--exclude","-x","--output"]),os=(e,t=[])=>{const n=new Set(t),o=[];let s=!1;for(let r=0;r<e.length;r++){const a=e[r];if(s){s=!1;continue}if(!n.has(a)){if(a.startsWith("-")){vl.has(a)&&!a.includes("=")&&(s=!0);continue}o.push(a)}}return o},[pt,ss]=os(process.argv.slice(2),["--pre-commit"]);var Al=(e,t,n,o,s,r,a)=>(async()=>{if(!pt)throw new m('Commit message file path is missing. This file should be called from the "pre-commit framework"');if(ss){console.log(`Skipping aicommit2 message generation for ${ss} commit`);return}const c={...e&&{locale:e},...t!=null&&{generate:t.toString()},...o&&{type:o},...s&&{systemPrompt:s},...r===!0&&{includeBody:"true"}};a&&(c.logLevel="verbose");const l=await Z(c);if(await lt(l),re.verbose(`[pre-commit] type=${l.type}, systemPrompt=${l.systemPrompt?"set":"empty"}`),l.systemPromptPath)try{await R.readFile(A.resolve(l.systemPromptPath),"utf-8")}catch{throw new m(`Error reading system prompt file: ${l.systemPromptPath}`)}const u=await on(n,l.exclude);if(!u)return;const d=new B;d.printTitle();const p=le(l,"commit");if(p.length===0)throw new m("Please set at least one API key via the `aicommit2 config set` command");const y=await Ne(),f=await _e(),$=new je(l,u,y,f);let S;try{S=await bt($.createCommitMsgRequests$(p).pipe(bn(N=>!N.isError),vn(N=>N.value),vt()))}finally{d.printAnalyzed()}const P=await R.readFile(pt,"utf8")!=="",v=S.length>1;let w="";P&&(w=`# \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
|
|
256
256
|
`,w+=`# ----------------------------------------
|
|
257
257
|
`,w+=`# How to use:
|
|
258
258
|
`,v?(w+=`# 1. Remove the "#" from your chosen message
|
|
@@ -265,7 +265,7 @@ ${h.green("Total:")} ${t.length} file${t.length!==1?"s":""}`)}catch(t){if(t.code
|
|
|
265
265
|
`),v&&P?(w+=`
|
|
266
266
|
# \u{1F4DD} Choose one of these messages:
|
|
267
267
|
`,w+=`
|
|
268
|
-
${S.map(
|
|
268
|
+
${S.map(N=>N.split(`
|
|
269
269
|
`).map(H=>`# ${H}`).join(`
|
|
270
270
|
`)).join(`
|
|
271
271
|
#
|
|
@@ -276,7 +276,7 @@ ${S[0]}
|
|
|
276
276
|
`),w+=`
|
|
277
277
|
${S[0]}
|
|
278
278
|
`);const I=await R.readFile(pt,"utf8"),L=w+`
|
|
279
|
-
`+I;await R.writeFile(pt,L),d.printSavedCommitMessage()})().catch(c=>{new B().printError(c.message),W(c),process.exit(1)});const[ht,
|
|
279
|
+
`+I;await R.writeFile(pt,L),d.printSavedCommitMessage()})().catch(c=>{new B().printError(c.message),W(c),process.exit(1)});const[ht,rs]=os(process.argv.slice(2),["--hook-mode"]);var Pl=(e,t,n,o,s,r,a)=>(async()=>{if(!ht)throw new m('Commit message file path is missing. This file should be called from the "prepare-commit-msg" git hook or with --hook-mode flag');if(rs){console.log(`Skipping aicommit2 message generation for ${rs} commit`);return}const c={...e&&{locale:e},...t!=null&&{generate:t.toString()},...o&&{type:o},...s&&{systemPrompt:s},...r===!0&&{includeBody:"true"}};a&&(c.logLevel="verbose");const l=await Z(c);if(await lt(l),re.verbose(`[hook-mode] type=${l.type}, systemPrompt=${l.systemPrompt?"set":"empty"}`),l.systemPromptPath)try{await R.readFile(A.resolve(l.systemPromptPath),"utf-8")}catch{throw new m(`Error reading system prompt file: ${l.systemPromptPath}`)}const u=await on(n,l.exclude);if(!u)return;const d=new B;d.printTitle();const p=le(l,"commit");if(p.length===0)throw new m("Please set at least one API key via the `aicommit2 config set` command");const y=await Ne(),f=await _e(),$=new je(l,u,y,f),S=d.displaySpinner("The AI is analyzing your changes");let x;try{x=await bt($.createCommitMsgRequests$(p).pipe(bn(ee=>!ee.isError),vn(ee=>ee.value),vt()))}finally{S.stop(),S.clear(),d.printAnalyzed()}const v=await R.readFile(ht,"utf8")!=="",w=x.length>1,I=await oc();let L="";v&&(L=`${I} \u{1F916} Generated by aicommit2 (https://github.com/tak-bro/aicommit2)
|
|
280
280
|
`,L+=`${I} ----------------------------------------
|
|
281
281
|
`,L+=`${I} How to use:
|
|
282
282
|
`,w?(L+=`${I} 1. Remove the "${I}" from your chosen message
|
|
@@ -289,7 +289,7 @@ ${S[0]}
|
|
|
289
289
|
`),w&&v?(L+=`
|
|
290
290
|
${I} \u{1F4DD} Choose one of these messages:
|
|
291
291
|
`,L+=`
|
|
292
|
-
${x.map(
|
|
292
|
+
${x.map(ee=>ee.split(`
|
|
293
293
|
`).map(V=>`${I} ${V}`).join(`
|
|
294
294
|
`)).join(`
|
|
295
295
|
${I}
|
|
@@ -299,30 +299,30 @@ ${x[0]}
|
|
|
299
299
|
${I} \u{1F4DD} Generated commit message:
|
|
300
300
|
`),L+=`
|
|
301
301
|
${x[0]}
|
|
302
|
-
`);const
|
|
303
|
-
`+
|
|
302
|
+
`);const N=await R.readFile(ht,"utf8"),H=L+`
|
|
303
|
+
`+N;await R.writeFile(ht,H),d.printSavedCommitMessage()})().catch(c=>{new B().printError(c.message),W(c),process.exit(1)});const Y=new B;var xl=G({name:"rewrite",parameters:["[commit-hash]"],help:{description:"Rewrite the commit message of a commit using AI (defaults to HEAD)",examples:["aicommit2 rewrite","aicommit2 rewrite -g 3","aicommit2 rewrite abc1234","aicommit2 rewrite HEAD~2 --dry-run"]},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 (default: 1)",alias:"g"},type:{type:String,description:"Type of commit message to generate (default: conventional)",alias:"t"},confirm:{type:Boolean,description:"Skip confirmation when rewriting after message generation (default: false)",alias:"y",default:!1},prompt:{type:String,description:"Custom prompt to fine-tune the generated message",alias:"p"},"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},verbose:{type:Boolean,description:"Enable verbose logging for this run",alias:"v",default:!1},"dry-run":{type:Boolean,description:"Generate commit message without rewriting (output only)",alias:"d",default:!1},"disable-lowercase":{type:Boolean,description:"Disable automatic lowercase conversion of commit messages",default:!1}}},e=>{(async()=>{Y.printTitle();const t=Y.displaySpinner("Detecting repository...");await at();const n=await De();if(n!=="git")throw new m(`Rewrite is only supported for Git repositories. Current VCS: ${n}.
|
|
304
304
|
|
|
305
305
|
For Jujutsu, use: jj describe -m "new message"
|
|
306
306
|
For YADM, use: yadm commit --amend -m "new message"`);const o=e._.commitHash||"HEAD";if(o!=="HEAD"){t.text="Validating commit reference...";try{await C("git",["rev-parse","--verify",`${o}^{commit}`])}catch{throw new m(`Invalid commit reference: ${o}.
|
|
307
307
|
|
|
308
|
-
Provide a valid commit hash, branch name, or relative reference (e.g., HEAD~2).`)}}t.text="Loading configuration...";const s={locale:e.flags.locale?.toString(),generate:e.flags.generate?.toString(),type:e.flags.type?.toString(),systemPrompt:e.flags.prompt?.toString(),...e.flags["disable-lowercase"]===!0&&{disableLowerCase:"true"}};e.flags.verbose&&(s.logLevel="verbose");const r=await Z(s,[]);await lt(r),e.flags["disable-lowercase"]&&
|
|
308
|
+
Provide a valid commit hash, branch name, or relative reference (e.g., HEAD~2).`)}}t.text="Loading configuration...";const s={locale:e.flags.locale?.toString(),generate:e.flags.generate?.toString(),type:e.flags.type?.toString(),systemPrompt:e.flags.prompt?.toString(),...e.flags["disable-lowercase"]===!0&&{disableLowerCase:"true"}};e.flags.verbose&&(s.logLevel="verbose");const r=await Z(s,[]);await lt(r),e.flags["disable-lowercase"]&&Ro(r),await cn(r),t.text="Reading commit information...";const a=await _o(o);if(t.stop(),!a)throw new m(`Could not retrieve the diff for commit ${o}.
|
|
309
309
|
|
|
310
310
|
Make sure the commit hash is correct and the commit exists.`,{code:k.VCS_NOT_FOUND});const c=await ac(o);if(!c)throw new m(`Could not retrieve the commit message for ${o}.
|
|
311
311
|
|
|
312
312
|
Make sure the commit hash is correct and the commit exists.`);const l=o==="HEAD";Y.printInfo(`${l?"Current":`Commit ${o}`} commit message:
|
|
313
313
|
${c}
|
|
314
|
-
`);const u=
|
|
314
|
+
`);const u=nn(a,{mode:r.diffCompression,maxHunkLines:r.maxHunkLines,maxDiffLines:r.maxDiffLines});Y.printStagedFiles(a,u.compression);const d=le(r,"commit");if(d.length===0)throw new m(Fe.noApiKeysConfigured(),{code:k.MISSING_API_KEY});const p=await Ne(),g=await _e(5,o),y=new je(r,a,p,g),f=e.flags["auto-select"]||!1,$=e.flags.edit||!1,S=e.flags.confirm||!1,x=e.flags["dry-run"]||!1,P=new ut(Go);let v=null;try{const w=new Map,I=P.initPrompt();P.startLoader();let L=0;v=y.createCommitMsgRequests$(d).subscribe({next:Q=>{const ie=Q;ie.value&&w.set(ie.value,ie),Q.value&&!Q.isError&&!Q.disabled&&(L++,P.updateLoaderText(`AI is analyzing your changes (${L} message${L>1?"s":""} generated)`)),P.refreshChoices(Q)},error:Q=>{console.error("Commit message generation error:",Q),P.checkErrorOnChoices()},complete:()=>P.checkErrorOnChoices()});const H=(await I).aicommit2Prompt?.value;if(!H)throw new m("An error occurred! No selected message");const ee=w.get(H);let V=H;if($){if(Y.printInfo("Opening editor to modify commit message..."),V=await $l(V),!V.trim())throw new m(Fe.emptyCommitMessage(),{code:k.EMPTY_COMMIT_MESSAGE});Y.printSuccess("Commit message edited successfully!"),Y.print(`
|
|
315
315
|
${V}
|
|
316
316
|
`)}if(x){process.stdout.write(V+`
|
|
317
|
-
`);return}if(S||f&&d.length===1){await
|
|
317
|
+
`);return}if(S||f&&d.length===1){await is(V,o);return}const{confirmationPrompt:ve}=await T.prompt([{type:"confirm",name:"confirmationPrompt",message:"Use selected message?",default:!0}]);ve?await is(V,o):Y.printCancelledCommit()}finally{v&&v.unsubscribe(),P.destroy()}})().catch(t=>{Y.printError(t.message),W(t),process.exit(1)})});async function is(e,t){if(await cc(t)){const o=t==="HEAD";Y.printWarning(`${o?"The HEAD":`Commit ${t.slice(0,7)}`} appears to have been pushed to the remote.
|
|
318
318
|
Rewriting will change its hash. You will need to force push:
|
|
319
|
-
git push --force-with-lease`);const{proceed:s}=await T.prompt([{type:"confirm",name:"proceed",message:"Continue with rewrite anyway?",default:!1}]);if(!s){Y.printCancelledCommit();return}}await ic(e,t),Y.printSuccess("Commit message rewritten successfully!")}async function $l(e){const t=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),n=A.join(ue.tmpdir(),`aicommit2-rewrite-${Date.now()}-${yt.randomBytes(4).toString("hex")}.txt`);try{O.writeFileSync(n,e,"utf8");const o=t.split(" "),[s,...r]=o;await C(s,[...r,n],{stdio:"inherit"});const a=O.readFileSync(n,"utf8").trim();if(O.unlinkSync(n),!a)throw new m("Rewrite cancelled - empty message");return a}catch(o){try{O.unlinkSync(n)}catch{}throw o instanceof m?o:o&&typeof o=="object"&&"exitCode"in o&&o.exitCode!==0?new m("Rewrite cancelled"):new m(`Failed to open editor "${t}". Please set your EDITOR or VISUAL environment variable.`)}}const X=new B,
|
|
320
|
-
`);;){const t=await kl();if(!t)break;await Rl(t.key,t.info);const{addMore:n}=await T.prompt([{type:"confirm",name:"addMore",message:"Would you like to configure another provider?",default:!1}]);if(!n)break;console.log()}X.printSuccess("Setup complete! Run `aic2` to generate commit messages.")})().catch(t=>{X.printError(t.message),W(t),process.exit(1)})});const kl=async()=>{const e=
|
|
319
|
+
git push --force-with-lease`);const{proceed:s}=await T.prompt([{type:"confirm",name:"proceed",message:"Continue with rewrite anyway?",default:!1}]);if(!s){Y.printCancelledCommit();return}}await ic(e,t),Y.printSuccess("Commit message rewritten successfully!")}async function $l(e){const t=process.env.VISUAL||process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),n=A.join(ue.tmpdir(),`aicommit2-rewrite-${Date.now()}-${yt.randomBytes(4).toString("hex")}.txt`);try{O.writeFileSync(n,e,"utf8");const o=t.split(" "),[s,...r]=o;await C(s,[...r,n],{stdio:"inherit"});const a=O.readFileSync(n,"utf8").trim();if(O.unlinkSync(n),!a)throw new m("Rewrite cancelled - empty message");return a}catch(o){try{O.unlinkSync(n)}catch{}throw o instanceof m?o:o&&typeof o=="object"&&"exitCode"in o&&o.exitCode!==0?new m("Rewrite cancelled"):new m(`Failed to open editor "${t}". Please set your EDITOR or VISUAL environment variable.`)}}const X=new B,fn={OPENAI:{displayName:"OpenAI (ChatGPT)",authType:"api-key",envKeyHint:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini"},COPILOT_SDK:{displayName:"GitHub Copilot SDK (Preview)",authType:"none",defaultModel:"gpt-4.1",setupNotes:"Uses local Copilot SDK auth flow (via Copilot CLI session), not GitHub Models API keys. Install/authenticate Copilot CLI first."},OPENROUTER:{displayName:"OpenRouter",authType:"api-key",envKeyHint:"OPENROUTER_API_KEY",defaultModel:"openrouter/auto",setupNotes:"OpenRouter supports many upstream models. You can keep openrouter/auto or choose a specific model slug."},ANTHROPIC:{displayName:"Anthropic (Claude)",authType:"api-key",envKeyHint:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514"},GEMINI:{displayName:"Google Gemini",authType:"api-key",envKeyHint:"GEMINI_API_KEY",defaultModel:"gemini-1.5-flash"},OLLAMA:{displayName:"Ollama (Local)",authType:"none",defaultModel:"llama3.2",setupNotes:"Ollama runs locally \u2014 no API key needed. Make sure Ollama is running."},GROQ:{displayName:"Groq",authType:"api-key",envKeyHint:"GROQ_API_KEY",defaultModel:"llama-3.3-70b-versatile"},DEEPSEEK:{displayName:"DeepSeek",authType:"api-key",envKeyHint:"DEEPSEEK_API_KEY",defaultModel:"deepseek-v4-flash"},MISTRAL:{displayName:"Mistral AI",authType:"api-key",envKeyHint:"MISTRAL_API_KEY",defaultModel:"mistral-small-latest"},CODESTRAL:{displayName:"Codestral",authType:"api-key",envKeyHint:"CODESTRAL_API_KEY",defaultModel:"codestral-latest"},COHERE:{displayName:"Cohere",authType:"api-key",envKeyHint:"COHERE_API_KEY",defaultModel:"command-r-plus"},PERPLEXITY:{displayName:"Perplexity",authType:"api-key",envKeyHint:"PERPLEXITY_API_KEY",defaultModel:"sonar"},GITHUB_MODELS:{displayName:"GitHub Models",authType:"api-key",envKeyHint:"GITHUB_MODELS_API_KEY",defaultModel:"openai/gpt-4o-mini",setupNotes:"Use a GitHub personal access token (including github_pat_...). Run `aic2 github-login` for browser-based auth."},HUGGINGFACE:{displayName:"Hugging Face",authType:"cookie",defaultModel:"CohereForAI/c4ai-command-r-plus",setupNotes:"Requires a Hugging Face cookie for authentication."},BEDROCK:{displayName:"AWS Bedrock",authType:"complex",setupNotes:"Requires AWS credentials. Configure via AWS CLI or set region + access keys."}},as=["OPENAI","OPENROUTER","ANTHROPIC","GEMINI","OLLAMA","GROQ","DEEPSEEK"];var Sl=G({name:"setup",parameters:[],help:{description:"Interactive setup wizard for configuring AI providers",examples:["aic2 setup"]}},e=>{(async()=>{for(X.printTitle(),console.log(),X.printInfo(`Welcome to aicommit2 setup! Let's configure your AI providers.
|
|
320
|
+
`);;){const t=await kl();if(!t)break;await Rl(t.key,t.info);const{addMore:n}=await T.prompt([{type:"confirm",name:"addMore",message:"Would you like to configure another provider?",default:!1}]);if(!n)break;console.log()}X.printSuccess("Setup complete! Run `aic2` to generate commit messages.")})().catch(t=>{X.printError(t.message),W(t),process.exit(1)})});const kl=async()=>{const e=as.map(r=>({name:fn[r].displayName,value:r})),n=Ce.filter(r=>!as.includes(r)).map(r=>({name:fn[r]?.displayName||r,value:r})),{provider:o}=await T.prompt([{type:"list",name:"provider",message:"Select an AI provider to configure:",choices:[new T.Separator("\u2500\u2500 Popular \u2500\u2500"),...e,new T.Separator("\u2500\u2500 Other \u2500\u2500"),...n,new T.Separator,{name:"Done (exit setup)",value:null}]}]);if(!o)return null;const s=fn[o]||{displayName:o,authType:"api-key"};return{key:o,info:s}},Rl=async(e,t)=>{console.log(),t.setupNotes&&(X.printInfo(t.setupNotes),console.log());const n=[];switch(t.authType){case"api-key":{const{apiKey:r}=await T.prompt([{type:"password",name:"apiKey",message:`Enter your ${t.displayName} API key:`,mask:"*",validate:a=>a.trim()?!0:"API key is required"}]);n.push([`${e}.key`,r.trim()]);break}case"cookie":{const{cookie:r}=await T.prompt([{type:"password",name:"cookie",message:`Enter your ${t.displayName} cookie:`,mask:"*",validate:a=>a.trim()?!0:"Cookie is required"}]);n.push([`${e}.cookie`,r.trim()]);break}case"none":{if(e==="OLLAMA"){const{host:r}=await T.prompt([{type:"input",name:"host",message:"Ollama host URL:",default:Re}]);r&&r!==Re&&n.push([`${e}.host`,r.trim()])}break}case"complex":{X.printInfo("AWS Bedrock requires region and credentials."),console.log();const{region:r}=await T.prompt([{type:"input",name:"region",message:"AWS Region (e.g., us-east-1):",validate:c=>c.trim()?!0:"Region is required"}]);n.push([`${e}.region`,r.trim()]);const{authMethod:a}=await T.prompt([{type:"list",name:"authMethod",message:"Authentication method:",choices:[{name:"AWS Profile (from ~/.aws/credentials)",value:"profile"},{name:"Access Key + Secret Key",value:"keys"},{name:"Environment variables (already set)",value:"env"}]}]);if(a==="profile"){const{profile:c}=await T.prompt([{type:"input",name:"profile",message:"AWS Profile name:",default:"default"}]);n.push([`${e}.profile`,c.trim()])}else if(a==="keys"){const{accessKeyId:c,secretAccessKey:l}=await T.prompt([{type:"password",name:"accessKeyId",message:"AWS Access Key ID:",mask:"*"},{type:"password",name:"secretAccessKey",message:"AWS Secret Access Key:",mask:"*"}]);n.push([`${e}.accessKeyId`,c.trim()]),n.push([`${e}.secretAccessKey`,l.trim()])}break}}const{model:o}=await T.prompt([{type:"input",name:"model",message:"Model to use (comma-separated for multiple):",default:t.defaultModel||"",validate:r=>r.trim()?!0:"At least one model is required"}]);n.push([`${e}.model`,o.trim()]);const s=X.displaySpinner("Saving configuration...");try{await tt(n),X.stopSpinner(s),X.printSuccess(`${t.displayName} configured successfully!`),t.envKeyHint&&console.log(` Tip: You can also set the ${t.envKeyHint} environment variable instead.`)}catch(r){X.stopSpinner(s),X.printError(`Failed to save configuration: ${r.message}`)}},cs=20,ls=e=>e<1e3?`${e}ms`:`${(e/1e3).toFixed(1)}s`,us=e=>new Date(e).toLocaleDateString(),Il=e=>{const t=Math.round(e/100*cs),n=cs-t;return(e>=80?h.green:e>=50?h.yellow:h.red)("\u2588".repeat(t))+h.gray("\u2591".repeat(n))},Ll=e=>{const t=e.totalRequests>0?Math.round(e.successCount/e.totalRequests*100):0,n=Il(t),o=e.provider.padEnd(14),s=`${t}%`.padStart(4),r=`${e.totalRequests}`.padStart(4),a=`${e.selectedCount}`.padStart(4),c=e.selectionRate>0?`(${e.selectionRate}%)`.padStart(7):"".padStart(7),l=ls(e.avgResponseTimeMs).padStart(6);console.log(` ${h.bold(o)} ${s} ${n} ${r} ${h.cyan(a)} ${h.gray(c)} ${l}`)},Ml=async e=>{if(!await Za()){console.log(h.yellow(`
|
|
321
321
|
No statistics recorded yet.`)),console.log(h.gray(`Statistics will be collected as you generate commit messages.
|
|
322
322
|
`));return}const n=await Xa(e);if(n.totalRequests===0){console.log(h.yellow(`
|
|
323
323
|
No statistics in the last ${e} days.
|
|
324
|
-
`));return}if(console.log(""),console.log(h.bold("\u{1F4CA} aicommit2 Statistics")),console.log(h.gray(` Period: ${
|
|
324
|
+
`));return}if(console.log(""),console.log(h.bold("\u{1F4CA} aicommit2 Statistics")),console.log(h.gray(` Period: ${us(n.periodStart)} - ${us(n.periodEnd)}`)),console.log(""),console.log(h.bold("Overview:")),console.log(` Total requests: ${h.cyan(n.totalRequests)}`),console.log(` Success rate: ${h.green(n.successRate+"%")}`),console.log(` Avg response time: ${h.yellow(ls(n.avgResponseTimeMs))}`),console.log(""),n.providerStats.length>0){console.log(h.bold("Provider Usage:")),console.log(h.gray(" Provider Rate Bar Cnt Selected Time"));for(const o of n.providerStats)Ll(o);console.log("")}},Ol=async()=>{await Qa(),console.log(h.green(`
|
|
325
325
|
Statistics cleared successfully.
|
|
326
|
-
`))},Tl=G({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"]}},e=>{(async()=>{const t=e._[0],{days:n}=e.flags;switch(t){case"clear":await Ol();break;default:await Ml(n);break}})().catch(t=>{console.error(h.red(t.message)),W(t),process.exit(1)})});class
|
|
326
|
+
`))},Tl=G({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"]}},e=>{(async()=>{const t=e._[0],{days:n}=e.flags;switch(t){case"clear":await Ol();break;default:await Ml(n);break}})().catch(t=>{console.error(h.red(t.message)),W(t),process.exit(1)})});class ds{constructor(t="SubscriptionManager"){this.destroyed$=new _s,this.subscriptions=new Et,this.isDestroyed=!1,this.name=t}add(t,n){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`);const s=new Et;return s.unsubscribe(),s}const o=t.pipe($n(this.destroyed$),Sn(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Observable finalized`)})).subscribe({next:n?.next,error:s=>{console.error(`${this.name}: Observable error:`,s),n?.error?.(s)},complete:n?.complete});return this.subscriptions.add(o),o}pipe(t){return this.isDestroyed?(console.warn(`${this.name}: Cannot pipe - manager is destroyed`),t):t.pipe($n(this.destroyed$),Sn(()=>{process.env.NODE_ENV==="development"&&console.log(`${this.name}: Piped observable finalized`)}))}addSubscription(t){if(this.isDestroyed){console.warn(`${this.name}: Cannot add subscription - manager is destroyed`),t.unsubscribe();return}this.subscriptions.add(t)}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 Dl=new ds("Global"),Ge=()=>{Dl.destroy()};process.on("exit",Ge),process.on("SIGINT",Ge),process.on("SIGTERM",Ge),process.on("uncaughtException",e=>{console.error("Uncaught exception:",e),Ge(),process.exit(1)}),process.on("unhandledRejection",(e,t)=>{console.error("Unhandled rejection at:",t,"reason:",e),Ge(),process.exit(1)});const Nl=Is(bs),ms=5,_l=3e3,jl=500,Fl=100,Gl=1e3,Bl=200;class Hl{constructor(){this.consoleManager=new B,this.subscriptionManager=new ds,this.currentCodeReviewSubscription=null,this.currentCodeReviewPromptManager=null,this.watcher=null,this.lastCommitHash=null,this.isProcessingCommit=!1,this.retryCount=0,this.processingLock=!1,this.pendingCommitHash=null,this.excludeFiles=[],this.configExclude=[],this.REPO_PATH=process.cwd(),this.GIT_PATH=A.join(this.REPO_PATH,".git"),this.HEAD_PATH=A.join(this.GIT_PATH,"HEAD"),this.REFS_PATH=A.join(this.GIT_PATH,"refs","heads"),this.COMMIT_MSG_PATH=A.join(this.GIT_PATH,"COMMIT_EDITMSG"),this.setupProcessHandlers=()=>{const t=()=>{this.destroy(),process.exit(0)};process.on("SIGINT",t),process.on("SIGTERM",t),process.on("SIGQUIT",t)},this.watch=async(t,n,o,s,r,a)=>{this.consoleManager.printTitle(),await at();const c=await De();if(c!=="git")throw new m(`Watch mode is only supported for Git repositories. Current VCS: ${c}`);this.excludeFiles=o;const l=await this.initializeConfig(t,n,s,r,a);this.configExclude=l.exclude||[],await this.initializeCurrentCommit(),await this.startWatchLoop(l)},this.startWatchLoop=async t=>{try{await this.watchGitEvents(t)}catch(n){this.retryCount<ms||(this.consoleManager.printError("Watch mode failed after maximum retries. Exiting."),this.destroy(),process.exit(1)),this.retryCount++;const s=_l*Math.pow(2,this.retryCount-1);return await this.handleWatchGitError(n,s),this.startWatchLoop(t)}},this.initializeConfig=async(t,n,o,s,r)=>{const a={locale:t?.toString(),generate:n?.toString(),systemPrompt:o?.toString()};s&&(a.logLevel="verbose");const c=await Z(a,r);return await cn(c),le(c,"watch").length===0&&(this.consoleManager.printError(`Please set at least one API key and watchMode via the config command:
|
|
327
327
|
aicommit2 config set [MODEL].key="YOUR_API_KEY"
|
|
328
|
-
aicommit2 config set [MODEL].watchMode="true"`),process.exit()),c},this.handleWatchGitError=async(t,n)=>{this.consoleManager.printError(`An error occurred: ${t.message}`),W(t),await new Promise(o=>setTimeout(o,n)),this.consoleManager.printWarning(`Restarting the commit monitoring process... (retry ${this.retryCount}/${ds})`)},this.initializeCurrentCommit=async()=>{try{const t=await this.executeGitCommand("git rev-parse HEAD");this.lastCommitHash=t.trim();const n=this.lastCommitHash.substring(0,8);this.consoleManager.printInfo(`Starting watch from commit: ${n}`)}catch{this.consoleManager.printWarning("No commits found in repository"),this.lastCommitHash=null}},this.executeGitCommand=async t=>{const{stdout:n}=await Nl(t,{cwd:this.REPO_PATH});return n},this.clearTerminal=()=>{process.stdout.write("\x1Bc")},this.handleCommitEvent=async(t,n)=>{try{const o=await No(n,this.excludeFiles,this.configExclude);if(!o){this.consoleManager.printWarning("No changes found in this commit");return}this.consoleManager.stopLoader(),this.consoleManager.printStagedFiles(o);const s=le(t,"watch");await this.performCodeReview(t,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${n.substring(0,8)}: ${o.message}`)}},this.performCodeReview=async(t,n,o)=>{this.cleanupPreviousCodeReview();const s=await Ne(),r=await _e(),a=new je(t,n,s,r),c=[];let l=!1;this.currentCodeReviewSubscription=this.subscriptionManager.add(a.createCodeReviewRequests$(o),{next:u=>{c.push(u),this.currentCodeReviewPromptManager?.refreshChoices(u)},error:u=>{re.error(`Code review request error: ${u}`),l=!0,this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)},complete:()=>{l=!0,this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)}});try{let u=!0;for(;u;){this.currentCodeReviewPromptManager=new ut(Go);const d=this.initializeCodeReviewInquirer();this.currentCodeReviewPromptManager.startLoader();for(const f of c)this.currentCodeReviewPromptManager.refreshChoices(f);l&&this.currentCodeReviewPromptManager.checkErrorOnChoices(!1);const g=!!(await d)?.codeReviewPrompt?.value,y=!this.currentCodeReviewPromptManager;g||l||y?u=!1:(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)}}finally{this.cleanupCodeReview()}},this.cleanupPreviousCodeReview=()=>{this.cleanupCurrentReviewResources()},this.initializeCodeReviewInquirer=()=>this.currentCodeReviewPromptManager.initPrompt({...sn,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Bo}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20}),this.cleanupCurrentReviewResources=()=>{this.currentCodeReviewSubscription&&(this.currentCodeReviewSubscription.unsubscribe(),this.currentCodeReviewSubscription=null),this.currentCodeReviewPromptManager&&(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)},this.cleanupCodeReview=()=>{this.cleanupCurrentReviewResources()},this.isGitReset=async t=>{if(!this.lastCommitHash)return!1;try{return await this.executeGitCommand(`git merge-base --is-ancestor ${t} ${this.lastCommitHash}`),!0}catch{return!1}},this.cancelCurrentReview=()=>{this.currentCodeReviewPromptManager&&this.currentCodeReviewPromptManager.cancel(),this.cleanupCurrentReviewResources()},this.closeWatcher=async()=>{this.watcher&&(await this.watcher.close(),this.watcher=null)},this.watchGitEvents=async t=>{this.consoleManager.showLoader("Watching for new Git commits...");const o=[this.HEAD_PATH,this.REFS_PATH,this.COMMIT_MSG_PATH,A.join(this.GIT_PATH,"logs","HEAD")].filter(s=>{try{return O.accessSync(s),!0}catch{return!1}});this.watcher=Ks.watch(o,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:jl,pollInterval:Fl}}),this.watcher.on("change",async s=>{await this.handleGitChange(t,s)}),this.watcher.on("add",async s=>{await this.handleGitChange(t,s)}),this.watcher.on("error",async s=>{this.consoleManager.printError(`Watcher error: ${s.message}`),await this.closeWatcher(),setTimeout(()=>{this.watchGitEvents(t).catch(r=>{re.error(`Failed to restart watcher: ${r}`)})},Gl)})},this.handleGitChange=async(t,n)=>{if(this.processingLock){try{const s=(await this.executeGitCommand("git rev-parse HEAD")).trim();s!==this.lastCommitHash&&(this.pendingCommitHash=s,this.isProcessingCommit&&this.cancelCurrentReview())}catch{}return}this.processingLock=!0;try{await this.processGitChange(t),this.pendingCommitHash&&this.pendingCommitHash!==this.lastCommitHash&&(this.pendingCommitHash=null,await this.processGitChange(t)),this.pendingCommitHash=null}finally{this.processingLock=!1}},this.processGitChange=async t=>{try{const o=(await this.executeGitCommand("git rev-parse HEAD")).trim();if(o===this.lastCommitHash)return;if(this.retryCount=0,await this.isGitReset(o)){this.consoleManager.printInfo(`Git reset detected: ${o.substring(0,8)}`),this.lastCommitHash=o,this.isProcessingCommit&&(this.cancelCurrentReview(),this.isProcessingCommit=!1);return}if(this.isProcessingCommit){this.consoleManager.printInfo("New commit detected, cancelling current review...");try{this.cancelCurrentReview(),await new Promise(r=>setTimeout(r,Bl))}catch(r){re.warn(`Error during review cancellation: ${r}`)}}this.isProcessingCommit=!0;try{this.consoleManager.stopLoader(),this.consoleManager.printInfo(`New commit detected: ${o.substring(0,8)}`),this.lastCommitHash=o,this.clearTerminal(),await this.handleCommitEvent(t,o)}catch(r){this.consoleManager.printError(`Error processing commit ${o.substring(0,8)}: ${r.message}`)}finally{this.isProcessingCommit=!1}}catch(n){this.isProcessingCommit=!1;const o=n.message??"";o.includes("fatal: not a git repository")||this.consoleManager.printError(`Error checking for new commits: ${o}`)}finally{this.consoleManager.showLoader("Watching for new Git commits...")}},this.destroy=()=>{this.isProcessingCommit=!1,this.lastCommitHash=null;try{this.subscriptionManager.destroy(),this.cleanupCurrentReviewResources(),this.watcher&&(this.watcher.close(),this.watcher=null),this.consoleManager.stopLoader()}catch(t){re.warn(`Error during WatchGitManager destruction: ${t}`)}},this.setupProcessHandlers()}}const Ul=new Hl,Kl=async(e,t,n,o,s,r)=>Ul.watch(e,t,n,o,s,r),ms={"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"]},Wl=e=>{if(!e||typeof e!="object")return!1;const t=e;return t.data?.name!==void 0&&typeof t.data.name=="string"},ql=e=>Wl(e)?e.data.name:null,zl=e=>{for(const[t,n]of Object.entries(ms))if(n.includes(e))return t;return null},Yl=e=>e.type==="section"&&e.data?.title==="Flags:",Vl=e=>e.data?.body?.data?.tableData!==void 0,Jl=e=>{const t=new Map;for(const n of Object.keys(ms))t.set(n,[]);if(t.set("Other",[]),!Array.isArray(e))return t;for(const n of e){if(!Array.isArray(n))continue;const o=ql(n[0]),s=o&&zl(o)||"Other";t.get(s)?.push(n)}return t},Xl=(e,t,n,o,s)=>({type:"section",data:{title:s?`Flags - ${e}:`:` ${e}:`,body:{type:"table",data:{tableData:t,tableOptions:n,tableBreakpoints:o}}}}),Ql=(e,t)=>{const n=[];for(const o of e){if(!Yl(o)||!Vl(o)){n.push(o);continue}const{tableData:s,tableOptions:r,tableBreakpoints:a}=o.data.body.data;[...Jl(s).entries()].filter(([,u])=>u.length>0).forEach(([u,d],p)=>{n.push(Xl(u,d,r,a,p===0))})}return t.render(n)};process.env.NODE_NO_WARNINGS||(process.env.NODE_NO_WARNINGS="1");const gt=process.argv.slice(2),{version:fs,description:Zl}=ir;gs({name:"aicommit2",version:fs,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:[Rc,cl,ll,pl,bl,xl,Sl,Tl],help:{description:Zl,render:Ql},ignoreArgv:e=>e==="unknown-flag"||e==="argument"},async e=>{const t={};e.flags.verbose&&(t.logLevel="verbose");const n=await Z(t,gt);if(await lt(n),re.info(`aicommit2 version: ${fs}`),e.flags["pre-commit"]){Al(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.type,e.flags.prompt,e.flags["include-body"],e.flags.verbose);return}if(e.flags["hook-mode"]||fl){Pl(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.type,e.flags.prompt,e.flags["include-body"],e.flags.verbose);return}if(e.flags["watch-commit"]){Kl(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.prompt,e.flags.verbose,gt);return}Pc(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.all,e.flags.type,e.flags.confirm,e.flags.clipboard,e.flags.prompt,e.flags["include-body"],e.flags["auto-select"],e.flags.edit,e.flags["disable-lowercase"],e.flags.verbose,e.flags["dry-run"],e.flags["jj-auto-new"],e.flags.output,gt)},gt);export{q as A,qo as C,Ho as D,k as E,dt as G,mt as H,m as K,z as P,Ra as a,wc as b,Aa as c,Ac as d,dc as e,mc as f,yc as g,uc as h,xa as i,oe as j,de as k,re as l,qt as m,Dc as n,Tc as o,Oc as p,Mc as q,Nc as r,Ia as s,Pa as t,Re as u,jo as v,un as w,jc as x,cn as y,ln as z};
|
|
328
|
+
aicommit2 config set [MODEL].watchMode="true"`),process.exit()),c},this.handleWatchGitError=async(t,n)=>{this.consoleManager.printError(`An error occurred: ${t.message}`),W(t),await new Promise(o=>setTimeout(o,n)),this.consoleManager.printWarning(`Restarting the commit monitoring process... (retry ${this.retryCount}/${ms})`)},this.initializeCurrentCommit=async()=>{try{const t=await this.executeGitCommand("git rev-parse HEAD");this.lastCommitHash=t.trim();const n=this.lastCommitHash.substring(0,8);this.consoleManager.printInfo(`Starting watch from commit: ${n}`)}catch{this.consoleManager.printWarning("No commits found in repository"),this.lastCommitHash=null}},this.executeGitCommand=async t=>{const{stdout:n}=await Nl(t,{cwd:this.REPO_PATH});return n},this.clearTerminal=()=>{process.stdout.write("\x1Bc")},this.handleCommitEvent=async(t,n)=>{try{const o=await _o(n,this.excludeFiles,this.configExclude);if(!o){this.consoleManager.printWarning("No changes found in this commit");return}this.consoleManager.stopLoader(),this.consoleManager.printStagedFiles(o);const s=le(t,"watch");await this.performCodeReview(t,o,s)}catch(o){this.consoleManager.printError(`Error processing commit ${n.substring(0,8)}: ${o.message}`)}},this.performCodeReview=async(t,n,o)=>{this.cleanupPreviousCodeReview();const s=await Ne(),r=await _e(),a=new je(t,n,s,r),c=[];let l=!1;this.currentCodeReviewSubscription=this.subscriptionManager.add(a.createCodeReviewRequests$(o),{next:u=>{c.push(u),this.currentCodeReviewPromptManager?.refreshChoices(u)},error:u=>{re.error(`Code review request error: ${u}`),l=!0,this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)},complete:()=>{l=!0,this.currentCodeReviewPromptManager?.checkErrorOnChoices(!1)}});try{let u=!0;for(;u;){this.currentCodeReviewPromptManager=new ut(Bo);const d=this.initializeCodeReviewInquirer();this.currentCodeReviewPromptManager.startLoader();for(const f of c)this.currentCodeReviewPromptManager.refreshChoices(f);l&&this.currentCodeReviewPromptManager.checkErrorOnChoices(!1);const g=!!(await d)?.codeReviewPrompt?.value,y=!this.currentCodeReviewPromptManager;g||l||y?u=!1:(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)}}finally{this.cleanupCodeReview()}},this.cleanupPreviousCodeReview=()=>{this.cleanupCurrentReviewResources()},this.initializeCodeReviewInquirer=()=>this.currentCodeReviewPromptManager.initPrompt({...rn,name:"codeReviewPrompt",message:"Please check code reviews: ",emptyMessage:`\u26A0 ${Ho}`,isDescriptionDim:!1,stopMessage:"Code review completed",descPageSize:20}),this.cleanupCurrentReviewResources=()=>{this.currentCodeReviewSubscription&&(this.currentCodeReviewSubscription.unsubscribe(),this.currentCodeReviewSubscription=null),this.currentCodeReviewPromptManager&&(this.currentCodeReviewPromptManager.destroy(),this.currentCodeReviewPromptManager=null)},this.cleanupCodeReview=()=>{this.cleanupCurrentReviewResources()},this.isGitReset=async t=>{if(!this.lastCommitHash)return!1;try{return await this.executeGitCommand(`git merge-base --is-ancestor ${t} ${this.lastCommitHash}`),!0}catch{return!1}},this.cancelCurrentReview=()=>{this.currentCodeReviewPromptManager&&this.currentCodeReviewPromptManager.cancel(),this.cleanupCurrentReviewResources()},this.closeWatcher=async()=>{this.watcher&&(await this.watcher.close(),this.watcher=null)},this.watchGitEvents=async t=>{this.consoleManager.showLoader("Watching for new Git commits...");const o=[this.HEAD_PATH,this.REFS_PATH,this.COMMIT_MSG_PATH,A.join(this.GIT_PATH,"logs","HEAD")].filter(s=>{try{return O.accessSync(s),!0}catch{return!1}});this.watcher=Ws.watch(o,{persistent:!0,ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:jl,pollInterval:Fl}}),this.watcher.on("change",async s=>{await this.handleGitChange(t,s)}),this.watcher.on("add",async s=>{await this.handleGitChange(t,s)}),this.watcher.on("error",async s=>{this.consoleManager.printError(`Watcher error: ${s.message}`),await this.closeWatcher(),setTimeout(()=>{this.watchGitEvents(t).catch(r=>{re.error(`Failed to restart watcher: ${r}`)})},Gl)})},this.handleGitChange=async(t,n)=>{if(this.processingLock){try{const s=(await this.executeGitCommand("git rev-parse HEAD")).trim();s!==this.lastCommitHash&&(this.pendingCommitHash=s,this.isProcessingCommit&&this.cancelCurrentReview())}catch{}return}this.processingLock=!0;try{await this.processGitChange(t),this.pendingCommitHash&&this.pendingCommitHash!==this.lastCommitHash&&(this.pendingCommitHash=null,await this.processGitChange(t)),this.pendingCommitHash=null}finally{this.processingLock=!1}},this.processGitChange=async t=>{try{const o=(await this.executeGitCommand("git rev-parse HEAD")).trim();if(o===this.lastCommitHash)return;if(this.retryCount=0,await this.isGitReset(o)){this.consoleManager.printInfo(`Git reset detected: ${o.substring(0,8)}`),this.lastCommitHash=o,this.isProcessingCommit&&(this.cancelCurrentReview(),this.isProcessingCommit=!1);return}if(this.isProcessingCommit){this.consoleManager.printInfo("New commit detected, cancelling current review...");try{this.cancelCurrentReview(),await new Promise(r=>setTimeout(r,Bl))}catch(r){re.warn(`Error during review cancellation: ${r}`)}}this.isProcessingCommit=!0;try{this.consoleManager.stopLoader(),this.consoleManager.printInfo(`New commit detected: ${o.substring(0,8)}`),this.lastCommitHash=o,this.clearTerminal(),await this.handleCommitEvent(t,o)}catch(r){this.consoleManager.printError(`Error processing commit ${o.substring(0,8)}: ${r.message}`)}finally{this.isProcessingCommit=!1}}catch(n){this.isProcessingCommit=!1;const o=n.message??"";o.includes("fatal: not a git repository")||this.consoleManager.printError(`Error checking for new commits: ${o}`)}finally{this.consoleManager.showLoader("Watching for new Git commits...")}},this.destroy=()=>{this.isProcessingCommit=!1,this.lastCommitHash=null;try{this.subscriptionManager.destroy(),this.cleanupCurrentReviewResources(),this.watcher&&(this.watcher.close(),this.watcher=null),this.consoleManager.stopLoader()}catch(t){re.warn(`Error during WatchGitManager destruction: ${t}`)}},this.setupProcessHandlers()}}const Ul=new Hl,Kl=async(e,t,n,o,s,r)=>Ul.watch(e,t,n,o,s,r),fs={"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"]},Wl=e=>{if(!e||typeof e!="object")return!1;const t=e;return t.data?.name!==void 0&&typeof t.data.name=="string"},ql=e=>Wl(e)?e.data.name:null,zl=e=>{for(const[t,n]of Object.entries(fs))if(n.includes(e))return t;return null},Yl=e=>e.type==="section"&&e.data?.title==="Flags:",Vl=e=>e.data?.body?.data?.tableData!==void 0,Jl=e=>{const t=new Map;for(const n of Object.keys(fs))t.set(n,[]);if(t.set("Other",[]),!Array.isArray(e))return t;for(const n of e){if(!Array.isArray(n))continue;const o=ql(n[0]),s=o&&zl(o)||"Other";t.get(s)?.push(n)}return t},Xl=(e,t,n,o,s)=>({type:"section",data:{title:s?`Flags - ${e}:`:` ${e}:`,body:{type:"table",data:{tableData:t,tableOptions:n,tableBreakpoints:o}}}}),Ql=(e,t)=>{const n=[];for(const o of e){if(!Yl(o)||!Vl(o)){n.push(o);continue}const{tableData:s,tableOptions:r,tableBreakpoints:a}=o.data.body.data;[...Jl(s).entries()].filter(([,u])=>u.length>0).forEach(([u,d],p)=>{n.push(Xl(u,d,r,a,p===0))})}return t.render(n)};process.env.NODE_NO_WARNINGS||(process.env.NODE_NO_WARNINGS="1");const gt=process.argv.slice(2),{version:ps,description:Zl}=ar;ys({name:"aicommit2",version:ps,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:[Rc,cl,ll,pl,bl,xl,Sl,Tl],help:{description:Zl,render:Ql},ignoreArgv:e=>e==="unknown-flag"||e==="argument"},async e=>{const t={};e.flags.verbose&&(t.logLevel="verbose");const n=await Z(t,gt);if(await lt(n),re.info(`aicommit2 version: ${ps}`),e.flags["pre-commit"]){Al(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.type,e.flags.prompt,e.flags["include-body"],e.flags.verbose);return}if(e.flags["hook-mode"]||fl){Pl(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.type,e.flags.prompt,e.flags["include-body"],e.flags.verbose);return}if(e.flags["watch-commit"]){Kl(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.prompt,e.flags.verbose,gt);return}Pc(e.flags.locale,e.flags.generate,e.flags.exclude,e.flags.all,e.flags.type,e.flags.confirm,e.flags.clipboard,e.flags.prompt,e.flags["include-body"],e.flags["auto-select"],e.flags.edit,e.flags["disable-lowercase"],e.flags.verbose,e.flags["dry-run"],e.flags["jj-auto-new"],e.flags.output,gt)},gt);export{q as A,zo as C,Uo as D,k as E,dt as G,mt as H,m as K,z as P,Ia as a,wc as b,Pa as c,Ac as d,dc as e,mc as f,yc as g,uc as h,$a as i,ne as j,de as k,re as l,qt as m,Dc as n,Tc as o,Oc as p,Mc as q,Nc as r,La as s,xa as t,Re as u,Fo as v,dn as w,jc as x,ln as y,un as z};
|