@r5n/hydra 0.4.0 → 0.5.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/README.md +74 -14
- package/dist/cli.js +113 -318
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,322 +1,117 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
var Lo=Object.create;var{getPrototypeOf:No,defineProperty:ht,getOwnPropertyNames:Go}=Object;var Ao=Object.prototype.hasOwnProperty;var $n=(n,o,r)=>{r=n!=null?Lo(No(n)):{};let e=o||!n||!n.__esModule?ht(r,"default",{value:n,enumerable:!0}):r;for(let i of Go(n))if(!Ao.call(e,i))ht(e,i,{get:()=>n[i],enumerable:!0});return e};var bt=(n,o)=>()=>(o||n((o={exports:{}}).exports,o),o.exports);var In=bt((Je,yt)=>{var Wn={to(n,o){if(!o)return`\x1B[${n+1}G`;return`\x1B[${o+1};${n+1}H`},move(n,o){let r="";if(n<0)r+=`\x1B[${-n}D`;else if(n>0)r+=`\x1B[${n}C`;if(o<0)r+=`\x1B[${-o}A`;else if(o>0)r+=`\x1B[${o}B`;return r},up:(n=1)=>`\x1B[${n}A`,down:(n=1)=>`\x1B[${n}B`,forward:(n=1)=>`\x1B[${n}C`,backward:(n=1)=>`\x1B[${n}D`,nextLine:(n=1)=>"\x1B[E".repeat(n),prevLine:(n=1)=>"\x1B[F".repeat(n),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},Xo={up:(n=1)=>"\x1B[S".repeat(n),down:(n=1)=>"\x1B[T".repeat(n)},_o={screen:"\x1B[2J",up:(n=1)=>"\x1B[1J".repeat(n),down:(n=1)=>"\x1B[J".repeat(n),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(n){let o="";for(let r=0;r<n;r++)o+=this.line+(r<n-1?Wn.up():"");if(n)o+=Wn.left;return o}};yt.exports={cursor:Wn,scroll:Xo,erase:_o,beep:"\x07"}});var zn=bt((Ye,Kn)=>{var On=process||{},wt=On.argv||[],En=On.env||{},Uo=!(!!En.NO_COLOR||wt.includes("--no-color"))&&(!!En.FORCE_COLOR||wt.includes("--color")||On.platform==="win32"||(On.stdout||{}).isTTY&&En.TERM!=="dumb"||!!En.CI),qo=(n,o,r=n)=>(e)=>{let i=""+e,s=i.indexOf(o,n.length);return~s?n+Co(i,o,r,s)+o:n+i+o},Co=(n,o,r,e)=>{let i="",s=0;do i+=n.substring(s,e)+r,s=e+o.length,e=n.indexOf(o,s);while(~e);return i+n.substring(s)},xt=(n=Uo)=>{let o=n?qo:()=>String;return{isColorSupported:n,reset:o("\x1B[0m","\x1B[0m"),bold:o("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:o("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:o("\x1B[3m","\x1B[23m"),underline:o("\x1B[4m","\x1B[24m"),inverse:o("\x1B[7m","\x1B[27m"),hidden:o("\x1B[8m","\x1B[28m"),strikethrough:o("\x1B[9m","\x1B[29m"),black:o("\x1B[30m","\x1B[39m"),red:o("\x1B[31m","\x1B[39m"),green:o("\x1B[32m","\x1B[39m"),yellow:o("\x1B[33m","\x1B[39m"),blue:o("\x1B[34m","\x1B[39m"),magenta:o("\x1B[35m","\x1B[39m"),cyan:o("\x1B[36m","\x1B[39m"),white:o("\x1B[37m","\x1B[39m"),gray:o("\x1B[90m","\x1B[39m"),bgBlack:o("\x1B[40m","\x1B[49m"),bgRed:o("\x1B[41m","\x1B[49m"),bgGreen:o("\x1B[42m","\x1B[49m"),bgYellow:o("\x1B[43m","\x1B[49m"),bgBlue:o("\x1B[44m","\x1B[49m"),bgMagenta:o("\x1B[45m","\x1B[49m"),bgCyan:o("\x1B[46m","\x1B[49m"),bgWhite:o("\x1B[47m","\x1B[49m"),blackBright:o("\x1B[90m","\x1B[39m"),redBright:o("\x1B[91m","\x1B[39m"),greenBright:o("\x1B[92m","\x1B[39m"),yellowBright:o("\x1B[93m","\x1B[39m"),blueBright:o("\x1B[94m","\x1B[39m"),magentaBright:o("\x1B[95m","\x1B[39m"),cyanBright:o("\x1B[96m","\x1B[39m"),whiteBright:o("\x1B[97m","\x1B[39m"),bgBlackBright:o("\x1B[100m","\x1B[49m"),bgRedBright:o("\x1B[101m","\x1B[49m"),bgGreenBright:o("\x1B[102m","\x1B[49m"),bgYellowBright:o("\x1B[103m","\x1B[49m"),bgBlueBright:o("\x1B[104m","\x1B[49m"),bgMagentaBright:o("\x1B[105m","\x1B[49m"),bgCyanBright:o("\x1B[106m","\x1B[49m"),bgWhiteBright:o("\x1B[107m","\x1B[49m")}};Kn.exports=xt();Kn.exports.createColors=xt});var G=$n(In(),1),Xt=$n(zn(),1);import{stdin as Gt,stdout as At}from"process";import*as Q from"readline";import $t from"readline";import{Writable as vo}from"stream";function Ho({onlyFirst:n=!1}={}){let o=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");return new RegExp(o,n?void 0:"g")}var Po=Ho();function _t(n){if(typeof n!="string")throw new TypeError(`Expected a \`string\`, got \`${typeof n}\``);return n.replace(Po,"")}function Ut(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var qt={exports:{}};(function(n){var o={};n.exports=o,o.eastAsianWidth=function(e){var i=e.charCodeAt(0),s=e.length==2?e.charCodeAt(1):0,t=i;return 55296<=i&&i<=56319&&56320<=s&&s<=57343&&(i&=1023,s&=1023,t=i<<10|s,t+=65536),t==12288||65281<=t&&t<=65376||65504<=t&&t<=65510?"F":t==8361||65377<=t&&t<=65470||65474<=t&&t<=65479||65482<=t&&t<=65487||65490<=t&&t<=65495||65498<=t&&t<=65500||65512<=t&&t<=65518?"H":4352<=t&&t<=4447||4515<=t&&t<=4519||4602<=t&&t<=4607||9001<=t&&t<=9002||11904<=t&&t<=11929||11931<=t&&t<=12019||12032<=t&&t<=12245||12272<=t&&t<=12283||12289<=t&&t<=12350||12353<=t&&t<=12438||12441<=t&&t<=12543||12549<=t&&t<=12589||12593<=t&&t<=12686||12688<=t&&t<=12730||12736<=t&&t<=12771||12784<=t&&t<=12830||12832<=t&&t<=12871||12880<=t&&t<=13054||13056<=t&&t<=19903||19968<=t&&t<=42124||42128<=t&&t<=42182||43360<=t&&t<=43388||44032<=t&&t<=55203||55216<=t&&t<=55238||55243<=t&&t<=55291||63744<=t&&t<=64255||65040<=t&&t<=65049||65072<=t&&t<=65106||65108<=t&&t<=65126||65128<=t&&t<=65131||110592<=t&&t<=110593||127488<=t&&t<=127490||127504<=t&&t<=127546||127552<=t&&t<=127560||127568<=t&&t<=127569||131072<=t&&t<=194367||177984<=t&&t<=196605||196608<=t&&t<=262141?"W":32<=t&&t<=126||162<=t&&t<=163||165<=t&&t<=166||t==172||t==175||10214<=t&&t<=10221||10629<=t&&t<=10630?"Na":t==161||t==164||167<=t&&t<=168||t==170||173<=t&&t<=174||176<=t&&t<=180||182<=t&&t<=186||188<=t&&t<=191||t==198||t==208||215<=t&&t<=216||222<=t&&t<=225||t==230||232<=t&&t<=234||236<=t&&t<=237||t==240||242<=t&&t<=243||247<=t&&t<=250||t==252||t==254||t==257||t==273||t==275||t==283||294<=t&&t<=295||t==299||305<=t&&t<=307||t==312||319<=t&&t<=322||t==324||328<=t&&t<=331||t==333||338<=t&&t<=339||358<=t&&t<=359||t==363||t==462||t==464||t==466||t==468||t==470||t==472||t==474||t==476||t==593||t==609||t==708||t==711||713<=t&&t<=715||t==717||t==720||728<=t&&t<=731||t==733||t==735||768<=t&&t<=879||913<=t&&t<=929||931<=t&&t<=937||945<=t&&t<=961||963<=t&&t<=969||t==1025||1040<=t&&t<=1103||t==1105||t==8208||8211<=t&&t<=8214||8216<=t&&t<=8217||8220<=t&&t<=8221||8224<=t&&t<=8226||8228<=t&&t<=8231||t==8240||8242<=t&&t<=8243||t==8245||t==8251||t==8254||t==8308||t==8319||8321<=t&&t<=8324||t==8364||t==8451||t==8453||t==8457||t==8467||t==8470||8481<=t&&t<=8482||t==8486||t==8491||8531<=t&&t<=8532||8539<=t&&t<=8542||8544<=t&&t<=8555||8560<=t&&t<=8569||t==8585||8592<=t&&t<=8601||8632<=t&&t<=8633||t==8658||t==8660||t==8679||t==8704||8706<=t&&t<=8707||8711<=t&&t<=8712||t==8715||t==8719||t==8721||t==8725||t==8730||8733<=t&&t<=8736||t==8739||t==8741||8743<=t&&t<=8748||t==8750||8756<=t&&t<=8759||8764<=t&&t<=8765||t==8776||t==8780||t==8786||8800<=t&&t<=8801||8804<=t&&t<=8807||8810<=t&&t<=8811||8814<=t&&t<=8815||8834<=t&&t<=8835||8838<=t&&t<=8839||t==8853||t==8857||t==8869||t==8895||t==8978||9312<=t&&t<=9449||9451<=t&&t<=9547||9552<=t&&t<=9587||9600<=t&&t<=9615||9618<=t&&t<=9621||9632<=t&&t<=9633||9635<=t&&t<=9641||9650<=t&&t<=9651||9654<=t&&t<=9655||9660<=t&&t<=9661||9664<=t&&t<=9665||9670<=t&&t<=9672||t==9675||9678<=t&&t<=9681||9698<=t&&t<=9701||t==9711||9733<=t&&t<=9734||t==9737||9742<=t&&t<=9743||9748<=t&&t<=9749||t==9756||t==9758||t==9792||t==9794||9824<=t&&t<=9825||9827<=t&&t<=9829||9831<=t&&t<=9834||9836<=t&&t<=9837||t==9839||9886<=t&&t<=9887||9918<=t&&t<=9919||9924<=t&&t<=9933||9935<=t&&t<=9953||t==9955||9960<=t&&t<=9983||t==10045||t==10071||10102<=t&&t<=10111||11093<=t&&t<=11097||12872<=t&&t<=12879||57344<=t&&t<=63743||65024<=t&&t<=65039||t==65533||127232<=t&&t<=127242||127248<=t&&t<=127277||127280<=t&&t<=127337||127344<=t&&t<=127386||917760<=t&&t<=917999||983040<=t&&t<=1048573||1048576<=t&&t<=1114109?"A":"N"},o.characterLength=function(e){var i=this.eastAsianWidth(e);return i=="F"||i=="W"||i=="A"?2:1};function r(e){return e.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g)||[]}o.length=function(e){for(var i=r(e),s=0,t=0;t<i.length;t++)s=s+this.characterLength(i[t]);return s},o.slice=function(e,i,s){textLen=o.length(e),i=i||0,s=s||1,i<0&&(i=textLen+i),s<0&&(s=textLen+s);for(var t="",f=0,a=r(e),c=0;c<a.length;c++){var m=a[c],l=o.length(m);if(f>=i-(l==2?1:0))if(f+l<=s)t+=m;else break;f+=l}return t}})(qt);var Mo=qt.exports,Bo=Ut(Mo),Wo=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g},Io=Ut(Wo);function dn(n,o={}){if(typeof n!="string"||n.length===0||(o={ambiguousIsNarrow:!0,...o},n=_t(n),n.length===0))return 0;n=n.replace(Io()," ");let r=o.ambiguousIsNarrow?1:2,e=0;for(let i of n){let s=i.codePointAt(0);if(s<=31||s>=127&&s<=159||s>=768&&s<=879)continue;switch(Bo.eastAsianWidth(i)){case"F":case"W":e+=2;break;case"A":e+=r;break;default:e+=1}}return e}var kn=10,Et=(n=0)=>(o)=>`\x1B[${o+n}m`,Ot=(n=0)=>(o)=>`\x1B[${38+n};5;${o}m`,Rt=(n=0)=>(o,r,e)=>`\x1B[${38+n};2;${o};${r};${e}m`,O={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(O.modifier);var Ko=Object.keys(O.color),zo=Object.keys(O.bgColor);[...Ko];function ko(){let n=new Map;for(let[o,r]of Object.entries(O)){for(let[e,i]of Object.entries(r))O[e]={open:`\x1B[${i[0]}m`,close:`\x1B[${i[1]}m`},r[e]=O[e],n.set(i[0],i[1]);Object.defineProperty(O,o,{value:r,enumerable:!1})}return Object.defineProperty(O,"codes",{value:n,enumerable:!1}),O.color.close="\x1B[39m",O.bgColor.close="\x1B[49m",O.color.ansi=Et(),O.color.ansi256=Ot(),O.color.ansi16m=Rt(),O.bgColor.ansi=Et(kn),O.bgColor.ansi256=Ot(kn),O.bgColor.ansi16m=Rt(kn),Object.defineProperties(O,{rgbToAnsi256:{value:(o,r,e)=>o===r&&r===e?o<8?16:o>248?231:Math.round((o-8)/247*24)+232:16+36*Math.round(o/255*5)+6*Math.round(r/255*5)+Math.round(e/255*5),enumerable:!1},hexToRgb:{value:(o)=>{let r=/[a-f\d]{6}|[a-f\d]{3}/i.exec(o.toString(16));if(!r)return[0,0,0];let[e]=r;e.length===3&&(e=[...e].map((s)=>s+s).join(""));let i=Number.parseInt(e,16);return[i>>16&255,i>>8&255,i&255]},enumerable:!1},hexToAnsi256:{value:(o)=>O.rgbToAnsi256(...O.hexToRgb(o)),enumerable:!1},ansi256ToAnsi:{value:(o)=>{if(o<8)return 30+o;if(o<16)return 90+(o-8);let r,e,i;if(o>=232)r=((o-232)*10+8)/255,e=r,i=r;else{o-=16;let f=o%36;r=Math.floor(o/36)/5,e=Math.floor(f/6)/5,i=f%6/5}let s=Math.max(r,e,i)*2;if(s===0)return 30;let t=30+(Math.round(i)<<2|Math.round(e)<<1|Math.round(r));return s===2&&(t+=60),t},enumerable:!1},rgbToAnsi:{value:(o,r,e)=>O.ansi256ToAnsi(O.rgbToAnsi256(o,r,e)),enumerable:!1},hexToAnsi:{value:(o)=>O.ansi256ToAnsi(O.hexToAnsi256(o)),enumerable:!1}}),O}var Jo=ko(),Tn=new Set(["\x1B","\x9B"]),Yo=39,jn="\x07",Ct="[",jo="]",vt="m",Zn=`${jo}8;;`,St=(n)=>`${Tn.values().next().value}${Ct}${n}${vt}`,Tt=(n)=>`${Tn.values().next().value}${Zn}${n}${jn}`,Zo=(n)=>n.split(" ").map((o)=>dn(o)),Jn=(n,o,r)=>{let e=[...o],i=!1,s=!1,t=dn(_t(n[n.length-1]));for(let[f,a]of e.entries()){let c=dn(a);if(t+c<=r?n[n.length-1]+=a:(n.push(a),t=0),Tn.has(a)&&(i=!0,s=e.slice(f+1).join("").startsWith(Zn)),i){s?a===jn&&(i=!1,s=!1):a===vt&&(i=!1);continue}t+=c,t===r&&f<e.length-1&&(n.push(""),t=0)}!t&&n[n.length-1].length>0&&n.length>1&&(n[n.length-2]+=n.pop())},Qo=(n)=>{let o=n.split(" "),r=o.length;for(;r>0&&!(dn(o[r-1])>0);)r--;return r===o.length?n:o.slice(0,r).join(" ")+o.slice(r).join("")},Vo=(n,o,r={})=>{if(r.trim!==!1&&n.trim()==="")return"";let e="",i,s,t=Zo(n),f=[""];for(let[c,m]of n.split(" ").entries()){r.trim!==!1&&(f[f.length-1]=f[f.length-1].trimStart());let l=dn(f[f.length-1]);if(c!==0&&(l>=o&&(r.wordWrap===!1||r.trim===!1)&&(f.push(""),l=0),(l>0||r.trim===!1)&&(f[f.length-1]+=" ",l++)),r.hard&&t[c]>o){let u=o-l,b=1+Math.floor((t[c]-u-1)/o);Math.floor((t[c]-1)/o)<b&&f.push(""),Jn(f,m,o);continue}if(l+t[c]>o&&l>0&&t[c]>0){if(r.wordWrap===!1&&l<o){Jn(f,m,o);continue}f.push("")}if(l+t[c]>o&&r.wordWrap===!1){Jn(f,m,o);continue}f[f.length-1]+=m}r.trim!==!1&&(f=f.map((c)=>Qo(c)));let a=[...f.join(`
|
|
3
|
-
`)
|
|
4
|
-
`?(s&&(e+=Tt("")),i&&l&&(e+=St(l))):m===`
|
|
5
|
-
`&&(i&&l&&(e+=St(i)),s&&(e+=Tt(s)))}return e};function Lt(n,o,r){return String(n).normalize().replace(/\r\n/g,`
|
|
2
|
+
var pr=Object.create;var{getPrototypeOf:hr,defineProperty:Ne,getOwnPropertyNames:dr}=Object;var gr=Object.prototype.hasOwnProperty;var dt=(t,e,n)=>{n=t!=null?pr(hr(t)):{};let i=e||!t||!t.__esModule?Ne(n,"default",{value:t,enumerable:!0}):n;for(let r of dr(t))if(!gr.call(i,r))Ne(i,r,{get:()=>t[r],enumerable:!0});return i};var Xn=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var ie=(t,e)=>{for(var n in e)Ne(t,n,{get:e[n],enumerable:!0,configurable:!0,set:(i)=>e[n]=()=>i})};var v=(t,e)=>()=>(t&&(e=t(t=0)),e);var oe=import.meta.require;function Se(t){return(e)=>mr?`${t}${e}${Vn.reset}`:e}function Kn({bright:t=!1,color:e}){let n=Bun.color(e,"ansi");if(!n||typeof n!=="string")return"";return t&&n in Qn?Qn[n]??n:n}var mr,yr,br,Vn,Qn,wr,xr,P;var Me=v(()=>{mr=!process.env.NO_COLOR&&(process.env.FORCE_COLOR||(process.stdout?.isTTY??!1)),yr=["blue","cyan","gray","green","magenta","red","white","yellow"],br=["bold","dim","italic","underline","reset"],Vn={bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",reset:"\x1B[0m",underline:"\x1B[4m"},Qn={"\x1B[30m":"\x1B[90m","\x1B[31m":"\x1B[91m","\x1B[32m":"\x1B[92m","\x1B[33m":"\x1B[93m","\x1B[34m":"\x1B[94m","\x1B[35m":"\x1B[95m","\x1B[36m":"\x1B[96m","\x1B[37m":"\x1B[97m"};wr=yr.reduce((t,e)=>{return t[e]=Se(Kn({color:e})),t[`${e}Bright`]=Se(Kn({bright:!0,color:e})),t},{}),xr=br.reduce((t,e)=>{return t[e]=Se(Vn[e]),t},{}),P={...wr,...xr}});function vr({prefix:t,level:e,message:n}){let i="";try{let o=new Date().toISOString().split("T")[1];if(o)i=o.split(".")[0]||""}catch{i="00:00:00"}let r=t?`[${t}] `:"";return`${P.dim(i)} ${e} ${r}${n}`}var We,$r,$=({prefix:t="",level:e=process.env.DEBUG?0:1}={})=>{let n={};for(let i of $r)n[i.method]=e<=i.level?(...r)=>{let s=r.map((o)=>String(o??"")).join(" ");i.console(vr({level:i.color(i.label),message:s,prefix:t}))}:()=>{};return n.child=(i)=>$({level:e,prefix:`${t}:${i}`}),n},re;var Zn=v(()=>{Me();((r)=>{r[r.DEBUG=0]="DEBUG";r[r.INFO=1]="INFO";r[r.WARN=2]="WARN";r[r.ERROR=3]="ERROR"})(We||={});$r=[{color:P.dim,console:console.log,label:"DEBUG",level:0,method:"debug"},{color:P.cyan,console:console.info,label:"INFO ",level:1,method:"info"},{color:P.yellow,console:console.warn,label:"WARN ",level:2,method:"warn"},{color:P.red,console:console.error,label:"ERROR",level:3,method:"error"}],re=$()});var G=v(()=>{Me();Zn()});var c;var Be=v(()=>{G();c={arrow:P.yellow,bold:P.bold,boolean:P.cyan,bullet:P.yellow,busy:P.yellow,command:P.green,dim:P.dim,error:P.red,flag:P.yellow,info:P.cyan,number:P.magenta,offline:P.red,online:P.green,separator:P.dim,string:P.green,success:P.green,value:P.cyan,warning:P.yellow}});function Rr(t){return t}function Er(t){let e=[t.description];if(t.usage)e.push("","USAGE",` ${t.usage}`);if(t.options&&Object.keys(t.options).length>0){e.push("","OPTIONS");for(let[n,i]of Object.entries(t.options)){let r=i.short?`-${i.short}, `:" ",s=`--${n}`,o=i.type==="boolean"?"":` <${i.type||"string"}>`,a=i.default!==void 0?` (default: ${i.default})`:"",f=i.required?" (required)":"",u=i.description||"",p=`${r}${s}${o}`;e.push(` ${p.padEnd(24)} ${u}${a}${f}`)}}if(t.positionals&&t.positionals.length>0){e.push("","ARGUMENTS");for(let n of t.positionals){let i=n.required?" (required)":" (optional)";e.push(` ${n.name.padEnd(20)} ${n.description}${i}`)}}if(t.examples&&t.examples.length>0){e.push("","EXAMPLES");for(let n of t.examples)e.push(` # ${n.description}`,` ${n.command}`,"");e.pop()}console.log(e.join(`
|
|
3
|
+
`))}var qe=Xn((_f,zn)=>{var Ue={to(t,e){if(!e)return`\x1B[${t+1}G`;return`\x1B[${e+1};${t+1}H`},move(t,e){let n="";if(t<0)n+=`\x1B[${-t}D`;else if(t>0)n+=`\x1B[${t}C`;if(e<0)n+=`\x1B[${-e}A`;else if(e>0)n+=`\x1B[${e}B`;return n},up:(t=1)=>`\x1B[${t}A`,down:(t=1)=>`\x1B[${t}B`,forward:(t=1)=>`\x1B[${t}C`,backward:(t=1)=>`\x1B[${t}D`,nextLine:(t=1)=>"\x1B[E".repeat(t),prevLine:(t=1)=>"\x1B[F".repeat(t),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},Pr={up:(t=1)=>"\x1B[S".repeat(t),down:(t=1)=>"\x1B[T".repeat(t)},Ar={screen:"\x1B[2J",up:(t=1)=>"\x1B[1J".repeat(t),down:(t=1)=>"\x1B[J".repeat(t),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(t){let e="";for(let n=0;n<t;n++)e+=this.line+(n<t-1?Ue.up():"");if(t)e+=Ue.left;return e}};zn.exports={cursor:Ue,scroll:Pr,erase:Ar,beep:"\x07"}});var Ge=Xn((Nf,Le)=>{var ae=process||{},Yn=ae.argv||[],se=ae.env||{},Tr=!(!!se.NO_COLOR||Yn.includes("--no-color"))&&(!!se.FORCE_COLOR||Yn.includes("--color")||ae.platform==="win32"||(ae.stdout||{}).isTTY&&se.TERM!=="dumb"||!!se.CI),Or=(t,e,n=t)=>(i)=>{let r=""+i,s=r.indexOf(e,t.length);return~s?t+Hr(r,e,n,s)+e:t+r+e},Hr=(t,e,n,i)=>{let r="",s=0;do r+=t.substring(s,i)+n,s=i+e.length,i=t.indexOf(e,s);while(~i);return r+t.substring(s)},In=(t=Tr)=>{let e=t?Or:()=>String;return{isColorSupported:t,reset:e("\x1B[0m","\x1B[0m"),bold:e("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:e("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:e("\x1B[3m","\x1B[23m"),underline:e("\x1B[4m","\x1B[24m"),inverse:e("\x1B[7m","\x1B[27m"),hidden:e("\x1B[8m","\x1B[28m"),strikethrough:e("\x1B[9m","\x1B[29m"),black:e("\x1B[30m","\x1B[39m"),red:e("\x1B[31m","\x1B[39m"),green:e("\x1B[32m","\x1B[39m"),yellow:e("\x1B[33m","\x1B[39m"),blue:e("\x1B[34m","\x1B[39m"),magenta:e("\x1B[35m","\x1B[39m"),cyan:e("\x1B[36m","\x1B[39m"),white:e("\x1B[37m","\x1B[39m"),gray:e("\x1B[90m","\x1B[39m"),bgBlack:e("\x1B[40m","\x1B[49m"),bgRed:e("\x1B[41m","\x1B[49m"),bgGreen:e("\x1B[42m","\x1B[49m"),bgYellow:e("\x1B[43m","\x1B[49m"),bgBlue:e("\x1B[44m","\x1B[49m"),bgMagenta:e("\x1B[45m","\x1B[49m"),bgCyan:e("\x1B[46m","\x1B[49m"),bgWhite:e("\x1B[47m","\x1B[49m"),blackBright:e("\x1B[90m","\x1B[39m"),redBright:e("\x1B[91m","\x1B[39m"),greenBright:e("\x1B[92m","\x1B[39m"),yellowBright:e("\x1B[93m","\x1B[39m"),blueBright:e("\x1B[94m","\x1B[39m"),magentaBright:e("\x1B[95m","\x1B[39m"),cyanBright:e("\x1B[96m","\x1B[39m"),whiteBright:e("\x1B[97m","\x1B[39m"),bgBlackBright:e("\x1B[100m","\x1B[49m"),bgRedBright:e("\x1B[101m","\x1B[49m"),bgGreenBright:e("\x1B[102m","\x1B[49m"),bgYellowBright:e("\x1B[103m","\x1B[49m"),bgBlueBright:e("\x1B[104m","\x1B[49m"),bgMagentaBright:e("\x1B[105m","\x1B[49m"),bgCyanBright:e("\x1B[106m","\x1B[49m"),bgWhiteBright:e("\x1B[107m","\x1B[49m")}};Le.exports=In();Le.exports.createColors=In});import{stdin as ai,stdout as li}from"process";import*as gt from"readline";import Fn from"readline";import{Writable as Cr}from"stream";function _r({onlyFirst:t=!1}={}){let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");return new RegExp(e,t?void 0:"g")}function ui(t){if(typeof t!="string")throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);return t.replace(Nr,"")}function ci(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function Jt(t,e={}){if(typeof t!="string"||t.length===0||(e={ambiguousIsNarrow:!0,...e},t=ui(t),t.length===0))return 0;t=t.replace(Br()," ");let n=e.ambiguousIsNarrow?1:2,i=0;for(let r of t){let s=r.codePointAt(0);if(s<=31||s>=127&&s<=159||s>=768&&s<=879)continue;switch(Mr.eastAsianWidth(r)){case"F":case"W":i+=2;break;case"A":i+=n;break;default:i+=1}}return i}function Lr(){let t=new Map;for(let[e,n]of Object.entries(_)){for(let[i,r]of Object.entries(n))_[i]={open:`\x1B[${r[0]}m`,close:`\x1B[${r[1]}m`},n[i]=_[i],t.set(r[0],r[1]);Object.defineProperty(_,e,{value:n,enumerable:!1})}return Object.defineProperty(_,"codes",{value:t,enumerable:!1}),_.color.close="\x1B[39m",_.bgColor.close="\x1B[49m",_.color.ansi=Dn(),_.color.ansi256=ti(),_.color.ansi16m=ei(),_.bgColor.ansi=Dn(je),_.bgColor.ansi256=ti(je),_.bgColor.ansi16m=ei(je),Object.defineProperties(_,{rgbToAnsi256:{value:(e,n,i)=>e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5),enumerable:!1},hexToRgb:{value:(e)=>{let n=/[a-f\d]{6}|[a-f\d]{3}/i.exec(e.toString(16));if(!n)return[0,0,0];let[i]=n;i.length===3&&(i=[...i].map((s)=>s+s).join(""));let r=Number.parseInt(i,16);return[r>>16&255,r>>8&255,r&255]},enumerable:!1},hexToAnsi256:{value:(e)=>_.rgbToAnsi256(..._.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value:(e)=>{if(e<8)return 30+e;if(e<16)return 90+(e-8);let n,i,r;if(e>=232)n=((e-232)*10+8)/255,i=n,r=n;else{e-=16;let a=e%36;n=Math.floor(e/36)/5,i=Math.floor(a/6)/5,r=a%6/5}let s=Math.max(n,i,r)*2;if(s===0)return 30;let o=30+(Math.round(r)<<2|Math.round(i)<<1|Math.round(n));return s===2&&(o+=60),o},enumerable:!1},rgbToAnsi:{value:(e,n,i)=>_.ansi256ToAnsi(_.rgbToAnsi256(e,n,i)),enumerable:!1},hexToAnsi:{value:(e)=>_.ansi256ToAnsi(_.hexToAnsi256(e)),enumerable:!1}}),_}function oi(t,e,n){return String(t).normalize().replace(/\r\n/g,`
|
|
6
4
|
`).split(`
|
|
7
|
-
`).map((
|
|
8
|
-
`)}
|
|
9
|
-
`),e
|
|
10
|
-
`),
|
|
11
|
-
`),
|
|
12
|
-
`).length-1;this.output.write(
|
|
13
|
-
`);this.output.write(
|
|
14
|
-
`).slice(
|
|
15
|
-
`)),this._prevFrame=n;return}this.output.write(G.erase.down())}this.output.write(n),this.state==="initial"&&(this.state="active"),this._prevFrame=n}}}class Vn extends Ln{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(n){super(n,!1),this.value=!!n.initialValue,this.on("value",()=>{this.value=this._value}),this.on("confirm",(o)=>{this.output.write(G.cursor.move(0,-1)),this.value=o,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}}var rr;rr=new WeakMap;var er=Object.defineProperty,ir=(n,o,r)=>(o in n)?er(n,o,{enumerable:!0,configurable:!0,writable:!0,value:r}):n[o]=r,Nt=(n,o,r)=>(ir(n,typeof o!="symbol"?o+"":o,r),r);class Fn extends Ln{constructor(n){super(n,!1),Nt(this,"options"),Nt(this,"cursor",0),this.options=n.options,this.cursor=this.options.findIndex(({value:o})=>o===n.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",(o)=>{switch(o){case"left":case"up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case"down":case"right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue()})}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value}}class Dn extends Ln{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return`${this.value}\u2588`;let n=this.value.slice(0,this.cursor),[o,...r]=this.value.slice(this.cursor);return`${n}${Xt.default.inverse(o)}${r.join("")}`}get cursor(){return this._cursor}constructor(n){super(n),this.on("finalize",()=>{this.value||(this.value=n.defaultValue)})}}var d=$n(zn(),1),Nn=$n(In(),1);import z from"process";function sr(){return z.platform!=="win32"?z.env.TERM!=="linux":!!z.env.CI||!!z.env.WT_SESSION||!!z.env.TERMINUS_SUBLIME||z.env.ConEmuTask==="{cmd::Cmder}"||z.env.TERM_PROGRAM==="Terminus-Sublime"||z.env.TERM_PROGRAM==="vscode"||z.env.TERM==="xterm-256color"||z.env.TERM==="alacritty"||z.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var nt=sr(),N=(n,o)=>nt?n:o,fr=N("\u25C6","*"),Pt=N("\u25A0","x"),Mt=N("\u25B2","x"),rt=N("\u25C7","o"),ar=N("\u250C","T"),S=N("\u2502","|"),fn=N("\u2514","\u2014"),tt=N("\u25CF",">"),ot=N("\u25CB"," "),ii=N("\u25FB","[\u2022]"),si=N("\u25FC","[+]"),fi=N("\u25FB","[ ]"),ai=N("\u25AA","\u2022"),ci=N("\u2500","-"),mi=N("\u256E","+"),li=N("\u251C","+"),pi=N("\u256F","+"),cr=N("\u25CF","\u2022"),mr=N("\u25C6","*"),lr=N("\u25B2","!"),pr=N("\u25A0","x"),et=(n)=>{switch(n){case"initial":case"active":return d.default.cyan(fr);case"cancel":return d.default.red(Pt);case"error":return d.default.yellow(Mt);case"submit":return d.default.green(rt)}},ur=(n)=>{let{cursor:o,options:r,style:e}=n,i=n.maxItems??Number.POSITIVE_INFINITY,s=Math.max(process.stdout.rows-4,0),t=Math.min(s,Math.max(i,5)),f=0;o>=f+t-3?f=Math.max(Math.min(o-t+3,r.length-t),0):o<f+2&&(f=Math.max(o-2,0));let a=t<r.length&&f>0,c=t<r.length&&f+t<r.length;return r.slice(f,f+t).map((m,l,u)=>{let b=l===0&&a,g=l===u.length-1&&c;return b||g?d.default.dim("..."):e(m,l+f===o)})},q=(n)=>new Dn({validate:n.validate,placeholder:n.placeholder,defaultValue:n.defaultValue,initialValue:n.initialValue,render(){let o=`${d.default.gray(S)}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
${
|
|
20
|
-
|
|
21
|
-
${
|
|
22
|
-
${
|
|
23
|
-
|
|
24
|
-
${
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
${
|
|
28
|
-
|
|
29
|
-
${
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
${
|
|
33
|
-
${
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`)},
|
|
38
|
-
${
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
5
|
+
`).map((i)=>Qr(i,e,n)).join(`
|
|
6
|
+
`)}function Ke(t,e){if(typeof t=="string")return fe.aliases.get(t)===e;for(let n of t)if(n!==void 0&&Ke(n,e))return!0;return!1}function Vr(t,e){if(t===e)return;let n=t.split(`
|
|
7
|
+
`),i=e.split(`
|
|
8
|
+
`),r=[];for(let s=0;s<Math.max(n.length,i.length);s++)n[s]!==i[s]&&r.push(s);return r}function k(t){return t===ke}function le(t,e){let n=t;n.isTTY&&n.setRawMode(e)}function gi({input:t=ai,output:e=li,overwrite:n=!0,hideCursor:i=!0}={}){let r=gt.createInterface({input:t,output:e,prompt:"",tabSize:1});gt.emitKeypressEvents(t,r),t.isTTY&&t.setRawMode(!0);let s=(o,{name:a,sequence:f})=>{let u=String(o);if(Ke([u,a,f],"cancel")){i&&e.write(J.cursor.show),process.exit(0);return}if(!n)return;gt.moveCursor(e,a==="return"?0:-1,a==="return"?-1:0,()=>{gt.clearLine(e,1,()=>{t.once("keypress",s)})})};return i&&e.write(J.cursor.hide),t.once("keypress",s),()=>{t.off("keypress",s),i&&e.write(J.cursor.show),t.isTTY&&!Zr&&t.setRawMode(!1),r.terminal=!1,r.close()}}class kt{constructor(t,e=!0){z(this,"input"),z(this,"output"),z(this,"_abortSignal"),z(this,"rl"),z(this,"opts"),z(this,"_render"),z(this,"_track",!1),z(this,"_prevFrame",""),z(this,"_subscribers",new Map),z(this,"_cursor",0),z(this,"state","initial"),z(this,"error",""),z(this,"value");let{input:n=ai,output:i=li,render:r,signal:s,...o}=t;this.opts=o,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=r.bind(this),this._track=e,this._abortSignal=s,this.input=n,this.output=i}unsubscribe(){this._subscribers.clear()}setSubscriber(t,e){let n=this._subscribers.get(t)??[];n.push(e),this._subscribers.set(t,n)}on(t,e){this.setSubscriber(t,{cb:e})}once(t,e){this.setSubscriber(t,{cb:e,once:!0})}emit(t,...e){let n=this._subscribers.get(t)??[],i=[];for(let r of n)r.cb(...e),r.once&&i.push(()=>n.splice(n.indexOf(r),1));for(let r of i)r()}prompt(){return new Promise((t,e)=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),t(ke);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}let n=new Cr;n._write=(i,r,s)=>{this._track&&(this.value=this.rl?.line.replace(/\t/g,""),this._cursor=this.rl?.cursor??0,this.emit("value",this.value)),s()},this.input.pipe(n),this.rl=Fn.createInterface({input:this.input,output:n,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),Fn.emitKeypressEvents(this.input,this.rl),this.rl.prompt(),this.opts.initialValue!==void 0&&this._track&&this.rl.write(this.opts.initialValue),this.input.on("keypress",this.onKeypress),le(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(J.cursor.show),this.output.off("resize",this.render),le(this.input,!1),t(this.value)}),this.once("cancel",()=>{this.output.write(J.cursor.show),this.output.off("resize",this.render),le(this.input,!1),t(ke)})})}onKeypress(t,e){if(this.state==="error"&&(this.state="active"),e?.name&&(!this._track&&fe.aliases.has(e.name)&&this.emit("cursor",fe.aliases.get(e.name)),fe.actions.has(e.name)&&this.emit("cursor",e.name)),t&&(t.toLowerCase()==="y"||t.toLowerCase()==="n")&&this.emit("confirm",t.toLowerCase()==="y"),t==="\t"&&this.opts.placeholder&&(this.value||(this.rl?.write(this.opts.placeholder),this.emit("value",this.opts.placeholder))),t&&this.emit("key",t.toLowerCase()),e?.name==="return"){if(this.opts.validate){let n=this.opts.validate(this.value);n&&(this.error=n instanceof Error?n.message:n,this.state="error",this.rl?.write(this.value))}this.state!=="error"&&(this.state="submit")}Ke([t,e?.name,e?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close()}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(`
|
|
9
|
+
`),le(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let t=oi(this._prevFrame,process.stdout.columns,{hard:!0}).split(`
|
|
10
|
+
`).length-1;this.output.write(J.cursor.move(-999,t*-1))}render(){let t=oi(this._render(this)??"",process.stdout.columns,{hard:!0});if(t!==this._prevFrame){if(this.state==="initial")this.output.write(J.cursor.hide);else{let e=Vr(this._prevFrame,t);if(this.restoreCursor(),e&&e?.length===1){let n=e[0];this.output.write(J.cursor.move(0,n)),this.output.write(J.erase.lines(1));let i=t.split(`
|
|
11
|
+
`);this.output.write(i[n]),this._prevFrame=t,this.output.write(J.cursor.move(0,i.length-n-1));return}if(e&&e?.length>1){let n=e[0];this.output.write(J.cursor.move(0,n)),this.output.write(J.erase.down());let i=t.split(`
|
|
12
|
+
`).slice(n);this.output.write(i.join(`
|
|
13
|
+
`)),this._prevFrame=t;return}this.output.write(J.erase.down())}this.output.write(t),this.state==="initial"&&(this.state="active"),this._prevFrame=t}}}var J,fi,Nr,pi,Sr,Mr,Wr=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g},Br,je=10,Dn=(t=0)=>(e)=>`\x1B[${e+t}m`,ti=(t=0)=>(e)=>`\x1B[${38+t};5;${e}m`,ei=(t=0)=>(e,n,i)=>`\x1B[${38+t};2;${e};${n};${i}m`,_,Ur,qr,Gr,ue,jr=39,Xe="\x07",hi="[",Jr="]",di="m",Qe,ni=(t)=>`${ue.values().next().value}${hi}${t}${di}`,ii=(t)=>`${ue.values().next().value}${Qe}${t}${Xe}`,kr=(t)=>t.split(" ").map((e)=>Jt(e)),Je=(t,e,n)=>{let i=[...e],r=!1,s=!1,o=Jt(ui(t[t.length-1]));for(let[a,f]of i.entries()){let u=Jt(f);if(o+u<=n?t[t.length-1]+=f:(t.push(f),o=0),ue.has(f)&&(r=!0,s=i.slice(a+1).join("").startsWith(Qe)),r){s?f===Xe&&(r=!1,s=!1):f===di&&(r=!1);continue}o+=u,o===n&&a<i.length-1&&(t.push(""),o=0)}!o&&t[t.length-1].length>0&&t.length>1&&(t[t.length-2]+=t.pop())},Xr=(t)=>{let e=t.split(" "),n=e.length;for(;n>0&&!(Jt(e[n-1])>0);)n--;return n===e.length?t:e.slice(0,n).join(" ")+e.slice(n).join("")},Qr=(t,e,n={})=>{if(n.trim!==!1&&t.trim()==="")return"";let i="",r,s,o=kr(t),a=[""];for(let[u,p]of t.split(" ").entries()){n.trim!==!1&&(a[a.length-1]=a[a.length-1].trimStart());let d=Jt(a[a.length-1]);if(u!==0&&(d>=e&&(n.wordWrap===!1||n.trim===!1)&&(a.push(""),d=0),(d>0||n.trim===!1)&&(a[a.length-1]+=" ",d++)),n.hard&&o[u]>e){let g=e-d,b=1+Math.floor((o[u]-g-1)/e);Math.floor((o[u]-1)/e)<b&&a.push(""),Je(a,p,e);continue}if(d+o[u]>e&&d>0&&o[u]>0){if(n.wordWrap===!1&&d<e){Je(a,p,e);continue}a.push("")}if(d+o[u]>e&&n.wordWrap===!1){Je(a,p,e);continue}a[a.length-1]+=p}n.trim!==!1&&(a=a.map((u)=>Xr(u)));let f=[...a.join(`
|
|
14
|
+
`)];for(let[u,p]of f.entries()){if(i+=p,ue.has(p)){let{groups:g}=new RegExp(`(?:\\${hi}(?<code>\\d+)m|\\${Qe}(?<uri>.*)${Xe})`).exec(f.slice(u).join(""))||{groups:{}};if(g.code!==void 0){let b=Number.parseFloat(g.code);r=b===jr?void 0:b}else g.uri!==void 0&&(s=g.uri.length===0?void 0:g.uri)}let d=Gr.codes.get(Number(r));f[u+1]===`
|
|
15
|
+
`?(s&&(i+=ii("")),r&&d&&(i+=ni(d))):p===`
|
|
16
|
+
`&&(r&&d&&(i+=ni(r)),s&&(i+=ii(s)))}return i},Kr,fe,Zr,ke,zr,Yr=(t,e,n)=>(e in t)?zr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,z=(t,e,n)=>(Yr(t,typeof e!="symbol"?e+"":e,n),n),Ve,Ir,Fr,Dr=(t,e,n)=>(e in t)?Fr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,ri=(t,e,n)=>(Dr(t,typeof e!="symbol"?e+"":e,n),n),mi,ts,es=(t,e,n)=>(e in t)?ts(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,si=(t,e,n)=>(es(t,typeof e!="symbol"?e+"":e,n),n),Ze,ze;var Ye=v(()=>{J=dt(qe(),1),fi=dt(Ge(),1);Nr=_r();pi={exports:{}};(function(t){var e={};t.exports=e,e.eastAsianWidth=function(i){var r=i.charCodeAt(0),s=i.length==2?i.charCodeAt(1):0,o=r;return 55296<=r&&r<=56319&&56320<=s&&s<=57343&&(r&=1023,s&=1023,o=r<<10|s,o+=65536),o==12288||65281<=o&&o<=65376||65504<=o&&o<=65510?"F":o==8361||65377<=o&&o<=65470||65474<=o&&o<=65479||65482<=o&&o<=65487||65490<=o&&o<=65495||65498<=o&&o<=65500||65512<=o&&o<=65518?"H":4352<=o&&o<=4447||4515<=o&&o<=4519||4602<=o&&o<=4607||9001<=o&&o<=9002||11904<=o&&o<=11929||11931<=o&&o<=12019||12032<=o&&o<=12245||12272<=o&&o<=12283||12289<=o&&o<=12350||12353<=o&&o<=12438||12441<=o&&o<=12543||12549<=o&&o<=12589||12593<=o&&o<=12686||12688<=o&&o<=12730||12736<=o&&o<=12771||12784<=o&&o<=12830||12832<=o&&o<=12871||12880<=o&&o<=13054||13056<=o&&o<=19903||19968<=o&&o<=42124||42128<=o&&o<=42182||43360<=o&&o<=43388||44032<=o&&o<=55203||55216<=o&&o<=55238||55243<=o&&o<=55291||63744<=o&&o<=64255||65040<=o&&o<=65049||65072<=o&&o<=65106||65108<=o&&o<=65126||65128<=o&&o<=65131||110592<=o&&o<=110593||127488<=o&&o<=127490||127504<=o&&o<=127546||127552<=o&&o<=127560||127568<=o&&o<=127569||131072<=o&&o<=194367||177984<=o&&o<=196605||196608<=o&&o<=262141?"W":32<=o&&o<=126||162<=o&&o<=163||165<=o&&o<=166||o==172||o==175||10214<=o&&o<=10221||10629<=o&&o<=10630?"Na":o==161||o==164||167<=o&&o<=168||o==170||173<=o&&o<=174||176<=o&&o<=180||182<=o&&o<=186||188<=o&&o<=191||o==198||o==208||215<=o&&o<=216||222<=o&&o<=225||o==230||232<=o&&o<=234||236<=o&&o<=237||o==240||242<=o&&o<=243||247<=o&&o<=250||o==252||o==254||o==257||o==273||o==275||o==283||294<=o&&o<=295||o==299||305<=o&&o<=307||o==312||319<=o&&o<=322||o==324||328<=o&&o<=331||o==333||338<=o&&o<=339||358<=o&&o<=359||o==363||o==462||o==464||o==466||o==468||o==470||o==472||o==474||o==476||o==593||o==609||o==708||o==711||713<=o&&o<=715||o==717||o==720||728<=o&&o<=731||o==733||o==735||768<=o&&o<=879||913<=o&&o<=929||931<=o&&o<=937||945<=o&&o<=961||963<=o&&o<=969||o==1025||1040<=o&&o<=1103||o==1105||o==8208||8211<=o&&o<=8214||8216<=o&&o<=8217||8220<=o&&o<=8221||8224<=o&&o<=8226||8228<=o&&o<=8231||o==8240||8242<=o&&o<=8243||o==8245||o==8251||o==8254||o==8308||o==8319||8321<=o&&o<=8324||o==8364||o==8451||o==8453||o==8457||o==8467||o==8470||8481<=o&&o<=8482||o==8486||o==8491||8531<=o&&o<=8532||8539<=o&&o<=8542||8544<=o&&o<=8555||8560<=o&&o<=8569||o==8585||8592<=o&&o<=8601||8632<=o&&o<=8633||o==8658||o==8660||o==8679||o==8704||8706<=o&&o<=8707||8711<=o&&o<=8712||o==8715||o==8719||o==8721||o==8725||o==8730||8733<=o&&o<=8736||o==8739||o==8741||8743<=o&&o<=8748||o==8750||8756<=o&&o<=8759||8764<=o&&o<=8765||o==8776||o==8780||o==8786||8800<=o&&o<=8801||8804<=o&&o<=8807||8810<=o&&o<=8811||8814<=o&&o<=8815||8834<=o&&o<=8835||8838<=o&&o<=8839||o==8853||o==8857||o==8869||o==8895||o==8978||9312<=o&&o<=9449||9451<=o&&o<=9547||9552<=o&&o<=9587||9600<=o&&o<=9615||9618<=o&&o<=9621||9632<=o&&o<=9633||9635<=o&&o<=9641||9650<=o&&o<=9651||9654<=o&&o<=9655||9660<=o&&o<=9661||9664<=o&&o<=9665||9670<=o&&o<=9672||o==9675||9678<=o&&o<=9681||9698<=o&&o<=9701||o==9711||9733<=o&&o<=9734||o==9737||9742<=o&&o<=9743||9748<=o&&o<=9749||o==9756||o==9758||o==9792||o==9794||9824<=o&&o<=9825||9827<=o&&o<=9829||9831<=o&&o<=9834||9836<=o&&o<=9837||o==9839||9886<=o&&o<=9887||9918<=o&&o<=9919||9924<=o&&o<=9933||9935<=o&&o<=9953||o==9955||9960<=o&&o<=9983||o==10045||o==10071||10102<=o&&o<=10111||11093<=o&&o<=11097||12872<=o&&o<=12879||57344<=o&&o<=63743||65024<=o&&o<=65039||o==65533||127232<=o&&o<=127242||127248<=o&&o<=127277||127280<=o&&o<=127337||127344<=o&&o<=127386||917760<=o&&o<=917999||983040<=o&&o<=1048573||1048576<=o&&o<=1114109?"A":"N"},e.characterLength=function(i){var r=this.eastAsianWidth(i);return r=="F"||r=="W"||r=="A"?2:1};function n(i){return i.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g)||[]}e.length=function(i){for(var r=n(i),s=0,o=0;o<r.length;o++)s=s+this.characterLength(r[o]);return s},e.slice=function(i,r,s){textLen=e.length(i),r=r||0,s=s||1,r<0&&(r=textLen+r),s<0&&(s=textLen+s);for(var o="",a=0,f=n(i),u=0;u<f.length;u++){var p=f[u],d=e.length(p);if(a>=r-(d==2?1:0))if(a+d<=s)o+=p;else break;a+=d}return o}})(pi);Sr=pi.exports,Mr=ci(Sr),Br=ci(Wr);_={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(_.modifier);Ur=Object.keys(_.color),qr=Object.keys(_.bgColor);[...Ur];Gr=Lr(),ue=new Set(["\x1B","\x9B"]),Qe=`${Jr}8;;`;Kr=["up","down","left","right","space","enter","cancel"],fe={actions:new Set(Kr),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]])};Zr=globalThis.process.platform.startsWith("win"),ke=Symbol("clack:cancel");zr=Object.defineProperty;Ve=class Ve extends kt{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(t){super(t,!1),this.value=!!t.initialValue,this.on("value",()=>{this.value=this._value}),this.on("confirm",(e)=>{this.output.write(J.cursor.move(0,-1)),this.value=e,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}};Ir=new WeakMap;Fr=Object.defineProperty,mi=class extends kt{constructor(t){super(t,!1),ri(this,"options"),ri(this,"cursor",0),this.options=t.options,this.value=[...t.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:e})=>e===t.cursorAt),0),this.on("key",(e)=>{e==="a"&&this.toggleAll()}),this.on("cursor",(e)=>{switch(e){case"left":case"up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case"down":case"right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break;case"space":this.toggleValue();break}})}get _value(){return this.options[this.cursor].value}toggleAll(){let t=this.value.length===this.options.length;this.value=t?[]:this.options.map((e)=>e.value)}toggleValue(){let t=this.value.includes(this._value);this.value=t?this.value.filter((e)=>e!==this._value):[...this.value,this._value]}},ts=Object.defineProperty;Ze=class Ze extends kt{constructor(t){super(t,!1),si(this,"options"),si(this,"cursor",0),this.options=t.options,this.cursor=this.options.findIndex(({value:e})=>e===t.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",(e)=>{switch(e){case"left":case"up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case"down":case"right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue()})}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value}};ze=class ze extends kt{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return`${this.value}\u2588`;let t=this.value.slice(0,this.cursor),[e,...n]=this.value.slice(this.cursor);return`${t}${fi.default.inverse(e)}${n.join("")}`}get cursor(){return this._cursor}constructor(t){super(t),this.on("finalize",()=>{this.value||(this.value=t.defaultValue)})}}});import et from"process";function ns(){return et.platform!=="win32"?et.env.TERM!=="linux":!!et.env.CI||!!et.env.WT_SESSION||!!et.env.TERMINUS_SUBLIME||et.env.ConEmuTask==="{cmd::Cmder}"||et.env.TERM_PROGRAM==="Terminus-Sublime"||et.env.TERM_PROGRAM==="vscode"||et.env.TERM==="xterm-256color"||et.env.TERM==="alacritty"||et.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var h,ce,Ie,U=(t,e)=>Ie?t:e,is,bi,wi,en,os,R,mt,Fe,De,rs,yi,ss,Xf,Qf,Kf,Vf,Zf,as,ls,fs,us,pe=(t)=>{switch(t){case"initial":case"active":return h.default.cyan(is);case"cancel":return h.default.red(bi);case"error":return h.default.yellow(wi);case"submit":return h.default.green(en)}},tn=(t)=>{let{cursor:e,options:n,style:i}=t,r=t.maxItems??Number.POSITIVE_INFINITY,s=Math.max(process.stdout.rows-4,0),o=Math.min(s,Math.max(r,5)),a=0;e>=a+o-3?a=Math.max(Math.min(e-o+3,n.length-o),0):e<a+2&&(a=Math.max(e-2,0));let f=o<n.length&&a>0,u=o<n.length&&a+o<n.length;return n.slice(a,a+o).map((p,d,g)=>{let b=d===0&&f,m=d===g.length-1&&u;return b||m?h.default.dim("..."):i(p,d+a===e)})},A=(t)=>new ze({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,render(){let e=`${h.default.gray(R)}
|
|
17
|
+
${pe(this.state)} ${t.message}
|
|
18
|
+
`,n=t.placeholder?h.default.inverse(t.placeholder[0])+h.default.dim(t.placeholder.slice(1)):h.default.inverse(h.default.hidden("_")),i=this.value?this.valueWithCursor:n;switch(this.state){case"error":return`${e.trim()}
|
|
19
|
+
${h.default.yellow(R)} ${i}
|
|
20
|
+
${h.default.yellow(mt)} ${h.default.yellow(this.error)}
|
|
21
|
+
`;case"submit":return`${e}${h.default.gray(R)} ${h.default.dim(this.value||t.placeholder)}`;case"cancel":return`${e}${h.default.gray(R)} ${h.default.strikethrough(h.default.dim(this.value??""))}${this.value?.trim()?`
|
|
22
|
+
${h.default.gray(R)}`:""}`;default:return`${e}${h.default.cyan(R)} ${i}
|
|
23
|
+
${h.default.cyan(mt)}
|
|
24
|
+
`}}}).prompt(),C=(t)=>{let e=t.active??"Yes",n=t.inactive??"No";return new Ve({active:e,inactive:n,initialValue:t.initialValue??!0,render(){let i=`${h.default.gray(R)}
|
|
25
|
+
${pe(this.state)} ${t.message}
|
|
26
|
+
`,r=this.value?e:n;switch(this.state){case"submit":return`${i}${h.default.gray(R)} ${h.default.dim(r)}`;case"cancel":return`${i}${h.default.gray(R)} ${h.default.strikethrough(h.default.dim(r))}
|
|
27
|
+
${h.default.gray(R)}`;default:return`${i}${h.default.cyan(R)} ${this.value?`${h.default.green(Fe)} ${e}`:`${h.default.dim(De)} ${h.default.dim(e)}`} ${h.default.dim("/")} ${this.value?`${h.default.dim(De)} ${h.default.dim(n)}`:`${h.default.green(Fe)} ${n}`}
|
|
28
|
+
${h.default.cyan(mt)}
|
|
29
|
+
`}}}).prompt()},K=(t)=>{let e=(n,i)=>{let r=n.label??String(n.value);switch(i){case"selected":return`${h.default.dim(r)}`;case"active":return`${h.default.green(Fe)} ${r} ${n.hint?h.default.dim(`(${n.hint})`):""}`;case"cancelled":return`${h.default.strikethrough(h.default.dim(r))}`;default:return`${h.default.dim(De)} ${h.default.dim(r)}`}};return new Ze({options:t.options,initialValue:t.initialValue,render(){let n=`${h.default.gray(R)}
|
|
30
|
+
${pe(this.state)} ${t.message}
|
|
31
|
+
`;switch(this.state){case"submit":return`${n}${h.default.gray(R)} ${e(this.options[this.cursor],"selected")}`;case"cancel":return`${n}${h.default.gray(R)} ${e(this.options[this.cursor],"cancelled")}
|
|
32
|
+
${h.default.gray(R)}`;default:return`${n}${h.default.cyan(R)} ${tn({cursor:this.cursor,options:this.options,maxItems:t.maxItems,style:(i,r)=>e(i,r?"active":"inactive")}).join(`
|
|
33
|
+
${h.default.cyan(R)} `)}
|
|
34
|
+
${h.default.cyan(mt)}
|
|
35
|
+
`}}}).prompt()},xi=(t)=>{let e=(n,i)=>{let r=n.label??String(n.value);return i==="active"?`${h.default.cyan(rs)} ${r} ${n.hint?h.default.dim(`(${n.hint})`):""}`:i==="selected"?`${h.default.green(yi)} ${h.default.dim(r)} ${n.hint?h.default.dim(`(${n.hint})`):""}`:i==="cancelled"?`${h.default.strikethrough(h.default.dim(r))}`:i==="active-selected"?`${h.default.green(yi)} ${r} ${n.hint?h.default.dim(`(${n.hint})`):""}`:i==="submitted"?`${h.default.dim(r)}`:`${h.default.dim(ss)} ${h.default.dim(r)}`};return new mi({options:t.options,initialValues:t.initialValues,required:t.required??!0,cursorAt:t.cursorAt,validate(n){if(this.required&&n.length===0)return`Please select at least one option.
|
|
36
|
+
${h.default.reset(h.default.dim(`Press ${h.default.gray(h.default.bgWhite(h.default.inverse(" space ")))} to select, ${h.default.gray(h.default.bgWhite(h.default.inverse(" enter ")))} to submit`))}`},render(){let n=`${h.default.gray(R)}
|
|
37
|
+
${pe(this.state)} ${t.message}
|
|
38
|
+
`,i=(r,s)=>{let o=this.value.includes(r.value);return s&&o?e(r,"active-selected"):o?e(r,"selected"):e(r,s?"active":"inactive")};switch(this.state){case"submit":return`${n}${h.default.gray(R)} ${this.options.filter(({value:r})=>this.value.includes(r)).map((r)=>e(r,"submitted")).join(h.default.dim(", "))||h.default.dim("none")}`;case"cancel":{let r=this.options.filter(({value:s})=>this.value.includes(s)).map((s)=>e(s,"cancelled")).join(h.default.dim(", "));return`${n}${h.default.gray(R)} ${r.trim()?`${r}
|
|
39
|
+
${h.default.gray(R)}`:""}`}case"error":{let r=this.error.split(`
|
|
40
|
+
`).map((s,o)=>o===0?`${h.default.yellow(mt)} ${h.default.yellow(s)}`:` ${s}`).join(`
|
|
41
|
+
`);return`${n+h.default.yellow(R)} ${tn({options:this.options,cursor:this.cursor,maxItems:t.maxItems,style:i}).join(`
|
|
42
|
+
${h.default.yellow(R)} `)}
|
|
43
|
+
${r}
|
|
44
|
+
`}default:return`${n}${h.default.cyan(R)} ${tn({options:this.options,cursor:this.cursor,maxItems:t.maxItems,style:i}).join(`
|
|
45
|
+
${h.default.cyan(R)} `)}
|
|
46
|
+
${h.default.cyan(mt)}
|
|
47
|
+
`}}}).prompt()},nn=(t="")=>{process.stdout.write(`${h.default.gray(mt)} ${h.default.red(t)}
|
|
48
|
+
|
|
49
|
+
`)},he=(t="")=>{process.stdout.write(`${h.default.gray(os)} ${t}
|
|
50
|
+
`)},at=(t="")=>{process.stdout.write(`${h.default.gray(R)}
|
|
51
|
+
${h.default.gray(mt)} ${t}
|
|
52
|
+
|
|
53
|
+
`)},l,zf,T=({indicator:t="dots"}={})=>{let e=Ie?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],n=Ie?80:120,i=process.env.CI==="true",r,s,o=!1,a="",f,u=performance.now(),p=(H)=>{let W=H>1?"Something went wrong":"Canceled";o&&D(W,H)},d=()=>p(2),g=()=>p(1),b=()=>{process.on("uncaughtExceptionMonitor",d),process.on("unhandledRejection",d),process.on("SIGINT",g),process.on("SIGTERM",g),process.on("exit",p)},m=()=>{process.removeListener("uncaughtExceptionMonitor",d),process.removeListener("unhandledRejection",d),process.removeListener("SIGINT",g),process.removeListener("SIGTERM",g),process.removeListener("exit",p)},x=()=>{if(f===void 0)return;i&&process.stdout.write(`
|
|
54
|
+
`);let H=f.split(`
|
|
55
|
+
`);process.stdout.write(ce.cursor.move(-999,H.length-1)),process.stdout.write(ce.erase.down(H.length))},M=(H)=>H.replace(/\.+$/,""),Q=(H)=>{let W=(performance.now()-H)/1000,Z=Math.floor(W/60),ut=Math.floor(W%60);return Z>0?`[${Z}m ${ut}s]`:`[${ut}s]`},E=(H="")=>{o=!0,r=gi(),a=M(H),u=performance.now(),process.stdout.write(`${h.default.gray(R)}
|
|
56
|
+
`);let W=0,Z=0;b(),s=setInterval(()=>{if(i&&a===f)return;x(),f=a;let ut=h.default.magenta(e[W]);if(i)process.stdout.write(`${ut} ${a}...`);else if(t==="timer")process.stdout.write(`${ut} ${a} ${Q(u)}`);else{let At=".".repeat(Math.floor(Z)).slice(0,3);process.stdout.write(`${ut} ${a}${At}`)}W=W+1<e.length?W+1:0,Z=Z<e.length?Z+0.125:0},n)},D=(H="",W=0)=>{o=!1,clearInterval(s),x();let Z=W===0?h.default.green(en):W===1?h.default.red(bi):h.default.red(wi);a=M(H??a),t==="timer"?process.stdout.write(`${Z} ${a} ${Q(u)}
|
|
57
|
+
`):process.stdout.write(`${Z} ${a}
|
|
58
|
+
`),m(),r()};return{start:E,stop:D,message:(H="")=>{a=M(H??a)}}},$i=async(t,e)=>{let n={},i=Object.keys(t);for(let r of i){let s=t[r],o=await s({results:n})?.catch((a)=>{throw a});if(typeof e?.onCancel=="function"&&k(o)){n[r]="canceled",e.onCancel({results:n});continue}n[r]=o}return n};var q=v(()=>{Ye();Ye();h=dt(Ge(),1),ce=dt(qe(),1);Ie=ns(),is=U("\u25C6","*"),bi=U("\u25A0","x"),wi=U("\u25B2","x"),en=U("\u25C7","o"),os=U("\u250C","T"),R=U("\u2502","|"),mt=U("\u2514","\u2014"),Fe=U("\u25CF",">"),De=U("\u25CB"," "),rs=U("\u25FB","[\u2022]"),yi=U("\u25FC","[+]"),ss=U("\u25FB","[ ]"),Xf=U("\u25AA","\u2022"),Qf=U("\u2500","-"),Kf=U("\u256E","+"),Vf=U("\u251C","+"),Zf=U("\u256F","+"),as=U("\u25CF","\u2022"),ls=U("\u25C6","*"),fs=U("\u25B2","!"),us=U("\u25A0","x"),l={message:(t="",{symbol:e=h.default.gray(R)}={})=>{let n=[`${h.default.gray(R)}`];if(t){let[i,...r]=t.split(`
|
|
59
|
+
`);n.push(`${e} ${i}`,...r.map((s)=>`${h.default.gray(R)} ${s}`))}process.stdout.write(`${n.join(`
|
|
42
60
|
`)}
|
|
43
|
-
`)},info:(
|
|
44
|
-
`);let
|
|
45
|
-
`);
|
|
46
|
-
`);let
|
|
47
|
-
`):process.stdout.write(`${v} ${f}
|
|
48
|
-
`),g(),i()};return{start:y,stop:B,message:(E="")=>{f=L(E??f)}}},It=async(n,o)=>{let r={},e=Object.keys(n);for(let i of e){let s=n[i],t=await s({results:r})?.catch((f)=>{throw f});if(typeof o?.onCancel=="function"&&U(t)){r[i]="canceled",o.onCancel({results:r});continue}r[i]=t}return r};var dr=!process.env.NO_COLOR&&(process.env.FORCE_COLOR||process.stdout.isTTY),gr=["blue","cyan","gray","green","magenta","red","white","yellow"],hr=["bold","dim","italic","underline","reset"],zt={bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",reset:"\x1B[0m",underline:"\x1B[4m"},br={"\x1B[30m":"\x1B[90m","\x1B[31m":"\x1B[91m","\x1B[32m":"\x1B[92m","\x1B[33m":"\x1B[93m","\x1B[34m":"\x1B[94m","\x1B[35m":"\x1B[95m","\x1B[36m":"\x1B[96m","\x1B[37m":"\x1B[97m"};function st(n){return(o)=>dr?`${n}${o}${zt.reset}`:o}function Kt({bright:n=!1,color:o}){let r=Bun.color(o,"ansi");if(!r)return"";return n?br[r]||r:r}var yr=gr.reduce((n,o)=>{return n[o]=st(Kt({color:o})),n[`${o}Bright`]=st(Kt({bright:!0,color:o})),n},{}),wr=hr.reduce((n,o)=>{return n[o]=st(zt[o]),n},{}),w={...yr,...wr};var x=({prefix:n="",level:o=process.env.DEBUG?0:1}={})=>{function r(...f){if(o<=0){let a=f.join(" ");console.log(An({level:w.dim("DEBUG"),message:a,prefix:n}))}}function e(...f){if(o<=1){let a=f.join(" ");console.info(An({level:w.cyan("INFO "),message:a,prefix:n}))}}function i(...f){if(o<=2){let a=f.join(" ");console.warn(An({level:w.yellow("WARN "),message:a,prefix:n}))}}function s(...f){if(o<=3){let a=f.join(" ");console.error(An({level:w.red("ERROR"),message:a,prefix:n}))}}function t(f){return x({level:o,prefix:`${n}:${f}`})}return{child:t,debug:r,error:s,info:e,warn:i}},ft=x();function An({prefix:n,level:o,message:r}){let e=new Date().toISOString().split("T")[1]?.split(".")[0]||"",i=n?`[${n}] `:"";return`${w.dim(e||"")} ${o} ${i}${r}`}var p={arrow:w.yellow,bold:w.bold,boolean:w.cyan,bullet:w.yellow,busy:w.yellow,command:w.green,dim:w.dim,error:w.red,flag:w.yellow,info:w.cyan,number:w.magenta,offline:w.red,online:w.green,separator:w.dim,string:w.green,success:w.green,value:w.cyan,warning:w.yellow};var Ai=x({prefix:"cli-core"}).child("error");var j=new Uint32Array(65536),xr=(n,o)=>{let r=n.length,e=o.length,i=1<<r-1,s=-1,t=0,f=r,a=r;while(a--)j[n.charCodeAt(a)]|=1<<a;for(a=0;a<e;a++){let c=j[o.charCodeAt(a)],m=c|t;if(c|=(c&s)+s^s,t|=~(c|s),s&=c,t&i)f++;if(s&i)f--;t=t<<1|1,s=s<<1|~(m|t),t&=m}a=r;while(a--)j[n.charCodeAt(a)]=0;return f},$r=(n,o)=>{let r=o.length,e=n.length,i=[],s=[],t=Math.ceil(r/32),f=Math.ceil(e/32);for(let g=0;g<t;g++)s[g]=-1,i[g]=0;let a=0;for(;a<f-1;a++){let g=0,$=-1,L=a*32,_=Math.min(32,e)+L;for(let y=L;y<_;y++)j[n.charCodeAt(y)]|=1<<y;for(let y=0;y<r;y++){let B=j[o.charCodeAt(y)],E=s[y/32|0]>>>y&1,R=i[y/32|0]>>>y&1,v=B|g,Y=((B|R)&$)+$^$|B|R,D=g|~(Y|$),xn=$&Y;if(D>>>31^E)s[y/32|0]^=1<<y;if(xn>>>31^R)i[y/32|0]^=1<<y;D=D<<1|E,xn=xn<<1|R,$=xn|~(v|D),g=D&v}for(let y=L;y<_;y++)j[n.charCodeAt(y)]=0}let c=0,m=-1,l=a*32,u=Math.min(32,e-l)+l;for(let g=l;g<u;g++)j[n.charCodeAt(g)]|=1<<g;let b=e;for(let g=0;g<r;g++){let $=j[o.charCodeAt(g)],L=s[g/32|0]>>>g&1,_=i[g/32|0]>>>g&1,y=$|c,B=(($|_)&m)+m^m|$|_,E=c|~(B|m),R=m&B;if(b+=E>>>e-1&1,b-=R>>>e-1&1,E>>>31^L)s[g/32|0]^=1<<g;if(R>>>31^_)i[g/32|0]^=1<<g;E=E<<1|L,R=R<<1|_,m=R|~(y|E),c=E&y}for(let g=l;g<u;g++)j[n.charCodeAt(g)]=0;return b},kt=(n,o)=>{if(n.length<o.length){let r=o;o=n,n=r}if(o.length===0)return n.length;if(n.length<=32)return xr(n,o);return $r(n,o)};function Jt(n,o,r=3){return o.map((s)=>({distance:kt(n.toLowerCase(),s.toLowerCase()),option:s})).filter(({distance:s})=>s<=Math.max(3,n.length/2)).sort((s,t)=>s.distance-t.distance).slice(0,r).map(({option:s})=>s)}function Yt(n,o){return o[n.toLowerCase()]||null}var jt=x({prefix:"cli-core"}).child("graceful");async function an(n,o={}){let{fallback:r,logLevel:e="warn",message:i="Operation failed gracefully"}=o;try{return await n()}catch(s){let t=s instanceof Error?s.message:String(s);if(jt[e](`${i}: ${t}`),r)try{await r()}catch(f){jt.error(`Fallback also failed: ${f instanceof Error?f.message:String(f)}`)}return}}var Er={backoffMultiplier:2,initialDelay:1000,maxAttempts:3,maxDelay:30000,onRetry:(n,o)=>{ft.warn(`Retry attempt ${n}: ${o.message}`)},retryableErrors:["ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENOTFOUND","rate limit","429","503","502","504","npm ERR!","EPUBLISHCONFLICT"]};async function Z(n,o={}){let r={...Er,...o},e=new Error("Operation failed");for(let i=1;i<=r.maxAttempts;i++)try{return await n()}catch(s){if(e=s instanceof Error?s:new Error(String(s)),!r.retryableErrors.some((a)=>e.message.toLowerCase().includes(a.toLowerCase()))||i===r.maxAttempts)throw e;r.onRetry(i,e);let f=Math.min(r.initialDelay*r.backoffMultiplier**(i-1),r.maxDelay);await new Promise((a)=>setTimeout(a,f))}throw e}var k=(n)=>{return n.map=(o)=>k((r)=>o(n(r))),n.or=(o)=>k((r)=>{try{return n(r)}catch(e){return o(r)}}),n},Xn=()=>"bad banditype"();var Zt=(n)=>k((o)=>n.includes(o)?o:Xn()),_n=(n)=>k((o)=>typeof o===typeof n?o:Xn()),gn=()=>_n(""),Qt=()=>_n(0),Vt=()=>_n(!0);var Ft=()=>_n();var Dt=(n)=>k((o)=>o instanceof n?o:Xn()),at=(n)=>Dt(Object).map((o)=>{let r={};for(let e in o){let i=n(o[e]);i!==void 0&&(r[e]=i)}return r}),cn=(n)=>Dt(Object).map((o)=>{let r={};for(let e in n){let i=n[e](o[e]);i!==void 0&&(r[e]=i)}return r});function Or(n,o){return k((r)=>{try{return n(r)}catch{try{return o(r)}catch{throw new Error("No matching schema in union")}}})}function nn(n,o){return(r)=>{if(r===void 0)return o;return n(r)}}function no(){return k((n)=>{let o=Qt()(n);if(!Number.isInteger(o)||o<=0)throw new Error("Must be a positive integer");return o})}function to(){return k((n)=>{let o=gn()(n);try{return new URL(o),o}catch{throw new Error("Must be a valid URL")}})}function oo(n,o){return k((r)=>{let e=gn()(r);if(!n.test(e))throw new Error(o||`Must match pattern ${n}`);return e})}function hn(n){return{parse(o){try{return n(o)}catch(r){throw new Error(r instanceof Error?r.message:"Validation failed")}},safeParse(o){try{return{data:n(o),success:!0}}catch(r){return{error:r instanceof Error?r:new Error("Validation failed"),success:!1}}},validator:n}}function tn(){return Or(Ft(),gn())}function on(n){return nn(gn(),n)}function mn(n){return nn(Vt(),n)}function Un(n,o){return nn(Zt(n),o)}import{existsSync as V}from"fs";import{copyFile as Ar,mkdir as ln,readdir as mt}from"fs/promises";import{join as T,resolve as Xr}from"path";import{parseArgs as _r}from"util";var{$:pn}=globalThis.Bun;import{join as so}from"path";var{$:io}=globalThis.Bun;import{tmpdir as Rr}from"os";var ro={MACHINES_DIR:"machines",TEMP_DIR:Rr()};var Sr=cn({directory:on("./gh-runners"),labels:tn(),name:on("runner"),numberOfMachines:nn(no(),1),os:Un(["osx","linux","windows"],"osx"),overwrite:mn(!1),run:mn(!1),runnerGroup:tn(),url:tn()}),Tr=hn(Sr),eo=hn(cn({defaultProfile:tn(),profiles:at(Tr.validator)}));var Lr=["hydra.json",".hydra.json","hydra.toml",".hydra.toml"];async function Nr(n=process.cwd()){for(let o of Lr){let r=so(n,o);if(await Bun.file(r).exists())return r}return null}async function A(n){let o=n?.configPath||await Nr();if(!o)return null;let r=Bun.file(o);if(!await r.exists())return null;try{let e=await r.text(),i=o.endsWith(".toml")?await Gr(e):JSON.parse(e);return eo.parse(i)}catch(e){if(e instanceof Error)throw new Error(`Invalid config file: ${e.message}`);throw e}}async function X(n,o){if(!n)return null;let r=o||n.defaultProfile;if(!r)return null;return n.profiles[r]||null}async function Gr(n){let o=so(ro.TEMP_DIR,`hydra-config-${Date.now()}.toml`);await Bun.write(o,n);try{let r=await import(o);return await io`rm -f ${o}`.quiet(),r.default}catch(r){throw await io`rm -f ${o}`.quiet(),new Error(`Failed to parse TOML configuration: ${r}`)}}var Ur=x({prefix:"hydra"}).child("backup");async function qr(){let{values:n}=_r({allowPositionals:!0,args:Bun.argv,options:{compress:{default:!0,type:"boolean"},config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},list:{default:!1,short:"l",type:"boolean"},output:{short:"o",type:"string"},profile:{short:"p",type:"string"},restore:{short:"r",type:"string"}},strict:!0}),o=await A({configPath:n.config}),r=await X(o,n.profile);return{compress:n.compress,directory:n.directory||r?.directory||`${process.cwd()}/gh-runners`,list:n.list,output:n.output,restore:n.restore}}async function fo(){try{let n=await qr();if(n.list){await vr(n.output||T(n.directory,"backups"));return}if(n.restore){await Hr(n);return}await Cr(n)}catch(n){Ur.error("Backup operation failed:",n),process.exit(1)}}async function Cr(n){let o=Xr(n.directory),r=T(o,"machines");if(!V(r)){h.error(`No runners found in ${n.directory}`);return}let e=W();e.start("Creating backup...");try{let i=await mt(r);if(i.length===0){e.stop("No runners to backup");return}let s=`backup-${new Date().toISOString().replace(/[:.]/g,"-")}`,t=n.output||T(o,"backups"),f=T(t,s);await ln(f,{recursive:!0});let a=0,c=[];for(let l of i){let u=T(r,l),b=T(f,"runners",l);await ln(b,{recursive:!0});let g=[".runner",".credentials",".credentials_rsaparams",".path",".env","config.sh"];for(let $ of g){let L=T(u,$);if(V(L)){let _=T(b,$);await Ar(L,_);let y=await Bun.file(L).stat();a+=y.size,c.push(`runners/${l}/${$}`)}}}let m={configFiles:c,date:new Date,id:s,runnerCount:i.length,size:a};if(await Bun.write(T(f,"metadata.json"),JSON.stringify(m,null,2)),n.compress){e.message("Compressing backup..."),await pn`cd ${t} && tar -czf ${s}.tar.gz ${s}`.quiet(),await pn`rm -rf ${f}`.quiet();let l=await Bun.file(T(t,`${s}.tar.gz`)).stat();e.stop(`Backup created: ${s}.tar.gz (${ct(l.size)})`)}else e.stop(`Backup created: ${s} (${ct(a)})`);h.success(`Backed up ${i.length} runner(s)`)}catch(i){throw e.stop("Backup failed"),i}}async function vr(n){if(!V(n)){h.info("No backups found");return}let o=W();o.start("Scanning backups...");try{let r=await mt(n),e=[];for(let i of r){let s=T(n,i);if(i.endsWith(".tar.gz")){let t=i.replace(".tar.gz",""),f=await Bun.file(s).stat();e.push({configFiles:[],date:new Date(f.mtime),id:t,runnerCount:0,size:f.size})}else{let t=T(s,"metadata.json");if(V(t)){let f=await Bun.file(t).json();e.push(f)}}}if(o.stop("Found backups"),e.length===0){h.info("No backups found");return}console.log(),console.log(p.bold("\uD83D\uDCE6 Available Backups")),console.log("\u2500".repeat(80));for(let i of e.sort((s,t)=>new Date(t.date).getTime()-new Date(s.date).getTime())){let s=new Date(i.date).toLocaleString(),t=ct(i.size),f=i.runnerCount>0?`${i.runnerCount} runners`:"compressed";console.log(`${p.value(i.id)}`),console.log(` Date: ${s}`),console.log(` Size: ${t}`),console.log(` Content: ${f}`),console.log()}}catch(r){throw o.stop("Failed to list backups"),r}}async function Hr(n){let o=n.output||T(n.directory,"backups"),r=T(o,n.restore),e=`${r}.tar.gz`,i=V(e),s=V(r);if(!i&&!s){h.error(`Backup not found: ${n.restore}`);return}if(!await C({initialValue:!1,message:"This will overwrite existing runner configurations. Continue?"})){h.info("Restore cancelled");return}let f=W();f.start("Restoring backup...");try{let a=r;if(i){f.message("Extracting backup...");let g=T(o,`temp-${Date.now()}`);await ln(g,{recursive:!0}),await pn`cd ${g} && tar -xzf ${e}`.quiet(),a=T(g,n.restore)}let c=T(a,"metadata.json");if(!V(c))throw new Error("Invalid backup: metadata.json not found");await Bun.file(c).json();let m=T(a,"runners"),l=T(n.directory,"machines");await ln(l,{recursive:!0});let u=await mt(m),b=0;for(let g of u){let $=T(m,g),L=T(l,g);if(V(L)){let _=await Gn({message:`Runner ${g} already exists. What should we do?`,options:[{label:"Skip",value:"skip"},{label:"Overwrite",value:"overwrite"},{label:"Rename",value:"rename"}]});if(_==="skip")continue;else if(_==="rename"){let y=await q({message:"Enter new runner name:",placeholder:`${g}-restored`});if(!y)continue;let B=T(l,y);await ln(B,{recursive:!0}),await pn`cp -r ${$}/* ${B}/`.quiet(),b++;continue}}await ln(L,{recursive:!0}),await pn`cp -r ${$}/* ${L}/`.quiet(),b++}if(i){let g=a.replace(`/${n.restore}`,"");await pn`rm -rf ${g}`.quiet()}f.stop("Restore completed"),h.success(`Restored ${b} runner(s) from backup ${n.restore}`)}catch(a){throw f.stop("Restore failed"),a}}function ct(n){if(n<1024)return`${n}B`;if(n<1048576)return`${(n/1024).toFixed(1)}KB`;if(n<1073741824)return`${(n/1048576).toFixed(1)}MB`;return`${(n/1073741824).toFixed(2)}GB`}import{parseArgs as Kr}from"util";var{$:I}=globalThis.Bun;function bn(){let n=import.meta.path,o=n.substring(0,n.lastIndexOf("/"));return o.substring(0,o.lastIndexOf("/"))}var Pr=cn({directory:on(`${process.cwd()}/gh-runners`),labels:tn(),name:on("runner"),numberOfMachines:nn(oo(/^\d+$/,"Number of machines must be a positive integer"),"1"),os:Un(["osx","linux","windows"],"osx"),overwrite:mn(!1),run:mn(!1),token:on(process.env.GITHUB_PERSONAL_ACCESS_TOKEN??""),url:to()}),Os=hn(Pr);var rn=x({prefix:"WorkerManager"}),P=new Set,ao=!1;function Mr(){if(ao)return;ao=!0;let n=()=>{if(P.size>0)rn.info("Cleaning up workers...");co()};process.on("exit",n),process.on("SIGINT",n),process.on("SIGTERM",n),process.on("uncaughtException",(o)=>{rn.error("Uncaught exception:",o),n(),process.exit(1)})}function Br(n){P.add(n),rn.debug(`Worker added. Total workers: ${P.size}`),n.addEventListener("exit",()=>{P.delete(n),rn.debug(`Worker exited. Remaining workers: ${P.size}`)})}function Wr(n){if(P.has(n))n.terminate(),P.delete(n),rn.debug(`Worker removed. Remaining workers: ${P.size}`)}function co(){if(P.size>0){rn.info(`Terminating ${P.size} workers...`);for(let n of P)try{n.terminate()}catch(o){rn.error("Failed to terminate worker:",o)}P.clear()}}function Ir(){return P.size}Mr();var qn={add:Br,remove:Wr,get size(){return Ir()},terminateAll:co};var M=x({prefix:"createMachines"});async function Cn(){let n=await kr(),{overwrite:o,directory:r,numberOfMachines:e,os:i,run:s,name:t,labels:f,runnerGroup:a}=n,{token:c,url:m}=n;if(!m)throw new Error("URL (-u) parameter is required");if(!c){let b=zr(m),g=await C({message:`No token provided. Would you like to open GitHub to get a runner token?
|
|
49
|
-
${b}`});if(U(g)||!g)throw new Error("Token is required to create runners");M.info("Opening GitHub runner settings..."),await I`open ${b}`.quiet();let $=await q({message:"Enter the runner registration token:",placeholder:"AXXXXXXXXXXXXXXXXXXXXXXXXX",validate:(L)=>{if(!L||L.trim().length===0)return"Token is required";return}});if(U($))throw new Error("Token is required to create runners");c=$.trim()}if(M.info(`Creating ${e} runners in ${r}`),M.debug(`OS: ${i}, Name: ${t}, Labels: ${f||"none"}`),await Bun.file(r).exists())if(o)M.warn(`Directory ${r} exists, removing...`),await I`rm -rf ${r}`;else throw new Error(`Directory ${r} already exists`);let u=await Jr({directory:r,os:i});if(await Yr({directory:r,numberOfMachines:e,overwrite:o,runnerBase:u}),!s){M.info("Runners created but not started");return}jr({directory:r,labels:f,name:t,numberOfMachines:e,runnerGroup:a,token:c,url:m})}function zr(n){try{let o=new URL(n),r=o.pathname.split("/").filter(Boolean);if(o.hostname==="github.com"||o.hostname==="www.github.com"){if(r[0]==="orgs"&&r[1])return`https://github.com/organizations/${r[1]}/settings/actions/runners/new`;else if(r.length>=2)return`https://github.com/${r[0]}/${r[1]}/settings/actions/runners/new`}else if(r[0]==="orgs"&&r[1])return`${o.origin}/organizations/${r[1]}/settings/actions/runners/new`;else if(r.length>=2)return`${o.origin}/${r[0]}/${r[1]}/settings/actions/runners/new`;return n}catch{return n}}async function kr(){let{values:n}=Kr({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},labels:{short:"l",type:"string"},name:{default:"runner",short:"n",type:"string"},numberOfMachines:{default:"1",short:"m",type:"string"},os:{default:"osx",short:"s",type:"string"},overwrite:{default:!1,short:"f",type:"boolean"},profile:{short:"p",type:"string"},run:{default:!1,short:"r",type:"boolean"},runnerGroup:{short:"g",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),o=await A({configPath:n.config}),r=await X(o,n.profile),e={directory:n.directory,labels:n.labels,name:n.name,numberOfMachines:n.numberOfMachines,os:n.os,overwrite:n.overwrite,run:n.run,runnerGroup:n.runnerGroup,token:n.token,url:n.url};if(r)return{directory:e.directory??r.directory??`${process.cwd()}/gh-runners`,labels:e.labels??r.labels,name:e.name??r.name??"runner",numberOfMachines:e.numberOfMachines??String(r.numberOfMachines)??"1",os:e.os??r.os??"osx",overwrite:e.overwrite??r.overwrite??!1,run:e.run??r.run??!1,runnerGroup:e.runnerGroup??r.runnerGroup,token:e.token,url:e.url??r.url};return{directory:e.directory,labels:e.labels,name:e.name,numberOfMachines:e.numberOfMachines,os:e.os,overwrite:e.overwrite,run:e.run,runnerGroup:e.runnerGroup,token:e.token,url:e.url}}async function Jr({directory:n,os:o}){let r=M.child("download");r.info(`Fetching latest runner version for ${o}...`);let e=await Z(async()=>(await I`curl -Ls -o /dev/null -w "%{url_effective}" https://github.com/actions/runner/releases/latest`).text(),{onRetry:(c,m)=>{r.warn(`Retrying GitHub API call (attempt ${c}): ${m.message}`)}}),s=(await I`basename ${e}`).text().trim().replace("v",""),t=`actions-runner-${o}-x64-${s}.tar.gz`,f=`https://github.com/actions/runner/releases/download/v${s}/${t}`;if(r.debug(`Runner version: ${s}`),r.debug(`Download URL: ${f}`),await I`mkdir -p ${n}`,await I`mkdir -p ${n}/machines`,!await Bun.file(`${n}/${t}`).exists())r.info("Downloading runner image..."),await Z(async()=>await I`curl -o ${n}/${t} -L ${f}`,{maxAttempts:5,onRetry:(c,m)=>{r.warn(`Retrying runner download (attempt ${c}): ${m.message}`)}}),r.info("Download complete");else r.info("Runner image already exists, skipping download");return t}async function Yr({overwrite:n,numberOfMachines:o,directory:r,runnerBase:e}){let i=M.child("extract"),s=Number(o),t=(()=>{try{let m=Bun.spawnSync(["nproc"]);return Number.parseInt(m.stdout.toString().trim(),10)||4}catch{try{let m=Bun.spawnSync(["sysctl","-n","hw.ncpu"]);return Number.parseInt(m.stdout.toString().trim(),10)||4}catch{return 4}}})(),f=Math.min(Math.max(2,Math.floor(t/2)),s,8);i.info(`Extracting ${s} runners with concurrency of ${f}`);let a=Array.from({length:s},(m,l)=>l+1).map((m)=>({execute:async()=>{let l=`${r}/machines/${m}`;if(await Bun.file(l).exists())if(n)i.debug(`Machine ${m} already exists, removing...`),await I`rm -rf ${l}`;else{i.debug(`Machine ${m} already exists, skipping...`);return}await I`mkdir -p ${l}`,await I`tar xzf ${e} -C ${l.replace(`${r}/`,"")}`.cwd(r);let b=`${bn()}/src/runner`;await I`cp -R ${b}/hooks ${l}`,await I`cp -R ${b}/.runner-env ${l}/.runner-env`,i.debug(`Machine ${m} extracted successfully`)},runnerIndex:m})),c=[];for(let m=0;m<a.length;m+=f){let l=a.slice(m,m+f),u=await Promise.allSettled(l.map((b)=>b.execute()));for(let[b,g]of u.entries())if(g.status==="rejected")throw i.error(`Failed to extract runner ${l[b]?.runnerIndex}: ${g.reason}`),g.reason;c.push(...u)}i.info(`Successfully extracted ${s} runners`)}function jr({directory:n,numberOfMachines:o,token:r,url:e,name:i,labels:s,runnerGroup:t}){M.info(`Starting ${o} runners...`);for(let f=1;f<=Number(o);f++){let a=`${bn()}/src/runner-worker.ts`,c=`${i}-${f}`,m=new Worker(a,{name:c,ref:!0});m.addEventListener("open",()=>{M.info(`Worker ${c} started`),m.postMessage({index:f,labels:s,machineCwd:`${n}/machines/${f}`,name:i,runnerGroup:t,token:r,url:e})}),m.addEventListener("message",({data:l})=>{let u=l.type==="error"?"error":"info";M[u](`${c}: ${l.message}`)}),m.addEventListener("error",(l)=>{M.error(`Worker ${c} error:`,l)}),m.addEventListener("exit",(l)=>{M.info(`Worker ${c} exited with code ${l}`)}),qn.add(m)}M.info("All workers started. Press Ctrl+C to stop all machines")}import{existsSync as yn}from"fs";import{readdir as mo}from"fs/promises";import{join as F,resolve as Zr}from"path";import{parseArgs as Qr}from"util";var{$:lt}=globalThis.Bun;var Vr=x({prefix:"hydra"}).child("health");async function Fr(){let{values:n}=Qr({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},fix:{default:!1,short:"f",type:"boolean"},json:{default:!1,short:"j",type:"boolean"},profile:{short:"p",type:"string"},runner:{short:"r",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),o=await A({configPath:n.config}),r=await X(o,n.profile);return{directory:n.directory||r?.directory||`${process.cwd()}/gh-runners`,fix:n.fix,json:n.json,runner:n.runner,token:n.token,url:n.url||r?.url}}async function lo(){try{let n=await Fr(),o=Zr(n.directory),r=F(o,"machines");if(!yn(r)){h.error(`No runners found in ${n.directory}`);return}let e=W();e.start("Performing health checks...");let i=await mo(r),s=[];for(let t of i){if(n.runner&&t!==n.runner)continue;let f=F(r,t),a=await Dr(t,f,n);s.push(a)}if(e.stop("Health checks completed"),n.json){console.log(JSON.stringify(s,null,2));return}if(re(s),n.fix)await ee(s,n)}catch(n){Vr.error("Failed to perform health checks:",n),process.exit(1)}}async function Dr(n,o,r){let e=[],i={configuration:!1,connectivity:!1,disk:{percentage:0,total:0,used:0},lastActivity:null,process:!1};try{let t=F(o,".runner");if(yn(t)){let f=await Bun.file(t).text(),a=await ne(f.trim());if(i.process=a,!a)e.push("Runner process is not running")}else e.push("No PID file found")}catch{e.push("Could not check process status")}try{let t=await te(o);if(i.disk=t,t.percentage>90)e.push(`Low disk space: ${t.percentage.toFixed(1)}% used`)}catch{e.push("Could not check disk space")}try{let t=F(o,"_diag");if(yn(t)){let f=await mo(t),a=null;for(let c of f)if(c.endsWith(".log")){let m=await Bun.file(F(t,c)).stat();if(!a||m.mtime>a)a=new Date(m.mtime)}if(i.lastActivity=a,a){let c=(Date.now()-a.getTime())/3600000;if(c>24)e.push(`No activity for ${Math.floor(c)} hours`)}}}catch{e.push("Could not check last activity")}try{let t=F(o,".runner"),f=F(o,".credentials");if(i.configuration=yn(t)&&yn(f),!i.configuration)e.push("Missing configuration files")}catch{e.push("Could not check configuration")}if(r.token&&r.url)try{let t=await oe(r.url,r.token);if(i.connectivity=t,!t)e.push("Cannot connect to GitHub API")}catch{e.push("Failed to check GitHub connectivity")}let s="healthy";if(e.length===0)s="healthy";else if(e.some((t)=>t.includes("not running")||t.includes("Missing configuration")||t.includes("Cannot connect")))s="critical";else if(e.length>0)s="warning";return{checks:i,issues:e,runner:n,status:s}}async function ne(n){try{return await lt`kill -0 ${n}`.quiet(),!0}catch{return!1}}async function te(n){let r=(await lt`df -k ${n} | tail -1`.text()).trim().split(/\s+/),e=parseInt(r[1]||"0",10)*1024,i=parseInt(r[2]||"0",10)*1024;return{percentage:parseInt(r[4]?.replace("%","")||"0",10),total:e,used:i}}async function oe(n,o){return Z(async()=>{let r=n.match(/github\.com[:/]([^/]+)(?:\/([^/.]+))?/);if(!r)return!1;let[,e,i]=r,s=i?`https://api.github.com/repos/${e}/${i}`:`https://api.github.com/orgs/${e}`;return(await fetch(s,{headers:{Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${o}`}})).ok},{maxAttempts:3})}function re(n){console.log(),console.log(p.bold("\uD83C\uDFE5 Runner Health Status")),console.log("\u2500".repeat(80));let o={critical:"\u274C",healthy:"\u2705",unknown:"\u2753",warning:"\u26A0\uFE0F"},r={critical:p.error,healthy:p.success,unknown:p.dim,warning:p.warning};for(let i of n){let s=o[i.status],t=r[i.status];if(console.log(`${s} ${p.bold(`Runner ${i.runner}`)}: ${t(i.status.toUpperCase())}`),console.log(` Process: ${i.checks.process?"\u2705 Running":"\u274C Not running"}`),console.log(` Config: ${i.checks.configuration?"\u2705 Valid":"\u274C Missing"}`),i.checks.disk.total>0){let f=i.checks.disk.percentage>90?p.error:p.success;console.log(` Disk: ${f(`${i.checks.disk.percentage.toFixed(1)}% used`)}`)}if(i.checks.lastActivity){let a=(Date.now()-i.checks.lastActivity.getTime())/3600000>24?p.warning:p.success;console.log(` Last Activity: ${a(ie(i.checks.lastActivity))}`)}if(i.checks.connectivity!==null)console.log(` GitHub API: ${i.checks.connectivity?"\u2705 Connected":"\u274C Disconnected"}`);if(i.issues.length>0){console.log(" Issues:");for(let f of i.issues)console.log(` - ${p.dim(f)}`)}console.log()}let e={critical:n.filter((i)=>i.status==="critical").length,healthy:n.filter((i)=>i.status==="healthy").length,total:n.length,warning:n.filter((i)=>i.status==="warning").length};console.log("\u2500".repeat(80)),console.log(`Summary: Total: ${e.total} | ${p.success(`Healthy: ${e.healthy}`)} | ${p.warning(`Warning: ${e.warning}`)} | ${p.error(`Critical: ${e.critical}`)}`)}async function ee(n,o){let r=n.filter((i)=>i.status==="critical");if(r.length===0){h.info("No critical issues found that require fixing");return}if(console.log(),!await C({initialValue:!1,message:`Found ${r.length} runners with critical issues. Attempt to fix?`}))return;for(let i of r){if(console.log(),h.info(`Attempting to fix runner ${i.runner}...`),!i.checks.process&&i.checks.configuration){h.info("Attempting to restart runner...");try{let s=F(o.directory,"machines",i.runner);await lt`cd ${s} && ./run.sh`.quiet(),h.success(`Runner ${i.runner} restarted successfully`)}catch(s){h.error(`Failed to restart runner ${i.runner}`)}}if(!i.checks.configuration)h.warning(`Runner ${i.runner} needs to be reconfigured. Run 'hydra create' to set up again.`)}}function ie(n){let r=new Date().getTime()-n.getTime(),e=Math.floor(r/3600000);if(e<1)return`${Math.floor(r/60000)}m ago`;if(e<24)return`${e}h ago`;return`${Math.floor(e/24)}d ago`}var po="0.4.0";var uo={backup:`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
hydra
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-d, --directory Runners directory [string]
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
hydra backup -o /path/to/backups
|
|
70
|
-
|
|
71
|
-
# List available backups
|
|
72
|
-
hydra backup --list
|
|
73
|
-
|
|
74
|
-
# Restore from backup
|
|
75
|
-
hydra backup --restore backup-2024-01-15T10-30-00-000Z
|
|
76
|
-
|
|
77
|
-
# Create uncompressed backup
|
|
78
|
-
hydra backup --no-compress
|
|
79
|
-
|
|
80
|
-
NOTES
|
|
81
|
-
- Backs up runner configuration files (.runner, .credentials, etc.)
|
|
82
|
-
- Does NOT backup work directories or logs
|
|
83
|
-
- Compressed backups save space but take longer
|
|
84
|
-
- Restore will prompt before overwriting existing runners
|
|
85
|
-
`,create:`
|
|
86
|
-
hydra create - Create and register new GitHub runner machines
|
|
87
|
-
|
|
88
|
-
USAGE
|
|
89
|
-
hydra create [options]
|
|
90
|
-
|
|
91
|
-
OPTIONS
|
|
92
|
-
-t, --token GitHub Personal Access Token [string] (required)
|
|
93
|
-
-u, --url GitHub repository or org URL [string] (required)
|
|
94
|
-
-m, --numberOfMachines Number of machines [number] (default: 1)
|
|
95
|
-
-n, --name Runner name prefix [string]
|
|
96
|
-
-l, --labels Comma-separated runner labels [string]
|
|
97
|
-
-o, --os Runner OS [string] (default: osx)
|
|
98
|
-
-d, --directory Runners directory [string]
|
|
99
|
-
-O, --overwrite Overwrite existing runners [boolean]
|
|
100
|
-
-p, --profile Configuration profile [string]
|
|
101
|
-
-c, --config Configuration file path [string]
|
|
102
|
-
|
|
103
|
-
EXAMPLES
|
|
104
|
-
# Create a single runner
|
|
105
|
-
hydra create -t TOKEN -u https://github.com/org/repo
|
|
106
|
-
|
|
107
|
-
# Create 3 runners with labels
|
|
108
|
-
hydra create -m 3 -t TOKEN -u URL -l docker,gpu
|
|
109
|
-
|
|
110
|
-
# Create using profile
|
|
111
|
-
hydra create -p production -t TOKEN
|
|
112
|
-
`,health:`
|
|
113
|
-
hydra health - Check runner health and diagnose issues
|
|
114
|
-
|
|
115
|
-
USAGE
|
|
116
|
-
hydra health [options]
|
|
117
|
-
|
|
118
|
-
OPTIONS
|
|
119
|
-
-d, --directory Runners directory [string]
|
|
120
|
-
-r, --runner Specific runner ID [string]
|
|
121
|
-
-t, --token GitHub Personal Access Token [string]
|
|
122
|
-
-u, --url GitHub repository or org URL [string]
|
|
123
|
-
-f, --fix Attempt to fix issues [boolean]
|
|
124
|
-
-j, --json Output in JSON format [boolean]
|
|
125
|
-
-p, --profile Configuration profile [string]
|
|
126
|
-
-c, --config Configuration file path [string]
|
|
127
|
-
|
|
128
|
-
EXAMPLES
|
|
129
|
-
# Check health of all runners
|
|
130
|
-
hydra health
|
|
131
|
-
|
|
132
|
-
# Check specific runner
|
|
133
|
-
hydra health --runner 1
|
|
134
|
-
|
|
135
|
-
# Check with GitHub connectivity test
|
|
136
|
-
hydra health -t TOKEN -u URL
|
|
137
|
-
|
|
138
|
-
# Attempt to fix issues
|
|
139
|
-
hydra health --fix
|
|
140
|
-
|
|
141
|
-
# Output as JSON
|
|
142
|
-
hydra health --json
|
|
143
|
-
`,init:`
|
|
144
|
-
hydra init - Initialize a new Hydra configuration file
|
|
145
|
-
|
|
146
|
-
USAGE
|
|
147
|
-
hydra init [options]
|
|
148
|
-
|
|
149
|
-
OPTIONS
|
|
150
|
-
-t, --toml Use TOML format instead of JSON [boolean]
|
|
151
|
-
|
|
152
|
-
EXAMPLES
|
|
153
|
-
# Initialize with interactive prompts
|
|
154
|
-
hydra init
|
|
155
|
-
|
|
156
|
-
# Initialize with TOML format
|
|
157
|
-
hydra init --toml
|
|
158
|
-
`,logs:`
|
|
159
|
-
hydra logs - View runner logs and diagnostics
|
|
160
|
-
|
|
161
|
-
USAGE
|
|
162
|
-
hydra logs [options]
|
|
163
|
-
|
|
164
|
-
OPTIONS
|
|
165
|
-
-d, --directory Runners directory [string]
|
|
166
|
-
-l, --list List all available logs [boolean]
|
|
167
|
-
-r, --runner Specific runner ID [string]
|
|
168
|
-
-t, --type Log type (runner/worker/actions) [string]
|
|
169
|
-
-p, --profile Configuration profile [string]
|
|
170
|
-
-c, --config Configuration file path [string]
|
|
171
|
-
|
|
172
|
-
EXAMPLES
|
|
173
|
-
# View logs interactively
|
|
174
|
-
hydra logs
|
|
175
|
-
|
|
176
|
-
# List all available logs
|
|
177
|
-
hydra logs --list
|
|
178
|
-
|
|
179
|
-
# View specific runner's log
|
|
180
|
-
hydra logs --runner 1 --type runner
|
|
181
|
-
|
|
182
|
-
# View logs using profile
|
|
183
|
-
hydra logs -p production
|
|
184
|
-
`,remove:`
|
|
185
|
-
hydra remove - Remove GitHub runner machines
|
|
186
|
-
|
|
187
|
-
USAGE
|
|
188
|
-
hydra remove [options]
|
|
189
|
-
|
|
190
|
-
OPTIONS
|
|
191
|
-
-t, --token GitHub Personal Access Token [string] (required)
|
|
192
|
-
-u, --url GitHub repository or org URL [string] (required)
|
|
193
|
-
-m, --numberOfMachines Number of machines [number] (default: 1)
|
|
194
|
-
-n, --name Runner name prefix [string]
|
|
195
|
-
-d, --directory Runners directory [string]
|
|
196
|
-
-f, --force Force removal [boolean]
|
|
197
|
-
-p, --profile Configuration profile [string]
|
|
198
|
-
-c, --config Configuration file path [string]
|
|
199
|
-
|
|
200
|
-
EXAMPLES
|
|
201
|
-
# Remove and unregister
|
|
202
|
-
hydra remove -t TOKEN -u https://github.com/org/repo
|
|
203
|
-
|
|
204
|
-
# Force remove
|
|
205
|
-
hydra remove -m 2 --force
|
|
206
|
-
|
|
207
|
-
# Remove specific runners
|
|
208
|
-
hydra remove -n custom -m 3 -t TOKEN -u URL
|
|
209
|
-
`,run:`
|
|
210
|
-
hydra run - Start existing GitHub runner machines
|
|
211
|
-
|
|
212
|
-
USAGE
|
|
213
|
-
hydra run [options]
|
|
214
|
-
|
|
215
|
-
OPTIONS
|
|
216
|
-
-t, --token GitHub Personal Access Token [string] (required)
|
|
217
|
-
-u, --url GitHub repository or org URL [string] (required)
|
|
218
|
-
-m, --numberOfMachines Number of machines [number] (default: 1)
|
|
219
|
-
-n, --name Runner name prefix [string]
|
|
220
|
-
-d, --directory Runners directory [string]
|
|
221
|
-
-p, --profile Configuration profile [string]
|
|
222
|
-
-c, --config Configuration file path [string]
|
|
223
|
-
|
|
224
|
-
EXAMPLES
|
|
225
|
-
# Run existing runners
|
|
226
|
-
hydra run -t TOKEN -u https://github.com/org/repo
|
|
227
|
-
|
|
228
|
-
# Run specific runners
|
|
229
|
-
hydra run -m 2 -n custom -t TOKEN -u URL
|
|
230
|
-
`,scale:`
|
|
231
|
-
hydra scale - Automatically scale runners based on job queue
|
|
232
|
-
|
|
233
|
-
USAGE
|
|
234
|
-
hydra scale [options]
|
|
235
|
-
|
|
236
|
-
OPTIONS
|
|
237
|
-
-t, --token GitHub Personal Access Token [string] (required)
|
|
238
|
-
-u, --url GitHub repository or org URL [string] (required)
|
|
239
|
-
-m, --min Minimum number of runners [number] (default: 1)
|
|
240
|
-
-M, --max Maximum number of runners [number] (default: 5)
|
|
241
|
-
-w, --watch Watch mode - continuous scaling [boolean]
|
|
242
|
-
-i, --interval Check interval in seconds [number] (default: 60)
|
|
243
|
-
--scale-up-threshold Jobs in queue to trigger scale up [number] (default: 2)
|
|
244
|
-
--scale-down-idle Minutes idle before scale down [number] (default: 30)
|
|
245
|
-
--dry Preview actions without changes [boolean]
|
|
246
|
-
-d, --directory Runners directory [string]
|
|
247
|
-
-p, --profile Configuration profile [string]
|
|
248
|
-
-c, --config Configuration file path [string]
|
|
249
|
-
|
|
250
|
-
EXAMPLES
|
|
251
|
-
# Check and scale once
|
|
252
|
-
hydra scale -t TOKEN -u URL
|
|
253
|
-
|
|
254
|
-
# Watch mode with custom thresholds
|
|
255
|
-
hydra scale -t TOKEN -u URL --watch --min 2 --max 10
|
|
256
|
-
|
|
257
|
-
# Scale with faster response time
|
|
258
|
-
hydra scale -t TOKEN -u URL -w -i 30 --scale-up-threshold 1
|
|
259
|
-
|
|
260
|
-
# Preview scaling decisions
|
|
261
|
-
hydra scale -t TOKEN -u URL --dry
|
|
262
|
-
|
|
263
|
-
NOTES
|
|
264
|
-
- Monitors GitHub job queue and automatically adjusts runner count
|
|
265
|
-
- Scale up when pending jobs exceed threshold
|
|
266
|
-
- Scale down when runners are idle for specified duration
|
|
267
|
-
- Respects min/max limits to control costs
|
|
268
|
-
- Watch mode runs continuously until stopped (Ctrl+C)
|
|
269
|
-
`,status:`
|
|
270
|
-
hydra status - Check the status of GitHub runner machines
|
|
271
|
-
|
|
272
|
-
USAGE
|
|
273
|
-
hydra status [options]
|
|
274
|
-
|
|
275
|
-
OPTIONS
|
|
276
|
-
-t, --token GitHub Personal Access Token [string] (required)
|
|
277
|
-
-u, --url GitHub repository or org URL [string] (required)
|
|
278
|
-
-d, --directory Runners directory [string]
|
|
279
|
-
-j, --json Output status in JSON format [boolean]
|
|
280
|
-
-p, --profile Configuration profile [string]
|
|
281
|
-
-c, --config Configuration file path [string]
|
|
282
|
-
|
|
283
|
-
EXAMPLES
|
|
284
|
-
# Check runner status
|
|
285
|
-
hydra status -t TOKEN -u https://github.com/org/repo
|
|
286
|
-
|
|
287
|
-
# Output as JSON
|
|
288
|
-
hydra status -t TOKEN -u URL --json
|
|
289
|
-
|
|
290
|
-
# Status using profile
|
|
291
|
-
hydra status -p production
|
|
292
|
-
`};function wn(n){if(n&&uo[n]){let r=uo[n].split(`
|
|
293
|
-
`).map((e)=>{if(e.startsWith("hydra"))return p.bold(e);if(e==="USAGE"||e==="OPTIONS"||e==="EXAMPLES")return p.bold(e);if(e.startsWith(" -")){let i=e.match(/^(\s+-\w,\s--\w+)\s+(.+)$/);if(i){let[,s="",t=""]=i,f=t.replace("(required)",p.error("(required)")).replace(/\(default: ([^)]+)\)/g,(a,c)=>p.dim(`(default: ${c})`)).replace(/\[boolean\]/g,p.boolean("[boolean]")).replace(/\[string\]/g,p.string("[string]")).replace(/\[number\]/g,p.number("[number]"));return` ${p.flag(s.padEnd(26))} ${f}`}}if(e.startsWith(" # "))return p.dim(e);if(e.startsWith(" hydra"))return` ${p.value(e.trim())}`;return e}).join(`
|
|
294
|
-
`);console.info(r);return}console.info(`
|
|
295
|
-
${p.bold(`Hydra@${po} - GitHub self-hosted runner manager`)}
|
|
296
|
-
|
|
297
|
-
${p.bold("USAGE")}
|
|
298
|
-
hydra <command> [options]
|
|
299
|
-
|
|
300
|
-
${p.bold("COMMANDS")}
|
|
301
|
-
${p.command("init")} Initialize a new Hydra configuration file
|
|
302
|
-
${p.command("create")} Create and register new GitHub runner machines
|
|
303
|
-
${p.command("run")} Start existing GitHub runner machines
|
|
304
|
-
${p.command("remove")} Remove GitHub runner machines
|
|
305
|
-
${p.command("status")} Check the status of GitHub runner machines
|
|
306
|
-
${p.command("logs")} View runner logs and diagnostics
|
|
307
|
-
${p.command("health")} Check runner health and diagnose issues
|
|
308
|
-
${p.command("scale")} Automatically scale runners based on job queue
|
|
309
|
-
${p.command("backup")} Backup and restore runner configurations
|
|
310
|
-
${p.command("help")} Show this help message
|
|
311
|
-
|
|
312
|
-
Use ${p.value("hydra <command> --help")} for more information about a command.
|
|
313
|
-
`)}import{resolve as fe}from"path";import{parseArgs as ae}from"util";var{$:pt}=globalThis.Bun;var en=x({prefix:"hydra"}).child("init");async function go(){let{toml:n}=me(),o=n?"hydra.toml":"hydra.json",r=fe(process.cwd(),o);if(await Bun.file(r).exists()){let l=await C({initialValue:!1,message:`Configuration file ${o} already exists. Overwrite?`});if(U(l)||!l)it("Configuration cancelled"),process.exit(0)}Bt(w.cyan("\uD83D\uDE80 Hydra Configuration Setup")),en.info("This will create a configuration file with your runner settings."),en.info("You can always edit the file later or create additional profiles.");let i=await It({profileName:()=>q({message:"Profile name?",placeholder:"default"}),directory:()=>q({defaultValue:"./gh-runners",message:"Directory to store runners?",placeholder:"./gh-runners"}),name:()=>q({defaultValue:"runner",message:"Runner name prefix?",placeholder:"runner"}),labels:({results:l})=>{let u=l.name||"runner";return q({defaultValue:u,message:"Runner labels (comma-separated)?",placeholder:u})},numberOfMachines:()=>q({defaultValue:"1",message:"Number of runner machines?",placeholder:"1",validate:(l)=>{let u=Number.parseInt(l,10);if(Number.isNaN(u)||u<1)return"Please enter a valid number greater than 0";return}}),url:()=>q({message:"GitHub repository or organization URL? (optional)",placeholder:"https://github.com/org/repo"})},{onCancel:()=>{it("Configuration cancelled"),process.exit(0)}}),{profileName:s,labels:t,numberOfMachines:f,...a}=i,c={defaultProfile:s,profiles:{[s]:{...a,labels:t,numberOfMachines:Number.parseInt(f,10),os:"osx",overwrite:!1,run:!1}}},m=JSON.stringify(c,null,2);if(await Bun.write(r,m),await an(async()=>{await pt`chmod 600 ${r}`.quiet()},{logLevel:"warn",message:"Could not set secure file permissions"}),Wt(w.green(`\u2713 Configuration saved to ${o}`)),en.info("Example usage:"),en.info(` hydra create -p ${s} --token YOUR_TOKEN${i.url?"":" --url REPO_URL"}`),en.info("You can add more profiles by editing the configuration file."),i.url)await ce(i.url)}async function ce(n){let o=/github\.com[:/]([^/]+)(?:\/([^/.]+))?/,r=n.match(o);if(!r)return;let[,e,i]=r,t=`https://github.com/${i?`${e}/${i}`:`organizations/${e}`}/settings/actions/runners`;en.info(`Opening GitHub settings: ${t}`),await an(async()=>{await pt`open ${t}`.quiet()},{fallback:async()=>{await an(async()=>{await pt`xdg-open ${t}`.quiet()},{fallback:()=>{en.info("Please open the URL manually to add a new runner token.")},logLevel:"info",message:"Alternative browser open method also failed"})},logLevel:"info",message:"Could not open browser automatically"})}function me(){let{values:n}=ae({allowPositionals:!0,args:Bun.argv,options:{toml:{default:!1,short:"t",type:"boolean"}},strict:!0});return n}import{existsSync as ho}from"fs";import{readdir as bo}from"fs/promises";import{join as vn,resolve as le}from"path";import{parseArgs as pe}from"util";var ue=x({prefix:"hydra"}).child("logs");async function de(){let{values:n}=pe({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},list:{default:!1,short:"l",type:"boolean"},profile:{short:"p",type:"string"},runner:{short:"r",type:"string"},type:{short:"t",type:"string"}},strict:!0}),o=await A({configPath:n.config}),r=await X(o,n.profile);return{directory:n.directory||r?.directory||`${process.cwd()}/gh-runners`,list:n.list,runner:n.runner,type:n.type}}async function yo(){try{let n=await de(),o=le(n.directory),r=vn(o,"machines");if(!ho(r)){h.error(`No runners found in ${n.directory}`);return}let e=W();e.start("Scanning for runner logs...");let i=await bo(r),s=[];for(let f of i){let a=vn(r,f),c=vn(a,"_diag");if(ho(c)){let m=await ge(c);if(m.length>0)s.push({logs:m,runner:f})}}if(e.stop("Found runner logs"),s.length===0){h.info("No log files found");return}if(n.list){he(s);return}if(n.runner&&n.type){await ye(s,n.runner,n.type);return}let t=await be(s);if(t)await wo(t)}catch(n){ue.error("Failed to retrieve logs:",n),process.exit(1)}}async function ge(n){let o=await bo(n),r=[];for(let e of o)if(e.endsWith(".log")){let i=vn(n,e),s=await Bun.file(i).stat();r.push({modified:new Date(s.mtime),name:e,path:i,size:s.size})}return r.sort((e,i)=>i.modified.getTime()-e.modified.getTime())}function he(n){console.log(p.bold(`
|
|
61
|
+
`)},info:(t)=>{l.message(t,{symbol:h.default.blue(as)})},success:(t)=>{l.message(t,{symbol:h.default.green(ls)})},step:(t)=>{l.message(t,{symbol:h.default.green(en)})},warn:(t)=>{l.message(t,{symbol:h.default.yellow(fs)})},warning:(t)=>{l.warn(t)},error:(t)=>{l.message(t,{symbol:h.default.red(us)})}},zf=`${h.default.gray(R)} `});function de(t,e){let n=vi[t]||"Unknown error";return e?`${n}: ${e}`:n}function cs(t,e){let n=new Error(de(t,e));return n.code=t,n}var vi,Ri;var on=v(()=>{vi={"core.auth.failed":"Authentication failed","core.auth.invalid_token":"Token is invalid or expired","core.fs.cannot_read":"Cannot read file","core.fs.cannot_write":"Cannot write to file","core.fs.directory_not_found":"Directory not found","core.fs.file_not_found":"File not found","core.git.dirty_working_dir":"Working directory has uncommitted changes","core.git.no_commits":"No commits found","core.git.not_repository":"Not a git repository","core.git.operation_failed":"Git operation failed","core.invalid_argument":"Invalid argument","core.invalid_config":"Invalid configuration","core.network.request_failed":"Network request failed","core.operation_cancelled":"Operation cancelled","core.operation_failed":"Operation failed","core.permission_denied":"Permission denied","hydra.config.invalid_format":"Invalid configuration format","hydra.config.missing_required":"Missing required configuration","hydra.config.not_found":"Configuration file not found","hydra.runner.creation_failed":"Runner creation failed","hydra.runner.not_found":"Runner not found","hydra.runner.removal_failed":"Runner removal failed","hydra.token.decryption_failed":"Token decryption failed","hydra.token.encryption_failed":"Token encryption failed","sisyphus.publish.failed":"Publishing failed","sisyphus.release.no_changes":"No changes to release","sisyphus.stone.invalid":"Invalid stone format","sisyphus.stone.not_found":"No stones found","sisyphus.version.conflict":"Version conflict detected","sisyphus.version.invalid_format":"Invalid version format"};((o)=>{o[o.Success=0]="Success";o[o.UnknownError=1]="UnknownError";o[o.ValidationError=2]="ValidationError";o[o.MissingConfig=3]="MissingConfig";o[o.NotFound=4]="NotFound";o[o.UnknownCommand=5]="UnknownCommand"})(Ri||={})});function ps(t={}){let{errorPrefix:e="\u2717"}=t;return function n(i){if(k(i))_t.info("Operation cancelled"),process.exit(0);if(i instanceof nt){if(_t.error(`${e} ${i.message}`),i.code)_t.error(` Error code: ${i.code}`)}else if(i instanceof Error)_t.error(`${e} ${i.message}`);else _t.error(`${e} An unexpected error occurred`),_t.error(String(i));process.exit(1)}}function hs(t,e,n,i){if(!t)throw new nt(e,n,i)}var _t,nt,ds;var Ei=v(()=>{q();G();on();_t=$({prefix:"cli-core"}).child("error");nt=class nt extends Error{code;context;constructor(t,e,n){let i=t.includes(".")&&!t.includes(" ")?de(t,n):t;super(i);this.code=e;this.context=n;this.name="CLIError"}};ds={DIRTY_WORKING_DIR:"core.git.dirty_working_dir",FILE_NOT_FOUND:"core.fs.file_not_found",INVALID_ARGUMENT:"core.invalid_argument",INVALID_CONFIG:"core.invalid_config",NOT_GIT_REPO:"core.git.not_repository",OPERATION_FAILED:"core.operation_failed",PERMISSION_DENIED:"core.permission_denied",USER_CANCELLED:"core.operation_cancelled"}});var ct,gs=(t,e)=>{let n=t.length,i=e.length,r=1<<n-1,s=-1,o=0,a=n,f=n;while(f--)ct[t.charCodeAt(f)]|=1<<f;for(f=0;f<i;f++){let u=ct[e.charCodeAt(f)],p=u|o;if(u|=(u&s)+s^s,o|=~(u|s),s&=u,o&r)a++;if(s&r)a--;o=o<<1|1,s=s<<1|~(p|o),o&=p}f=n;while(f--)ct[t.charCodeAt(f)]=0;return a},ms=(t,e)=>{let n=e.length,i=t.length,r=[],s=[],o=Math.ceil(n/32),a=Math.ceil(i/32);for(let m=0;m<o;m++)s[m]=-1,r[m]=0;let f=0;for(;f<a-1;f++){let m=0,x=-1,M=f*32,Q=Math.min(32,i)+M;for(let E=M;E<Q;E++)ct[t.charCodeAt(E)]|=1<<E;for(let E=0;E<n;E++){let D=ct[e.charCodeAt(E)],H=s[E/32|0]>>>E&1,W=r[E/32|0]>>>E&1,Z=D|m,ut=((D|W)&x)+x^x|D|W,At=m|~(ut|x),ne=x&ut;if(At>>>31^H)s[E/32|0]^=1<<E;if(ne>>>31^W)r[E/32|0]^=1<<E;At=At<<1|H,ne=ne<<1|W,x=ne|~(Z|At),m=At&Z}for(let E=M;E<Q;E++)ct[t.charCodeAt(E)]=0}let u=0,p=-1,d=f*32,g=Math.min(32,i-d)+d;for(let m=d;m<g;m++)ct[t.charCodeAt(m)]|=1<<m;let b=i;for(let m=0;m<n;m++){let x=ct[e.charCodeAt(m)],M=s[m/32|0]>>>m&1,Q=r[m/32|0]>>>m&1,E=x|u,D=((x|Q)&p)+p^p|x|Q,H=u|~(D|p),W=p&D;if(b+=H>>>i-1&1,b-=W>>>i-1&1,H>>>31^M)s[m/32|0]^=1<<m;if(W>>>31^Q)r[m/32|0]^=1<<m;H=H<<1|M,W=W<<1|Q,p=W|~(E|H),u=H&E}for(let m=d;m<g;m++)ct[t.charCodeAt(m)]=0;return b},ge=(t,e)=>{if(t.length<e.length){let n=e;e=t,t=n}if(e.length===0)return t.length;if(t.length<=32)return gs(t,e);return ms(t,e)},Pi=(t,e)=>{let n=1/0,i=0;for(let r=0;r<e.length;r++){let s=ge(t,e[r]);if(s<n)n=s,i=r}return e[i]};var Ai=v(()=>{ct=new Uint32Array(65536)});function ys(t,e){if(e.length===0)return null;let n=Pi(t.toLowerCase(),e.map((o)=>o.toLowerCase())),i=e.findIndex((o)=>o.toLowerCase()===n),r=i!==-1?e[i]:null;if(!r)return null;if(ge(t.toLowerCase(),r.toLowerCase())>Math.max(3,t.length/2))return null;return r}function rn(t,e,n=3){return e.map((s)=>({distance:ge(t.toLowerCase(),s.toLowerCase()),option:s})).filter(({distance:s})=>s<=Math.max(3,t.length/2)).sort((s,o)=>s.distance-o.distance).slice(0,n).map(({option:s})=>s)}function sn(t,e){return e[t.toLowerCase()]||null}var Ti=v(()=>{Ai()});async function Nt(t,e={}){let{fallback:n,logLevel:i="warn",message:r="Operation failed gracefully"}=e;try{return await t()}catch(s){let o=s instanceof Error?s.message:String(s);if(Oi[i](`${r}: ${o}`),n)try{await n()}catch(a){Oi.error(`Fallback also failed: ${a instanceof Error?a.message:String(a)}`)}return}}function bs(t,e={}){return async(...n)=>{return Nt(()=>t(...n),e)}}var Oi;var Hi=v(()=>{G();Oi=$({prefix:"cli-core"}).child("graceful")});function me(t){let e=[];if(e.push(c.bold(`${t.name} - ${t.description}`)),e.push(""),e.push(c.bold("USAGE")),e.push(` ${t.usage}`),e.push(""),t.options&&t.options.length>0){e.push(c.bold("OPTIONS"));for(let n of t.options){let i=n.type?n.type==="boolean"?c.boolean("[boolean]"):n.type==="string"?c.string("[string]"):n.type==="number"?c.number("[number]"):`[${n.type}]`:"",r=n.default!==void 0?c.dim(`(default: ${n.default})`):"",s=n.required?c.error("(required)"):"",o=[n.description,i,r,s].filter(Boolean);e.push(` ${c.flag(n.flags.padEnd(26))} ${o.join(" ")}`)}e.push("")}if(t.examples&&t.examples.length>0){e.push(c.bold("EXAMPLES"));for(let n of t.examples)e.push(c.dim(` # ${n.description}`)),e.push(` ${c.value(n.command)}`),e.push("")}if(t.sections&&t.sections.length>0)for(let n of t.sections){if(e.push(c.bold(n.title)),typeof n.content==="string")e.push(n.content);else e.push(...n.content);e.push("")}if(t.notes&&t.notes.length>0){e.push(c.bold("NOTES"));for(let n of t.notes)e.push(` - ${n}`);e.push("")}if(e[e.length-1]==="")e.pop();return e.join(`
|
|
62
|
+
`)}function an(t,e,n,i){let r=[];r.push(c.bold(t)),r.push(""),r.push(c.bold("USAGE")),r.push(` ${e}`),r.push(""),r.push(c.bold("COMMANDS"));let s=Math.max(...n.map((o)=>o.name.length));for(let o of n)r.push(` ${c.command(o.name.padEnd(s+2))} ${o.description}`);if(i)r.push(""),r.push(i);return r.join(`
|
|
63
|
+
`)}var Ci=v(()=>{Be()});var _i=v(()=>{G()});class Ni{options;queue=[];tokens;lastRefill;processing=!1;constructor(t){this.options=t;this.tokens=t.maxBurst||t.maxRequests,this.lastRefill=Date.now()}async acquire(){return new Promise((t)=>{this.queue.push({resolve:t,timestamp:Date.now()}),this.processQueue()})}processQueue(){if(this.processing)return;this.processing=!0;let t=()=>{this.refillTokens();while(this.queue.length>0&&this.tokens>0){let e=this.queue.shift();if(e)this.tokens--,e.resolve()}if(this.queue.length>0){let e=this.options.windowMs/this.options.maxRequests;setTimeout(()=>t(),e)}else this.processing=!1};t()}refillTokens(){let t=Date.now(),e=t-this.lastRefill,n=Math.floor(e/(this.options.windowMs/this.options.maxRequests));if(n>0)this.tokens=Math.min(this.tokens+n,this.options.maxBurst||this.options.maxRequests),this.lastRefill=t}reset(){this.queue=[],this.tokens=this.options.maxBurst||this.options.maxRequests,this.lastRefill=Date.now(),this.processing=!1}getQueueLength(){return this.queue.length}}async function it(t,e={}){let n={...ws,...e},i=new Error("Operation failed");for(let r=1;r<=n.maxAttempts;r++)try{return await t()}catch(s){if(i=s instanceof Error?s:new Error(String(s)),!n.retryableErrors.some((f)=>i.message.toLowerCase().includes(f.toLowerCase()))||r===n.maxAttempts)throw i;n.onRetry(r,i);let a=Math.min(n.initialDelay*n.backoffMultiplier**(r-1),n.maxDelay);await new Promise((f)=>setTimeout(f,a))}throw i}function xs(t,e={}){return async(...n)=>{return it(()=>t(...n),e)}}var ws;var Si=v(()=>{G();ws={backoffMultiplier:2,initialDelay:1000,maxAttempts:3,maxDelay:30000,onRetry:(t,e)=>{re.warn(`Retry attempt ${t}: ${e.message}`)},retryableErrors:["ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENOTFOUND","rate limit","429","503","502","504","npm ERR!","EPUBLISHCONFLICT"]}});import{existsSync as $s}from"fs";import{readFile as vs}from"fs/promises";import{homedir as Rs}from"os";import{join as Wi}from"path";async function As(){try{if($s(ln)){let t=await vs(ln,"utf-8");return JSON.parse(t)}}catch{}return{}}async function Ts(t){try{await Bun.write(ln,JSON.stringify(t,null,2))}catch{}}async function Os(t){try{let e=await fetch(`https://registry.npmjs.org/${t}/latest`,{signal:AbortSignal.timeout(5000)});if(!e.ok)return null;return(await e.json()).version}catch{return null}}async function Bi(t){let{packageName:e,currentVersion:n,checkInterval:i=Es,silent:r=!1}=t;if(process.env.CI||process.env.CONTINUOUS_INTEGRATION)return null;if(process.env.R5N_NO_UPDATE_CHECK==="1")return null;try{let s=await As(),o=s[e],a=Date.now();if(o&&a-o.lastChecked<i)return{currentVersion:n,lastChecked:o.lastChecked,latestVersion:o.latestVersion,name:e,updateAvailable:Mi(o.latestVersion,n)>0};let f=await Os(e);if(!f)return null;if(s[e]={lastChecked:a,latestVersion:f},!r)Ts(s).catch(()=>{});return{currentVersion:n,lastChecked:a,latestVersion:f,name:e,updateAvailable:Mi(f,n)>0}}catch{return null}}function Ui(t){let{name:e,currentVersion:n,latestVersion:i}=t;return["","\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510","\u2502 \u2502",`\u2502 Update available for ${(e.split("/").pop()||e).padEnd(29)} \u2502`,`\u2502 ${n.padEnd(15)} \u2192 ${i.padEnd(32)} \u2502`,"\u2502 \u2502",`\u2502 Run: bun update -g ${e.padEnd(30)} \u2502`,"\u2502 \u2502","\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",""].join(`
|
|
64
|
+
`)}async function Hs(t,e){let n=await Bi({currentVersion:e,packageName:t,silent:!1});if(n?.updateAvailable&&process.stdout.isTTY)setTimeout(()=>{console.log(Ui(n))},100)}function Mi(t,e){let n=t.split(".").map(Number),i=e.split(".").map(Number);for(let r=0;r<Math.max(n.length,i.length);r++){let s=n[r]||0,o=i[r]||0;if(s>o)return 1;if(s<o)return-1}return 0}var Es=86400000,Ps,ln;var qi=v(()=>{Ps=Wi(Rs(),".r5n","cache"),ln=Wi(Ps,"update-check.json")});var Y=(t)=>{return t.map=(e)=>Y((n)=>e(t(n))),t.or=(e)=>Y((n)=>{try{return t(n)}catch(i){return e(n)}}),t},Xt=()=>"bad banditype"(),fn=(t)=>Y((e)=>t.includes(e)?e:Xt()),ye=(t)=>Y((e)=>typeof e===typeof t?e:Xt()),X=()=>ye(""),yt=()=>ye(0),Tt=()=>ye(!0),Qt=()=>ye(),un=(t)=>Y((e)=>e instanceof t?e:Xt()),be=(t)=>un(Object).map((e)=>{let n={};for(let i in e){let r=t(e[i]);r!==void 0&&(n[i]=r)}return n}),I=(t)=>un(Object).map((e)=>{let n={};for(let i in t){let r=t[i](e[i]);r!==void 0&&(n[i]=r)}return n}),Li=(t)=>un(Array).map((e)=>e.map(t));function we(t,e){return Y((n)=>{try{return t(n)}catch{try{return e(n)}catch{throw new Error("No matching schema in union")}}})}function lt(t,e){return(n)=>{if(n===void 0)return e;return t(n)}}function cn(){return Y((t)=>{let e=yt()(t);if(!Number.isInteger(e)||e<=0)throw new Error("Must be a positive integer");return e})}function pn(){return Y((t)=>{let e=X()(t);try{return new URL(e),e}catch{throw new Error("Must be a valid URL")}})}function Cs(){return Y((t)=>{let e=X()(t);if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))throw new Error("Must be a valid email");return e})}function _s(t){return Y((e)=>{let n=yt()(e);if(n<t)throw new Error(`Must be at least ${t}`);return n})}function Ns(t){return Y((e)=>{let n=X()(e);if(n.length<t)throw new Error(`Must be at least ${t} characters`);return n})}function hn(t,e){return Y((n)=>{let i=X()(n);if(!t.test(i))throw new Error(e||`Must match pattern ${t}`);return i})}function Ot(t){return{parse(e){try{return t(e)}catch(n){throw new Error(n instanceof Error?n.message:"Validation failed")}},safeParse(e){try{return{data:t(e),success:!0}}catch(n){return{error:n instanceof Error?n:new Error("Validation failed"),success:!1}}},validator:t}}function Ss(t){let e=Ot(t);return{parse:e.parse,parseJSON(n){let i=JSON.parse(n),r=e.safeParse(i);if(!r.success)throw r.error instanceof Error?new Error(`Invalid JSON: ${r.error.message}`):r.error;return r.data},safeParse:e.safeParse}}function pt(){return we(Qt(),X())}function Gi(){return we(Qt(),Tt())}function bt(t){return lt(X(),t)}function Ht(t){return lt(Tt(),t)}function Ms(t){return lt(pt(),t)}function Ws(t){return lt(Gi(),t)}function Bs(t){return we(Qt(),t)}function Kt(t,e){return lt(fn(t),e)}var ji=()=>{};var Us,qs,Ls,Gs,js,Js;var Ji=v(()=>{Us=/^https:\/\/github\.com\/[\w-]+\/[\w.-]+$/,qs=/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/,Ls=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,Gs=/^[a-zA-Z0-9][a-zA-Z0-9-_]*$/,js=/\.\.[/\\]/,Js={isValidGitHubOrgUrl(t){if(!t||typeof t!=="string")return!1;return/^https:\/\/github\.com\/[\w-]+$/.test(t.trim())},isValidGitHubToken(t){if(!t||typeof t!=="string")return!1;return[/^ghp_[a-zA-Z0-9]{36}$/,/^github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}$/,/^ghs_[a-zA-Z0-9]{36}$/,/^gho_[a-zA-Z0-9]{36}$/].some((n)=>n.test(t))},isValidGitHubUrl(t){if(!t||typeof t!=="string")return!1;return Us.test(t.trim())},isValidNpmPackageName(t){if(!t||typeof t!=="string")return!1;if(t.length>214)return!1;return qs.test(t)},isValidRunnerCount(t){return Number.isInteger(t)&&t>0&&t<=50},isValidRunnerName(t){if(!t||typeof t!=="string")return!1;if(t.length<1||t.length>64)return!1;return Gs.test(t)},isValidSemver(t){if(!t||typeof t!=="string")return!1;return Ls.test(t)},sanitizePath(t){if(!t||typeof t!=="string")return"";let e=t.trim();if(js.test(e))e=e.replace(/\.\.[/\\]/g,"");let n=/[<>:"|?*]/g;e=e.replace(n,"");for(let i=0;i<32;i++)e=e.replace(new RegExp(String.fromCharCode(i),"g"),"");return e=e.replace(/\/+/g,"/"),e=e.replace(/\\+/g,"\\"),e},sanitizeRunnerName(t){if(!t||typeof t!=="string")return"runner";let e=t.trim();if(e=e.replace(/[^a-zA-Z0-9-_]/g,"-"),e=e.replace(/^[^a-zA-Z0-9]+/,""),e=e.replace(/-+/g,"-"),e.length===0)return"runner";if(e.length>64)return e.substring(0,64);return e},validateLabels(t){if(!t||typeof t!=="string")return[];return t.split(",").map((e)=>e.trim()).filter((e)=>e.length>0&&e.length<=50).filter((e)=>/^[a-zA-Z0-9-_.]+$/.test(e))}}});var ki={};ie(ki,{withRetry:()=>it,validators:()=>Js,url:()=>pn,union:()=>we,string:()=>X,showCommandHelp:()=>Er,regex:()=>hn,record:()=>be,positiveInt:()=>cn,optionalString:()=>pt,optionalObject:()=>Bs,optionalBoolean:()=>Gi,optional:()=>Qt,object:()=>I,number:()=>yt,minLength:()=>Ns,min:()=>_s,logger:()=>re,gracefulTry:()=>Nt,getSuggestions:()=>rn,getErrorMessage:()=>de,formatUpdateMessage:()=>Ui,formatMainHelp:()=>an,formatCommandHelp:()=>me,findClosestMatch:()=>ys,fail:()=>Xt,errorWithCode:()=>cs,enums:()=>fn,email:()=>Cs,defineCommand:()=>Rr,defaultTo:()=>lt,defaultString:()=>bt,defaultOptionalString:()=>Ms,defaultOptionalBoolean:()=>Ws,defaultEnum:()=>Kt,defaultBoolean:()=>Ht,createSchema:()=>Ot,createRetryableOperation:()=>xs,createLogger:()=>$,createGracefulWrapper:()=>bs,createErrorHandler:()=>ps,createConfigValidator:()=>Ss,cliColors:()=>c,checkForUpdate:()=>Bi,checkCommonMistakes:()=>sn,checkAndNotify:()=>Hs,boolean:()=>Tt,assert:()=>hs,array:()=>Li,RateLimiter:()=>Ni,LogLevel:()=>We,ErrorCode:()=>Ri,ERROR_MESSAGES:()=>vi,CLIError:()=>nt,BaseErrorCodes:()=>ds});var O=v(()=>{Be();Ei();on();Ti();Hi();Ci();_i();Si();qi();ji();Ji()});class Ki{cache=new Map;maxAge;constructor(t=300000){this.maxAge=t}get(t){let e=this.cache.get(t);if(!e)return null;if(Date.now()-e.timestamp>this.maxAge)return this.cache.delete(t),null;return e.config}set(t,e){this.cache.set(t,{config:e,path:t,timestamp:Date.now()})}clear(){this.cache.clear()}invalidate(t){this.cache.delete(t)}}var gn;var Vi=v(()=>{gn=new Ki});function xe(){let t=import.meta.path,e=t.substring(0,t.lastIndexOf("/"));return e.substring(0,e.lastIndexOf("/"))}function j(t){return t.replace(/[^a-zA-Z0-9\-_./\s]/g,"")}function Zi(t,e){let n=t;for(let i of e)if(i&&i.length>0){let r=i.length>8?`${i.slice(0,2)}${"*".repeat(i.length-4)}${i.slice(-2)}`:"*".repeat(i.length),s=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");n=n.replace(new RegExp(s,"g"),r)}return n=n.replace(/ghp_[a-zA-Z0-9]{36}/g,"ghp_************************************"),n=n.replace(/github_pat_[a-zA-Z0-9_]{82}/g,"github_pat_**********************************"),n=n.replace(/\b[A-Z]{20,}\b/g,(i)=>{return`${i.slice(0,2)}${"*".repeat(i.length-4)}${i.slice(-2)}`}),n}var Qs,Qu;var Mt=v(()=>{O();Qs=I({directory:bt(`${process.cwd()}/gh-runners`),labels:pt(),name:bt("runner"),numberOfMachines:lt(hn(/^\d+$/,"Number of machines must be a positive integer"),"1"),os:Kt(["osx","linux","windows"],"osx"),overwrite:Ht(!1),run:Ht(!1),token:bt(process.env.GITHUB_PERSONAL_ACCESS_TOKEN??""),url:pn()}),Qu=Ot(Qs)});var{$:ft}=globalThis.Bun;class $e{async exists(t){return Bun.file(t).exists()}async readFile(t){let e=Bun.file(t);if(!await e.exists())throw new Error(`File not found: ${t}`);return e.text()}async writeFile(t,e){await Bun.write(t,e)}async deleteFile(t){let e=j(t);await ft`rm -f ${e}`.quiet()}async createDirectory(t,e){let n=j(t);if(e?.recursive)await ft`mkdir -p ${n}`.quiet();else await ft`mkdir ${n}`.quiet()}async deleteDirectory(t,e){let n=j(t);if(e?.recursive)await ft`rm -rf ${n}`.quiet();else await ft`rmdir ${n}`.quiet()}async listDirectory(t){let e=j(t),i=(await ft`ls -la ${e}`.quiet()).stdout.toString().trim().split(`
|
|
65
|
+
`),r=[];for(let s of i.slice(1)){let o=s.split(/\s+/);if(o.length<9)continue;let a=o[0],f=Number.parseInt(o[4]||"0",10),u=o.slice(8).join(" ");if(u==="."||u==="..")continue;r.push({isDirectory:a?.startsWith("d")||!1,modifiedTime:new Date,name:u,size:f})}return r}async copyFile(t,e){let n=j(t),i=j(e);await ft`cp ${n} ${i}`.quiet()}async moveFile(t,e){let n=j(t),i=j(e);await ft`mv ${n} ${i}`.quiet()}async getFileInfo(t){if(!await Bun.file(t).exists())return null;let n=j(t),r=(await ft`stat -f "%z %m %Y" ${n} 2>/dev/null || stat -c "%s %Y %F" ${n}`.quiet()).stdout.toString().trim().split(" "),s=r[0]||"0",o=r[1]||"0";return{isDirectory:!1,modifiedTime:new Date(Number.parseInt(o,10)*1000),name:t.split("/").pop()||t,size:Number.parseInt(s,10)}}async chmod(t,e){let n=j(t);await ft`chmod ${e} ${n}`.quiet()}async readDir(t){return(await this.listDirectory(t)).map((n)=>({isDirectory:n.isDirectory,isFile:!n.isDirectory,name:n.name}))}async ensureDir(t){if(!await this.exists(t))await this.createDirectory(t,{recursive:!0})}}async function mn(t){if(!await y.exists(t))await y.createDirectory(t,{recursive:!0})}async function zi(t,e){let n=JSON.stringify(e,null,2);await y.writeFile(t,n)}var y;var F=v(()=>{Mt();y=new $e});var Ks,Vs,Yi;var Ii=v(()=>{O();Ks=I({directory:bt("./gh-runners"),labels:pt(),name:bt("runner"),numberOfMachines:lt(cn(),1),os:Kt(["osx","linux","windows"],"osx"),overwrite:Ht(!1),run:Ht(!1),runnerGroup:pt(),url:pt()}),Vs=Ot(Ks),Yi=Ot(I({defaultProfile:pt(),profiles:be(Vs.validator)}))});import{join as Zs}from"path";async function yn(t=process.cwd()){for(let e of zs){let n=Zs(t,e);if(await y.exists(n))return n}return null}async function N(t){let e=t?.configPath||await yn();if(!e)return null;let n=gn.get(e);if(n)return n;if(!await y.exists(e))return null;try{let i=await y.readFile(e),r=e.endsWith(".toml")?Ys(i):JSON.parse(i),s=Yi.parse(r);return gn.set(e,s),s}catch(i){if(i instanceof Error)throw new Error(`Invalid config file: ${i.message}`);throw i}}async function S(t,e){if(!t)return null;let n=e||t.defaultProfile;if(!n)return null;return t.profiles[n]||null}function ve(t,e){if(!t)return e;let n={...e};for(let[i,r]of Object.entries(t)){let s=i;if(n[s]===void 0&&r!==void 0)n[s]=r}return n}function Ys(t){try{return Bun.TOML.parse(t)}catch(e){throw new Error(`Failed to parse TOML configuration: ${e}`)}}var zs;var V=v(()=>{Vi();F();Ii();zs=["hydra.json",".hydra.json","hydra.toml",".hydra.toml"]});function w({prefix:t,secrets:e=[]}){let n=$({prefix:t}),i=[...e];if(process.env.GITHUB_TOKEN)i.push(process.env.GITHUB_TOKEN);if(process.env.RUNNER_TOKEN)i.push(process.env.RUNNER_TOKEN);if(process.env.RUNNER_CFG_PAT)i.push(process.env.RUNNER_CFG_PAT);let r=(s)=>{if(typeof s==="string")return Zi(s,i);if(typeof s==="object"&&s!==null){let o=Array.isArray(s)?[]:{};for(let a in s)o[a]=r(s[a]);return o}return s};return{...n,addSecret:(s)=>{if(s&&!i.includes(s))i.push(s)},child:(s)=>w({prefix:`${t}:${s}`,secrets:i}),debug:(...s)=>n.debug(...s.map(r)),error:(...s)=>n.error(...s.map(r)),info:(...s)=>n.info(...s.map(r)),warn:(...s)=>n.warn(...s.map(r))}}var tt=v(()=>{G();Mt()});import{EventEmitter as Is}from"events";class Fi{name;options;state="closed";failureCount=0;lastFailureTime;halfOpenAttempts=0;resetTimer;logger=w({prefix:"CircuitBreaker"});constructor(t,e){this.name=t;this.options=e}async execute(t){if(this.state==="open")if(this.shouldAttemptReset())this.state="half_open",this.halfOpenAttempts=0;else throw new Error(`Circuit breaker ${this.name} is OPEN`);try{let e=await t();return this.onSuccess(),e}catch(e){throw this.onFailure(),e}}shouldAttemptReset(){if(!this.lastFailureTime)return!1;return Date.now()-this.lastFailureTime.getTime()>=this.options.resetTimeout}onSuccess(){if(this.state==="half_open"){if(this.halfOpenAttempts++,this.halfOpenAttempts>=this.options.halfOpenMaxAttempts)this.reset()}else if(this.state==="closed")this.failureCount=0}onFailure(){if(this.lastFailureTime=new Date,this.failureCount++,this.state==="half_open")this.trip();else if(this.failureCount>=this.options.failureThreshold)this.trip()}trip(){if(this.state="open",this.logger.warn(`Circuit breaker ${this.name} tripped`),this.resetTimer)clearTimeout(this.resetTimer);this.resetTimer=setTimeout(()=>{this.state="half_open",this.halfOpenAttempts=0,this.logger.info(`Circuit breaker ${this.name} attempting reset`)},this.options.resetTimeout)}reset(){if(this.state="closed",this.failureCount=0,this.halfOpenAttempts=0,this.lastFailureTime=void 0,this.resetTimer)clearTimeout(this.resetTimer),this.resetTimer=void 0;this.logger.info(`Circuit breaker ${this.name} reset`)}getState(){return this.state}getStats(){return{failureCount:this.failureCount,halfOpenAttempts:this.halfOpenAttempts,lastFailureTime:this.lastFailureTime,state:this.state}}}var Di,ht;var bn=v(()=>{tt();Di=class Di extends Is{strategies=new Map;circuitBreakers=new Map;errorMetrics=new Map;logger=w({prefix:"ErrorRecovery"});constructor(){super();this.setupDefaultStrategies()}setupDefaultStrategies(){this.addStrategy({backoffMultiplier:2,baseDelay:1000,maxDelay:30000,maxRetries:3,shouldRetry:(t,e)=>{return e<3&&this.isTransientError(t)},type:"transient"}),this.addStrategy({backoffMultiplier:1.5,baseDelay:2000,maxDelay:60000,maxRetries:5,onRetry:(t,e,n)=>{this.logger.info(`Network error retry attempt ${e} after ${n}ms`)},shouldRetry:(t,e)=>{return e<5&&this.isNetworkError(t)},type:"network"}),this.addStrategy({backoffMultiplier:1,baseDelay:0,maxDelay:0,maxRetries:0,shouldRetry:()=>!1,type:"configuration"}),this.addStrategy({backoffMultiplier:2,baseDelay:5000,maxDelay:30000,maxRetries:2,shouldRetry:(t,e)=>{return e<2&&this.isResourceError(t)},type:"resource"})}addStrategy(t){this.strategies.set(t.type,t)}createCircuitBreaker(t,e={}){let n=new Fi(t,{failureThreshold:e.failureThreshold??5,halfOpenMaxAttempts:e.halfOpenMaxAttempts??3,resetTimeout:e.resetTimeout??60000});return this.circuitBreakers.set(t,n),n}async executeWithRecovery(t,e){let n,i=0;while(!0)try{let r=await t();return this.recordSuccess(e),r}catch(r){n=r,i++;let s=this.classifyError(n),o=this.strategies.get(s);if(this.recordError(e,n,s),!o||!o.shouldRetry(n,i)){if(o?.onMaxRetriesExceeded)o.onMaxRetriesExceeded(n);throw n}let a=this.calculateDelay(i,o);if(o.onRetry)o.onRetry(n,i,a);this.emit("retryAttempt",{attempt:i,context:e,delay:a,error:n,errorType:s}),await this.sleep(a)}}classifyError(t){if(this.isNetworkError(t))return"network";if(this.isConfigurationError(t))return"configuration";if(this.isResourceError(t))return"resource";if(this.isTransientError(t))return"transient";return"unknown"}isNetworkError(t){let e=["econnrefused","enotfound","etimedout","econnreset","network","socket","dns"],n=t.message.toLowerCase();return e.some((i)=>n.includes(i))}isConfigurationError(t){let e=["invalid configuration","missing required","invalid token","authentication failed","permission denied"],n=t.message.toLowerCase();return e.some((i)=>n.includes(i))}isResourceError(t){let e=["out of memory","disk full","no space","resource exhausted","too many open files"],n=t.message.toLowerCase();return e.some((i)=>n.includes(i))}isTransientError(t){let e=["temporary","try again","rate limit","busy","unavailable"],n=t.message.toLowerCase();return e.some((i)=>n.includes(i))}calculateDelay(t,e){let i=e.baseDelay*e.backoffMultiplier**(t-1)*(0.5+Math.random()*0.5);return Math.min(i,e.maxDelay)}recordError(t,e,n){let i=`${t.operation}:${n}`,r=this.errorMetrics.get(i)||{count:0,lastOccurred:new Date};r.count++,r.lastOccurred=new Date,this.errorMetrics.set(i,r),this.emit("errorRecorded",{context:t,error:e,errorType:n,metrics:r}),this.logger.error(`Error in ${t.operation}:`,e)}recordSuccess(t){this.emit("operationSuccess",{context:t})}sleep(t){return new Promise((e)=>setTimeout(e,t))}getErrorMetrics(){return new Map(this.errorMetrics)}getCircuitBreaker(t){return this.circuitBreakers.get(t)}getAllCircuitBreakers(){return new Map(this.circuitBreakers)}resetMetrics(){this.errorMetrics.clear(),this.emit("metricsReset")}};ht=new Di});import{EventEmitter as Fs}from"events";var wn;var to=v(()=>{tt();wn=class wn extends Fs{healthMetrics=new Map;healthCheckIntervals=new Map;heartbeatTimeouts=new Map;logger=w({prefix:"WorkerHealthMonitor"});options;constructor(t={}){super();this.options={autoRestart:t.autoRestart??!0,criticalThreshold:t.criticalThreshold??180000,healthCheckInterval:t.healthCheckInterval??60000,heartbeatInterval:t.heartbeatInterval??30000,maxRestarts:t.maxRestarts??3,unhealthyThreshold:t.unhealthyThreshold??90000}}startMonitoring(t,e){if(this.healthMetrics.has(t)){this.logger.warn(`Already monitoring worker ${t}`);return}let n={errorCount:0,lastHeartbeat:new Date,restartCount:e.restartCount,status:"healthy",uptime:0,workerId:t};this.healthMetrics.set(t,n),this.logger.info(`Started monitoring worker ${t}`),this.scheduleHealthCheck(t),this.scheduleHeartbeatTimeout(t),this.emit("monitoringStarted",t,n)}stopMonitoring(t){let e=this.healthCheckIntervals.get(t);if(e)clearInterval(e),this.healthCheckIntervals.delete(t);let n=this.heartbeatTimeouts.get(t);if(n)clearTimeout(n),this.heartbeatTimeouts.delete(t);this.healthMetrics.delete(t),this.logger.info(`Stopped monitoring worker ${t}`),this.emit("monitoringStopped",t)}recordHeartbeat(t,e){let n=this.healthMetrics.get(t);if(!n){this.logger.warn(`Received heartbeat for unmonitored worker ${t}`);return}if(n.lastHeartbeat=new Date,e?.cpuUsage!==void 0)n.cpuUsage=e.cpuUsage;if(e?.memoryUsage!==void 0)n.memoryUsage=e.memoryUsage;if(e?.responseTime!==void 0)n.responseTime=e.responseTime;n.uptime=Date.now()-n.lastHeartbeat.getTime();let i=n.status;if(n.status=this.calculateHealthStatus(n),i!==n.status)this.logger.info(`Worker ${t} health changed: ${i} -> ${n.status}`),this.emit("healthChanged",t,n.status,i);this.scheduleHeartbeatTimeout(t)}recordError(t,e){let n=this.healthMetrics.get(t);if(!n)return;n.errorCount++,n.lastError=e.message;let i=n.status;if(n.status=this.calculateHealthStatus(n),i!==n.status)this.emit("healthChanged",t,n.status,i);this.logger.warn(`Worker ${t} error recorded: ${e.message}`)}getHealthMetrics(t){return this.healthMetrics.get(t)}getAllHealthMetrics(){return Array.from(this.healthMetrics.values())}getHealthSummary(){let t={critical:0,healthy:0,total:0,unknown:0,warning:0};for(let e of this.healthMetrics.values())t.total++,t[e.status]++;return t}scheduleHealthCheck(t){let e=setInterval(()=>{this.performHealthCheck(t)},this.options.healthCheckInterval);this.healthCheckIntervals.set(t,e)}scheduleHeartbeatTimeout(t){let e=this.heartbeatTimeouts.get(t);if(e)clearTimeout(e);let n=setTimeout(()=>{this.handleMissedHeartbeat(t)},this.options.heartbeatInterval*2);this.heartbeatTimeouts.set(t,n)}performHealthCheck(t){let e=this.healthMetrics.get(t);if(!e)return;let n=e.status;if(e.status=this.calculateHealthStatus(e),n!==e.status)this.logger.info(`Worker ${t} health check: ${n} -> ${e.status}`),this.emit("healthChanged",t,e.status,n);if(e.status==="critical"&&this.options.autoRestart)if(e.restartCount<this.options.maxRestarts)this.logger.warn(`Worker ${t} is critical, requesting restart`),this.emit("restartRequired",t,e);else this.logger.error(`Worker ${t} exceeded max restarts (${this.options.maxRestarts})`),this.emit("maxRestartsExceeded",t,e);this.emit("healthCheckCompleted",t,e)}handleMissedHeartbeat(t){let e=this.healthMetrics.get(t);if(!e)return;this.logger.warn(`Worker ${t} missed heartbeat`);let n=e.status;if(e.status=this.calculateHealthStatus(e),n!==e.status)this.emit("healthChanged",t,e.status,n);this.emit("heartbeatMissed",t,e)}calculateHealthStatus(t){let e=Date.now()-t.lastHeartbeat.getTime();if(e>this.options.criticalThreshold)return"critical";if(e>this.options.unhealthyThreshold)return"warning";if(t.errorCount>10)return"warning";if(t.cpuUsage&&t.cpuUsage>90)return"warning";if(t.memoryUsage&&t.memoryUsage>90)return"warning";if(t.responseTime&&t.responseTime>5000)return"warning";return"healthy"}async checkWorkerResponsiveness(t,e=5000){return new Promise((n)=>{let i=setTimeout(()=>{n(!1)},e);this.once(`workerResponse:${t}`,()=>{clearTimeout(i),n(!0)}),this.emit("pingWorker",t)})}reportWorkerResponse(t){this.emit(`workerResponse:${t}`)}}});import{EventEmitter as Ds}from"events";var wt,Vt;var Wt=v(()=>{bn();tt();to();wt=class wt extends Ds{options;workers=new Map;workerInfo=new Map;shutdownInProgress=!1;logger=w({prefix:"WorkerManager"});cleanupRegistered=!1;healthMonitor;circuitBreaker=ht.createCircuitBreaker("worker-operations",{failureThreshold:5,halfOpenMaxAttempts:3,resetTimeout:60000});constructor(t={}){super();this.options=t;this.options={gracefulShutdownTimeout:30000,maxRestarts:3,maxWorkers:100,restartDelay:1000,restartOnError:!0,...t},this.healthMonitor=new wn({autoRestart:this.options.restartOnError??!0,maxRestarts:this.options.maxRestarts||3}),this.setupHealthMonitorHandlers(),this.registerCleanup()}setupHealthMonitorHandlers(){this.healthMonitor.on("restartRequired",(t)=>{let e=this.getWorkerConfig(t);if(e){let n=this.workerInfo.get(t);if(n)this.scheduleRestart(e,n)}}),this.healthMonitor.on("healthChanged",(t,e,n)=>{this.emit("workerHealthChanged",t,e,n)}),this.healthMonitor.on("maxRestartsExceeded",(t)=>{this.logger.error(`Worker ${t} exceeded max restarts, not restarting`),this.emit("workerMaxRestartsExceeded",t)})}getWorkerConfig(t){return}registerCleanup(){if(this.cleanupRegistered)return;this.cleanupRegistered=!0;let t=async()=>{if(!this.shutdownInProgress)await this.shutdown()};process.on("exit",()=>{if(!this.shutdownInProgress&&this.workers.size>0)this.logger.warn("Forced exit with active workers")}),process.on("SIGINT",async()=>{this.logger.info("Received SIGINT, initiating graceful shutdown..."),await t(),process.exit(0)}),process.on("SIGTERM",async()=>{this.logger.info("Received SIGTERM, initiating graceful shutdown..."),await t(),process.exit(0)}),process.on("uncaughtException",async(e)=>{this.logger.error("Uncaught exception:",e),await t(),process.exit(1)})}async createWorker(t){if(this.shutdownInProgress)throw new Error("Cannot create worker during shutdown");if(this.workers.size>=(this.options.maxWorkers||100))throw new Error(`Maximum worker limit reached: ${this.options.maxWorkers}`);if(this.workers.has(t.id))throw new Error(`Worker with id ${t.id} already exists`);let e={id:t.id,name:t.name,restartCount:0,startTime:new Date,status:"starting"};this.workerInfo.set(t.id,e);let n={operation:"createWorker",runnerName:t.name,workerId:t.id};try{await this.circuitBreaker.execute(async()=>{await ht.executeWithRecovery(async()=>{let i=new Worker(t.scriptPath,{name:t.name,ref:!0});if(this.workers.set(t.id,i),this.setupWorkerHandlers(i,t,e),t.data)i.postMessage(t.data);e.status="running",this.emit("workerStarted",e),this.logger.info(`Worker ${t.name} (${t.id}) started`),this.healthMonitor.startMonitoring(t.id,e)},n)})}catch(i){throw e.status="error",e.error=i,e.endTime=new Date,this.emit("workerError",e,i),i}}setupWorkerHandlers(t,e,n){t.addEventListener("message",({data:i})=>{if(i.type==="heartbeat")this.healthMonitor.recordHeartbeat(e.id,i.metrics);else this.emit("workerMessage",n,i),e.onMessage?.(i)}),t.addEventListener("error",(i)=>{if(this.logger.error(`Worker ${e.name} error:`,i),n.status="error",n.error=i.error||i,this.emit("workerError",n,i),e.onError?.(i.error||i),this.healthMonitor.recordError(e.id,i.error||i),this.options.restartOnError&&n.restartCount<(this.options.maxRestarts||3))this.scheduleRestart(e,n)}),t.addEventListener("exit",(i)=>{let r=i.code||0;if(this.logger.info(`Worker ${e.name} exited with code ${r}`),this.workers.delete(e.id),n.status="stopped",n.endTime=new Date,this.emit("workerExit",n,r),e.onExit?.(r),this.healthMonitor.stopMonitoring(e.id),r!==0&&this.options.restartOnError&&n.restartCount<(this.options.maxRestarts||3))this.scheduleRestart(e,n)})}scheduleRestart(t,e){if(this.shutdownInProgress)return;e.restartCount++,this.logger.info(`Scheduling restart for worker ${t.name} (attempt ${e.restartCount}/${this.options.maxRestarts})`),setTimeout(async()=>{if(!this.shutdownInProgress)try{await this.createWorker(t)}catch(n){this.logger.error(`Failed to restart worker ${t.name}:`,n)}},this.options.restartDelay)}async terminateWorker(t,e=!1){let n=this.workers.get(t),i=this.workerInfo.get(t);if(!n||!i)throw new Error(`Worker ${t} not found`);if(i.status="stopping",this.emit("workerStopping",i),!e)n.postMessage({type:"shutdown"}),await new Promise((r)=>{let s=setTimeout(()=>{this.logger.warn(`Worker ${i.name} did not shutdown gracefully, terminating...`),n.terminate(),r()},this.options.gracefulShutdownTimeout);n.addEventListener("exit",()=>{clearTimeout(s),r()})});else n.terminate();this.workers.delete(t),i.status="stopped",i.endTime=new Date,this.workerInfo.delete(t),this.healthMonitor.stopMonitoring(t)}async shutdown(){if(this.shutdownInProgress)return;this.shutdownInProgress=!0,this.logger.info(`Shutting down ${this.workers.size} workers...`),this.emit("shutdown");let t=[];for(let[e]of this.workers)t.push(this.terminateWorker(e).catch((n)=>{this.logger.error(`Error terminating worker ${e}:`,n)}));await Promise.all(t),this.workers.clear(),this.workerInfo.clear(),this.logger.info("All workers terminated"),this.emit("shutdownComplete")}getWorkerInfo(t){return this.workerInfo.get(t)}getAllWorkerInfo(){return Array.from(this.workerInfo.values())}getWorkerCount(){return this.workers.size}getActiveWorkerCount(){return Array.from(this.workerInfo.values()).filter((t)=>t.status==="running").length}hasWorker(t){return this.workers.has(t)}isShuttingDown(){return this.shutdownInProgress}getWorkerHealth(t){return this.healthMonitor.getHealthMetrics(t)}getAllWorkerHealth(){return this.healthMonitor.getAllHealthMetrics()}getHealthSummary(){return this.healthMonitor.getHealthSummary()}};Vt=new wt});async function oo(t){try{let e=`${t}/hooks`;await Bun.$`mkdir -p ${e}`.quiet(),await Bun.write(`${e}/pre.sh`,vn.preHook),await Bun.$`chmod +x ${e}/pre.sh`.quiet(),await Bun.write(`${e}/post.sh`,vn.postHook),await Bun.$`chmod +x ${e}/post.sh`.quiet(),await Bun.write(`${t}/.runner-env`,vn.runnerEnv),io.debug(`Created runner hooks and environment for ${t}`)}catch(e){throw io.error("Failed to create runner files:",e),e}}var io,vn;var ro=v(()=>{O();io=$({prefix:"runner-templates"}),vn={postHook:`git reset --hard && git clean --force -df
|
|
66
|
+
`,preHook:`export BUN_INSTALL_CACHE_DIR=./.bun/cache
|
|
67
|
+
`,runnerEnv:`ACTIONS_RUNNER_HOOK_JOB_STARTED=./hooks/pre.sh
|
|
68
|
+
ACTIONS_RUNNER_HOOK_JOB_COMPLETED=./hooks/post.sh
|
|
69
|
+
`}});var so={};ie(so,{createMachines:()=>zt});import{homedir as pa}from"os";import{join as ha}from"path";import{parseArgs as da}from"util";var{$:Zt}=globalThis.Bun;async function zt(){let t=w({prefix:"createMachines"}),e=await ma(),{overwrite:n,directory:i,numberOfMachines:r,os:s,run:o,name:a,labels:f,runnerGroup:u}=e,{token:p,url:d}=e;if(!d)throw new Error("URL (-u) parameter is required");if(!p){let b=ga(d),m=await C({message:`No token provided. Would you like to open GitHub to get a runner token?
|
|
70
|
+
${b}`});if(k(m)||!m)throw new Error("Token is required to create runners");t.info("Opening GitHub runner settings..."),await Zt`open ${b}`.quiet();let x=await A({message:"Enter the runner registration token:",placeholder:"AXXXXXXXXXXXXXXXXXXXXXXXXX",validate:(M)=>{if(!M||M.trim().length===0)return"Token is required";return}});if(k(x))throw new Error("Token is required to create runners");p=x.trim()}if(t=w({prefix:"createMachines",secrets:[p]}),t.info(`Creating ${r} runners in ${i}`),t.debug(`OS: ${s}, Name: ${a}, Labels: ${f||"none"}`),await y.exists(i))if(n)t.warn(`Directory ${i} exists, removing...`),await y.deleteDirectory(i,{recursive:!0});else throw new Error(`Directory ${i} already exists`);let g=await ya({directory:i,os:s});if(await ba({directory:i,numberOfMachines:r,overwrite:n,runnerBase:g}),!o){t.info("Runners created but not started");return}await wa({directory:i,labels:f,name:a,numberOfMachines:r,runnerGroup:u,token:p,url:d})}function ga(t){try{let e=new URL(t),n=e.pathname.split("/").filter(Boolean);if(e.hostname==="github.com"||e.hostname==="www.github.com"){if(n[0]==="orgs"&&n[1])return`https://github.com/organizations/${n[1]}/settings/actions/runners/new`;if(n.length>=2)return`https://github.com/${n[0]}/${n[1]}/settings/actions/runners/new`}else{if(n[0]==="orgs"&&n[1])return`${e.origin}/organizations/${n[1]}/settings/actions/runners/new`;if(n.length>=2)return`${e.origin}/${n[0]}/${n[1]}/settings/actions/runners/new`}return t}catch{return t}}async function ma(){let{values:t}=da({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},labels:{short:"l",type:"string"},name:{default:"runner",short:"n",type:"string"},numberOfMachines:{default:"1",short:"m",type:"string"},os:{default:"osx",short:"s",type:"string"},overwrite:{default:!1,short:"f",type:"boolean"},profile:{short:"p",type:"string"},run:{default:!1,short:"r",type:"boolean"},runnerGroup:{short:"g",type:"string"},template:{short:"T",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile),i;if(t.template)i=await xa(t.template);let r={directory:t.directory,labels:t.labels,name:t.name,numberOfMachines:t.numberOfMachines,os:t.os,overwrite:t.overwrite,run:t.run,runnerGroup:t.runnerGroup,token:t.token||process.env.GITHUB_TOKEN||process.env.RUNNER_TOKEN,url:t.url},s=n||i?{directory:r.directory??n?.directory??i?.directory??`${process.cwd()}/gh-runners`,labels:r.labels??n?.labels??i?.labels,name:r.name??n?.name??i?.name??"runner",numberOfMachines:r.numberOfMachines??String(n?.numberOfMachines??i?.numberOfMachines)??"1",os:r.os??n?.os??i?.os??"osx",overwrite:r.overwrite??n?.overwrite??i?.overwrite??!1,run:r.run??n?.run??i?.run??!1,runnerGroup:r.runnerGroup??n?.runnerGroup??i?.runnerGroup,token:r.token,url:r.url??n?.url??i?.url}:null;if(s)return s;return{directory:r.directory,labels:r.labels,name:r.name,numberOfMachines:r.numberOfMachines,os:r.os,overwrite:r.overwrite,run:r.run,runnerGroup:r.runnerGroup,token:r.token,url:r.url}}async function ya({directory:t,os:e}){let n=w({prefix:"createMachines:download",secrets:[]}),i=j(t);n.info(`Fetching latest runner version for ${e}...`);let r=await it(async()=>(await Zt`curl -Ls -o /dev/null -w "%{url_effective}" https://github.com/actions/runner/releases/latest`).text(),{onRetry:(u,p)=>{n.warn(`Retrying GitHub API call (attempt ${u}): ${p.message}`)}}),o=(await Zt`basename ${j(r)}`).text().trim().replace("v",""),a=`actions-runner-${e}-x64-${o}.tar.gz`,f=`https://github.com/actions/runner/releases/download/v${o}/${a}`;if(n.debug(`Runner version: ${o}`),n.debug(`Download URL: ${f}`),await mn(t),await mn(`${t}/machines`),!await y.exists(`${t}/${a}`))n.info("Downloading runner image..."),await it(async()=>await Zt`curl -o ${i}/${j(a)} -L ${f}`,{maxAttempts:5,onRetry:(u,p)=>{n.warn(`Retrying runner download (attempt ${u}): ${p.message}`)}}),n.info("Download complete");else n.info("Runner image already exists, skipping download");return a}async function ba({overwrite:t,numberOfMachines:e,directory:n,runnerBase:i}){let r=w({prefix:"createMachines:extract",secrets:[]}),s=Number(e),o=(()=>{try{let p=Bun.spawnSync(["nproc"]);return Number.parseInt(p.stdout.toString().trim(),10)||4}catch{try{let p=Bun.spawnSync(["sysctl","-n","hw.ncpu"]);return Number.parseInt(p.stdout.toString().trim(),10)||4}catch{return 4}}})(),a=Math.min(Math.max(2,Math.floor(o/2)),s,8);r.info(`Extracting ${s} runners with concurrency of ${a}`);let f=Array.from({length:s},(p,d)=>d+1).map((p)=>({execute:async()=>{let d=`${n}/machines/${p}`;if(await y.exists(d))if(t)r.debug(`Machine ${p} already exists, removing...`),await y.deleteDirectory(d,{recursive:!0});else{r.debug(`Machine ${p} already exists, skipping...`);return}await y.createDirectory(d),await Zt`tar xzf ${i} -C ${d.replace(`${n}/`,"")}`.cwd(n),await oo(d),r.debug(`Machine ${p} extracted successfully`)},runnerIndex:p})),u=[];for(let p=0;p<f.length;p+=a){let d=f.slice(p,p+a),g=await Promise.allSettled(d.map((b)=>b.execute()));for(let[b,m]of g.entries())if(m.status==="rejected")throw r.error(`Failed to extract runner ${d[b]?.runnerIndex}: ${m.reason}`),m.reason;u.push(...g)}r.info(`Successfully extracted ${s} runners`)}async function wa({directory:t,numberOfMachines:e,token:n,url:i,name:r,labels:s,runnerGroup:o}){let a=w({prefix:"createMachines:start",secrets:[n]});a.info(`Starting ${e} runners...`);let f=new wt({maxRestarts:3,maxWorkers:Number(e),restartDelay:5000,restartOnError:!0});for(let u=1;u<=Number(e);u++){let p=`${xe()}/src/runner-worker.ts`,d=`${r}-${u}`,g=`runner-${u}`;await f.createWorker({data:{index:u,labels:s,machineCwd:`${t}/machines/${u}`,name:r,runnerGroup:o,token:n,url:i},id:g,name:d,onError:(b)=>{a.error(`Worker ${d} error:`,b)},onExit:(b)=>{a.info(`Worker ${d} exited with code ${b}`)},onMessage:(b)=>{let m=b.type==="error"?"error":"info";a[m](`${d}: ${b.message}`)},scriptPath:p})}a.info("All workers started. Press Ctrl+C to stop all machines")}async function xa(t){let e=w({prefix:"loadTemplate"}),n="./hydra-templates.json",i=Bun.file("./hydra-templates.json");if(await i.exists())try{let o=await i.json();if(o.templates?.[t])return e.info(`Using local template: ${t}`),Rn(o.templates[t],o.templates)}catch(o){e.warn(`Failed to load local templates: ${o}`)}let r=ha(pa(),".hydra","templates.json"),s=Bun.file(r);if(await s.exists())try{let o=await s.json();if(o.templates?.[t])return e.info(`Using global template: ${t}`),Rn(o.templates[t],o.templates)}catch(o){e.warn(`Failed to load global templates: ${o}`)}e.warn(`Template '${t}' not found`);return}function Rn(t,e,n=new Set){if(t.name&&n.has(t.name))throw new Error(`Circular template dependency detected: ${t.name}`);if(t.name)n.add(t.name);let i={};if(t.extends&&e[t.extends])i=Rn(e[t.extends],e,n);let{name:r,description:s,extends:o,metadata:a,...f}=t;return{...i,...f}}var Ee=v(()=>{q();O();V();Mt();F();ro();tt();Wt()});var ao={};ie(ao,{runMachines:()=>En});import{parseArgs as $a}from"util";var{$:va}=globalThis.Bun;async function En(){let t=await Ra(),{directory:e,numberOfMachines:n,name:i,labels:r,runnerGroup:s}=t,{token:o,url:a}=t;if(!a)throw new Error("URL (-u) parameter is required");if(!o){let f=Pa(a),u=await C({message:`No token provided. Would you like to open GitHub to get a runner token?
|
|
71
|
+
${f}`});if(k(u)||!u)throw new Error("Token is required to run machines");Pe.info("Opening GitHub runner settings..."),await va`open ${f}`.quiet();let p=await A({message:"Enter the runner registration token:",placeholder:"AXXXXXXXXXXXXXXXXXXXXXXXXX",validate:(d)=>{if(!d||d.trim().length===0)return"Token is required";return}});if(k(p))throw new Error("Token is required to run machines");o=p.trim()}if(Pe=w({prefix:"runMachines",secrets:[o]}),Pe.info(`Starting ${n} runners from ${e}`),Pe.debug(`Name: ${i}, Labels: ${r||"none"}`),!await y.exists(`${e}/machines`))throw new Error(`Machines directory not found at ${e}/machines. Run 'hydra create' first.`);await Ea({directory:e,labels:r,name:i,numberOfMachines:n,runnerGroup:s,token:o,url:a})}async function Ra(){let{values:t}=$a({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},labels:{short:"l",type:"string"},name:{default:"runner",short:"n",type:"string"},numberOfMachines:{default:"1",short:"m",type:"string"},profile:{short:"p",type:"string"},runnerGroup:{short:"g",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile),i={directory:t.directory,labels:t.labels,name:t.name,numberOfMachines:t.numberOfMachines,runnerGroup:t.runnerGroup,token:t.token||process.env.GITHUB_TOKEN||process.env.RUNNER_TOKEN,url:t.url};if(n)return{directory:i.directory??n.directory??`${process.cwd()}/gh-runners`,labels:i.labels??n.labels,name:i.name??n.name??"runner",numberOfMachines:i.numberOfMachines??String(n.numberOfMachines)??"1",runnerGroup:i.runnerGroup??n.runnerGroup,token:i.token,url:i.url??n.url};return i}async function Ea({directory:t,numberOfMachines:e,token:n,url:i,name:r,labels:s,runnerGroup:o}){let a=w({prefix:"runMachines:start",secrets:[n]});a.info(`Starting ${e} workers...`);let f=new wt({maxRestarts:3,maxWorkers:Number(e),restartDelay:5000,restartOnError:!0});f.on("workerError",(p,d)=>{a.error(`Worker ${p.name} encountered error:`,d)}),f.on("workerExit",(p,d)=>{if(d!==0)a.warn(`Worker ${p.name} exited with code ${d}`)});let u=0;for(let p=1;p<=Number(e);p++){let d=`${t}/machines/${p}`;if(!await y.exists(d)){a.warn(`Machine ${p} doesn't exist, skipping...`);continue}let g=`${xe()}/src/runner-worker.ts`,b=`${r}-${p}`,m=`runner-${p}`;try{await f.createWorker({data:{index:p,labels:s,machineCwd:d,name:r,runnerGroup:o,token:n,url:i},id:m,name:b,onError:(x)=>{a.error(`Worker ${b} error:`,x)},onExit:(x)=>{a.info(`Worker ${b} exited with code ${x}`)},onMessage:(x)=>{let M=x.type==="error"?"error":"info";a[M](`${b}: ${x.message}`)},scriptPath:g}),a.info(`Worker ${b} started successfully`),u++}catch(x){a.error(`Failed to start worker ${b}:`,x)}}if(u===0)throw new Error("No workers could be started");a.info(`${u} workers started. Press Ctrl+C to stop all machines`),process.on("SIGINT",async()=>{a.info("Gracefully shutting down workers..."),await f.shutdown(),process.exit(0)})}function Pa(t){try{let e=new URL(t),n=e.pathname.split("/").filter(Boolean);if(e.hostname==="github.com"||e.hostname==="www.github.com"){if(n[0]==="orgs"&&n[1])return`https://github.com/organizations/${n[1]}/settings/actions/runners/new`;if(n.length>=2)return`https://github.com/${n[0]}/${n[1]}/settings/actions/runners/new`}else{if(n[0]==="orgs"&&n[1])return`${e.origin}/organizations/${n[1]}/settings/actions/runners/new`;if(n.length>=2)return`${e.origin}/${n[0]}/${n[1]}/settings/actions/runners/new`}return t}catch{return t}}var Pe;var Pn=v(()=>{q();V();Mt();F();tt();Wt();Pe=w({prefix:"runMachines"})});var fo={};ie(fo,{removeMachines:()=>Yt});import{parseArgs as Aa}from"util";var{$:lo}=globalThis.Bun;async function Yt(){let t=await Ta(),{directory:e,numberOfMachines:n,force:i}=t,{token:r,url:s}=t,o=`${e}/machines`;if(!await y.exists(o))throw new Error(`Machines directory not found at ${o}. Nothing to remove.`);if(r)ot=w({prefix:"hydra:remove",secrets:[r]});if(!r&&!i){if(!s)throw ot.warn("No token or URL provided. Runners will not be unregistered from GitHub."),ot.warn("Use --force to remove runners without unregistering them."),new Error("Token (-t) and URL (-u) parameters are required or use --force");let a=Ca(s),f=await C({message:`No token provided. Would you like to open GitHub to get a runner token for unregistration?
|
|
72
|
+
${a}`});if(k(f)||!f)throw ot.warn("Use --force to remove runners without unregistering them."),new Error("Token is required to unregister runners (or use --force)");ot.info("Opening GitHub runner settings..."),await lo`open ${a}`.quiet();let u=await A({message:"Enter the runner removal token:",placeholder:"AXXXXXXXXXXXXXXXXXXXXXXXXX",validate:(p)=>{if(!p||p.trim().length===0)return"Token is required";return}});if(k(u))throw ot.warn("Use --force to remove runners without unregistering them."),new Error("Token is required to unregister runners (or use --force)");r=u.trim()}if(r&&s)ot.info("Unregistering runners from GitHub..."),await Oa({directory:e,numberOfMachines:n,token:r});else if(!i)throw ot.warn("No token or URL provided. Runners will not be unregistered from GitHub."),ot.warn("Use --force to remove runners without unregistering them."),new Error("Token (-t) and URL (-u) parameters are required or use --force");await Ha({directory:e,numberOfMachines:n}),ot.info("Runners successfully removed")}async function Ta(){let{values:t}=Aa({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},force:{default:!1,short:"f",type:"boolean"},numberOfMachines:{default:"1",short:"m",type:"string"},profile:{short:"p",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile),i={directory:t.directory,force:t.force,numberOfMachines:t.numberOfMachines,token:t.token||process.env.GITHUB_TOKEN||process.env.RUNNER_TOKEN,url:t.url};if(n)return{directory:i.directory??n.directory??`${process.cwd()}/gh-runners`,force:i.force,numberOfMachines:i.numberOfMachines??String(n.numberOfMachines)??"1",token:i.token,url:i.url??n.url};return i}async function Oa({directory:t,numberOfMachines:e,token:n}){let i=w({prefix:"hydra:remove:unregister",secrets:[n]}),r=Number(e),s=(()=>{try{let g=Bun.spawnSync(["nproc"]);return Number.parseInt(g.stdout.toString().trim(),10)||4}catch{try{let g=Bun.spawnSync(["sysctl","-n","hw.ncpu"]);return Number.parseInt(g.stdout.toString().trim(),10)||4}catch{return 4}}})(),o=Math.min(Math.max(2,Math.floor(s/2)),r,8);i.info(`Unregistering ${r} runners with concurrency of ${o}`);let a=Array.from({length:r},(g,b)=>b+1).map((g)=>({execute:async()=>{let b=`${t}/machines/${g}`;if(!await y.exists(b))return i.debug(`Machine ${g} doesn't exist, skipping...`),{runnerIndex:g,status:"skipped"};try{return i.debug(`Unregistering machine ${g}...`),await lo`${j(b)}/config.sh remove`.quiet().env({...process.env,RUNNER_CFG_PAT:n}),i.info(`Successfully unregistered machine ${g} from GitHub`),{runnerIndex:g,status:"success"}}catch(m){return i.warn(`Unable to unregister machine ${g}: ${m}`),{error:m,runnerIndex:g,status:"failed"}}},runnerIndex:g})),f=[];for(let g=0;g<a.length;g+=o){let b=a.slice(g,g+o),m=await Promise.allSettled(b.map((x)=>x.execute()));f.push(...m)}let u=f.filter((g)=>g.status==="fulfilled"&&g.value?.status==="success").length,p=f.filter((g)=>g.status==="fulfilled"&&g.value?.status==="failed").length,d=f.filter((g)=>g.status==="fulfilled"&&g.value?.status==="skipped").length;i.info(`Unregistration complete: ${u} successful, ${p} failed, ${d} skipped`)}async function Ha({directory:t,numberOfMachines:e}){let n=w({prefix:"hydra:remove:removeDirectories",secrets:[]}),i=Number(e),r=Array.from({length:i},(f,u)=>u+1).map((f)=>({execute:async()=>{let u=`${t}/machines/${f}`;if(!await y.exists(u))return{runnerIndex:f,status:"skipped"};try{return await y.deleteDirectory(u,{recursive:!0}),n.debug(`Removed machine ${f} directory`),{runnerIndex:f,status:"success"}}catch(p){return n.error(`Error removing machine ${f} directory: ${p}`),{error:p,runnerIndex:f,status:"failed"}}},runnerIndex:f})),s=await Promise.allSettled(r.map((f)=>f.execute())),o=s.filter((f)=>f.status==="fulfilled"&&f.value?.status==="success").length,a=s.filter((f)=>f.status==="fulfilled"&&f.value?.status==="failed").length;if(n.info(`Directory removal complete: ${o} removed, ${a} failed`),a>0)throw new Error(`Failed to remove ${a} runner directories`);try{let f=`${t}/machines`;if((await y.listDirectory(f)).length===0){if(await y.deleteDirectory(f,{recursive:!0}),(await y.listDirectory(t)).length===0)await y.deleteDirectory(t,{recursive:!0});ot.info("Removed empty directories")}}catch(f){}}function Ca(t){try{let e=new URL(t),n=e.pathname.split("/").filter(Boolean);if(e.hostname==="github.com"||e.hostname==="www.github.com"){if(n[0]==="orgs"&&n[1])return`https://github.com/organizations/${n[1]}/settings/actions/runners`;if(n.length>=2)return`https://github.com/${n[0]}/${n[1]}/settings/actions/runners`}else{if(n[0]==="orgs"&&n[1])return`${e.origin}/organizations/${n[1]}/settings/actions/runners`;if(n.length>=2)return`${e.origin}/${n[0]}/${n[1]}/settings/actions/runners`}return t}catch{return t}}var ot;var Ae=v(()=>{q();V();Mt();F();tt();ot=w({prefix:"hydra:remove"})});O();G();var St="0.5.1";O();class Xi{commands=new Map;aliases=new Map;register(t){if(this.commands.set(t.name,t),t.aliases)for(let e of t.aliases)this.aliases.set(e,t.name)}get(t){let e=this.aliases.get(t)||t;return this.commands.get(e)}has(t){return this.commands.has(t)||this.aliases.has(t)}getAll(){return Array.from(this.commands.values())}getNames(){return Array.from(this.commands.keys())}getAliases(){return new Map(this.aliases)}}var L=new Xi;var Qi={backup:{description:"Backup and restore runner configurations",examples:[{command:"hydra backup",description:"Create a backup"},{command:"hydra backup -o /path/to/backups",description:"Create backup in custom location"},{command:"hydra backup --list",description:"List available backups"},{command:"hydra backup --restore backup-2024-01-15T10-30-00-000Z",description:"Restore from backup"},{command:"hydra backup --no-compress",description:"Create uncompressed backup"}],name:"hydra backup",notes:["Backs up runner configuration files (.runner, .credentials, etc.)","Does NOT backup work directories or logs","Compressed backups save space but take longer","Restore will prompt before overwriting existing runners"],options:[{description:"Runners directory",flags:"-d, --directory",type:"string"},{description:"Backup output directory",flags:"-o, --output",type:"string"},{description:"List available backups",flags:"-l, --list",type:"boolean"},{description:"Restore from backup ID",flags:"-r, --restore",type:"string"},{default:!0,description:"Compress backup (tar.gz)",flags:"--compress",type:"boolean"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra backup [options]"},create:{description:"Create and register new GitHub runner machines",examples:[{command:"hydra create -t TOKEN -u https://github.com/org/repo",description:"Create a single runner"},{command:"hydra create -p production --run",description:"Create and start runners from profile"},{command:"hydra create -m 5 -l docker,linux --run",description:"Create 5 runners with custom labels"},{command:"hydra create --force",description:"Overwrite existing runners"},{command:"hydra create -T production -t TOKEN -u URL",description:"Create runners using a template"}],name:"hydra create",notes:["Requires a GitHub personal access token or runner registration token","Downloads the latest runner image if not cached","Creates runners in parallel for better performance","Use --run to start runners immediately after creation","Runners are created but not started by default"],options:[{description:"GitHub runner token",flags:"-t, --token",type:"string"},{description:"Repository/organization URL",flags:"-u, --url",type:"string"},{default:"./gh-runners",description:"Directory to store runners",flags:"-d, --directory",type:"string"},{default:"1",description:"Number of machines to create",flags:"-m, --numberOfMachines",type:"string"},{default:"runner",description:"Runner name prefix",flags:"-n, --name",type:"string"},{description:"Runner labels (comma-separated)",flags:"-l, --labels",type:"string"},{description:"Runner group",flags:"-g, --runnerGroup",type:"string"},{default:"osx",description:"Operating system (osx, linux, windows)",flags:"-s, --os",type:"string"},{default:!1,description:"Overwrite existing runners",flags:"-f, --overwrite",type:"boolean"},{default:!1,description:"Start runners after creation",flags:"-r, --run",type:"boolean"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"},{description:"Use a template configuration",flags:"-T, --template",type:"string"}],usage:"hydra create [options]"},dev:{description:"Development helper commands",examples:[{command:"hydra dev setup",description:"Set up development environment"},{command:"hydra dev test",description:"Test development setup"},{command:"hydra dev clean",description:"Clean development files"},{command:"hydra dev reset",description:"Reset development environment"}],name:"dev",notes:["Creates test configurations and directories","Sets up .env.development with sample values","Test action verifies setup completeness"],options:[{description:"Force action without prompts",flags:"-f, --force",type:"boolean"}],sections:[{content:["setup - Create development environment","test - Verify development setup","clean - Remove development files","reset - Clean and setup fresh"],title:"ACTIONS"}],usage:"hydra dev <action> [options]"},health:{description:"Check runner health and fix common issues",examples:[{command:"hydra health",description:"Interactive health check"},{command:"hydra health --json",description:"JSON output for automation"},{command:"hydra health --fix",description:"Automatically fix issues"},{command:"hydra health -l critical",description:"Show only critical issues"}],name:"hydra health",notes:["Checks runner processes, disk space, and configurations","Can automatically fix common issues like stale locks","Use --json for integration with monitoring systems","Exit code indicates health status (0=healthy, 1=warning, 2=critical)"],options:[{default:"./gh-runners",description:"Runners directory",flags:"-d, --directory",type:"string"},{default:!1,description:"Automatically fix issues",flags:"-f, --fix",type:"boolean"},{default:!1,description:"Output as JSON",flags:"-j, --json",type:"boolean"},{default:"all",description:"Filter by level (all, critical, warning)",flags:"-l, --level",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra health [options]"},logs:{description:"View runner diagnostic logs",examples:[{command:"hydra logs",description:"Interactive log viewer"},{command:"hydra logs --list",description:"List all available logs"},{command:"hydra logs -r 1 -t Worker",description:"View Worker logs for runner 1"},{command:"hydra logs --tail 50",description:"Show last 50 lines of logs"}],name:"hydra logs",notes:["Logs are stored in the _diag directory of each runner","Use --list to see all available log files","Interactive mode lets you browse and select logs","Log types include Runner, Worker, and SelfUpdater"],options:[{default:"./gh-runners",description:"Runners directory",flags:"-d, --directory",type:"string"},{description:"Runner ID (e.g., 1, 2, 3)",flags:"-r, --runner",type:"string"},{description:"Log type (Runner, Worker, etc.)",flags:"-t, --type",type:"string"},{default:!1,description:"List available logs",flags:"-l, --list",type:"boolean"},{description:"Number of lines to show",flags:"--tail",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra logs [options]"},migrate:{description:"Migrate configuration files between formats and versions",examples:[{command:"hydra migrate",description:"Interactively migrate a config file"},{command:"hydra migrate -p hydra.json",description:"Migrate specific config file"},{command:"hydra migrate -f toml",description:"Convert config to TOML format"},{command:"hydra migrate --all",description:"Find and migrate all config files"},{command:"hydra migrate --dry-run",description:"Preview migration changes"}],name:"hydra migrate",notes:["Supports migration between JSON and TOML formats","Automatically upgrades deprecated configuration options","Creates backups before modifying files (use --no-backup to skip)","Converts old root-level settings to profile-based configuration","Use --dry-run to see what changes would be made"],options:[{description:"Path to configuration file",flags:"-p, --path",type:"string"},{description:"Target format (json or toml)",flags:"-f, --format",type:"string"},{default:!1,description:"Find and migrate all config files",flags:"-a, --all",type:"boolean"},{default:!1,description:"Preview changes without modifying files",flags:"-d, --dry-run",type:"boolean"},{default:!0,description:"Create backup before migration",flags:"-b, --backup",type:"boolean"}],usage:"hydra migrate [options]"},monitor:{description:"Monitor worker health and performance",examples:[{command:"hydra monitor",description:"Show current worker health status"},{command:"hydra monitor --watch",description:"Continuously monitor health"},{command:"hydra monitor --json",description:"Output health data as JSON"},{command:"hydra monitor -w -i 10",description:"Watch mode with 10 second intervals"}],name:"hydra monitor",notes:["Displays health metrics for all active workers","Tracks CPU usage, memory, uptime, errors, and restarts","Health states: healthy, warning, critical, unknown","Watch mode refreshes display at specified intervals","Uses heartbeat mechanism to detect unresponsive workers"],options:[{default:"./gh-runners",description:"Runners directory",flags:"-d, --directory",type:"string"},{default:!1,description:"Output as JSON",flags:"-j, --json",type:"boolean"},{default:!1,description:"Continuous monitoring mode",flags:"-w, --watch",type:"boolean"},{default:"5",description:"Update interval in seconds",flags:"-i, --interval",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra monitor [options]"},plugin:{description:"Manage Hydra plugins",examples:[{command:"hydra plugin",description:"List installed plugins"},{command:"hydra plugin --list",description:"List all plugins with details"},{command:"hydra plugin --install ./my-plugin",description:"Install local plugin"},{command:"hydra plugin --install https://github.com/user/hydra-slack",description:"Install from git"},{command:"hydra plugin --uninstall slack",description:"Uninstall a plugin"},{command:"hydra plugin --info slack",description:"Show plugin details"}],name:"hydra plugin",notes:["Plugins extend Hydra with additional commands and hooks","Plugins are loaded from ~/.hydra/plugins directory","Set HYDRA_DISABLE_PLUGINS=true to disable all plugins","Set HYDRA_PLUGIN_DIR to load plugins from custom location"],options:[{description:"List installed plugins",flags:"-l, --list",type:"boolean"},{description:"Install a plugin",flags:"-i, --install",type:"boolean"},{description:"Uninstall a plugin",flags:"-u, --uninstall",type:"boolean"},{description:"Show plugin information",flags:"--info",type:"boolean"}],usage:"hydra plugin [action] [plugin-name]"},recovery:{description:"Advanced error recovery and resilience management",examples:[{command:"hydra recovery",description:"Interactive recovery management"},{command:"hydra recovery status",description:"View recovery system status"},{command:"hydra recovery metrics",description:"Show detailed error metrics"},{command:"hydra recovery breakers",description:"View circuit breaker states"},{command:"hydra recovery reset",description:"Reset error metrics"},{command:"hydra recovery status --json",description:"JSON output for monitoring"}],name:"hydra recovery",notes:["Provides automatic retry with exponential backoff for transient errors","Circuit breakers prevent cascading failures","Error classification helps determine recovery strategies","Metrics track error patterns for troubleshooting","Recovery strategies are customizable per error type"],options:[{default:!1,description:"Output as JSON",flags:"-j, --json",type:"boolean"}],sections:[{content:["status - View overall recovery system status","metrics - Show detailed error metrics by type","breakers - View circuit breaker states","reset - Reset all error metrics"],title:"ACTIONS"},{content:["transient - Temporary errors that may succeed on retry","network - Network connectivity issues","configuration - Invalid settings or permissions","resource - System resource exhaustion","unknown - Unclassified errors"],title:"ERROR TYPES"}],usage:"hydra recovery [action] [options]"},remove:{description:"Remove GitHub runner machines",examples:[{command:"hydra remove -t TOKEN -u https://github.com/org/repo",description:"Remove and unregister runners"},{command:"hydra remove --force",description:"Remove without unregistering"},{command:"hydra remove -m 3",description:"Remove specific number of runners"},{command:"hydra remove -p production",description:"Remove using profile settings"}],name:"hydra remove",notes:["Unregisters runners from GitHub before removing (requires token)","Use --force to skip unregistration (use with caution)","Removes runner directories and all associated data","Cannot be undone - consider using backup first"],options:[{description:"GitHub runner token",flags:"-t, --token",type:"string"},{description:"Repository/organization URL",flags:"-u, --url",type:"string"},{default:"./gh-runners",description:"Directory containing runners",flags:"-d, --directory",type:"string"},{default:"1",description:"Number of machines to remove",flags:"-m, --numberOfMachines",type:"string"},{default:!1,description:"Force removal without unregistering",flags:"-f, --force",type:"boolean"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra remove [options]"},run:{description:"Start existing GitHub runner machines",examples:[{command:"hydra run -t TOKEN -u https://github.com/org/repo",description:"Start runners with token"},{command:"hydra run -p production",description:"Start using profile settings"},{command:"hydra run -m 3",description:"Start specific number of runners"},{command:"hydra run -l docker,gpu",description:"Start with additional labels"}],name:"hydra run",notes:["Starts runners that were previously created","Each runner runs in a separate worker process","Press Ctrl+C to stop all runners gracefully","Requires token if runners need to be reconfigured"],options:[{description:"GitHub runner token",flags:"-t, --token",type:"string"},{description:"Repository/organization URL",flags:"-u, --url",type:"string"},{default:"./gh-runners",description:"Directory containing runners",flags:"-d, --directory",type:"string"},{default:"1",description:"Number of machines to run",flags:"-m, --numberOfMachines",type:"string"},{default:"runner",description:"Runner name prefix",flags:"-n, --name",type:"string"},{description:"Runner labels (comma-separated)",flags:"-l, --labels",type:"string"},{description:"Runner group",flags:"-g, --runnerGroup",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra run [options]"},scale:{description:"Automatically scale runners based on job queue",examples:[{command:"hydra scale",description:"One-time scaling check"},{command:"hydra scale --watch",description:"Continuous monitoring"},{command:"hydra scale --min 2 --max 10",description:"Set scaling limits"},{command:"hydra scale --dry-run",description:"Preview scaling actions"}],name:"hydra scale",notes:["Monitors GitHub job queue and scales runners accordingly","Requires token with workflow scope to read job queue","Respects min/max limits to prevent over-provisioning","Scale down only removes idle runners"],options:[{description:"GitHub token (needs workflow scope)",flags:"-t, --token",type:"string"},{description:"Repository/organization URL",flags:"-u, --url",type:"string"},{default:"./gh-runners",description:"Runners directory",flags:"-d, --directory",type:"string"},{default:1,description:"Minimum number of runners",flags:"--min",type:"number"},{default:10,description:"Maximum number of runners",flags:"--max",type:"number"},{default:!1,description:"Watch mode (continuous)",flags:"-w, --watch",type:"boolean"},{default:30,description:"Check interval in seconds",flags:"-i, --interval",type:"number"},{default:5,description:"Scale up threshold (pending jobs)",flags:"--scale-up-threshold",type:"number"},{default:300,description:"Idle time before scale down (seconds)",flags:"--idle-time",type:"number"},{default:!1,description:"Preview actions without executing",flags:"--dry-run",type:"boolean"},{description:"Runner labels",flags:"-l, --labels",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra scale [options]"},status:{description:"Show status of GitHub runner machines",examples:[{command:"hydra status",description:"Show all runners status"},{command:"hydra status --json",description:"Output as JSON"},{command:"hydra status -p production",description:"Status using profile"}],name:"hydra status",notes:["Shows runner process status and basic information","Online means the runner process is active","Use --json for integration with monitoring tools"],options:[{default:"./gh-runners",description:"Directory containing runners",flags:"-d, --directory",type:"string"},{default:!1,description:"Output as JSON",flags:"-j, --json",type:"boolean"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra status [options]"},template:{description:"Manage reusable runner configuration templates",examples:[{command:"hydra template",description:"Interactive template management"},{command:"hydra template list",description:"List all available templates"},{command:"hydra template create",description:"Create a new template"},{command:"hydra template use my-template",description:"Use a template"},{command:"hydra template show my-template",description:"Show template details"},{command:"hydra template delete my-template",description:"Delete a template"},{command:"hydra template create --global",description:"Create global template"}],name:"hydra template",notes:["Templates provide reusable runner configurations","Global templates are stored in ~/.hydra/templates.json","Local templates are stored in ./hydra-templates.json","Templates can extend other templates for composition","Use 'hydra create --template <name>' to create runners from a template"],options:[{description:"Template name",flags:"-n, --name",type:"string"},{default:!1,description:"Use global template storage",flags:"-g, --global",type:"boolean"},{default:!1,description:"Force action without prompts",flags:"-f, --force",type:"boolean"},{description:"Create from existing template",flags:"-F, --from",type:"string"}],sections:[{content:["list - List all available templates","create - Create a new template","use - Generate config from template","show - Display template details","delete - Remove a template"],title:"ACTIONS"}],usage:"hydra template [action] [name] [options]"},validate:{description:"Validate Hydra configuration",examples:[{command:"hydra validate",description:"Validate current configuration"},{command:"hydra validate --fix",description:"Fix configuration issues"},{command:"hydra validate --json",description:"Machine-readable output"}],name:"validate",notes:["Checks for syntax errors and invalid values","Provides warnings for potential issues","Fix mode can resolve some common problems"],options:[{description:"Config file path",flags:"-c, --config <path>",type:"string"},{description:"Output as JSON",flags:"-j, --json",type:"boolean"},{description:"Attempt to fix issues",flags:"-f, --fix",type:"boolean"}],usage:"hydra validate [options]"},watch:{description:"Watch directory for changes and run commands",examples:[{command:"hydra watch status",description:"Watch and run status on changes"},{command:"hydra watch health --debounce 5000",description:"Watch with 5 second debounce"}],name:"watch",notes:["Watches recursively for any file changes","Debounce prevents rapid command execution","Use exclude patterns to ignore specific files"],options:[{default:"./gh-runners",description:"Directory to watch",flags:"-d, --directory <path>",type:"string"},{default:"1000",description:"Debounce time in milliseconds",flags:"--debounce <ms>",type:"string"},{description:"Patterns to exclude from watching",flags:"--exclude <pattern>",type:"string"},{description:"Configuration profile",flags:"-p, --profile <name>",type:"string"}],usage:"hydra watch [command] [options]"}};function Xs(t){let e=[...L.getAll().map((n)=>({description:n.description,name:n.name})),...Object.entries(Qi).map(([n,i])=>({description:i.description,name:n}))];if(t){let n=L.get(t);if(n){console.log(me(n.help));return}let i=Qi[t];if(i){console.log(me(i));return}console.error(`Unknown command: ${t}`),process.exit(1)}console.log(an("Hydra - GitHub Self-Hosted Runner Manager","hydra <command> [options]",e,`Hydra v${St} - Simplifying GitHub runner management`))}var dn={aliases:["h","--help","-h"],description:"Show help information",execute:async()=>{let t=process.argv.slice(3);Xs(t[0])},help:{description:"Show help information",examples:[{command:"hydra help",description:"Show general help"},{command:"hydra help create",description:"Show help for create command"}],name:"hydra help",usage:"hydra help [command]"},name:"help"};q();O();G();import{resolve as ta}from"path";import{parseArgs as ea}from"util";var{$:no}=globalThis.Bun;V();F();tt();Wt();class eo{services=new Map;factories=new Map;register(t,e,n=!0){let i=String(t);if(n)this.factories.set(i,()=>{if(!this.services.has(i))this.services.set(i,e());return this.services.get(i)});else this.factories.set(i,e)}get(t){let e=this.factories.get(String(t));if(!e)throw new Error(`Service ${String(t)} not registered`);return e()}getFileSystem(){return this.get("fileSystem")}getCommandRegistry(){return this.get("commandRegistry")}createWorkerManager(t){return this.get("workerManagerFactory")(t)}createLogger(t){return this.get("loggerFactory")(t)}async loadConfig(t){return this.get("configLoader")(t)}reset(){this.services.clear()}}var Bt=new eo;Bt.register("fileSystem",()=>new $e,!0);Bt.register("commandRegistry",()=>L,!0);Bt.register("workerManagerFactory",()=>(t)=>new wt(t),!1);Bt.register("loggerFactory",()=>w,!1);Bt.register("configLoader",()=>N,!1);function Re(t=Bt){return{services:t}}F();async function na(t){let e=t||Re(),n=e.services.createLogger({prefix:"hydra:init"}),i=e.services.getFileSystem(),{toml:r}=oa(),s=r?"hydra.toml":"hydra.json",o=ta(process.cwd(),s);if(await i.exists(o)){let b=await C({initialValue:!1,message:`Configuration file ${s} already exists. Overwrite?`});if(k(b)||!b)nn("Configuration cancelled"),process.exit(0)}he(P.cyan("\uD83D\uDE80 Hydra Configuration Setup")),n.info("This will create a configuration file with your runner settings."),n.info("You can always edit the file later or create additional profiles.");let a=await $i({directory:()=>A({defaultValue:"./gh-runners",message:"Directory to store runners?",placeholder:"./gh-runners"}),labels:({results:b})=>{let m=b.name||"runner";return A({defaultValue:m,message:"Runner labels (comma-separated)?",placeholder:m})},name:()=>A({defaultValue:"runner",message:"Runner name prefix?",placeholder:"runner"}),numberOfMachines:()=>A({defaultValue:"1",message:"Number of runner machines?",placeholder:"1",validate:(b)=>{let m=Number.parseInt(b,10);if(Number.isNaN(m)||m<1)return"Please enter a valid number greater than 0";return}}),profileName:()=>A({message:"Profile name?",placeholder:"default"}),url:()=>A({message:"GitHub repository or organization URL? (optional)",placeholder:"https://github.com/org/repo"})},{onCancel:()=>{nn("Configuration cancelled"),process.exit(0)}}),{profileName:f,labels:u,numberOfMachines:p,...d}=a,g={defaultProfile:f,profiles:{[f]:{...d,labels:u,numberOfMachines:Number.parseInt(p,10),os:"osx",overwrite:!1,run:!1}}};if(await zi(o,g),await Nt(async()=>{await i.chmod(o,"600")},{logLevel:"warn",message:"Could not set secure file permissions"}),at(P.green(`\u2713 Configuration saved to ${s}`)),n.info("Example usage:"),n.info(` hydra create -p ${f} --token YOUR_TOKEN${a.url?"":" --url REPO_URL"}`),n.info("You can add more profiles by editing the configuration file."),a.url)await ia(a.url,e)}async function ia(t,e){let n=e.services.createLogger({prefix:"hydra:init"}),i=/github\.com[:/]([^/]+)(?:\/([^/.]+))?/,r=t.match(i);if(!r)return;let[,s,o]=r,f=`https://github.com/${o?`${s}/${o}`:`organizations/${s}`}/settings/actions/runners`;n.info(`Opening GitHub settings: ${f}`),await Nt(async()=>{await no`open ${f}`.quiet()},{fallback:async()=>{await Nt(async()=>{await no`xdg-open ${f}`.quiet()},{fallback:()=>{n.info("Please open the URL manually to add a new runner token.")},logLevel:"info",message:"Alternative browser open method also failed"})},logLevel:"info",message:"Could not open browser automatically"})}function oa(){let{values:t}=ea({allowPositionals:!0,args:Bun.argv,options:{toml:{default:!1,short:"t",type:"boolean"}},strict:!0});return t}var xn={aliases:["i","initialize"],description:"Initialize Hydra configuration",execute:()=>na(),help:{description:"Initialize Hydra configuration",examples:[{command:"hydra init",description:"Create a new configuration file"},{command:"hydra init --toml",description:"Create TOML configuration"}],name:"hydra init",notes:["Creates hydra.json (or hydra.toml) in the current directory","Walks through an interactive setup process","Sets secure file permissions (600) on the config file"],options:[{description:"Create TOML config instead of JSON",flags:"-t, --toml",type:"boolean"}],usage:"hydra init [options]"},name:"init"};q();O();V();import{parseArgs as ra}from"util";async function sa(t){let e=t||Re(),n=e.services.createLogger({prefix:"hydra:status"}),i=await aa(e),{directory:r,token:s,url:o,json:a}=i;if(!s||!o)throw new Error("Token (-t) and URL (-u) parameters are required");let f=T();f.start("Fetching runner status...");try{let u=await la(r,e),p=await fa(o,s,e),d=ua(u,p);if(f.stop("Runner status fetched"),a)n.info(JSON.stringify(d,null,2));else ca(d,e)}catch(u){throw f.stop("Failed to fetch runner status"),u}}async function aa(t){let{values:e}=ra({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},json:{default:!1,short:"j",type:"boolean"},profile:{short:"p",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),n=await t.services.loadConfig({configPath:e.config}),i=await S(n,e.profile);return{directory:e.directory||i?.directory||`${process.cwd()}/gh-runners`,json:e.json,token:e.token,url:e.url||i?.url}}async function la(t,e){let n=e.services.getFileSystem(),i=`${t}/machines`;if(!await n.exists(i))return[];try{return(await n.listDirectory(i)).filter((s)=>s.isDirectory&&/^\d+$/.test(s.name)).map((s)=>s.name)}catch{return[]}}async function fa(t,e,n){let i=t.match(/github\.com[:/]([^/]+)(?:\/([^/.]+))?/);if(!i)throw new Error("Invalid GitHub URL");let[,r,s]=i,o=s?`https://api.github.com/repos/${r}/${s}/actions/runners`:`https://api.github.com/orgs/${r}/actions/runners`;return it(async()=>{let a={Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${e}`},f=await fetch(o,{headers:a});if(!f.ok)throw new Error(`GitHub API error: ${f.status} ${f.statusText}`);return await f.json()},{onRetry:(a,f)=>{n.services.createLogger({prefix:"hydra:status"}).warn(`Retrying GitHub API call (attempt ${a}): ${f.message}`)}})}function ua(t,e){let n=[],i=new Map(e.runners.map((r)=>[r.name,r]));for(let r of t){let s=`runner-${r}`,o=i.get(s);if(o)n.push({busy:o.busy,labels:o.labels.map((a)=>a.name),name:s,os:o.os,status:o.busy?"busy":o.status==="online"?"online":"offline"});else n.push({busy:!1,labels:[],name:s,os:"unknown",status:"offline"})}return n}function ca(t,e){let n=e.services.createLogger({prefix:"hydra:status"});if(t.length===0){n.info("No runners found");return}n.info("Runner Status:"),n.info("\u2500".repeat(80));let i={busy:c.busy,offline:c.offline,online:c.online};for(let s of t){let o=i[s.status],a=s.status.toUpperCase().padEnd(7);n.info(`${o("\u25CF")} ${o(a)} ${c.value(s.name.padEnd(20))} ${c.dim(`OS: ${s.os.padEnd(10)}`)} ${s.labels.length>0?c.dim(`Labels: ${s.labels.join(", ")}`):""}`)}n.info("\u2500".repeat(80));let r={busy:t.filter((s)=>s.status==="busy").length,offline:t.filter((s)=>s.status==="offline").length,online:t.filter((s)=>s.status==="online").length,total:t.length};n.info(`Summary: Total: ${r.total} | ${c.online(`Online: ${r.online}`)} | ${c.busy(`Busy: ${r.busy}`)} | ${c.offline(`Offline: ${r.offline}`)}`)}var $n={aliases:["s","stat","ls","list"],description:"Show status of GitHub runner machines",execute:()=>sa(),help:{description:"Show status of GitHub runner machines",examples:[{command:"hydra status",description:"Show all runners status"},{command:"hydra status --json",description:"Output as JSON"},{command:"hydra status -p production",description:"Status using profile"}],name:"hydra status",notes:["Shows runner process status and basic information","Online means the runner process is active","Use --json for integration with monitoring tools"],options:[{default:"./gh-runners",description:"Directory containing runners",flags:"-d, --directory",type:"string"},{default:!1,description:"Output as JSON",flags:"-j, --json",type:"boolean"},{description:"GitHub runner token",flags:"-t, --token",type:"string"},{description:"Repository/organization URL",flags:"-u, --url",type:"string"},{description:"Configuration profile",flags:"-p, --profile",type:"string"},{description:"Configuration file path",flags:"-c, --config",type:"string"}],usage:"hydra status [options]"},name:"status"};var co=new Map;function An(t,e){co.set(t,e)}async function On(t){let e=L.get(t);if(e)return e;let n=co.get(t);if(!n)return null;try{let i=await n(),r;if(i.default&&Tn(i.default))r=i.default;else{let s=`${t}Command`;if(i[s]&&Tn(i[s]))r=i[s];else for(let[,o]of Object.entries(i))if(Tn(o)){r=o;break}}if(r)return L.register(r),r;return null}catch(i){return console.error(`Failed to load command ${t}:`,i),null}}function Tn(t){return t&&typeof t==="object"&&typeof t.name==="string"&&typeof t.description==="string"&&typeof t.execute==="function"&&t.help&&typeof t.help==="object"}function po(){An("create",async()=>{let{createMachines:t}=await Promise.resolve().then(() => (Ee(),so));return{default:{description:"Create and register new GitHub runner machines",execute:t,help:{description:"Create and register new GitHub runner machines",name:"create",usage:"hydra create [options]"},name:"create"}}}),An("run",async()=>{let{runMachines:t}=await Promise.resolve().then(() => (Pn(),ao));return{default:{description:"Start existing GitHub runner machines",execute:t,help:{description:"Start existing GitHub runner machines",name:"run",usage:"hydra run [options]"},name:"run"}}}),An("remove",async()=>{let{removeMachines:t}=await Promise.resolve().then(() => (Ae(),fo));return{default:{description:"Remove GitHub runner machines",execute:t,help:{description:"Remove GitHub runner machines",name:"remove",usage:"hydra remove [options]"},name:"remove"}}})}async function uo(t){await On(t)}function ho(){setTimeout(()=>{uo("create").catch(()=>{}),uo("status").catch(()=>{})},100)}O();tt();var xt=w({prefix:"Error"});class go extends Error{code;details;suggestion;constructor(t,e,n,i){super(t);this.code=e;this.details=n;this.suggestion=i;this.name="HydraError"}}function mo(t,e){if(t instanceof go){if(xt.error(t.message),t.details)xt.error(`Details: ${t.details}`);if(t.suggestion)xt.info(`
|
|
73
|
+
${c.value("Suggestion")}: ${t.suggestion}`);process.exit(1)}if(t instanceof Error){let n=_a(t,e);if(xt.error(n.message),n.suggestion)xt.info(`
|
|
74
|
+
${c.value("Suggestion")}: ${n.suggestion}`);if(process.env.DEBUG)xt.debug("Stack trace:"),xt.debug(t.stack||"No stack trace available");process.exit(1)}xt.error(`Unknown error: ${String(t)}`),process.exit(1)}function _a(t,e){let n=t.message.toLowerCase();if(n.includes("enoent")||n.includes("no such file"))return{message:`File or directory not found: ${Na(t.message)||"unknown"}`,suggestion:"Check that the path exists and you have permission to access it"};if(n.includes("eacces")||n.includes("permission denied"))return{message:"Permission denied",suggestion:"Try running with elevated permissions or check file ownership"};if(n.includes("eaddrinuse")||n.includes("address already in use"))return{message:"Port or address already in use",suggestion:"Check if another instance is already running"};if(n.includes("token")&&(n.includes("invalid")||n.includes("unauthorized")))return{message:"Invalid or expired GitHub token",suggestion:"Generate a new token at https://github.com/settings/tokens"};if(n.includes("rate limit"))return{message:"GitHub API rate limit exceeded",suggestion:"Wait a few minutes and try again, or use a different token"};if(n.includes("network")||n.includes("etimedout")||n.includes("enotfound"))return{message:"Network error - unable to connect",suggestion:"Check your internet connection and proxy settings"};if(n.includes("json")&&(n.includes("unexpected")||n.includes("parse")))return{message:"Invalid JSON in configuration file",suggestion:"Validate your JSON at https://jsonlint.com/"};if(n.includes("toml")&&n.includes("parse"))return{message:"Invalid TOML in configuration file",suggestion:"Check for syntax errors in your TOML file"};if(n.includes("directory")&&n.includes("exists"))return{message:t.message,suggestion:"Use --overwrite flag to replace existing directory"};if(n.includes("runner")&&n.includes("already"))return{message:"Runner already exists",suggestion:"Remove existing runner first with 'hydra remove'"};if(e?.command==="create"&&n.includes("token"))return{message:t.message,suggestion:"Provide a token with -t flag or set GITHUB_TOKEN environment variable"};if(e?.command==="run"&&n.includes("not found"))return{message:"No runners found to start",suggestion:"Create runners first with 'hydra create'"};return{message:t.message}}function Na(t){let e=t.match(/['"]([^'"]+)['"]/);return e?e[1]??null:null}F();import{EventEmitter as Sa}from"events";import{homedir as Ma}from"os";import{join as Cn}from"path";F();tt();import{join as Hn}from"path";class yo{eventBus;services;plugins=new Map;hooks=new Map;commands=new Map;logger=w({prefix:"PluginManager"});pluginContexts=new Map;constructor(t,e){this.eventBus=t;this.services=e}async loadPlugin(t){try{let e=Hn(t,"plugin.json");if(!await y.exists(e))throw new Error(`Plugin manifest not found at ${e}`);let n=await y.readFile(e),i=JSON.parse(n);if(!i.name||!i.version||!i.main)throw new Error("Invalid plugin manifest: missing required fields");if(this.plugins.has(i.name))throw new Error(`Plugin ${i.name} is already loaded`);let s=await import(Hn(t,i.main)),o={activate:s.activate||s.default?.activate,deactivate:s.deactivate||s.default?.deactivate,manifest:i};if(!o.activate)throw new Error(`Plugin ${i.name} does not export an activate function`);let a=this.createPluginContext(i.name);this.pluginContexts.set(i.name,a),await o.activate(a),this.plugins.set(i.name,o),this.logger.info(`Loaded plugin: ${i.name} v${i.version}`)}catch(e){throw this.logger.error(`Failed to load plugin from ${t}:`,e),e}}async loadPluginsFromDirectory(t){if(!await y.exists(t))return;let e=await y.readDir(t),n=[];for(let i of e)if(i.isDirectory){let r=Hn(t,i.name);n.push(this.loadPlugin(r).catch((s)=>{this.logger.warn(`Failed to load plugin ${i.name}:`,s)}))}await Promise.all(n)}async unloadPlugin(t){let e=this.plugins.get(t);if(!e)throw new Error(`Plugin ${t} is not loaded`);if(e.deactivate)await e.deactivate();for(let[n,i]of this.commands.entries())if(i.name.startsWith(`${t}:`))this.commands.delete(n);this.plugins.delete(t),this.pluginContexts.delete(t),this.logger.info(`Unloaded plugin: ${t}`)}async unloadAllPlugins(){let t=[];for(let[e]of this.plugins)t.push(this.unloadPlugin(e).catch((n)=>{this.logger.error(`Error unloading plugin ${e}:`,n)}));await Promise.all(t)}createPluginContext(t){return{config:{},eventBus:this.eventBus,fileSystem:y,getService:(e)=>{return this.services.get(e)},logger:w({prefix:`Plugin:${t}`}),registerCommand:(e)=>{let n=`${t}:${e.name}`;this.commands.set(n,{...e,name:n}),this.logger.debug(`Registered command: ${n}`)},registerHook:(e,n)=>{if(!this.hooks.has(e))this.hooks.set(e,new Set);this.hooks.get(e)?.add(n),this.logger.debug(`Registered hook: ${e} for plugin ${t}`)}}}async executeHook(t,...e){let n=this.hooks.get(t);if(!n||n.size===0)return;let i=[];for(let r of n)i.push(Promise.resolve(r(...e)).catch((s)=>{this.logger.error(`Hook ${t} handler error:`,s)}));await Promise.all(i)}getCommand(t){return this.commands.get(t)}getAllCommands(){return Array.from(this.commands.values())}getPlugin(t){return this.plugins.get(t)}getAllPlugins(){return Array.from(this.plugins.values())}isPluginLoaded(t){return this.plugins.has(t)}getLoadedPluginNames(){return Array.from(this.plugins.keys())}}function bo(t,e){return new yo(t,e)}var Wa=[Cn(Ma(),".hydra","plugins"),Cn(process.cwd(),".hydra","plugins"),Cn(process.cwd(),"hydra-plugins")],rt=null,Ut=null;function _n(){if(!Ut)Ut=new Sa;return Ut}async function wo(t){if(rt)return rt;let e=_n();if(rt=bo(e,t),process.env.HYDRA_DISABLE_PLUGINS!=="true")await Ba();return rt}async function Ba(){if(!rt)throw new Error("Plugin manager not initialized");for(let e of Wa)if(await y.exists(e))await rt.loadPluginsFromDirectory(e);let t=process.env.HYDRA_PLUGIN_DIR;if(t&&await y.exists(t))await rt.loadPluginsFromDirectory(t)}function xo(){return rt}async function Nn(){if(rt)await rt.unloadAllPlugins(),rt=null;if(Ut)Ut.removeAllListeners(),Ut=null}function Te(t,e=0){if(e>0)setTimeout(t,e);else if(typeof setImmediate!=="undefined")setImmediate(t);else process.nextTick(t)}class Sn{metrics;constructor(){this.metrics={startTime:performance.now()}}mark(t){let e=performance.now();this.metrics[t]=e-this.metrics.startTime}getMetrics(){return{...this.metrics,totalTime:performance.now()-this.metrics.startTime}}logMetrics(){if(process.env.DEBUG_STARTUP){let t=this.getMetrics();console.log("Startup metrics:");for(let[e,n]of Object.entries(t))if(n!==void 0)console.log(` ${e}: ${n.toFixed(2)}ms`)}}}function $o(){return!(process.env.CI||process.env.HYDRA_SKIP_UPDATE_CHECK||process.env.NO_UPDATE_CHECK)}function vo(t){let[,,e,...n]=t;if(!e||e==="--help"||e==="-h")return{needsHelp:!0};if(e==="--version"||e==="-v")return{command:"version",needsHelp:!1};if(n.includes("--help")||n.includes("-h"))return{command:e,needsHelp:!0};return{command:e,needsHelp:!1}}q();O();G();V();import{existsSync as $t}from"fs";import{copyFile as Ua,mkdir as qt,readdir as Wn}from"fs/promises";import{join as B,resolve as qa}from"path";import{parseArgs as La}from"util";var{$:Lt}=globalThis.Bun;var Ga=$({prefix:"hydra"}).child("backup");async function ja(){let{values:t}=La({allowPositionals:!0,args:Bun.argv,options:{compress:{default:!0,type:"boolean"},config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},list:{default:!1,short:"l",type:"boolean"},output:{short:"o",type:"string"},profile:{short:"p",type:"string"},restore:{short:"r",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile);return{compress:t.compress,directory:t.directory||n?.directory||`${process.cwd()}/gh-runners`,list:t.list,output:t.output,restore:t.restore}}async function Ro(){try{let t=await ja();if(t.list){await ka(t.output||B(t.directory,"backups"));return}if(t.restore){await Xa(t);return}await Ja(t)}catch(t){Ga.error("Backup operation failed:",t),process.exit(1)}}async function Ja(t){let e=qa(t.directory),n=B(e,"machines");if(!$t(n)){l.error(`No runners found in ${t.directory}`);return}let i=T();i.start("Creating backup...");try{let r=await Wn(n);if(r.length===0){i.stop("No runners to backup");return}let s=`backup-${new Date().toISOString().replace(/[:.]/g,"-")}`,o=t.output||B(e,"backups"),a=B(o,s);await qt(a,{recursive:!0});let f=0,u=[];for(let d of r){let g=B(n,d),b=B(a,"runners",d);await qt(b,{recursive:!0});let m=[".runner",".credentials",".credentials_rsaparams",".path",".env","config.sh"];for(let x of m){let M=B(g,x);if($t(M)){let Q=B(b,x);await Ua(M,Q);let E=await Bun.file(M).stat();f+=E.size,u.push(`runners/${d}/${x}`)}}}let p={configFiles:u,date:new Date,id:s,runnerCount:r.length,size:f};if(await Bun.write(B(a,"metadata.json"),JSON.stringify(p,null,2)),t.compress){i.message("Compressing backup..."),await Lt`cd ${o} && tar -czf ${s}.tar.gz ${s}`.quiet(),await Lt`rm -rf ${a}`.quiet();let d=await Bun.file(B(o,`${s}.tar.gz`)).stat();i.stop(`Backup created: ${s}.tar.gz (${Mn(d.size)})`)}else i.stop(`Backup created: ${s} (${Mn(f)})`);l.success(`Backed up ${r.length} runner(s)`)}catch(r){throw i.stop("Backup failed"),r}}async function ka(t){if(!$t(t)){l.info("No backups found");return}let e=T();e.start("Scanning backups...");try{let n=await Wn(t),i=[];for(let r of n){let s=B(t,r);if(r.endsWith(".tar.gz")){let o=r.replace(".tar.gz",""),a=await Bun.file(s).stat();i.push({configFiles:[],date:new Date(a.mtime),id:o,runnerCount:0,size:a.size})}else{let o=B(s,"metadata.json");if($t(o)){let a=await Bun.file(o).json();i.push(a)}}}if(e.stop("Found backups"),i.length===0){l.info("No backups found");return}console.log(),console.log(c.bold("\uD83D\uDCE6 Available Backups")),console.log("\u2500".repeat(80));for(let r of i.sort((s,o)=>new Date(o.date).getTime()-new Date(s.date).getTime())){let s=new Date(r.date).toLocaleString(),o=Mn(r.size),a=r.runnerCount>0?`${r.runnerCount} runners`:"compressed";console.log(`${c.value(r.id)}`),console.log(` Date: ${s}`),console.log(` Size: ${o}`),console.log(` Content: ${a}`),console.log()}}catch(n){throw e.stop("Failed to list backups"),n}}async function Xa(t){let e=t.output||B(t.directory,"backups"),n=B(e,t.restore),i=`${n}.tar.gz`,r=$t(i),s=$t(n);if(!r&&!s){l.error(`Backup not found: ${t.restore}`);return}if(!await C({initialValue:!1,message:"This will overwrite existing runner configurations. Continue?"})){l.info("Restore cancelled");return}let a=T();a.start("Restoring backup...");try{let f=n;if(r){a.message("Extracting backup...");let m=B(e,`temp-${Date.now()}`);await qt(m,{recursive:!0}),await Lt`cd ${m} && tar -xzf ${i}`.quiet(),f=B(m,t.restore)}let u=B(f,"metadata.json");if(!$t(u))throw new Error("Invalid backup: metadata.json not found");await Bun.file(u).json();let p=B(f,"runners"),d=B(t.directory,"machines");await qt(d,{recursive:!0});let g=await Wn(p),b=0;for(let m of g){let x=B(p,m),M=B(d,m);if($t(M)){let Q=await K({message:`Runner ${m} already exists. What should we do?`,options:[{label:"Skip",value:"skip"},{label:"Overwrite",value:"overwrite"},{label:"Rename",value:"rename"}]});if(Q==="skip")continue;if(Q==="rename"){let E=await A({message:"Enter new runner name:",placeholder:`${m}-restored`});if(!E)continue;let D=B(d,E);await qt(D,{recursive:!0}),await Lt`cp -r ${x}/* ${D}/`.quiet(),b++;continue}}await qt(M,{recursive:!0}),await Lt`cp -r ${x}/* ${M}/`.quiet(),b++}if(r){let m=f.replace(`/${t.restore}`,"");await Lt`rm -rf ${m}`.quiet()}a.stop("Restore completed"),l.success(`Restored ${b} runner(s) from backup ${t.restore}`)}catch(f){throw a.stop("Restore failed"),f}}function Mn(t){if(t<1024)return`${t}B`;if(t<1048576)return`${(t/1024).toFixed(1)}KB`;if(t<1073741824)return`${(t/1048576).toFixed(1)}MB`;return`${(t/1073741824).toFixed(2)}GB`}Ee();q();O();F();tt();import{parseArgs as Qa}from"util";var Ka=w({prefix:"dev"});async function Va(){let{values:t,positionals:e}=Qa({allowPositionals:!0,args:process.argv.slice(2),options:{force:{default:!1,short:"f",type:"boolean"}},strict:!0}),n=e[1]||"setup";if(!["setup","clean","reset","test"].includes(n))throw new Error(`Unknown dev action: ${n}`);return{action:n,force:t.force}}async function Eo(){let t=await Va();switch(t.action){case"setup":await Po(t);break;case"clean":await Ao();break;case"reset":await Za(t);break;case"test":await za();break}}async function Po(t){l.info("Setting up development environment...");let e=T();e.start("Creating test directories");let n="./test-runners";if(await y.exists(n)){if(!t.force){if(!await C({message:"Test directory already exists. Overwrite?"})){l.info("Setup cancelled");return}}await y.deleteDirectory(n,{recursive:!0})}await y.createDirectory(n,{recursive:!0}),e.stop("Test directories created"),e.start("Creating sample configuration");let i={defaultProfile:"development",profiles:{development:{directory:n,labels:"test,development",numberOfMachines:"2",os:"osx",url:"https://github.com/myorg/myrepo"},staging:{directory:"./staging-runners",labels:"staging",numberOfMachines:"3",os:"linux",url:"https://github.com/myorg/myrepo"}}};await y.writeFile("./hydra.dev.json",JSON.stringify(i,null,2)),e.stop("Sample configuration created"),e.start("Setting up environment variables");let r=`# Hydra Development Environment
|
|
75
|
+
HYDRA_LOG_LEVEL=debug
|
|
76
|
+
HYDRA_DISABLE_PLUGINS=false
|
|
77
|
+
HYDRA_PLUGIN_DIR=./dev-plugins
|
|
78
|
+
|
|
79
|
+
# GitHub tokens (replace with your own)
|
|
80
|
+
# GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
81
|
+
# RUNNER_TOKEN=AXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
82
|
+
`;await y.writeFile(".env.development",r),e.stop("Environment file created"),l.success(`
|
|
83
|
+
Development environment setup complete!`),l.info(`
|
|
84
|
+
Next steps:`),l.info("1. Update .env.development with your GitHub tokens"),l.info("2. Run: hydra create -c hydra.dev.json"),l.info("3. Use: hydra watch status -c hydra.dev.json")}async function Ao(){l.info("Cleaning development artifacts...");let t=["./test-runners","./staging-runners","./hydra.dev.json","./.env.development","./dev-plugins"],e=T();e.start("Cleaning files");for(let n of t)if(await y.exists(n)){if((await y.getFileInfo(n))?.isDirectory)await y.deleteDirectory(n,{recursive:!0});else await y.deleteFile(n);Ka.debug(`Removed: ${n}`)}e.stop("Development files cleaned"),l.success("Cleanup complete!")}async function Za(t){l.info("Resetting development environment..."),await Ao(),await Po({...t,force:!0}),l.success("Development environment reset complete!")}async function za(){l.info("Running development tests...");let t=[{check:async()=>await y.exists("./hydra.dev.json"),name:"Configuration exists"},{check:async()=>await y.exists("./test-runners"),name:"Test directory exists"},{check:async()=>await y.exists("./.env.development"),name:"Environment file exists"},{check:async()=>{return!(await y.readFile("./.env.development")).includes("# GITHUB_TOKEN=")},name:"GitHub token set"}],e=0,n=0;for(let i of t)try{if(await i.check())l.success(`\u2713 ${i.name}`),e++;else l.error(`\u2717 ${i.name}`),n++}catch(r){l.error(`\u2717 ${i.name}: ${r}`),n++}if(l.info(`
|
|
85
|
+
Tests: ${c.success(`${e} passed`)}, ${c.error(`${n} failed`)}`),n>0)l.info(`
|
|
86
|
+
Run 'hydra dev setup' to fix issues`),process.exit(1)}q();O();G();V();import{existsSync as It}from"fs";import{readdir as To}from"fs/promises";import{join as vt,resolve as Ya}from"path";import{parseArgs as Ia}from"util";var{$:Bn}=globalThis.Bun;var Fa=$({prefix:"hydra"}).child("health");async function Da(){let{values:t}=Ia({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},fix:{default:!1,short:"f",type:"boolean"},json:{default:!1,short:"j",type:"boolean"},profile:{short:"p",type:"string"},runner:{short:"r",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile);return{directory:t.directory||n?.directory||`${process.cwd()}/gh-runners`,fix:t.fix,json:t.json,runner:t.runner,token:t.token,url:t.url||n?.url}}async function Oo(){try{let t=await Da(),e=Ya(t.directory),n=vt(e,"machines");if(!It(n)){l.error(`No runners found in ${t.directory}`);return}let i=T();i.start("Performing health checks...");let r=await To(n),s=[];for(let o of r){if(t.runner&&o!==t.runner)continue;let a=vt(n,o),f=await tl(o,a,t);s.push(f)}if(i.stop("Health checks completed"),t.json){console.log(JSON.stringify(s,null,2));return}if(ol(s),t.fix)await rl(s,t)}catch(t){Fa.error("Failed to perform health checks:",t),process.exit(1)}}async function tl(t,e,n){let i=[],r={configuration:!1,connectivity:!1,disk:{percentage:0,total:0,used:0},lastActivity:null,process:!1};try{let o=vt(e,".runner");if(It(o)){let a=await Bun.file(o).text(),f=await el(a.trim());if(r.process=f,!f)i.push("Runner process is not running")}else i.push("No PID file found")}catch{i.push("Could not check process status")}try{let o=await nl(e);if(r.disk=o,o.percentage>90)i.push(`Low disk space: ${o.percentage.toFixed(1)}% used`)}catch{i.push("Could not check disk space")}try{let o=vt(e,"_diag");if(It(o)){let a=await To(o),f=null;for(let u of a)if(u.endsWith(".log")){let p=await Bun.file(vt(o,u)).stat();if(!f||p.mtime>f)f=new Date(p.mtime)}if(r.lastActivity=f,f){let u=(Date.now()-f.getTime())/3600000;if(u>24)i.push(`No activity for ${Math.floor(u)} hours`)}}}catch{i.push("Could not check last activity")}try{let o=vt(e,".runner"),a=vt(e,".credentials");if(r.configuration=It(o)&&It(a),!r.configuration)i.push("Missing configuration files")}catch{i.push("Could not check configuration")}if(n.token&&n.url)try{let o=await il(n.url,n.token);if(r.connectivity=o,!o)i.push("Cannot connect to GitHub API")}catch{i.push("Failed to check GitHub connectivity")}let s="healthy";if(i.length===0)s="healthy";else if(i.some((o)=>o.includes("not running")||o.includes("Missing configuration")||o.includes("Cannot connect")))s="critical";else if(i.length>0)s="warning";return{checks:r,issues:i,runner:t,status:s}}async function el(t){try{return await Bn`kill -0 ${t}`.quiet(),!0}catch{return!1}}async function nl(t){let n=(await Bn`df -k ${t} | tail -1`.text()).trim().split(/\s+/),i=Number.parseInt(n[1]||"0",10)*1024,r=Number.parseInt(n[2]||"0",10)*1024;return{percentage:Number.parseInt(n[4]?.replace("%","")||"0",10),total:i,used:r}}async function il(t,e){return it(async()=>{let n=t.match(/github\.com[:/]([^/]+)(?:\/([^/.]+))?/);if(!n)return!1;let[,i,r]=n,s=r?`https://api.github.com/repos/${i}/${r}`:`https://api.github.com/orgs/${i}`;return(await fetch(s,{headers:{Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${e}`}})).ok},{maxAttempts:3})}function ol(t){console.log(),console.log(c.bold("\uD83C\uDFE5 Runner Health Status")),console.log("\u2500".repeat(80));let e={critical:"\u274C",healthy:"\u2705",unknown:"\u2753",warning:"\u26A0\uFE0F"},n={critical:c.error,healthy:c.success,unknown:c.dim,warning:c.warning};for(let r of t){let s=e[r.status],o=n[r.status];if(console.log(`${s} ${c.bold(`Runner ${r.runner}`)}: ${o(r.status.toUpperCase())}`),console.log(` Process: ${r.checks.process?"\u2705 Running":"\u274C Not running"}`),console.log(` Config: ${r.checks.configuration?"\u2705 Valid":"\u274C Missing"}`),r.checks.disk.total>0){let a=r.checks.disk.percentage>90?c.error:c.success;console.log(` Disk: ${a(`${r.checks.disk.percentage.toFixed(1)}% used`)}`)}if(r.checks.lastActivity){let f=(Date.now()-r.checks.lastActivity.getTime())/3600000>24?c.warning:c.success;console.log(` Last Activity: ${f(sl(r.checks.lastActivity))}`)}if(r.checks.connectivity!==null)console.log(` GitHub API: ${r.checks.connectivity?"\u2705 Connected":"\u274C Disconnected"}`);if(r.issues.length>0){console.log(" Issues:");for(let a of r.issues)console.log(` - ${c.dim(a)}`)}console.log()}let i={critical:t.filter((r)=>r.status==="critical").length,healthy:t.filter((r)=>r.status==="healthy").length,total:t.length,warning:t.filter((r)=>r.status==="warning").length};console.log("\u2500".repeat(80)),console.log(`Summary: Total: ${i.total} | ${c.success(`Healthy: ${i.healthy}`)} | ${c.warning(`Warning: ${i.warning}`)} | ${c.error(`Critical: ${i.critical}`)}`)}async function rl(t,e){let n=t.filter((r)=>r.status==="critical");if(n.length===0){l.info("No critical issues found that require fixing");return}if(console.log(),!await C({initialValue:!1,message:`Found ${n.length} runners with critical issues. Attempt to fix?`}))return;for(let r of n){if(console.log(),l.info(`Attempting to fix runner ${r.runner}...`),!r.checks.process&&r.checks.configuration){l.info("Attempting to restart runner...");try{let s=vt(e.directory,"machines",r.runner);await Bn`cd ${s} && ./run.sh`.quiet(),l.success(`Runner ${r.runner} restarted successfully`)}catch(s){l.error(`Failed to restart runner ${r.runner}`)}}if(!r.checks.configuration)l.warning(`Runner ${r.runner} needs to be reconfigured. Run 'hydra create' to set up again.`)}}function sl(t){let n=new Date().getTime()-t.getTime(),i=Math.floor(n/3600000);if(i<1)return`${Math.floor(n/60000)}m ago`;if(i<24)return`${i}h ago`;return`${Math.floor(i/24)}d ago`}q();O();G();V();import{existsSync as Ho}from"fs";import{readdir as Co}from"fs/promises";import{join as Oe,resolve as al}from"path";import{parseArgs as ll}from"util";var fl=$({prefix:"hydra"}).child("logs");async function ul(){let{values:t}=ll({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},list:{default:!1,short:"l",type:"boolean"},profile:{short:"p",type:"string"},runner:{short:"r",type:"string"},type:{short:"t",type:"string"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile);return{directory:t.directory||n?.directory||`${process.cwd()}/gh-runners`,list:t.list,runner:t.runner,type:t.type}}async function _o(){try{let t=await ul(),e=al(t.directory),n=Oe(e,"machines");if(!Ho(n)){l.error(`No runners found in ${t.directory}`);return}let i=T();i.start("Scanning for runner logs...");let r=await Co(n),s=[];for(let a of r){let f=Oe(n,a),u=Oe(f,"_diag");if(Ho(u)){let p=await cl(u);if(p.length>0)s.push({logs:p,runner:a})}}if(i.stop("Found runner logs"),s.length===0){l.info("No log files found");return}if(t.list){pl(s);return}if(t.runner&&t.type){await dl(s,t.runner,t.type);return}let o=await hl(s);if(o)await No(o)}catch(t){fl.error("Failed to retrieve logs:",t),process.exit(1)}}async function cl(t){let e=await Co(t),n=[];for(let i of e)if(i.endsWith(".log")){let r=Oe(t,i),s=await Bun.file(r).stat();n.push({modified:new Date(s.mtime),name:i,path:r,size:s.size})}return n.sort((i,r)=>r.modified.getTime()-i.modified.getTime())}function pl(t){console.log(c.bold(`
|
|
314
87
|
\uD83D\uDCCB Available Logs
|
|
315
|
-
`));for(let{runner:
|
|
316
|
-
`);if(
|
|
317
|
-
`)),console.log(
|
|
318
|
-
`))}else console.log(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
88
|
+
`));for(let{runner:e,logs:n}of t){console.log(`${c.bold(`Runner ${e}:`)}`);for(let i of n){let r=Un(i.size),s=qn(i.modified),o=He(i.name);console.log(` ${c.value(o.padEnd(20))} ${c.dim(r.padEnd(10))} ${c.dim(s)}`)}console.log()}}async function hl(t){let e=[];for(let{runner:i,logs:r}of t)for(let s of r)e.push({hint:`${Un(s.size)} - ${qn(s.modified)}`,label:`Runner ${i} - ${He(s.name)}`,value:s});return await K({message:"Select a log file to view",options:e})}async function dl(t,e,n){let i=t.find(({runner:s})=>s===e);if(!i){l.error(`Runner ${e} not found`);return}let r=i.logs.find((s)=>He(s.name).toLowerCase().includes(n.toLowerCase()));if(!r){l.error(`Log type '${n}' not found for runner ${e}`);return}await No(r)}async function No(t){console.log(),console.log(c.bold(`\uD83D\uDCC4 ${He(t.name)}`)),console.log(c.dim(`Size: ${Un(t.size)} | Modified: ${qn(t.modified)}`)),console.log(c.dim("\u2500".repeat(80))),console.log();let e=await Bun.file(t.path).text(),n=e.split(`
|
|
89
|
+
`);if(n.length>100){let i=n.slice(-100);console.log(c.dim(`... (showing last 100 lines of ${n.length} total)
|
|
90
|
+
`)),console.log(i.join(`
|
|
91
|
+
`))}else console.log(e)}function He(t){if(t.includes("Runner_"))return"Runner Log";if(t.includes("Worker_"))return"Worker Log";if(t.includes("Actions"))return"Actions Log";if(t.includes("Listener"))return"Listener Log";return t.replace(".log","")}function Un(t){if(t<1024)return`${t}B`;if(t<1048576)return`${(t/1024).toFixed(1)}KB`;return`${(t/1048576).toFixed(1)}MB`}function qn(t){let n=new Date().getTime()-t.getTime(),i=Math.floor(n/3600000);if(i<1)return`${Math.floor(n/60000)}m ago`;if(i<24)return`${i}h ago`;let r=Math.floor(i/24);if(r<7)return`${r}d ago`;return t.toLocaleDateString()}q();O();import{parseArgs as gl}from"util";var{$:So,Glob:ml}=globalThis.Bun;async function yl(){let{values:t}=gl({args:process.argv.slice(2),options:{all:{default:!1,short:"a",type:"boolean"},backup:{default:!0,short:"b",type:"boolean"},dryRun:{default:!1,short:"d",type:"boolean"},format:{short:"f",type:"string"},path:{short:"p",type:"string"}},strict:!0});return{all:t.all,backup:t.backup,dryRun:t.dryRun,format:t.format,path:t.path}}async function Mo(){let t=await yl();if(!t.path&&!t.all)t.path=await A({message:"Path to configuration file:",placeholder:"./hydra.json",validate:(i)=>{if(!i)return"Path is required";return}});let e=await bl(t);if(e.length===0){l.error("No configuration files found");return}l.info(`Found ${e.length} configuration file(s) to migrate`);let n=[];for(let i of e){let r=await wl(i,t);n.push(r)}vl(n,t)}async function bl(t){if(t.path){if(!await Bun.file(t.path).exists())throw new Error(`Configuration file not found: ${t.path}`);return[t.path]}if(t.all){let e=new ml("**/hydra.{json,toml}"),n=[];for await(let i of e.scan("."))if(!i.includes("node_modules")&&!i.includes(".git"))n.push(i);return n}return[]}async function wl(t,e){let n=T();n.start(`Migrating ${t}...`);try{let i=await Bun.file(t).text(),r=t.endsWith(".toml")?"toml":"json",s=e.format||r,o,a=[];if(r==="toml"){let u=`.temp-${Date.now()}.toml`;await Bun.write(u,i),o=(await import(u)).default,await So`rm ${u}`.quiet()}else o=JSON.parse(i);let f=await xl(o,a);if(e.backup&&!e.dryRun){let u=`${t}.backup-${new Date().toISOString().replace(/:/g,"-")}`;await Bun.write(u,i),a.push(`Created backup at ${u}`)}if(!e.dryRun){let u=s!==r?t.replace(/\.(json|toml)$/,`.${s}`):t;if(s==="toml")await $l(u,f);else await Bun.write(u,JSON.stringify(f,null,2));if(u!==t){if(await C({initialValue:!0,message:`Remove original file ${t}?`}))await So`rm ${t}`.quiet(),a.push(`Removed original file ${t}`)}a.push(`Migrated to ${u}`)}return n.stop(`Migrated ${t}`),{changes:a,path:t,success:!0}}catch(i){return n.stop(`Failed to migrate ${t}`),{error:i.message,path:t,success:!1}}}async function xl(t,e){let n={profiles:{}};if(t.defaultProfile)n.defaultProfile=t.defaultProfile;if(t.url||t.numberOfMachines||t.directory||t.labels){let i={};if(t.directory)i.directory=t.directory;if(t.labels)i.labels=t.labels;if(t.name)i.name=t.name;if(t.numberOfMachines)i.numberOfMachines=t.numberOfMachines;if(t.os)i.os=t.os;if(t.runnerGroup)i.runnerGroup=t.runnerGroup;if(t.url)i.url=t.url;if(t.overwrite!==void 0)i.overwrite=t.overwrite;if(t.run!==void 0)i.run=t.run;n.profiles.default=i,e.push("Migrated root-level settings to default profile"),delete t.url,delete t.numberOfMachines,delete t.directory,delete t.labels,delete t.name,delete t.os,delete t.runnerGroup,delete t.overwrite,delete t.run}if(t.profiles)for(let[i,r]of Object.entries(t.profiles)){let s=typeof r==="object"&&r!==null?{...r}:{};if(typeof r==="object"&&r!==null){if("runnerCount"in r&&!("numberOfMachines"in r))s.numberOfMachines=r.runnerCount,delete s.runnerCount,e.push(`Renamed 'runnerCount' to 'numberOfMachines' in profile '${i}'`);if("workDir"in r&&!("directory"in r))s.directory=r.workDir,delete s.workDir,e.push(`Renamed 'workDir' to 'directory' in profile '${i}'`);if(typeof r.labels==="string")s.labels=r.labels.split(",").map((o)=>o.trim()),e.push(`Converted labels to array format in profile '${i}'`)}n.profiles[i]=s}for(let[i,r]of Object.entries(t))if(!["profiles","defaultProfile"].includes(i))n[i]=r,e.push(`Preserved unknown property '${i}'`);return n}async function $l(t,e){let n="";if(e.defaultProfile)n+=`defaultProfile = "${e.defaultProfile}"
|
|
92
|
+
|
|
93
|
+
`;for(let[i,r]of Object.entries(e.profiles)){n+=`[profiles.${i}]
|
|
94
|
+
`;for(let[s,o]of Object.entries(r)){if(o===void 0||o===null)continue;if(typeof o==="string")n+=`${s} = "${o}"
|
|
95
|
+
`;else if(typeof o==="number")n+=`${s} = ${o}
|
|
96
|
+
`;else if(Array.isArray(o))n+=`${s} = [${o.map((a)=>`"${a}"`).join(", ")}]
|
|
97
|
+
`;else n+=`${s} = ${JSON.stringify(o)}
|
|
98
|
+
`}n+=`
|
|
99
|
+
`}await Bun.write(t,n.trim())}function vl(t,e){if(l.info(""),e.dryRun)l.warn("DRY RUN MODE - No files were actually modified"),l.info("");let n=t.filter((r)=>r.success),i=t.filter((r)=>!r.success);if(n.length>0){l.success(`Successfully migrated ${n.length} file(s):`);for(let r of n)if(l.info(` ${c.value(r.path)}`),r.changes&&r.changes.length>0)for(let s of r.changes)l.info(` ${c.dim("\u2192")} ${s}`)}if(i.length>0){l.error(`Failed to migrate ${i.length} file(s):`);for(let r of i)l.error(` ${c.value(r.path)}: ${r.error}`)}l.info(""),l.info("Migration complete!")}q();O();V();Wt();import{parseArgs as Rl}from"util";async function El(){let{values:t}=Rl({args:process.argv.slice(2),options:{config:{short:"c",type:"string"},directory:{default:"./gh-runners",short:"d",type:"string"},interval:{default:"5",short:"i",type:"string"},json:{default:!1,short:"j",type:"boolean"},profile:{short:"p",type:"string"},watch:{default:!1,short:"w",type:"boolean"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile);return ve(n,{directory:t.directory,interval:Number.parseInt(t.interval,10),json:t.json,watch:t.watch})}async function Wo(){let t=await El();if(t.watch)await Pl(t);else await Bo(t)}async function Bo(t){let e=Vt.getAllWorkerHealth(),n=Vt.getHealthSummary();if(t.json){console.log(JSON.stringify({summary:n,workers:e},null,2));return}if(e.length===0){l.info("No active workers to monitor");return}if(l.info(c.value("Worker Health Monitor")),l.info(""),l.info("Summary:"),l.info(` Total: ${n.total}`),l.info(` ${c.success(`Healthy: ${n.healthy}`)}`),n.warning>0)l.info(` ${c.warning(`Warning: ${n.warning}`)}`);if(n.critical>0)l.info(` ${c.error(`Critical: ${n.critical}`)}`);if(n.unknown>0)l.info(` ${c.dim(`Unknown: ${n.unknown}`)}`);l.info(""),l.info("\u2500".repeat(80)),l.info(`${"Worker ID".padEnd(20)} ${"Status".padEnd(12)} ${"Uptime".padEnd(15)} ${"CPU %".padEnd(10)} ${"Memory %".padEnd(10)} ${"Errors".padEnd(10)} ${"Restarts".padEnd(10)}`),l.info("\u2500".repeat(80));for(let i of e){let r=Al(i.status),s=Tl(i.uptime),o=i.cpuUsage?`${i.cpuUsage.toFixed(1)}%`:"-",a=i.memoryUsage?`${i.memoryUsage.toFixed(1)}%`:"-",f=12+(r.length-i.status.length);l.info(`${i.workerId.padEnd(20)} ${r.padEnd(f)} ${s.padEnd(15)} ${o.padEnd(10)} ${a.padEnd(10)} ${i.errorCount.toString().padEnd(10)} ${i.restartCount.toString().padEnd(10)}`)}if(l.info("\u2500".repeat(80)),n.warning>0||n.critical>0)l.info(""),l.warn("Some workers are experiencing issues. Use --watch to monitor in real-time.")}async function Pl(t){let e=T();e.start("Starting health monitor...");let n=async()=>{console.clear(),await Bo({...t,json:!1});let r=new Date;console.log(""),console.log(c.dim(`Last updated: ${r.toLocaleTimeString()}`)),console.log(c.dim("Press Ctrl+C to exit"))};e.stop("Health monitor started"),await n();let i=setInterval(()=>n(),t.interval*1000);process.on("SIGINT",()=>{clearInterval(i),console.log(`
|
|
100
|
+
`),l.info("Health monitor stopped"),process.exit(0)}),await new Promise(()=>{})}function Al(t){switch(t){case"healthy":return c.success("\u25CF Healthy");case"warning":return c.warning("\u25CF Warning");case"critical":return c.error("\u25CF Critical");default:return c.dim("\u25CF Unknown")}}function Tl(t){let e=Math.floor(t/1000),n=Math.floor(e/60),i=Math.floor(n/60),r=Math.floor(i/24);if(r>0)return`${r}d ${i%24}h`;if(i>0)return`${i}h ${n%60}m`;if(n>0)return`${n}m ${e%60}s`;return`${e}s`}q();O();F();import{homedir as Ln}from"os";import{join as Gt}from"path";import{parseArgs as Ol}from"util";async function Hl(){let{values:t,positionals:e}=Ol({allowPositionals:!0,args:process.argv.slice(2),options:{disable:{default:!1,short:"d",type:"boolean"},enable:{default:!1,short:"e",type:"boolean"},info:{default:!1,type:"boolean"},install:{default:!1,short:"i",type:"boolean"},list:{default:!1,short:"l",type:"boolean"},uninstall:{default:!1,short:"u",type:"boolean"}},strict:!0});return{action:t.list?"list":t.install?"install":t.uninstall?"uninstall":t.enable?"enable":t.disable?"disable":t.info?"info":"list",pluginName:e[1]}}async function Uo(){let t=await Hl(),e=xo();if(!e)l.error("Plugin system is not initialized"),process.exit(1);switch(t.action){case"list":{let n=e.getAllPlugins();if(n.length===0){l.info("No plugins installed"),l.info(`
|
|
101
|
+
To install plugins, place them in: ${c.dim(Gt(Ln(),".hydra","plugins"))}`);return}l.info(`Installed plugins (${n.length}):
|
|
102
|
+
`);for(let i of n){let{manifest:r}=i;if(l.info(`${c.value(r.name)} v${r.version}`),r.description)l.info(` ${c.dim(r.description)}`);let s=e.getAllCommands().filter((o)=>o.name.startsWith(`${r.name}:`));if(s.length>0)l.info(` Commands: ${s.map((o)=>o.name).join(", ")}`)}break}case"info":{if(!t.pluginName)l.error("Plugin name required"),process.exit(1);let n=e.getPlugin(t.pluginName);if(!n)l.error(`Plugin '${t.pluginName}' not found`),process.exit(1);let{manifest:i}=n;if(l.info(`${c.value(i.name)} v${i.version}`),i.description)l.info(`
|
|
103
|
+
Description: ${i.description}`);if(i.hydraVersion)l.info(`Hydra Version: ${i.hydraVersion}`);let r=e.getAllCommands().filter((s)=>s.name.startsWith(`${i.name}:`));if(r.length>0){l.info(`
|
|
104
|
+
Commands:`);for(let s of r)l.info(` ${c.value(s.name)} - ${s.description}`)}if(i.hooks&&i.hooks.length>0){l.info(`
|
|
105
|
+
Hooks:`);for(let s of i.hooks)l.info(` ${s}`)}if(i.dependencies&&Object.keys(i.dependencies).length>0){l.info(`
|
|
106
|
+
Dependencies:`);for(let[s,o]of Object.entries(i.dependencies))l.info(` ${s}: ${o}`)}break}case"install":{if(!t.pluginName){let i=await A({message:"Enter plugin path or git URL:",placeholder:"./my-plugin or https://github.com/user/hydra-plugin"});if(!i||typeof i!=="string")l.error("Installation cancelled"),process.exit(1);t.pluginName=i}let n=T();n.start(`Installing plugin from ${t.pluginName}`);try{let i=Gt(Ln(),".hydra","plugins");if(await y.ensureDir(i),t.pluginName.startsWith("http")||t.pluginName.includes("github.com")){let{$:r}=awaitPromise.resolve(globalThis.Bun),s=t.pluginName.split("/").pop()?.replace(".git","")||"plugin",o=Gt(i,s);await r`git clone ${t.pluginName} ${o}`.quiet();let a=Gt(o,"package.json");if(await y.exists(a))await r`cd ${o} && bun install`.quiet();await e.loadPlugin(o),n.stop(`Plugin installed successfully: ${s}`)}else{let r=t.pluginName;if(!await y.exists(r))throw new Error(`Plugin path not found: ${r}`);let s=r.split("/").pop()||"plugin",o=Gt(i,s),{$:a}=awaitPromise.resolve(globalThis.Bun);await a`cp -r ${r} ${o}`.quiet(),await e.loadPlugin(o),n.stop(`Plugin installed successfully: ${s}`)}}catch(i){n.stop(`Failed to install plugin: ${i}`),process.exit(1)}break}case"uninstall":{if(!t.pluginName){let i=e.getAllPlugins();if(i.length===0)l.error("No plugins to uninstall"),process.exit(1);let r=await K({message:"Select plugin to uninstall:",options:i.map((s)=>({label:`${s.manifest.name} v${s.manifest.version}`,value:s.manifest.name}))});if(!r)l.error("Uninstall cancelled"),process.exit(1);t.pluginName=r}let n=T();n.start(`Uninstalling plugin: ${t.pluginName}`);try{await e.unloadPlugin(t.pluginName);let i=Gt(Ln(),".hydra","plugins",t.pluginName);if(await y.exists(i)){let{$:r}=awaitPromise.resolve(globalThis.Bun);await r`rm -rf ${i}`.quiet()}n.stop(`Plugin uninstalled successfully: ${t.pluginName}`)}catch(i){n.stop(`Failed to uninstall plugin: ${i}`),process.exit(1)}break}case"enable":case"disable":l.error(`Plugin ${t.action} not yet implemented`),process.exit(1)}}q();O();V();import{parseArgs as Cl}from"util";G();var Ft=$({prefix:"runner-pool"});class qo{pools=new Map;runnerToPool=new Map;createPool(t){let e=this.generatePoolId(t.name);if(this.pools.has(e))throw new Error(`Pool with name "${t.name}" already exists`);let n={created:new Date,id:e,labels:t.labels||[],lastScaled:new Date,maxRunners:t.maxRunners||10,minRunners:t.minRunners||1,name:t.name,profile:t.profile,runners:new Map};return this.pools.set(e,n),Ft.info(`Created runner pool: ${n.name} (${e})`),n}deletePool(t){let e=this.pools.get(t);if(!e)throw new Error(`Pool ${t} not found`);for(let n of e.runners.keys())this.runnerToPool.delete(n);this.pools.delete(t),Ft.info(`Deleted runner pool: ${e.name}`)}addRunner(t,e){let n=this.pools.get(t);if(!n)throw new Error(`Pool ${t} not found`);let i={...e,poolId:t};return n.runners.set(e.id,i),this.runnerToPool.set(e.id,t),Ft.debug(`Added runner ${e.name} to pool ${n.name}`),i}removeRunner(t){let e=this.runnerToPool.get(t);if(!e){Ft.warn(`Runner ${t} not found in any pool`);return}let n=this.pools.get(e);if(n)n.runners.delete(t);this.runnerToPool.delete(t),Ft.debug(`Removed runner ${t} from pool ${e}`)}updateRunnerStatus(t,e){let n=this.runnerToPool.get(t);if(!n)return;let r=this.pools.get(n)?.runners.get(t);if(r)r.status=e,r.lastSeen=new Date}getPool(t){return this.pools.get(t)}getPools(){return Array.from(this.pools.values())}getPoolByName(t){let e=this.generatePoolId(t);return this.pools.get(e)}getRunnerPool(t){let e=this.runnerToPool.get(t);return e?this.pools.get(e):void 0}getPoolMetrics(t){let e=this.pools.get(t);if(!e)return null;let n=Array.from(e.runners.values()),i=n.filter((a)=>a.status==="idle").length,r=n.filter((a)=>a.status==="busy").length,s=n.filter((a)=>a.status==="offline").length,o=n.length;return{busyRunners:r,idleRunners:i,offlineRunners:s,poolId:t,totalRunners:o,utilization:o>0?r/o:0}}getAllMetrics(){return Array.from(this.pools.keys()).map((t)=>this.getPoolMetrics(t)).filter((t)=>t!==null)}findRunnersWithLabels(t){let e=[];for(let n of this.pools.values())for(let i of n.runners.values())if(t.every((s)=>i.labels.includes(s)||n.labels.includes(s)))e.push(i);return e}getIdleRunnersInPool(t){let e=this.pools.get(t);if(!e)return[];return Array.from(e.runners.values()).filter((n)=>n.status==="idle")}generatePoolId(t){return t.toLowerCase().replace(/[^a-z0-9-]/g,"-")}}var Rt=new qo;async function Go(){let t=await Sl();if(t.list)await Lo();else if(t.create)await _l(t);else if(t.delete)await Nl(t);else await Lo()}async function Lo(){let t=Rt.getPools();if(t.length===0){at("No runner pools configured");return}console.log(`
|
|
107
|
+
\uD83D\uDCCA Runner Pools:`),console.log("\u2500".repeat(80));for(let e of t){let n=Rt.getPoolMetrics(e.id);if(console.log(`
|
|
108
|
+
\uD83C\uDFCA ${e.name} (${e.id})`),console.log(` Profile: ${e.profile.name}`),console.log(` Labels: ${e.labels.join(", ")||"none"}`),console.log(` Limits: ${e.minRunners}-${e.maxRunners} runners`),n)console.log(` Status: ${n.totalRunners} total (${n.busyRunners} busy, ${n.idleRunners} idle, ${n.offlineRunners} offline)`),console.log(` Utilization: ${(n.utilization*100).toFixed(1)}%`)}console.log(`
|
|
109
|
+
${"\u2500".repeat(80)}`)}async function _l(t){he("\uD83C\uDFCA Create Runner Pool");let e=t.name||await A({message:"Pool name",placeholder:"production-runners",validate:(o)=>{if(!o||o.trim().length===0)return"Pool name is required";if(Rt.getPoolByName(o))return"Pool with this name already exists";return}});if(typeof e==="symbol")throw new nt("Pool creation cancelled","CANCELLED");let n=t.labels?t.labels.split(",").map((o)=>o.trim()):[];if(!t.labels){let o=await xi({message:"Select runner labels",options:[{label:"self-hosted",value:"self-hosted"},{label:"Linux",value:"linux"},{label:"macOS",value:"macos"},{label:"Windows",value:"windows"},{label:"x64",value:"x64"},{label:"ARM64",value:"arm64"}],required:!1});if(typeof o!=="symbol")n.push(...o);let a=await A({message:"Additional labels (comma-separated)",placeholder:"gpu, high-memory"});if(typeof a==="string"&&a.trim())n.push(...a.split(",").map((f)=>f.trim()))}let i=await N({profile:t.profile}),r=await S(i,t.profile);if(!r)throw new nt("Profile not found","PROFILE_NOT_FOUND");let s=Rt.createPool({labels:n,maxRunners:t.maxRunners,minRunners:t.minRunners,name:e,profile:r});at(`\u2705 Created runner pool "${s.name}" with ${n.length} labels`)}async function Nl(t){let e=t.delete,n=Rt.getPoolByName(e);if(!n)throw new nt(`Pool "${e}" not found`,"POOL_NOT_FOUND");let i=Rt.getPoolMetrics(n.id);if(i&&i.totalRunners>0&&!t.force){if(!await C({initialValue:!1,message:`Pool has ${i.totalRunners} runners. Delete anyway?`})){at("Deletion cancelled");return}}Rt.deletePool(n.id),at(`\u2705 Deleted runner pool "${e}"`)}async function Sl(){let{values:t}=Cl({allowPositionals:!0,args:Bun.argv,options:{create:{short:"c",type:"boolean"},delete:{short:"d",type:"string"},force:{short:"f",type:"boolean"},labels:{type:"string"},list:{default:!1,short:"l",type:"boolean"},maxRunners:{default:"10",type:"string"},minRunners:{default:"1",type:"string"},name:{short:"n",type:"string"},profile:{short:"p",type:"string"}},strict:!0});return{create:t.create,delete:t.delete,force:t.force,labels:t.labels,list:t.list||!t.create&&!t.delete,maxRunners:Number.parseInt(t.maxRunners),minRunners:Number.parseInt(t.minRunners),name:t.name,profile:t.profile}}q();O();bn();Wt();import{parseArgs as Ml}from"util";async function Wl(){let{values:t,positionals:e}=Ml({allowPositionals:!0,args:process.argv.slice(2),options:{json:{default:!1,short:"j",type:"boolean"}},strict:!0});return{action:e[0],json:t.json}}async function jo(){let t=await Wl();if(!t.action)t.action=await K({message:"What would you like to do?",options:[{label:"View recovery status",value:"status"},{label:"View error metrics",value:"metrics"},{label:"View circuit breakers",value:"breakers"},{label:"Reset error metrics",value:"reset"}]});switch(t.action){case"status":await Bl(t);break;case"metrics":await Ul(t);break;case"breakers":await ql(t);break;case"reset":await Ll(t);break;default:l.error(`Unknown action: ${t.action}`),l.info("Available actions: status, metrics, breakers, reset")}}async function Bl(t){let e=ht.getErrorMetrics(),n=ht.getAllCircuitBreakers(),i=Vt.getAllWorkerInfo(),r={activeWorkers:i.filter((s)=>s.status==="running").length,circuitBreakers:{closed:Array.from(n.values()).filter((s)=>s.getState()==="closed").length,halfOpen:Array.from(n.values()).filter((s)=>s.getState()==="half_open").length,open:Array.from(n.values()).filter((s)=>s.getState()==="open").length,total:n.size},erroredWorkers:i.filter((s)=>s.status==="error").length,totalErrors:Array.from(e.values()).reduce((s,o)=>s+o.count,0),uniqueErrorTypes:e.size};if(t.json){console.log(JSON.stringify(r,null,2));return}if(l.info(c.value("Error Recovery Status")),l.info(""),l.info("Summary:"),l.info(` Total errors: ${r.totalErrors}`),l.info(` Unique error types: ${r.uniqueErrorTypes}`),l.info(` Active workers: ${r.activeWorkers}`),r.erroredWorkers>0)l.info(` ${c.error(`Errored workers: ${r.erroredWorkers}`)}`);if(l.info(""),l.info("Circuit Breakers:"),l.info(` Total: ${r.circuitBreakers.total}`),r.circuitBreakers.open>0)l.info(` ${c.error(`Open: ${r.circuitBreakers.open}`)}`);if(r.circuitBreakers.halfOpen>0)l.info(` ${c.warning(`Half-open: ${r.circuitBreakers.halfOpen}`)}`);if(l.info(` ${c.success(`Closed: ${r.circuitBreakers.closed}`)}`),r.totalErrors>0)l.info(""),l.info("Use 'hydra recovery metrics' to see detailed error breakdown")}async function Ul(t){let e=ht.getErrorMetrics();if(e.size===0){l.info("No error metrics recorded");return}let n=Array.from(e.entries()).map(([r,s])=>({count:s.count,errorType:r.split(":")[1]||"unknown",lastOccurred:s.lastOccurred,operation:r.split(":")[0]||"unknown"}));if(t.json){console.log(JSON.stringify(n,null,2));return}l.info(c.value("Error Metrics")),l.info(""),l.info("\u2500".repeat(80)),l.info(`${"Operation".padEnd(30)} ${"Error Type".padEnd(20)} ${"Count".padEnd(10)} ${"Last Occurred".padEnd(20)}`),l.info("\u2500".repeat(80));for(let r of n){let s=Jo(r.lastOccurred);l.info(`${r.operation.padEnd(30)} ${r.errorType.padEnd(20)} ${r.count.toString().padEnd(10)} ${s.padEnd(20)}`)}l.info("\u2500".repeat(80));let i=n.reduce((r,s)=>r+s.count,0);l.info(`Total errors: ${i}`)}async function ql(t){let e=ht.getAllCircuitBreakers();if(e.size===0){l.info("No circuit breakers configured");return}let n=Array.from(e.entries()).map(([i,r])=>{let s=r.getStats();return{name:i,...s}});if(t.json){console.log(JSON.stringify(n,null,2));return}l.info(c.value("Circuit Breakers")),l.info("");for(let i of n){let r=i.state==="open"?c.error:i.state==="half_open"?c.warning:c.success;if(l.info(`${c.value(i.name)}:`),l.info(` State: ${r(i.state)}`),l.info(` Failure count: ${i.failureCount}`),i.lastFailureTime)l.info(` Last failure: ${Jo(i.lastFailureTime)} ago`);if(i.state==="half_open")l.info(` Half-open attempts: ${i.halfOpenAttempts}`);l.info("")}}async function Ll(t){if(!t.json){if(!await C({initialValue:!1,message:"Are you sure you want to reset all error metrics?"})){l.info("Reset cancelled");return}}if(ht.resetMetrics(),t.json)console.log(JSON.stringify({message:"Error metrics reset",success:!0}));else l.success("Error metrics reset successfully")}function Jo(t){let e=Math.floor((Date.now()-t.getTime())/1000);if(e<60)return`${e}s`;let n=Math.floor(e/60);if(n<60)return`${n}m`;let i=Math.floor(n/60);if(i<24)return`${i}h ${n%60}m`;return`${Math.floor(i/24)}d ${i%24}h`}Ae();Pn();q();O();G();V();Ee();Ae();import{parseArgs as Gl}from"util";var ko=$({prefix:"hydra"}).child("scale");async function jl(){let{values:t}=Gl({allowPositionals:!0,args:Bun.argv,options:{config:{short:"c",type:"string"},directory:{default:`${process.cwd()}/gh-runners`,short:"d",type:"string"},dry:{default:!1,type:"boolean"},interval:{default:"60",short:"i",type:"string"},max:{default:"5",short:"M",type:"string"},min:{default:"1",short:"m",type:"string"},profile:{short:"p",type:"string"},"scale-down-idle":{default:"30",type:"string"},"scale-up-threshold":{default:"2",type:"string"},token:{short:"t",type:"string"},url:{short:"u",type:"string"},watch:{default:!1,short:"w",type:"boolean"}},strict:!0}),e=await N({configPath:t.config}),n=await S(e,t.profile);return{directory:t.directory||n?.directory||`${process.cwd()}/gh-runners`,dry:t.dry,scaleConfig:{checkIntervalSeconds:Number.parseInt(t.interval,10),maxRunners:Number.parseInt(t.max,10),minRunners:Number.parseInt(t.min,10),scaleDownIdleMinutes:Number.parseInt(t["scale-down-idle"],10),scaleUpThreshold:Number.parseInt(t["scale-up-threshold"],10)},token:t.token,url:t.url||n?.url,watch:t.watch}}async function Xo(){try{let t=await jl();if(!t.token||!t.url)throw new Error("Token (-t) and URL (-u) parameters are required");if(t.scaleConfig.minRunners>t.scaleConfig.maxRunners)throw new Error("Minimum runners cannot be greater than maximum runners");if(l.info("Autoscale Configuration:"),console.log(` Min Runners: ${c.value(String(t.scaleConfig.minRunners))}`),console.log(` Max Runners: ${c.value(String(t.scaleConfig.maxRunners))}`),console.log(` Scale Up Threshold: ${c.value(String(t.scaleConfig.scaleUpThreshold))} pending jobs`),console.log(` Scale Down After: ${c.value(String(t.scaleConfig.scaleDownIdleMinutes))} minutes idle`),console.log(),t.watch)await kl(t);else await Jl(t)}catch(t){ko.error("Failed to scale runners:",t),process.exit(1)}}async function Jl(t){let e=T();e.start("Analyzing queue and runners...");try{let n=await Qo(t.url,t.token,t.directory);e.stop("Analysis complete"),Kl(n);let i=Ko(n,t.scaleConfig);if(i.type==="none"){l.info("No scaling action needed");return}if(console.log(),i.type==="scale-up")l.info(`Recommendation: Scale UP by ${i.count} runner(s)`),l.info(`Reason: ${i.reason}`);else l.info(`Recommendation: Scale DOWN by ${i.count} runner(s)`),l.info(`Reason: ${i.reason}`);if(t.dry){l.info("Dry run - no changes made");return}if(!await C({initialValue:!0,message:`Proceed with ${i.type}?`})){l.info("Cancelled");return}await Vo(i,t)}catch(n){throw e.stop("Failed"),n}}async function kl(t){l.info(`Starting autoscale watch mode (checking every ${t.scaleConfig.checkIntervalSeconds}s)`),console.log(`Press Ctrl+C to stop
|
|
110
|
+
`);let e=new Map;while(!0)try{let n=await Qo(t.url,t.token,t.directory);await Ql(e,n,t);let i=Ko(n,t.scaleConfig,e),r=new Date().toLocaleTimeString();if(console.log(`[${r}] Queue: ${n.pendingJobs} | Active: ${n.activeRunners} | Idle: ${n.idleRunners} | Total: ${n.totalRunners}`),i.type!=="none"){if(console.log(`[${r}] ${c.warning(`Action: ${i.type} by ${i.count} - ${i.reason}`)}`),!t.dry)await Vo(i,t)}await Bun.sleep(t.scaleConfig.checkIntervalSeconds*1000)}catch(n){ko.error("Error in watch cycle:",n),await Bun.sleep(t.scaleConfig.checkIntervalSeconds*1000)}}async function Qo(t,e,n){let i=await Xl(t,e),r=await Gn(t,e,n),s=r.filter((f)=>f.busy).length,o=r.filter((f)=>f.status==="online"&&!f.busy).length,a=r.length;return{activeRunners:s,idleRunners:o,pendingJobs:i,totalRunners:a}}async function Xl(t,e){let n=t.match(/github\.com[:/]([^/]+)(?:\/([^/.]+))?/);if(!n)throw new Error("Invalid GitHub URL");let[,i,r]=n,s=r?`https://api.github.com/repos/${i}/${r}/actions/runs?status=queued&per_page=100`:`https://api.github.com/orgs/${i}/actions/runs?status=queued&per_page=100`;return it(async()=>{let o=await fetch(s,{headers:{Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${e}`}});if(!o.ok)throw new Error(`GitHub API error: ${o.status}`);let a=await o.json(),f=0;for(let u of a.workflow_runs||[]){let p=await fetch(`https://api.github.com/repos/${i}/${r}/actions/runs/${u.id}/jobs`,{headers:{Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${e}`}});if(p.ok){let d=await p.json();f+=d.jobs?.filter((g)=>g.status==="queued").length||0}}return f},{maxAttempts:3})}async function Gn(t,e,n){let i=t.match(/github\.com[:/]([^/]+)(?:\/([^/.]+))?/);if(!i)return[];let[,r,s]=i,o=s?`https://api.github.com/repos/${r}/${s}/actions/runners`:`https://api.github.com/orgs/${r}/actions/runners`,a=await fetch(o,{headers:{Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${e}`}});if(!a.ok)return[];return(await a.json()).runners||[]}function Ko(t,e,n){if(t.pendingJobs>=e.scaleUpThreshold&&t.totalRunners<e.maxRunners)return{count:Math.min(t.totalRunners+Math.ceil(t.pendingJobs/2),e.maxRunners)-t.totalRunners,reason:`${t.pendingJobs} jobs pending (threshold: ${e.scaleUpThreshold})`,type:"scale-up"};if(t.idleRunners>0&&t.totalRunners>e.minRunners){let i=0;if(n){let r=new Date;for(let[,s]of n)if((r.getTime()-s.getTime())/60000>=e.scaleDownIdleMinutes)i++}else i=t.idleRunners;if(i>0)return{count:Math.min(i,t.totalRunners-e.minRunners),reason:`${i} runners idle for ${e.scaleDownIdleMinutes}+ minutes`,type:"scale-down"}}return{count:0,reason:"",type:"none"}}async function Vo(t,e){if(t.type==="scale-up"){l.info(`Scaling up by ${t.count} runner(s)...`);let n=process.argv;try{process.argv=[process.argv[0],process.argv[1],"create","-t",e.token,"-u",e.url,"-m",String(t.count),"-d",e.directory],await zt(),l.success(`Successfully added ${t.count} runner(s)`)}finally{process.argv=n}}else if(t.type==="scale-down"){l.info(`Scaling down by ${t.count} runner(s)...`);let i=(await Gn(e.url,e.token,e.directory)).filter((s)=>s.status==="online"&&!s.busy).slice(0,t.count);if(i.length===0){l.warning("No idle runners to remove");return}let r=process.argv;try{for(let s of i){let o=s.name.match(/runner-(\d+)/)?.[1];if(!o)continue;process.argv=[process.argv[0],process.argv[1],"remove","-t",e.token,"-u",e.url,"-n",`runner-${o}`,"-d",e.directory,"-f"],await Yt()}l.success(`Successfully removed ${i.length} runner(s)`)}finally{process.argv=r}}}async function Ql(t,e,n){let i=await Gn(n.url,n.token,n.directory);for(let s of i)if(s.status==="online"&&!s.busy){if(!t.has(s.name))t.set(s.name,new Date)}else t.delete(s.name);let r=new Set(i.map((s)=>s.name));for(let[s]of t)if(!r.has(s))t.delete(s)}function Kl(t){console.log(),console.log(c.bold("\uD83D\uDCCA Current Status")),console.log(` Pending Jobs: ${c.value(String(t.pendingJobs))}`),console.log(` Total Runners: ${c.value(String(t.totalRunners))}`),console.log(` Active Runners: ${c.success(String(t.activeRunners))}`),console.log(` Idle Runners: ${c.warning(String(t.idleRunners))}`)}q();O();import{homedir as Zo}from"os";import{join as jn}from"path";import{parseArgs as Vl}from"util";var Ce={global:jn(Zo(),".hydra","templates.json"),local:"./hydra-templates.json"};async function Zl(){let{values:t,positionals:e}=Vl({allowPositionals:!0,args:process.argv.slice(2),options:{force:{default:!1,short:"f",type:"boolean"},from:{short:"F",type:"string"},global:{default:!1,short:"g",type:"boolean"},name:{short:"n",type:"string"}},strict:!0}),n=e[0],i=e[1];return{action:n,force:t.force,from:t.from,global:t.global,name:t.name||i}}async function zo(){let t=await Zl();if(!t.action)t.action=await K({message:"What would you like to do?",options:[{label:"List templates",value:"list"},{label:"Create a new template",value:"create"},{label:"Use a template",value:"use"},{label:"Show template details",value:"show"},{label:"Delete a template",value:"delete"}]});switch(t.action){case"list":await zl();break;case"create":await Yl(t);break;case"use":await Il(t);break;case"show":await Fl(t);break;case"delete":await Dl(t);break;default:l.error(`Unknown action: ${t.action}`),l.info("Available actions: list, create, use, show, delete")}}async function Et(t){let e=t?Ce.global:Ce.local,n=Bun.file(e);if(!await n.exists())return{templates:{},version:"1.0"};try{return await n.json()}catch{return{templates:{},version:"1.0"}}}async function Yo(t,e){let n=e?Ce.global:Ce.local;if(e){let i=jn(Zo(),".hydra");await Bun.write(jn(i,".gitkeep"),"")}await Bun.write(n,JSON.stringify(t,null,2))}async function zl(){let t=await Et(!0),e=await Et(!1),n={...t.templates,...e.templates};if(Object.keys(n).length===0){l.info("No templates found"),l.info(""),l.info("Create a template with: hydra template create");return}l.info(c.value("Available Templates:")),l.info("");for(let[i,r]of Object.entries(n)){let o=i in t.templates?c.dim(" (global)"):"";if(l.info(` ${c.value(i)}${o}`),r.description)l.info(` ${c.dim(r.description)}`);if(r.extends)l.info(` ${c.dim(`Extends: ${r.extends}`)}`);let a=[];if(r.numberOfMachines)a.push(`machines: ${r.numberOfMachines}`);if(r.os)a.push(`os: ${r.os}`);if(r.labels)a.push(`labels: ${r.labels}`);if(a.length>0)l.info(` ${c.dim(a.join(", "))}`);l.info("")}}async function Yl(t){let e=t.name||await A({message:"Template name:",placeholder:"my-template",validate:(p)=>{if(!p)return"Template name is required";if(!/^[a-zA-Z0-9-_]+$/.test(p))return"Template name can only contain letters, numbers, hyphens, and underscores";return}}),n=await Et(t.global??!1);if(!t.force&&e in n.templates){if(!await C({initialValue:!1,message:`Template '${e}' already exists. Overwrite?`})){l.info("Template creation cancelled");return}}let i=await A({message:"Description (optional):",placeholder:"Template for production runners"}),r={};if(t.from){let p=n.templates[t.from];if(p)r={...p},delete r.name,delete r.description,delete r.metadata,delete r.extends}let s=await A({initialValue:r.numberOfMachines?.toString()||"1",message:"Number of machines:",placeholder:r.numberOfMachines?.toString()||"1"}),o=await K({initialValue:r.os||"osx",message:"Operating system:",options:[{label:"macOS",value:"osx"},{label:"Linux",value:"linux"},{label:"Windows",value:"windows"}]}),a=await A({initialValue:r.labels,message:"Labels (comma-separated, optional):",placeholder:r.labels||"self-hosted,x64"}),f=await A({initialValue:r.directory||"./gh-runners",message:"Runner directory:",placeholder:r.directory||"./gh-runners"}),u={description:i||void 0,directory:f,extends:t.from||void 0,labels:a||void 0,metadata:{author:process.env.USER||void 0,created:new Date().toISOString(),updated:new Date().toISOString()},name:e,numberOfMachines:Number.parseInt(s,10),os:o};n.templates[e]=u,await Yo(n,t.global??!1),l.success(`Template '${e}' created successfully`),l.info(""),l.info(`Use it with: hydra create --template ${e}`)}async function Il(t){let e=await Et(!0),n=await Et(!1),i={...e.templates,...n.templates};if(Object.keys(i).length===0){l.error("No templates found"),l.info("Create a template with: hydra template create");return}let r=t.name||await K({message:"Select a template:",options:Object.entries(i).map(([f,u])=>({label:`${f}${u.description?` - ${u.description}`:""}`,value:f}))}),s=i[r];if(!s){l.error(`Template '${r}' not found`);return}let o=await Jn(s,i);if(l.info(""),l.info(c.value(`Using template: ${r}`)),l.info(""),l.info("This will create runners with the following configuration:"),l.info(` Number of machines: ${o.numberOfMachines||1}`),l.info(` OS: ${o.os||"osx"}`),l.info(` Directory: ${o.directory||"./gh-runners"}`),o.labels)l.info(` Labels: ${o.labels}`);l.info("");let a=await K({message:"Where should this configuration be saved?",options:[{label:"Create hydra.json in current directory",value:"json"},{label:"Create hydra.toml in current directory",value:"toml"},{label:"Just show the command",value:"command"}]});if(a==="command"){let f=[];if(o.numberOfMachines)f.push(`-m ${o.numberOfMachines}`);if(o.os)f.push(`-s ${o.os}`);if(o.directory)f.push(`-d "${o.directory}"`);if(o.labels)f.push(`-l "${o.labels}"`);if(o.name)f.push(`-n "${o.name}"`);l.info("Run the following command:"),l.info(""),l.info(c.value(`hydra create ${f.join(" ")} -t <TOKEN> -u <URL>`)),l.info("")}else{let f={defaultProfile:"default",profiles:{default:o}},u=a==="json"?"hydra.json":"hydra.toml";if(a==="json")await Bun.write(u,JSON.stringify(f,null,2));else{let p=`defaultProfile = "default"
|
|
111
|
+
|
|
112
|
+
[profiles.default]
|
|
113
|
+
`;for(let[d,g]of Object.entries(o))if(g!==void 0&&g!==null)if(typeof g==="string")p+=`${d} = "${g}"
|
|
114
|
+
`;else p+=`${d} = ${g}
|
|
115
|
+
`;await Bun.write(u,p)}l.success(`Created ${u}`),l.info(""),l.info("Now run:"),l.info(c.value("hydra create -t <TOKEN> -u <URL>"))}}async function Fl(t){let e=await Et(!0),n=await Et(!1),i={...e.templates,...n.templates},r=t.name||await K({message:"Select a template:",options:Object.entries(i).map(([a,f])=>({label:`${a}${f.description?` - ${f.description}`:""}`,value:a}))}),s=i[r];if(!s){l.error(`Template '${r}' not found`);return}let o=await Jn(s,i);if(l.info(""),l.info(c.value(`Template: ${r}`)),l.info("\u2500".repeat(40)),s.description)l.info(`Description: ${s.description}`);if(s.extends)l.info(`Extends: ${s.extends}`);if(s.metadata){if(s.metadata.author)l.info(`Author: ${s.metadata.author}`);if(s.metadata.created)l.info(`Created: ${new Date(s.metadata.created).toLocaleDateString()}`);if(s.metadata.updated)l.info(`Updated: ${new Date(s.metadata.updated).toLocaleDateString()}`);if(s.metadata.tags?.length)l.info(`Tags: ${s.metadata.tags.join(", ")}`)}l.info(""),l.info("Configuration:"),l.info(JSON.stringify(o,null,2))}async function Dl(t){let e=await Et(t.global??!1);if(Object.keys(e.templates).length===0){l.error("No templates found");return}let n=t.name||await K({message:"Select a template to delete:",options:Object.entries(e.templates).map(([i,r])=>({label:`${i}${r.description?` - ${r.description}`:""}`,value:i}))});if(!(n in e.templates)){l.error(`Template '${n}' not found`);return}if(!t.force){if(!await C({initialValue:!1,message:`Are you sure you want to delete template '${n}'?`})){l.info("Deletion cancelled");return}}delete e.templates[n],await Yo(e,t.global??!1),l.success(`Template '${n}' deleted`)}async function Jn(t,e,n=new Set){if(n.has(t.name))throw new Error(`Circular template dependency detected: ${t.name}`);n.add(t.name);let i={};if(t.extends){let u=e[t.extends];if(u)i=await Jn(u,e,n)}let{name:r,description:s,extends:o,metadata:a,...f}=t;return{...i,...f}}q();O();V();import{parseArgs as nf}from"util";O();G();var Io=$({prefix:"config-validator"}),tf=I({directory:X(),name:X(),numberOfMachines:yt(),os:X(),overwrite:Tt(),run:Tt()}),ef=I({profiles:I({})});class Fo{validateConfig(t){let e={errors:[],valid:!0,warnings:[]};try{ef(t)}catch(n){return e.valid=!1,e.errors.push({code:"SCHEMA_VALIDATION_FAILED",field:"config",message:`Schema validation failed: ${n}`}),e}return this.validateProfiles(t.profiles,e),this.validateDefaultProfile(t.defaultProfile,t.profiles,e),e}validateProfile(t){let e={errors:[],valid:!0,warnings:[]};try{tf(t)}catch(n){return e.valid=!1,e.errors.push({code:"SCHEMA_VALIDATION_FAILED",field:"profile",message:`Schema validation failed: ${n}`}),e}return this.validateProfileFields(t,e),e}validateProfiles(t,e){if(Object.keys(t).length===0){e.valid=!1,e.errors.push({code:"NO_PROFILES",field:"profiles",message:"At least one profile is required"});return}for(let[i,r]of Object.entries(t)){if(r.name!==i)e.warnings.push({code:"PROFILE_NAME_MISMATCH",field:`profiles.${i}`,message:`Profile name "${r.name}" does not match key "${i}"`});let s=this.validateProfile(r);if(!s.valid)e.valid=!1,e.errors.push(...s.errors.map((o)=>({...o,field:`profiles.${i}.${o.field}`})));e.warnings.push(...s.warnings.map((o)=>({...o,field:`profiles.${i}.${o.field}`})))}}validateDefaultProfile(t,e,n){if(t){if(!e[t])n.valid=!1,n.errors.push({code:"DEFAULT_PROFILE_NOT_FOUND",field:"defaultProfile",message:`Default profile "${t}" not found in profiles`})}}validateProfileFields(t,e){if(t.numberOfMachines<1)e.valid=!1,e.errors.push({code:"INVALID_NUMBER_OF_MACHINES",field:"numberOfMachines",message:"Number of machines must be at least 1"});if(t.numberOfMachines>100)e.warnings.push({code:"LARGE_NUMBER_OF_MACHINES",field:"numberOfMachines",message:"Large number of machines may impact performance"});let n=["osx","linux","windows"];if(!n.includes(t.os))e.valid=!1,e.errors.push({code:"INVALID_OS",field:"os",message:`Invalid OS "${t.os}". Must be one of: ${n.join(", ")}`});if(!t.directory.startsWith("/")&&!t.directory.match(/^[A-Z]:\\/)&&!t.directory.startsWith("./"))e.warnings.push({code:"RELATIVE_PATH_WARNING",field:"directory",message:"Directory path should be absolute or relative (starting with ./)"});if(t.name.length<1)e.valid=!1,e.errors.push({code:"EMPTY_NAME",field:"name",message:"Profile name cannot be empty"});if(t.name.includes(" "))e.warnings.push({code:"SPACES_IN_NAME",field:"name",message:"Profile name contains spaces, which may cause issues"});if(t.labels&&t.labels.length>0){if(t.labels.split(",").map((r)=>r.trim()).some((r)=>r.length===0))e.warnings.push({code:"EMPTY_LABELS",field:"labels",message:"Empty labels found in label list"})}if(t.runnerGroup!==void 0&&t.runnerGroup.length===0)e.warnings.push({code:"EMPTY_RUNNER_GROUP",field:"runnerGroup",message:"Runner group is empty"});if(t.url&&!t.url.startsWith("https://"))e.warnings.push({code:"INSECURE_URL",field:"url",message:"URL should use HTTPS for security"})}}function Dt(t){return new Fo().validateConfig(t)}function Do(t){let e=Dt(t);if(!e.valid)for(let n of e.errors)Io.error(`${n.field}: ${n.message}`);if(e.warnings.length>0)for(let n of e.warnings)Io.warn(`${n.field}: ${n.message}`);return e.valid}F();async function of(){let{values:t}=nf({args:process.argv.slice(2),options:{config:{short:"c",type:"string"},fix:{default:!1,short:"f",type:"boolean"},json:{default:!1,short:"j",type:"boolean"}},strict:!0});return{configPath:t.config,fix:t.fix,json:t.json}}async function tr(){let t=await of(),e=t.configPath||await yn();if(!e)l.error("No configuration file found"),l.info("Create one with: hydra init"),process.exit(1);if(!await y.exists(e))l.error(`Configuration file not found: ${e}`),process.exit(1);l.info(`Validating configuration: ${c.dim(e)}`);try{let n=await y.readFile(e),i=e.endsWith(".toml"),r;if(i)r=Bun.TOML.parse(n);else r=JSON.parse(n);if(t.json){let o=Dt(r);console.log(JSON.stringify(o,null,2)),process.exit(o.valid?0:1)}let s=Do(r);if(t.fix&&!s)if(l.info(`
|
|
116
|
+
Attempting to fix configuration issues...`),await rf(r,e))l.success("Configuration issues fixed and saved");else l.error("Unable to automatically fix all issues"),l.info("Please manually review and update your configuration");process.exit(s?0:1)}catch(n){if(n instanceof SyntaxError)l.error("Configuration file has syntax errors:"),l.error(n.message);else l.error(`Failed to validate configuration: ${n}`);process.exit(1)}}async function rf(t,e){let n=Dt(t);if(!t.profiles)t.profiles={};for(let r of n.errors){if(r.path==="defaultProfile"&&t.defaultProfile)delete t.defaultProfile,l.info("Removed invalid defaultProfile");if(r.path?.startsWith("profiles.")&&r.path?.includes(".numberOfMachines")){let o=r.path.split(".")[1];if(o&&t.profiles[o]){let a=t.profiles[o].numberOfMachines,f=Number.parseInt(String(a),10);if(Number.isNaN(f)||f<1)t.profiles[o].numberOfMachines="1",l.info(`Fixed numberOfMachines for profile '${o}'`)}}if(r.path?.startsWith("profiles.")&&r.path?.includes(".labels")){let o=r.path.split(".")[1];if(o&&t.profiles[o]&&t.profiles[o].labels){let a=t.profiles[o].labels.split(",").map((f)=>f.trim()).filter((f)=>f.match(/^[a-zA-Z0-9\-_]+$/)).join(",");t.profiles[o].labels=a,l.info(`Fixed labels for profile '${o}'`)}}}if(Dt(t).valid){let s=e.endsWith(".toml")?JSON.stringify(t,null,2):JSON.stringify(t,null,2);return await y.writeFile(e,s),!0}return!1}q();O();V();F();tt();import{watch as sf}from"fs";import{parseArgs as af}from"util";var Pt=w({prefix:"watch"});async function lf(){let{values:t,positionals:e}=af({allowPositionals:!0,args:process.argv.slice(2),options:{config:{short:"c",type:"string"},debounce:{default:"1000",type:"string"},directory:{default:"./gh-runners",short:"d",type:"string"},exclude:{default:[],multiple:!0,type:"string"},profile:{short:"p",type:"string"}},strict:!0}),n=await N({configPath:t.config}),i=await S(n,t.profile);return ve(i,{command:e[1]||"status",debounce:Number.parseInt(t.debounce,10),directory:t.directory,exclude:t.exclude})}async function er(){let t=await lf();if(!await y.exists(t.directory))Pt.error(`Directory not found: ${t.directory}`),process.exit(1);Pt.info(`Watching ${t.directory} for changes...`),Pt.info(`Will run: hydra ${t.command}`),Pt.info(`Debounce: ${t.debounce}ms`);let e=T(),n=null,i=!1,r=async()=>{if(i)return;i=!0,e.start(`Running: hydra ${t.command}`);try{let{$:a}=awaitPromise.resolve(globalThis.Bun),f=await a`hydra ${t.command} -d ${t.directory}`.quiet();if(f.exitCode===0)e.stop(c.success("\u2713 Command completed successfully"));else e.stop(c.error(`\u2717 Command failed with exit code ${f.exitCode}`)),Pt.error(f.stderr.toString())}catch(a){e.stop(c.error("\u2717 Command failed")),Pt.error("Error running command:",a)}finally{i=!1}},s=(a,f)=>{if(!f)return;if(t.exclude.some((p)=>{if(p.includes("*"))return new RegExp(p.replace(/\*/g,".*")).test(f);return f.includes(p)}))return;if(Pt.info(`Detected ${a}: ${f}`),n)clearTimeout(n);n=setTimeout(()=>{r()},t.debounce)};await r();let o=sf(t.directory,{recursive:!0},s);process.on("SIGINT",()=>{Pt.info(`
|
|
117
|
+
Stopping watch mode...`),o.close(),process.exit(0)}),await new Promise(()=>{})}q();O();G();V();import{parseArgs as mf}from"util";G();var _e=$({prefix:"queue-monitor"}),kn="https://api.github.com",ff=30000,uf=300000;class nr{config;intervalId=null;metrics={averageWaitTime:0,completedJobs:0,jobsByLabel:new Map,oldestJobAge:0,queuedJobs:0,runningJobs:0};listeners=new Map;constructor(t){this.config=t}async start(){_e.info("Starting queue monitor"),await this.updateMetrics(),this.intervalId=setInterval(()=>this.updateMetrics(),this.config.pollingInterval||ff)}stop(){if(this.intervalId)clearInterval(this.intervalId),this.intervalId=null,_e.info("Queue monitor stopped")}onMetricsUpdate(t){let e=Math.random().toString(36).substring(7);return this.listeners.set(e,t),()=>this.listeners.delete(e)}getMetrics(){return{...this.metrics}}async updateMetrics(){try{let t=await this.fetchQueuedJobs(),e=Date.now(),n=0,i=0,r=new Map,s=0,o=0,a=0;for(let f of t){switch(f.status){case"queued":{s++;let u=e-new Date(f.created_at||e).getTime();n+=u,i=Math.max(i,u);break}case"in_progress":o++;break;case"completed":a++;break}for(let u of f.labels)r.set(u,(r.get(u)||0)+1)}this.metrics={averageWaitTime:s>0?n/s:0,completedJobs:a,jobsByLabel:r,oldestJobAge:i,queuedJobs:s,runningJobs:o},_e.debug(`Updated metrics: ${s} queued, ${o} running`);for(let f of Array.from(this.listeners.values()))f(this.getMetrics())}catch(t){_e.error("Failed to update queue metrics:",t)}}async fetchQueuedJobs(){let t={Accept:"application/vnd.github.v3+json",Authorization:`Bearer ${this.config.token}`,"User-Agent":"Hydra-Runner-Manager"},e=this.config.repo?`${kn}/repos/${this.config.owner}/${this.config.repo}/actions/runs`:`${kn}/orgs/${this.config.owner}/actions/runs`,i=(await this.fetchPaginated(e,t)).filter((s)=>{return Date.now()-new Date(s.created_at).getTime()<uf&&(s.status==="queued"||s.status==="in_progress")}),r=[];for(let s of i){let o=`${kn}/repos/${this.config.owner}/${this.config.repo||s.repository?.name}/actions/runs/${s.id}/jobs`,a=await this.fetchPaginated(o,t),f=this.config.labels?a.filter((u)=>u.labels.some((p)=>this.config.labels?.includes(p))):a;r.push(...f)}return r}async fetchPaginated(t,e){let n=[],i=t;while(i){let r=await fetch(i,{headers:e});if(!r.ok)throw new Error(`GitHub API error: ${r.status} ${r.statusText}`);let s=await r.json();n.push(...s.workflow_runs||s.jobs||[]);let o=r.headers.get("link");i=this.getNextPageUrl(o)}return n}getNextPageUrl(t){if(!t)return null;let n=t.split(",").map((r)=>r.trim()).find((r)=>r.includes('rel="next"'));if(!n)return null;return n.match(/<([^>]+)>/)?.[1]||null}}async function ir(t,e){let i=new URL(t.url||"").pathname.split("/").filter(Boolean),r={labels:t.labels?.split(",").map((s)=>s.trim()),owner:i[0]||"",repo:i[1]||"",token:e};return new nr(r)}G();var or=$({prefix:"scaling-engine"}),cf=2,pf=60000,rr=300000,hf=120000,sr=5;class ar{config;lastScaleAction=null;currentRunnerCount=0;runnerStatuses=new Map;constructor(t,e){this.config=t;this.currentRunnerCount=t.minRunners}analyzeMetrics(t){if(this.isInCoolDown())return{action:"no-change",delta:0,reason:"Cooling down after recent scaling action",targetCount:this.currentRunnerCount};let e=this.config.scaleUpThreshold||cf,n=this.calculateUtilization();if(t.queuedJobs>e||t.averageWaitTime>pf)return this.recommendScaleUp(t);if(n<(this.config.targetUtilization||0.3)&&this.currentRunnerCount>this.config.minRunners)return this.recommendScaleDown();return{action:"no-change",delta:0,reason:"Metrics within acceptable range",targetCount:this.currentRunnerCount}}updateRunnerStatus(t,e){let n=this.runnerStatuses.get(t)||{id:t,labels:[],lastActivity:new Date,name:e.name||t,status:"idle"};this.runnerStatuses.set(t,{...n,...e,lastActivity:e.lastActivity||new Date})}removeRunner(t){this.runnerStatuses.delete(t),this.currentRunnerCount=Math.max(0,this.currentRunnerCount-1)}applyScalingDecision(t){if(t.action==="no-change")return;this.currentRunnerCount=t.targetCount,this.lastScaleAction=new Date,or.info(`Applied scaling decision: ${t.action} by ${t.delta} runners`),or.info(`New runner count: ${this.currentRunnerCount}`)}getIdleRunners(){let t=Date.now()-rr;return Array.from(this.runnerStatuses.values()).filter((e)=>e.status==="idle"&&e.lastActivity.getTime()<t)}recommendScaleUp(t){let e=Math.ceil(t.queuedJobs/2),n=Math.min(e-this.currentRunnerCount,sr);if(n=Math.min(n,this.config.maxRunners-this.currentRunnerCount),n<=0)return{action:"no-change",delta:0,reason:"Already at maximum runner capacity",targetCount:this.currentRunnerCount};return{action:"scale-up",delta:n,reason:`Queue depth: ${t.queuedJobs}, Wait time: ${Math.round(t.averageWaitTime/1000)}s`,targetCount:this.currentRunnerCount+n}}recommendScaleDown(){let t=this.getIdleRunners();if(t.length===0)return{action:"no-change",delta:0,reason:"No idle runners to remove",targetCount:this.currentRunnerCount};let e=Math.min(t.length,this.currentRunnerCount-this.config.minRunners,sr);if(e<=0)return{action:"no-change",delta:0,reason:"Already at minimum runner capacity",targetCount:this.currentRunnerCount};return{action:"scale-down",delta:e,reason:`${t.length} runners idle for over ${rr/60000} minutes`,targetCount:this.currentRunnerCount-e}}calculateUtilization(){if(this.runnerStatuses.size===0)return 0;return Array.from(this.runnerStatuses.values()).filter((e)=>e.status==="busy").length/this.runnerStatuses.size}isInCoolDown(){if(!this.lastScaleAction)return!1;let t=this.config.coolDownPeriod??hf;if(t===0)return!1;return Date.now()-this.lastScaleAction.getTime()<t}}function lr(t,e){let n={maxRunners:10,minRunners:1,...e};return new ar(n,t)}G();import{createHmac as df}from"crypto";var Ct=$({prefix:"webhook-receiver"}),gf=I({host:X(),path:X(),port:yt(),secret:X()});class fr{config;server=null;eventHandlers=new Map;constructor(t){this.config=t;try{this.config={host:t.host||"0.0.0.0",path:t.path||"/webhook",port:t.port||8080,secret:t.secret},gf(this.config)}catch(e){throw new Error(`Invalid webhook config: ${e}`)}}on(t,e){return this.eventHandlers.set(t,e),this}async start(){if(this.server)throw new Error("Webhook server already running");this.server=Bun.serve({fetch:async(t)=>{if(new URL(t.url).pathname!==this.config.path)return new Response("Not found",{status:404});if(t.method!=="POST")return new Response("Method not allowed",{status:405});try{let n=await t.text(),i=t.headers.get("x-hub-signature-256"),r=t.headers.get("x-github-event"),s=t.headers.get("x-github-delivery");if(!i||!r||!s)return Ct.warn("Missing required GitHub headers"),new Response("Bad request",{status:400});if(!this.verifySignature(n,i))return Ct.error("Invalid webhook signature"),new Response("Unauthorized",{status:401});let o={deliveryId:s,payload:JSON.parse(n),type:r};Ct.info(`Received ${r} webhook event (${s})`);let a=this.eventHandlers.get(r)||this.eventHandlers.get("*");if(a)await a(o);else Ct.debug(`No handler registered for ${r} event`);return new Response(JSON.stringify({status:"ok"}),{headers:{"Content-Type":"application/json"},status:200})}catch(n){return Ct.error("Error processing webhook:",n),new Response("Internal server error",{status:500})}},hostname:this.config.host,port:this.config.port}),Ct.info(`Webhook server listening on ${this.getUrl()}`)}async stop(){if(this.server)this.server.stop(),this.server=null,Ct.info("Webhook server stopped")}getUrl(){return`http://${this.config.host==="0.0.0.0"?"localhost":this.config.host}:${this.config.port}${this.config.path}`}verifySignature(t,e){let n=df("sha256",this.config.secret);n.update(t);let i=`sha256=${n.digest("hex")}`,r=Buffer.from(i),s=Buffer.from(e);if(r.length!==s.length)return!1;return r.equals(s)}}async function ur(t){return new fr(t)}var st=$({prefix:"webhook"});async function cr(){let t=await yf(),e=T();try{e.start("Starting webhook server...");let n=await ur({host:t.host,path:t.path,port:t.port,secret:t.secret});n.on("workflow_job",async(s)=>{let o=s.payload;if(o.action==="queued"){if(st.info(`New job queued: ${o.workflow_job.name}`),st.info(`Labels: ${o.workflow_job.labels.join(", ")}`),t.autoScale)st.info("Auto-scaling triggered - would scale up runners")}else if(o.action==="completed"){if(st.info(`Job completed: ${o.workflow_job.name}`),t.autoScale)st.info("Job completed - checking if scale down needed")}}),n.on("ping",async(s)=>{st.info("Received ping event from GitHub")}),await n.start(),e.stop("Webhook server started");let i=null,r=null;if(t.autoScale&&t.profile){let s=t.token||process.env.GITHUB_PERSONAL_ACCESS_TOKEN;if(s)i=await ir(t.profile,s),r=lr(t.profile,{maxRunners:t.maxRunners,minRunners:t.minRunners}),await i.start(),i.onMetricsUpdate((o)=>{if(st.info(`Queue metrics: ${o.queuedJobs} queued, ${o.runningJobs} running`),r){let a=r.analyzeMetrics(o);if(a.action!=="no-change"){if(st.info(`Scaling recommendation: ${a.action} by ${a.delta} runners - ${a.reason}`),!t.dryRun)st.info("Auto-scaling execution would happen here"),r.applyScalingDecision(a)}}}),n.on("workflow_job",async(o)=>{let a=o.payload;if(a.workflow_job.runner_id&&r)r.updateRunnerStatus(String(a.workflow_job.runner_id),{id:String(a.workflow_job.runner_id),labels:a.workflow_job.labels,name:a.workflow_job.runner_name||"",status:a.action==="in_progress"?"busy":"idle"})});else st.warn("Auto-scaling enabled but no GitHub token provided")}at(`\uD83C\uDFAF Webhook server listening at ${n.getUrl()}`),at("Configure this URL in your GitHub repository or organization webhook settings"),process.on("SIGINT",async()=>{if(st.info("Shutting down webhook server..."),i)i.stop();await n.stop(),process.exit(0)}),await new Promise(()=>{})}catch(n){throw e.stop("Failed to start webhook server"),new nt("Failed to start webhook server","WEBHOOK_START_FAILED",String(n))}}async function yf(){let{values:t}=mf({allowPositionals:!0,args:Bun.argv,options:{autoScale:{default:!1,type:"boolean"},dryRun:{default:!1,type:"boolean"},host:{default:"0.0.0.0",type:"string"},maxRunners:{default:"10",type:"string"},minRunners:{default:"1",type:"string"},path:{default:"/webhook",type:"string"},port:{default:"8080",short:"p",type:"string"},profile:{short:"P",type:"string"},secret:{short:"s",type:"string"},token:{short:"t",type:"string"}},strict:!0}),e=await N({profile:t.profile}),n=await S(e,t.profile),i=t.secret||process.env.GITHUB_WEBHOOK_SECRET;if(!i)throw new Error("Webhook secret is required. Use --secret or set GITHUB_WEBHOOK_SECRET env var");return{autoScale:t.autoScale,dryRun:t.dryRun,host:t.host,maxRunners:Number.parseInt(t.maxRunners,10),minRunners:Number.parseInt(t.minRunners,10),path:t.path,port:Number.parseInt(t.port,10),profile:n,secret:i,token:t.token}}L.register(dn);L.register(xn);L.register($n);Te(()=>{po(),ho()});var ee=["create","run","remove","logs","health","scale","backup","plugin","pool","watch","validate","dev","monitor","migrate","template","recovery","webhook"],bf=[...L.getNames(),...ee],te=$({prefix:"hydra"}),wf={auto:"scale",autoscale:"scale",b:"backup",back:"backup",bak:"backup",c:"create",ceate:"create",check:"health",craete:"create",cretae:"create",del:"remove",delete:"remove",diagnose:"health",h:"help",heal:"health",healthy:"health",i:"init",info:"status",initialise:"init",inti:"init",intialize:"init",l:"logs",list:"status",log:"logs",ls:"status",m:"monitor",mig:"migrate",mon:"monitor",new:"create",r:"run",rec:"recovery",recover:"recovery",remvoe:"remove",resize:"scale",restore:"backup",rm:"remove",rmove:"remove",rnu:"run",runn:"run",s:"status",save:"backup",scal:"scale",start:"run",stat:"status",stop:"remove",sttaus:"status",t:"troubleshoot",tail:"logs",temp:"template",templ:"template"};async function xf(){let t=new Sn,e="",n,i;try{let s=await wo(new Map([["logger",te],["registry",L]])),o=_n();if(Te(()=>{o.emit("hydra:startup",{version:St})}),{command:n,needsHelp:i}=vo(process.argv),t.mark("commandParseTime"),n==="version")console.log(St),t.logMetrics(),process.exit(0);if($o()){let{checkAndNotify:u}=await Promise.resolve().then(() => (O(),ki));Te(()=>u("@r5n/hydra",St),100)}if(i&&!n){let u=L.get("help");if(u)await u.execute();process.exit(0)}e=n||"";let a=s.getCommand(n||"");if(!a&&n?.includes(":"))a=s.getAllCommands().find((p)=>p.name===n);if(!a&&n&&!L.has(n)&&!ee.includes(n)){let u=sn(n,wf);if(u&&(L.has(u)||ee.includes(u)))e=u,te.warn(`Assuming you meant '${u}'`)}if(!a&&!L.has(e)&&!ee.includes(e)){te.error(`Unknown command: ${n}`);let u=[...bf,...s.getAllCommands().map((g)=>g.name)],p=n?rn(n,u):[];if(p.length>0){te.error("Did you mean one of these?");for(let g of p)te.error(` ${g}`)}let d=L.get("help");if(d)await d.execute();process.exit(1)}if(i&&n){let u=L.get("help");if(u){let p=process.argv;process.argv=[process.argv[0]||"node",process.argv[1]||"hydra","help",e||""],await u.execute(),process.argv=p}process.exit(0)}t.mark("registrationTime");let f=L.get(e);if(!f&&!ee.includes(e))f=await On(e)||void 0;if(t.mark("executionStartTime"),o.emit("hydra:beforeCommand",{command:e||n}),a)await a.execute(process.argv.slice(3));else if(f)await f.execute();else switch(e){case"create":await zt();break;case"run":await En();break;case"remove":await Yt();break;case"logs":await _o();break;case"health":await Oo();break;case"scale":await Xo();break;case"backup":await Ro();break;case"plugin":await Uo();break;case"pool":await Go();break;case"watch":await er();break;case"validate":await tr();break;case"dev":await Eo();break;case"monitor":await Wo();break;case"migrate":await Mo();break;case"template":await zo();break;case"recovery":await jo();break;case"webhook":await cr();break;default:throw new Error(`Unknown command: ${e}`)}o.emit("hydra:afterCommand",{command:e||n}),t.logMetrics(),await Nn(),process.exit(0)}catch(r){t.logMetrics(),await Nn(),mo(r,{command:e||n||""})}}await xf();
|