@stacksjs/ts-cloud 0.16.42 → 0.16.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aws/bedrock.d.ts +73 -0
- package/dist/aws/index.js +1 -1
- package/dist/bin/{chunk-rsnmb1cd.js → chunk-2r9tj1ac.js} +2 -2
- package/dist/bin/{chunk-04s4mqs2.js → chunk-g3a9a8bx.js} +1 -1
- package/dist/bin/chunk-gngsb689.js +2 -0
- package/dist/bin/{chunk-kg3nbcfs.js → chunk-yxpzm8ce.js} +1 -1
- package/dist/bin/cli.js +5 -5
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-hc140wnm.js → chunk-1w9v8g26.js} +1 -1
- package/dist/{chunk-vps4v353.js → chunk-8jsf214f.js} +6 -6
- package/dist/{chunk-qztdtcc8.js → chunk-96vc5w8w.js} +3 -3
- package/dist/{chunk-nqb7yefs.js → chunk-a102vqez.js} +16 -16
- package/dist/{chunk-bj4kvqwz.js → chunk-c5jyzyqw.js} +13 -13
- package/dist/{chunk-qbbap3bt.js → chunk-d02jxsxv.js} +1 -1
- package/dist/{chunk-2vrv31sk.js → chunk-e4pxs9g6.js} +3 -3
- package/dist/{chunk-vd2jqt9w.js → chunk-g8zgpxgz.js} +1 -1
- package/dist/chunk-gp9tkznp.js +2 -0
- package/dist/{chunk-xejwnb6f.js → chunk-hm6pwhne.js} +2 -2
- package/dist/{chunk-j1adw51p.js → chunk-j5x0qn7z.js} +5 -5
- package/dist/chunk-mqwdq7w1.js +1 -0
- package/dist/chunk-qjghqymj.js +1 -0
- package/dist/{chunk-cv5e8c74.js → chunk-txwnpxzf.js} +51 -51
- package/dist/{chunk-e3evn28t.js → chunk-v3w791ze.js} +15 -15
- package/dist/{chunk-13pfck91.js → chunk-vkrgf3sv.js} +1 -1
- package/dist/{chunk-my61jkg1.js → chunk-x2pxtfk0.js} +2 -2
- package/dist/deploy/index.js +1 -1
- package/dist/dns/cloudflare.d.ts +26 -0
- package/dist/dns/delegate-from-config.d.ts +1 -0
- package/dist/dns/index.js +1 -1
- package/dist/dns/tiered-cache.test.d.ts +1 -0
- package/dist/drivers/index.js +1 -1
- package/dist/index.js +4 -4
- package/dist/operations/index.js +1 -1
- package/dist/protection/index.js +1 -1
- package/dist/spend/index.js +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +1 -1
- package/dist/ui/account/automation.html +6 -6
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +6 -6
- package/dist/ui/data/services.html +6 -6
- package/dist/ui/data/volumes.html +6 -6
- package/dist/ui/index.html +6 -6
- package/dist/ui/infrastructure/topology.html +5 -5
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +6 -6
- package/dist/ui/operations/configuration.html +6 -6
- package/dist/ui/operations/jobs.html +5 -5
- package/dist/ui/operations/maintenance.html +5 -5
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +5 -5
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +2 -2
- package/dist/ui/server/actions.html +6 -6
- package/dist/ui/server/activity.html +1 -1
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +6 -6
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +6 -6
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +1 -1
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +2 -2
- package/dist/ui/serverless/alarms.html +6 -6
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +6 -6
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +6 -6
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +6 -6
- package/package.json +3 -3
- package/dist/bin/chunk-nk7fqc8z.js +0 -2
- package/dist/chunk-epbe0p3n.js +0 -1
- package/dist/chunk-pahyn8p3.js +0 -1
- package/dist/chunk-zy0crzsb.js +0 -2
package/dist/bin/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import{C,jt,n,r,a,Rr,e,d,i,s,R,u,Do,c,dn,Ce,Ms,Us,Bs,Fs,f}from"./chunk-5amvqed8.js";import{sa,H,$r,w,F,Fo,l,o,T,la,da,ua,xe,Fe,tt,Vo,bn,xi,Sn,zo,fa,ha,ya,ba,va,j,b,L,rt,k,fe,qo,Ve,qt,_i,Ae,Go,Oi,Gt,At,Ca,Ta}from"./chunk-tf8qxy9k.js";import"./chunk-4yym8xm4.js";import{Oe,x,Pn,y,Dn,Hi,kn,es,Fr,it,ke,Nn,xn,_n,On,$n,Ln,Mn,Un,ie,Zt,er,Bn,jr,jn,Vn,zn,Hn,qn,Gn,Wn,Kn,ot,tr,rr,Dt,Vr,nr,ir,qi,kt,Jn,ce,Xn,Qn,Yn,zr,Hr,Zn,qr,or,sr,st,Nt,xt,Gr,le,ei,ac,cc,ar,lc,q,Gi,ze,at,ct,ti,Wr,Kr,ri,ni,ii,Jr,ts,de,be,$e,Se,oi,cr}from"./chunk-erf79tm2.js";import{p,ta}from"./chunk-dkf2kcsc.js";import{ae,h,Or}from"./chunk-pnj95hwr.js";import{Dr,Tt,kr,Nr,xr,_r,gn}from"./chunk-8z4wgqkh.js";import{S,Ot,pi,fs,hr,yc,bc,Sc,mi,gi,mt,nn,$t,on,gt,Je,Me,Xe,ft,yr,Ue,Qe,fi,hi,Ye,sn,an,so,co,vr,Lt,ht,Mt,ee,mo,Si,vi,Is}from"./chunk-vjfwnj9z.js";import{Ze,Ut,Tr,ks,Ns,Er,ge,Ci,wr,yo,bo,So,vo,Co,To,W,Bt,M,Ti}from"./chunk-
|
|
2
|
+
import{C,jt,n,r,a,Rr,e,d,i,s,R,u,Do,c,dn,Ce,Ms,Us,Bs,Fs,f}from"./chunk-5amvqed8.js";import{sa,H,$r,w,F,Fo,l,o,T,la,da,ua,xe,Fe,tt,Vo,bn,xi,Sn,zo,fa,ha,ya,ba,va,j,b,L,rt,k,fe,qo,Ve,qt,_i,Ae,Go,Oi,Gt,At,Ca,Ta}from"./chunk-tf8qxy9k.js";import"./chunk-4yym8xm4.js";import{Oe,x,Pn,y,Dn,Hi,kn,es,Fr,it,ke,Nn,xn,_n,On,$n,Ln,Mn,Un,ie,Zt,er,Bn,jr,jn,Vn,zn,Hn,qn,Gn,Wn,Kn,ot,tr,rr,Dt,Vr,nr,ir,qi,kt,Jn,ce,Xn,Qn,Yn,zr,Hr,Zn,qr,or,sr,st,Nt,xt,Gr,le,ei,ac,cc,ar,lc,q,Gi,ze,at,ct,ti,Wr,Kr,ri,ni,ii,Jr,ts,de,be,$e,Se,oi,cr}from"./chunk-erf79tm2.js";import{p,ta}from"./chunk-dkf2kcsc.js";import{ae,h,Or}from"./chunk-pnj95hwr.js";import{Dr,Tt,kr,Nr,xr,_r,gn}from"./chunk-8z4wgqkh.js";import{S,Ot,pi,fs,hr,yc,bc,Sc,mi,gi,mt,nn,$t,on,gt,Je,Me,Xe,ft,yr,Ue,Qe,fi,hi,Ye,sn,an,so,co,vr,Lt,ht,Mt,ee,mo,Si,vi,Is}from"./chunk-vjfwnj9z.js";import{Ze,Ut,Tr,ks,Ns,Er,ge,Ci,wr,yo,bo,So,vo,Co,To,W,Bt,M,Ti}from"./chunk-gngsb689.js";import{J,P,ko,Hs,qs,Vc,zc,Ai,vt,Ri}from"./chunk-cqc4e8md.js";import{v}from"./chunk-7593hjcq.js";import{Q}from"./chunk-pf9dbm3b.js";import{Ct,g}from"./chunk-nmqjmx30.js";import{qe,rs,ue,Wi,ai,Ki,Ji,Xr,Xi,Qi,ve,Z,Ge,Ne,Qr,lr,We,dr,Yr,dt,pe,ut,pr,mr,gr,Zr,fr,O,Zi,eo,ci,ns,en,is,os,pc,to,ss,as,cs,ls,pt,ds,ro,no}from"./chunk-t80pxn04.js";import"./chunk-xxe9ga9r.js";import{I}from"./chunk-7p2va3nj.js";import{me}from"./chunk-kzpzkdpd.js";import{K,bt,Io}from"./chunk-qj6tr7bw.js";import{oe,G,dc,uc,He}from"./chunk-3v2pd05g.js";import{Qt,Rn,Yt,Vi,In,Zo}from"./chunk-zvbc92pc.js";import"./chunk-jaexpxs8.js";import{E}from"./chunk-gn03w47w.js";import{lt}from"./chunk-35x7z78g.js";import{te,Te}from"./chunk-kdsgbvep.js";import{V}from"./chunk-9eqpnanr.js";import"./chunk-nj9x0tb8.js";import{zi}from"./chunk-2r9tj1ac.js";import"./chunk-dryvqne2.js";import"./chunk-sg8hcdev.js";import{ui}from"./chunk-n7yefy09.js";import{Cr}from"./chunk-k343q24p.js";import{yt}from"./chunk-fkzp9sg5.js";import{B}from"./chunk-f64jvh96.js";import{N}from"./chunk-kbwm0sqv.js";import{existsSync as Lu}from"node:fs";import Ea from"node:fs/promises";import zl from"node:os";import Na from"node:path";import lo from"node:process";import{EventEmitter as ju}from"node:events";import ji from"node:process";import Ul from"node:process";import ja from"node:process";import js from"node:process";import Jo from"node:process";import Hl from"node:tty";import km,{stdin as Xh,stdout as ey}from"node:process";class Gl{configPath;config=null;events=[];retryCount=0;maxRetries=3;retryDelayMs=1000;constructor(){let D=zl.homedir(),t=Na.join(D,".config","clapp");this.configPath=Na.join(t,"telemetry.json")}async isEnabled(){if(lo.env.DO_NOT_TRACK==="1"||lo.env.DO_NOT_TRACK==="true")return!1;if(lo.env.NO_TELEMETRY==="1"||lo.env.NO_TELEMETRY==="true")return!1;return(await this.loadConfig()).enabled}async enable(){let D=await this.loadConfig();if(D.enabled=!0,!D.userId)D.userId=this.generateUserId();await this.saveConfig(D)}async disable(){let D=await this.loadConfig();D.enabled=!1,await this.saveConfig(D)}async track(D,t){if(!await this.isEnabled())return;let A={event:D,...t,timestamp:Date.now(),platform:zl.platform(),nodeVersion:lo.version};if(this.events.push(A),this.events.length>=10)await this.send()}async trackCommand(D,t){await this.track("command",{command:D,duration:t})}async trackError(D,t){await this.track("error",{error:D,command:t})}async send(){if(!await this.isEnabled()||this.events.length===0)return!0;try{this.events=[],this.retryCount=0;let t=await this.loadConfig();return t.lastSent=Date.now(),await this.saveConfig(t),!0}catch{if(this.retryCount<this.maxRetries){this.retryCount++;let t=this.retryDelayMs*2**(this.retryCount-1);return await this.sleep(t),this.send()}return this.events=[],this.retryCount=0,!1}}async flush(){if(this.events.length===0)return!0;return this.send()}sleep(D){return new Promise((t)=>setTimeout(t,D))}async status(){let D=await this.loadConfig();return{enabled:D.enabled,doNotTrack:lo.env.DO_NOT_TRACK==="1"||lo.env.DO_NOT_TRACK==="true",eventsQueued:this.events.length,lastSent:D.lastSent}}async loadConfig(){if(this.config)return this.config;try{if(Lu(this.configPath)){let D=await Ea.readFile(this.configPath,"utf-8");return this.config=JSON.parse(D),this.config}}catch{}return this.config={enabled:!1},this.config}async saveConfig(D){this.config=D;try{let t=Na.dirname(this.configPath);await Ea.mkdir(t,{recursive:!0}),await Ea.writeFile(this.configPath,JSON.stringify(D,null,2),"utf-8")}catch{}}generateUserId(){let D=Math.random().toString(36).substring(2,15),t=Date.now().toString(36);return`${D}-${t}`}}var _h=new Gl;function La(D){return D.replace(/[<[].+/,"").trim()}function Fu(D){let t=/<([^>]+)>/g,m=/\[([^\]]+)\]/g,A=[],_=(Y)=>{let X=!1,ne=Y[1];if(ne.startsWith("..."))ne=ne.slice(3),X=!0;return{required:Y[0].startsWith("<"),value:ne,variadic:X}},z;while(z=t.exec(D))A.push(_(z));let U;while(U=m.exec(D))A.push(_(U));return A}function Bu(D){let t={alias:{},boolean:[]};for(let[m,A]of D.entries()){if(A.names.length>1)t.alias[A.names[0]]=A.names.slice(1);if(A.isBoolean)if(A.negated){if(!D.some((z,U)=>U!==m&&z.names.some((Y)=>A.names.includes(Y))&&typeof z.required==="boolean"))t.boolean.push(A.names[0])}else t.boolean.push(A.names[0])}return t}function Wl(D){return D.reduce((t,m)=>t.length>=m.length?t:m,"")}function Oa(D,t){return D.length>=t?D:`${D}${" ".repeat(t-D.length)}`}function Ls(D){return D.replace(/([a-z])-([a-z])/g,(t,m,A)=>m+A.toUpperCase())}function Mu(D,t,m){let A=0,_=t.length,z=D,U;for(;A<_;++A)U=z[t[A]],z=z[t[A]]=A===_-1?m:U!=null?U:!!~t[A+1].indexOf(".")||!(+t[A+1]>-1)?{}:[]}function _u(D,t){for(let m of Object.keys(t)){let A=t[m];if(A.shouldTransform){if(D[m]=Array.prototype.concat.call([],D[m]),typeof A.transformFunction==="function")D[m]=D[m].map(A.transformFunction)}}}function zu(D){let t=/([^\\/]+)$/.exec(D);return t?t[1]:""}function Yo(D){return D.split(".").map((t,m)=>m===0?Ls(t):t).join(".")}class Qo extends Error{exitCode=2;isUsageError=!0;usage;constructor(D,t){super(D);if(this.name=this.constructor.name,t!==void 0)this.usage=t;if(typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,this.constructor);else this.stack=Error(D).stack}format(D=!1){if(D&&this.stack)return`${this.message}
|
|
3
3
|
|
|
4
4
|
Stack trace:
|
|
5
5
|
${this.stack}`;return this.message}}function Uu(D){if(D instanceof Qo)return!0;return!!D&&typeof D==="object"&&D.name==="ClappError"&&typeof D.message==="string"}function Wu(){let{env:D}=Ul,{TERM:t,TERM_PROGRAM:m}=D;if(Ul.platform!=="win32")return t!=="linux";return Boolean(D.WT_SESSION)||Boolean(D.TERMINUS_SUBLIME)||D.ConEmuTask==="{cmd::Cmder}"||m==="Terminus-Sublime"||m==="vscode"||t==="xterm-256color"||t==="alacritty"||t==="rxvt-unicode"||t==="rxvt-unicode-256color"||D.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var _s="\x1B",cn=`${_s}[`;var Vl={to(D,t){if(!t)return`${cn}${D+1}G`;return`${cn}${t+1};${D+1}H`},move(D,t){let m="";if(D<0)m+=`${cn}${-D}D`;else if(D>0)m+=`${cn}${D}C`;if(t<0)m+=`${cn}${-t}A`;else if(t>0)m+=`${cn}${t}B`;return m},up:(D=1)=>`${cn}${D}A`,down:(D=1)=>`${cn}${D}B`,forward:(D=1)=>`${cn}${D}C`,backward:(D=1)=>`${cn}${D}D`,nextLine:(D=1)=>`${cn}E`.repeat(D),prevLine:(D=1)=>`${cn}F`.repeat(D),left:`${cn}G`,hide:`${cn}?25l`,show:`${cn}?25h`,save:`${_s}7`,restore:`${_s}8`};var Vh={screen:`${cn}2J`,up:(D=1)=>`${cn}1J`.repeat(D),down:(D=1)=>`${cn}J`.repeat(D),line:`${cn}2K`,lineEnd:`${cn}K`,lineStart:`${cn}1K`,lines(D){let t="";for(let m=0;m<D;m++)t+=this.line+(m<D-1?Vl.up():"");if(D)t+=Vl.left;return t}},qh={screen:`${_s}c`};function Vu(D,t){let m=[];for(let A=0;A<=t.length;A++)m[A]=[A];for(let A=0;A<=D.length;A++)m[0][A]=A;for(let A=1;A<=t.length;A++)for(let _=1;_<=D.length;_++)if(t.charAt(A-1)===D.charAt(_-1))m[A][_]=m[A-1][_-1];else m[A][_]=Math.min(m[A-1][_-1]+1,m[A][_-1]+1,m[A-1][_]+1);return m[t.length][D.length]}function Kl(D,t,m=2,A=3){return t.map((_)=>({cmd:_,distance:Vu(D,_)})).filter(({distance:_})=>_<=m).sort((_,z)=>_.distance-z.distance).slice(0,A).map(({cmd:_})=>_)}function qu(D,t={}){let m={_:[]},A=t.alias||{},_=new Set(t.boolean||[]),z={};for(let X of Object.keys(A))for(let ne of A[X])z[ne]=X;for(let X of _)if(A[X])for(let ne of A[X])_.add(ne);function U(X,ne){if(X===void 0)return ne;if(typeof ne==="boolean")return ne;return Array.isArray(X)?[...X,ne]:[X,ne]}function Y(X,ne){let re=z[X]||X,se=U(m[re],ne);if(m[re]=se,A[re])for(let he of A[re])m[he]=se;if(z[X]&&A[z[X]])for(let he of A[z[X]])m[he]=se;m[X]=se}for(let X=0;X<D.length;X++){let ne=D[X];if(ne==="--"){m._.push(...D.slice(X+1));break}if(ne.startsWith("--")){let re=ne.indexOf("=");if(re!==-1){let se=Ls(ne.slice(2,re)),he=ne.slice(re+1);Y(se,he)}else{let se=ne.slice(2);if(se.startsWith("no-")){let Pe=Ls(se.slice(3));Y(Pe,!1);continue}let he=Ls(se),we=z[he]||he;if(_.has(we)||_.has(he))Y(he,!0);else{let Pe=D[X+1];if(Pe!==void 0&&!Pe.startsWith("-"))Y(he,Pe),X++;else Y(he,!0)}}}else if(ne.startsWith("-")&&ne.length>1){let re=ne.slice(1);for(let se=0;se<re.length;se++){let he=re[se],we=z[he]||he;if(se===re.length-1&&!_.has(we)&&!_.has(he)){let Pe=D[X+1];if(Pe!==void 0&&!Pe.startsWith("-"))Y(he,Pe),X++;else Y(he,!0)}else Y(he,!0)}}else m._.push(ne)}return m}class Jl{rawName;description;name;names;isBoolean;required;config;negated;constructor(D,t,m){if(this.rawName=D,this.description=t,this.config=Object.assign({},m),D=D.replace(/\.\*/g,""),this.negated=!1,this.names=La(D).split(",").map((A)=>{let _=A.trim().replace(/^-{1,2}/,"");if(_.startsWith("no-"))this.negated=!0,_=_.replace(/^no-/,"");return Yo(_)}).sort((A,_)=>A.length>_.length?1:-1),this.name=this.names[this.names.length-1],this.negated&&this.config.default==null)this.config.default=!0;if(D.includes("<"))this.required=!0;else if(D.includes("["))this.required=!1;else this.isBoolean=!0}}var Gh=ja.argv,Hu=`${ja.platform}-${ja.arch} bun-v${typeof Bun<"u"?Bun.version:"unknown"}`,ql=js.argv,Gu=`${js.platform}-${js.arch} node-${js.version}`;class Fa{rawName;description;config;cli;options;aliasNames;name;namespace;args;commandAction;usageText;versionNumber;examples;helpCallback;globalCommand;beforeHooks;afterHooks;middleware;constructor(D,t,m,A){this.rawName=D,this.description=t,this.config=m,this.cli=A,this.options=[],this.aliasNames=[],this.name=La(D);let _=La(D),z=_.indexOf(":");if(z>0)this.namespace=_.substring(0,z),this.name=_.substring(z+1);if(this.args=Fu(D),this.examples=[],this.beforeHooks=[],this.afterHooks=[],this.middleware=[],!m)this.config={}}usage(D){return this.usageText=D,this}allowUnknownOptions(){return this.config.allowUnknownOptions=!0,this}ignoreOptionDefaultValue(){return this.config.ignoreOptionDefaultValue=!0,this}version(D,t="-v, --version"){return this.versionNumber=D,this.option(t,"Display version number"),this}example(D){return this.examples.push(D),this}option(D,t,m){let A=new Jl(D,t,m);return this.options.push(A),this}alias(D){return this.aliasNames.push(D),this}action(D){return this.commandAction=D,this}before(D){return this.beforeHooks.push(D),this}after(D){return this.afterHooks.push(D),this}use(D){return this.middleware.push(D),this}isMatched(D){if(this.aliasNames.includes(D))return!0;if(this.namespace)return`${this.namespace}:${this.name}`===D;return this.name===D}get isDefaultCommand(){return this.name===""||this.aliasNames.includes("!")}get isGlobalCommand(){return this instanceof Ba}get displayName(){return this.namespace?`${this.namespace}:${this.name}`:this.name}hasOption(D){let t=Yo(D.split(".")[0]);return!!this.options.find((m)=>m.names.some((A)=>Yo(A)===t))}outputHelp(){let{name:D,commands:t}=this.cli,{versionNumber:m,options:A,helpCallback:_}=this.cli.globalCommand,z=[{body:`${D}${m?`/${m}`:""}`}];if(z.push({title:"Usage",body:` $ ${D} ${this.usageText||this.rawName}`}),(this.isGlobalCommand||this.isDefaultCommand)&&t.length>0){let ne=Wl(t.map((Pe)=>Pe.rawName)),re=new Map,se=[];for(let Pe of t)if(Pe.namespace){if(!re.has(Pe.namespace))re.set(Pe.namespace,[]);re.get(Pe.namespace).push(Pe)}else se.push(Pe);let he="";if(se.sort((Pe,ye)=>Pe.rawName<ye.rawName?-1:Pe.rawName>ye.rawName?1:0),se.length>0)he+=se.map((Pe)=>` ${Oa(Pe.rawName,ne.length)} ${Pe.description}`).join(`
|
|
@@ -28,7 +28,7 @@ Received ${m}, cleaning up...`),D)try{await D()}catch(A){console.error("Error du
|
|
|
28
28
|
`)),this.enableDidYouMean){let t=[];for(let A of this.commands){if(A.displayName)t.push(A.displayName);if(A.aliasNames)t.push(...A.aliasNames)}let m=Kl(D,t);if(m.length>0)console.log(Ko.yellow("Did you mean one of these?")),m.forEach((A)=>console.log(` ${Ko.dim("•")} ${this.name} ${A}`)),console.log("")}console.log(Ko.dim("Run"),`${this.name} --help`,Ko.dim("to see all available commands")),ji.exit(1)}async parse(D=ql,t={}){let{run:m=!0,exitOnError:A=!1}=t;if(A)try{return await this.parse(D,{run:m})}catch(X){throw this.handleUsageError(X),X}if(this.rawArgs=D,!this.name)this.name=D[1]?zu(D[1]):"cli";let _=!0,z=D.slice(2),U=z[0];if(U&&!U.startsWith("-")){for(let X of this.commands)if(X.isMatched(U)){let ne=this.mri(z,X);_=!1;let re={...ne,args:ne.args.slice(1)};this.setParsedInfo(re,X,U),this.emit(`command:${U}`,X);break}if(_){let X=z[1];if(X&&!X.startsWith("-")){let ne=`${U}:${X}`;for(let re of this.commands)if(re.isMatched(ne)){let se=this.mri(z,re);_=!1;let he={...se,args:se.args.slice(2)};this.setParsedInfo(he,re,ne),this.emit(`command:${ne}`,re);break}}}}if(_){for(let X of this.commands)if(X.name===""){_=!1;let ne=this.mri(z,X);this.setParsedInfo(ne,X),this.emit("command:!",X);break}}if(_){let X=this.mri(D.slice(2));this.setParsedInfo(X)}if(this.options.verbose)this.isVerbose=!0;if(this.options.quiet)this.isQuiet=!0;if(this.options.debug)this.isDebug=!0;if(this.options.noInteraction||this.options.interaction===!1)this.isNoInteraction=!0;if(this.options.env)this.environment=String(this.options.env);if(this.options.dryRun)this.isDryRun=!0;if(this.options.force)this.isForce=!0;if(this.options.noEmoji||this.options.emoji===!1)this.useEmoji=!1;if(this.options.theme)this.theme=String(this.options.theme);if(this.options.noCache||this.options.cache===!1)this.isNoCache=!0;if(this.options.help&&this.showHelpOnExit)this.outputHelp(),m=!1,this.unsetMatchedCommand();if(this.options.version&&this.showVersionOnExit&&this.matchedCommandName==null)this.outputVersion(),m=!1,this.unsetMatchedCommand();let Y={args:this.args,options:this.options};if(m)await this.runMatchedCommand();if(!this.matchedCommand&&this.args[0]){if(this.emit("command:*"),!(this.listenerCount("command:*")>0))this.showCommandNotFound(this.args[0])}return Y}mri(D,t){let m=[...this.globalCommand.options,...t?t.options:[]],A=Bu(m),_=[],z=D.indexOf("--");if(z>-1)_=D.slice(z+1),D=D.slice(0,z);let U=qu(D,A),Y={_:U._};for(let he of Object.keys(U))if(he!=="_")Y[Yo(he)]=U[he];let X=Y._,ne={"--":_},re=t&&t.config.ignoreOptionDefaultValue?t.config.ignoreOptionDefaultValue:this.globalCommand.config.ignoreOptionDefaultValue,se=Object.create(null);for(let he of m){if(!re&&he.config.default!==void 0)for(let we of he.names)ne[we]=he.config.default;if(Array.isArray(he.config.type)){if(se[he.name]===void 0)se[he.name]={shouldTransform:!0,transformFunction:he.config.type[0]}}}for(let he of Object.keys(Y))if(he!=="_"){let we=he.split(".");Mu(ne,we,Y[he]),_u(ne,se)}return{args:X,options:ne}}async run(D=ql){return this.parse(D,{run:!0,exitOnError:!0})}handleUsageError(D){if(!Uu(D)||D.isUsageError===!1)return;let t=D.message||"command-line error",m=this.name?`${this.name}: `:"",A=/--help/.test(t)?"":D.usage?`
|
|
29
29
|
Usage: ${D.usage}`:`
|
|
30
30
|
Run \`${this.name??"cli"} --help\` for usage.`;ji.stderr.write(`${m}${t}${A}
|
|
31
|
-
`),ji.exit(D.exitCode??2)}async runMatchedCommand(){let{args:D,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let A=[];m.args.forEach((Y,X)=>{if(Y.variadic)A.push(D.slice(X));else A.push(D[X])}),A.push(t);let _={command:m,args:A,options:t};for(let Y of m.beforeHooks)await Y(_);let z,U=async()=>{let Y=m.commandAction.apply(this,A);if(Y instanceof Promise)z=await Y;else z=Y;return z};if(m.middleware.length>0){let Y=0,X=async()=>{if(Y<m.middleware.length){let ne=m.middleware[Y++];await ne({..._,next:X})}else await U()};await X()}else await U();for(let Y of m.afterHooks)await Y(_);return z}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ji.removeAllListeners("SIGINT"),ji.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Yl{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(D){if(!this.enabled){this.misses++;return}let t=this.cache.get(D);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(D),this.misses++;return}return this.hits++,t.value}set(D,t,m=5000){if(!this.enabled)return;this.cache.set(D,{value:t,timestamp:Date.now(),ttl:m})}has(D){if(!this.enabled)return!1;let t=this.cache.get(D);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(D),!1;return!0}delete(D){this.cache.delete(D)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let D=Date.now();for(let[t,m]of this.cache.entries())if(D-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Jh=new Yl;function Zu(){if("FORCE_COLOR"in Jo.env)return Jo.env.FORCE_COLOR!=="0";if("NO_COLOR"in Jo.env||Jo.env.TERM==="dumb")return!1;if(Jo.platform==="win32")return!0;return Hl.isatty(1)&&Hl.isatty(2)}var Zl=Zu();function rn(D,t){if(!Zl)return(m)=>m;return(m)=>D+m+t}var Qu=rn("\x1B[0m","\x1B[0m"),Xu=rn("\x1B[31m","\x1B[39m"),em=rn("\x1B[32m","\x1B[39m"),tm=rn("\x1B[33m","\x1B[39m"),nm=rn("\x1B[34m","\x1B[39m"),rm=rn("\x1B[35m","\x1B[39m"),im=rn("\x1B[36m","\x1B[39m"),om=rn("\x1B[37m","\x1B[39m"),sm=rn("\x1B[90m","\x1B[39m"),am=rn("\x1B[1m","\x1B[22m"),cm=rn("\x1B[3m","\x1B[23m"),lm=rn("\x1B[4m","\x1B[24m"),dm=rn("\x1B[2m","\x1B[22m"),um=rn("\x1B[7m","\x1B[27m"),mm=rn("\x1B[8m","\x1B[28m"),pm=rn("\x1B[9m","\x1B[29m"),fm=rn("\x1B[41m","\x1B[49m"),gm=rn("\x1B[42m","\x1B[49m"),hm=rn("\x1B[43m","\x1B[49m"),ym=rn("\x1B[44m","\x1B[49m"),vm=rn("\x1B[45m","\x1B[49m"),bm=rn("\x1B[46m","\x1B[49m"),wm=rn("\x1B[47m","\x1B[49m"),Sm=Zl,Cm={reset:Qu,red:Xu,green:em,yellow:tm,blue:nm,magenta:rm,cyan:im,white:om,gray:sm,bold:am,italic:cm,underline:lm,dim:dm,inverse:um,hidden:mm,strikethrough:pm,bgRed:fm,bgGreen:gm,bgYellow:hm,bgBlue:ym,bgMagenta:vm,bgCyan:bm,bgWhite:wm,isColorSupported:Sm},$m=Cm,Am=["up","down","left","right","space","enter","cancel"],ty={actions:new Set(Am),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ny=km.platform.startsWith("win"),ry=Symbol("clapp:cancel");var Rm=Wu();var tn=(D,t)=>Rm?D:t,iy=tn("◆","*"),oy=tn("■","x"),sy=tn("▲","x"),ay=tn("◇","o"),cy=tn("┌","T"),Im=tn("│","|"),ly=tn("└","—"),dy=tn("●",">"),uy=tn("○"," "),my=tn("◻","[•]"),py=tn("◼","[+]"),fy=tn("◻","[ ]"),gy=tn("▪","•"),hy=tn("─","-"),yy=tn("╮","+"),vy=tn("├","+"),by=tn("╯","+"),wy=tn("●","•"),Sy=tn("◆","*"),Cy=tn("▲","!"),$y=tn("■","x");var ky={light:tn("─","-"),heavy:tn("━","="),block:tn("█","#")};function Pm(){return`${$m.gray(Im)} `}var Ay=Pm();var _a="0.16.
|
|
31
|
+
`),ji.exit(D.exitCode??2)}async runMatchedCommand(){let{args:D,options:t,matchedCommand:m}=this;if(!m||!m.commandAction)return;m.checkUnknownOptions(),m.checkOptionValue(),m.checkRequiredArgs();let A=[];m.args.forEach((Y,X)=>{if(Y.variadic)A.push(D.slice(X));else A.push(D[X])}),A.push(t);let _={command:m,args:A,options:t};for(let Y of m.beforeHooks)await Y(_);let z,U=async()=>{let Y=m.commandAction.apply(this,A);if(Y instanceof Promise)z=await Y;else z=Y;return z};if(m.middleware.length>0){let Y=0,X=async()=>{if(Y<m.middleware.length){let ne=m.middleware[Y++];await ne({..._,next:X})}else await U()};await X()}else await U();for(let Y of m.afterHooks)await Y(_);return z}removeSignalHandlers(){if(!this.signalHandlersSet)return this;return ji.removeAllListeners("SIGINT"),ji.removeAllListeners("SIGTERM"),this.signalHandlersSet=!1,this}destroy(){this.removeSignalHandlers(),this.commands=[],this.rawArgs=[],this.args=[],this.options={},this.matchedCommand=void 0,this.matchedCommandName=void 0,this.removeAllListeners()}}class Yl{cache;enabled;cleanupInterval=null;hits=0;misses=0;constructor(){this.cache=new Map,this.enabled=!0,this.startCleanupInterval()}startCleanupInterval(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanup()},30000),this.cleanupInterval.unref()}stopCleanup(){if(this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}isEnabled(){return this.enabled}get(D){if(!this.enabled){this.misses++;return}let t=this.cache.get(D);if(!t){this.misses++;return}if(Date.now()-t.timestamp>t.ttl){this.cache.delete(D),this.misses++;return}return this.hits++,t.value}set(D,t,m=5000){if(!this.enabled)return;this.cache.set(D,{value:t,timestamp:Date.now(),ttl:m})}has(D){if(!this.enabled)return!1;let t=this.cache.get(D);if(!t)return!1;if(Date.now()-t.timestamp>t.ttl)return this.cache.delete(D),!1;return!0}delete(D){this.cache.delete(D)}clear(){this.cache.clear()}disable(){this.enabled=!1,this.clear()}enable(){this.enabled=!0}stats(){return{size:this.cache.size,enabled:this.enabled,hits:this.hits,misses:this.misses}}resetStats(){this.hits=0,this.misses=0}keys(){return Array.from(this.cache.keys())}cleanup(){let D=Date.now();for(let[t,m]of this.cache.entries())if(D-m.timestamp>m.ttl)this.cache.delete(t)}destroy(){this.stopCleanup(),this.clear(),this.resetStats()}}var Jh=new Yl;function Zu(){if("FORCE_COLOR"in Jo.env)return Jo.env.FORCE_COLOR!=="0";if("NO_COLOR"in Jo.env||Jo.env.TERM==="dumb")return!1;if(Jo.platform==="win32")return!0;return Hl.isatty(1)&&Hl.isatty(2)}var Zl=Zu();function rn(D,t){if(!Zl)return(m)=>m;return(m)=>D+m+t}var Qu=rn("\x1B[0m","\x1B[0m"),Xu=rn("\x1B[31m","\x1B[39m"),em=rn("\x1B[32m","\x1B[39m"),tm=rn("\x1B[33m","\x1B[39m"),nm=rn("\x1B[34m","\x1B[39m"),rm=rn("\x1B[35m","\x1B[39m"),im=rn("\x1B[36m","\x1B[39m"),om=rn("\x1B[37m","\x1B[39m"),sm=rn("\x1B[90m","\x1B[39m"),am=rn("\x1B[1m","\x1B[22m"),cm=rn("\x1B[3m","\x1B[23m"),lm=rn("\x1B[4m","\x1B[24m"),dm=rn("\x1B[2m","\x1B[22m"),um=rn("\x1B[7m","\x1B[27m"),mm=rn("\x1B[8m","\x1B[28m"),pm=rn("\x1B[9m","\x1B[29m"),fm=rn("\x1B[41m","\x1B[49m"),gm=rn("\x1B[42m","\x1B[49m"),hm=rn("\x1B[43m","\x1B[49m"),ym=rn("\x1B[44m","\x1B[49m"),vm=rn("\x1B[45m","\x1B[49m"),bm=rn("\x1B[46m","\x1B[49m"),wm=rn("\x1B[47m","\x1B[49m"),Sm=Zl,Cm={reset:Qu,red:Xu,green:em,yellow:tm,blue:nm,magenta:rm,cyan:im,white:om,gray:sm,bold:am,italic:cm,underline:lm,dim:dm,inverse:um,hidden:mm,strikethrough:pm,bgRed:fm,bgGreen:gm,bgYellow:hm,bgBlue:ym,bgMagenta:vm,bgCyan:bm,bgWhite:wm,isColorSupported:Sm},$m=Cm,Am=["up","down","left","right","space","enter","cancel"],ty={actions:new Set(Am),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"}};var ny=km.platform.startsWith("win"),ry=Symbol("clapp:cancel");var Rm=Wu();var tn=(D,t)=>Rm?D:t,iy=tn("◆","*"),oy=tn("■","x"),sy=tn("▲","x"),ay=tn("◇","o"),cy=tn("┌","T"),Im=tn("│","|"),ly=tn("└","—"),dy=tn("●",">"),uy=tn("○"," "),my=tn("◻","[•]"),py=tn("◼","[+]"),fy=tn("◻","[ ]"),gy=tn("▪","•"),hy=tn("─","-"),yy=tn("╮","+"),vy=tn("├","+"),by=tn("╯","+"),wy=tn("●","•"),Sy=tn("◆","*"),Cy=tn("▲","!"),$y=tn("■","x");var ky={light:tn("─","-"),heavy:tn("━","="),block:tn("█","#")};function Pm(){return`${$m.gray(Im)} `}var Ay=Pm();var _a="0.16.44";function Ql(D,t,m=process.env){let A=t?.options.find((U)=>U.name==="profile");if((!A||/\baws\b/i.test(A.description))&&typeof D.profile==="string"&&D.profile)m.AWS_PROFILE=D.profile,delete m.AWS_ACCESS_KEY_ID,delete m.AWS_SECRET_ACCESS_KEY,delete m.AWS_SESSION_TOKEN;if(!t?.options.some((U)=>U.name==="region")&&typeof D.region==="string"&&D.region)m.AWS_REGION=D.region,m.AWS_DEFAULT_REGION=D.region}import{existsSync as za}from"node:fs";import{mkdir as xm,writeFile as Xl}from"node:fs/promises";function Ua(D){D.command("init","Initialize a new ts-cloud project").option("--mode <mode>","Deployment mode: server or serverless").option("--name <name>","Project name").option("--region <region>","AWS Region").action(async(t)=>{if(i("Initializing ts-cloud Project"),za("cloud.config.ts")){if(!await u("cloud.config.ts already exists. Overwrite?",!1)){e("Initialization cancelled");return}}let m=t?.name||await R("Project name","my-app"),A=t?.mode||await Do("Select deployment mode",["serverless","server"]),_=t?.region||await Do("Select AWS region",["us-east-1","us-west-2","eu-west-1","eu-central-1","ap-southeast-1"]),z=new s("Creating configuration file...");z.start();let U=`import { defineConfig } from '@ts-cloud/core'
|
|
32
32
|
|
|
33
33
|
export default defineConfig({
|
|
34
34
|
project: {
|
|
@@ -315,7 +315,7 @@ Resources to create: ${Ee}`);let Ke={};for(let Be of Object.values(ne.Resources|
|
|
|
315
315
|
No changes detected - infrastructure is up to date`);return}if(e(`
|
|
316
316
|
Changes detected:
|
|
317
317
|
`),Ie.length>0){n(`Resources to add (${Ie.length}):`);for(let De of Ie){let Ee=we[De].Type;e(` + ${De} (${Ee})`)}console.log()}if(Le.length>0){r(`Resources to remove (${Le.length}):`);for(let De of Le){let Ee=he[De].Type;e(` - ${De} (${Ee})`)}console.log()}if(Re.length>0){a(`Resources to modify (${Re.length}):`);for(let De of Re){let Ee=we[De].Type;e(` ~ ${De} (${Ee})`)}console.log()}e("Summary:"),e(` - Add: ${Ie.length}`),e(` - Remove: ${Le.length}`),e(` - Modify: ${Re.length}`),e("\nRun `cloud deploy` to apply these changes")}catch(m){r(`Diff failed: ${m.message}`)}})}function Bi(D,t=0){let m=Number(D);return Number.isFinite(m)?m:t}function Ja(D){return Bi(D)*1024}function cp(D){let t=D?.date?.trim(),m=D?.time?.trim();if(!t||!m)return null;let A=new Date(`${t}T${m}Z`);return Number.isFinite(A.getTime())?A.toISOString():null}function lp(D,t,m){let A;try{A=JSON.parse(D)}catch{return[]}let _=(A?.sysstat?.hosts??[]).flatMap((U)=>U.statistics??[]),z=[];for(let U of _){let Y=cp(U.timestamp);if(!Y)continue;let X=new Date(Y).getTime();if(X<t.getTime()||X>m.getTime())continue;let ne=U["cpu-load"]?.find((se)=>se.cpu==="all")??U["cpu-load"]?.[0],re=Bi(ne?.idle,100);z.push({timestamp:Y,cpuUsedPercent:Math.max(0,Math.min(100,100-re)),cpuUserPercent:Bi(ne?.user),cpuSystemPercent:Bi(ne?.system),cpuIowaitPercent:Bi(ne?.iowait),memoryUsedPercent:Bi(U.memory?.["memused-percent"]),memoryUsedBytes:Ja(U.memory?.memused),memoryAvailableBytes:Ja(U.memory?.avail),swapUsedPercent:Bi(U.memory?.["swpused-percent"]),swapUsedBytes:Ja(U.memory?.swpused)})}return z.sort((U,Y)=>U.timestamp.localeCompare(Y.timestamp))}function dp(D){return Object.fromEntries(Object.entries(D.time_series??{}).map(([t,m])=>[t,(m.values??[]).map(([A,_])=>({timestamp:new Date(Number(A)*1000).toISOString(),value:Bi(_,Number.NaN)})).filter((A)=>Number.isFinite(A.value))]))}function pd(D){return D.length?D.reduce((t,m)=>t+m,0)/D.length:null}function Ya(D){return D.length?Math.max(...D):null}function up(D){return D.length?Math.min(...D):null}async function fd(D){let[t,m]=await Promise.all([D.client.getServerMetrics(D.serverId,{types:["cpu","disk","network"],start:D.from,end:D.to,step:D.step}),Ne(D.remote.host,"LC_ALL=C sadf -j -- -u -r -S",D.remote).catch(()=>"")]),A=lp(m,D.from,D.to),_=dp(t),U=(_.cpu??[]).map((se)=>Math.max(0,Math.min(100,se.value/Math.max(1,D.cores)))),Y=A.map((se)=>se.cpuUsedPercent),X=U.length?U:Y,ne=A.map((se)=>se.memoryUsedPercent),re=A.map((se)=>se.swapUsedPercent);return{from:D.from.toISOString(),to:D.to.toISOString(),cores:D.cores,host:A,provider:_,summary:{cpuAveragePercent:pd(X),cpuPeakPercent:Ya(X),memoryAveragePercent:pd(ne),memoryPeakPercent:Ya(ne),memoryMinimumAvailableBytes:up(A.map((se)=>se.memoryAvailableBytes)),swapPeakPercent:Ya(re)}}}function mp(D){if(D.length===0)throw Error("A server name cannot be empty.");if(D.length>253)throw Error(`'${D}' is longer than the 253 characters a hostname allows.`);for(let t of D.split(".")){if(t.length===0)throw Error(`'${D}' has an empty label — a hostname cannot contain '..'.`);if(t.length>63)throw Error(`'${t}' is longer than the 63 characters a hostname label allows.`);if(!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(t))throw Error(`'${t}' is not a valid hostname label. Use letters, digits and hyphens, not starting or ending with a hyphen.`)}}async function gd(D,t,m){if(mp(t),D===t)throw Error(`'${D}' is already named that.`);if((await m.takenNames()).some((z)=>z===t&&z!==D))throw Error(`'${t}' is already taken. Server names have to be unique within a provider project.`);let _=[];if(m.providerName&&m.renameProvider){let{providerName:z,renameProvider:U}=m;_.push({id:"provider",title:"Rename the server at the provider",change:{from:D,to:t},satisfied:async()=>await z()===t,apply:()=>U(t)})}if(m.stateName&&m.writeStateName){let{stateName:z,writeStateName:U}=m;_.push({id:"state-pin",title:"Update the recorded name in the local driver state",change:{from:D,to:t},satisfied:async()=>{let Y=await z();return Y===void 0||Y===t},apply:()=>U(t)})}if(m.remoteHostname&&m.setRemoteHostname){let{remoteHostname:z,setRemoteHostname:U}=m;_.push({id:"hostname",title:"Set the hostname on the box",change:{from:D,to:t},satisfied:async()=>await z()===t,apply:()=>U(t)})}return _.push({id:"inventory",title:"Rename the fleet inventory record",change:{from:D,to:t},satisfied:async()=>m.inventoryName()===t,apply:async()=>{await m.renameInventory(t)}}),{operation:"server:rename",target:D,steps:_}}function hd(D){let t=`'${D.replace(/'/g,`'"'"'`)}'`;return["set -eu",'TS_CLOUD_OLD="$(hostname)"',`hostnamectl set-hostname ${t} 2>/dev/null || { echo ${t} > /etc/hostname && hostname ${t}; }`,'if grep -q "^127.0.1.1" /etc/hosts; then',` TS_CLOUD_HOSTS="$(sed -E "s/^127\\.0\\.1\\.1.*/127.0.1.1\\t${D}/" /etc/hosts)"`,` printf '%s\\n' "$TS_CLOUD_HOSTS" > /etc/hosts`,"else",` printf '127.0.1.1\\t%s\\n' ${t} >> /etc/hosts`,"fi",'printf "%s -> %s\\n" "$TS_CLOUD_OLD" "$(hostname)"'].join(`
|
|
318
|
-
`)}async function pp(){let D=await je(),t=y(process.cwd(),D),m=new ke(t.store),A=new Nn(m,[new it("aws"),new it("hetzner"),new it("ssh")]);return{controlPlane:t,store:m,service:A}}async function bi(D){let t=await pp();try{return await D(t)}finally{t.controlPlane.store.close()}}var Mi=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},yn=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};function Za(D,t){let m=Number.parseInt(D??"",10);return Number.isFinite(m)&&m>=0?m:t}function fp(D="3h"){let t=D.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ps(D,t="%"){return D==null?"unavailable":`${D.toFixed(1)}${t}`}async function gp(D,t){let m=await je();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await pe(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to read ${D}: project state is pinned to ${z.serverName}.`);let U=lr(m),Y=new We({apiToken:dr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=new Date,se=new Date(re.getTime()-fp(t.range)),he=Math.min(3600,Math.max(60,Za(t.step,60))),we=await fd({client:Y,serverId:X.id,cores:Math.max(1,Number(X.server_type.cores)||1),from:se,to:re,step:he,remote:{host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:X.name,result:we},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[X.name,`${we.from} to ${we.to}`,`${ps(we.summary.cpuAveragePercent)} / ${ps(we.summary.cpuPeakPercent)}`,`${ps(we.summary.memoryAveragePercent)} / ${ps(we.summary.memoryPeakPercent)}`,we.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(we.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ps(we.summary.swapPeakPercent)]])}function yd(D){let t=D.targetType.prices?.find((m)=>m.location===D.location);return{serverId:D.serverId,serverName:D.serverName,location:D.location,from:D.currentType.name,to:D.targetType.name,capacityAvailable:D.capacityAvailable,alreadyComplete:D.alreadyComplete,upgradeDisk:D.upgradeDisk,target:{cores:D.targetType.cores,memoryGb:D.targetType.memory,diskGb:D.targetType.disk,architecture:D.targetType.architecture,cpuType:D.targetType.cpu_type},price:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function hp(D){let t=yd(D);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function yp(D,t,m){let A=await je();if(A.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let _=m.env??process.env.CLOUD_ENV??"production",z=T(A,_),U=await pe(z),Y=lr(A),X=new We({apiToken:dr(Y.apiToken,A)}),re=U&&(D===U.serverName||D===String(U.serverId)||D===U.stackName)?await X.getServer(U.serverId):(await X.listServers()).find((Be)=>Be.name===D||String(Be.id)===D);if(!re)throw Error(`Hetzner server ${D} was not found.`);if(U?.serverId&&U.serverId!==re.id)throw Error(`Refusing to resize ${D}: project state is pinned to server ${U.serverId}.`);let se=dt(t),he=m.upgradeDisk!==!1,we=await ci(X,re.id,se,he);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:yd(we)},null,2));else hp(we);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${re.name} to execute.`);return}if(m.confirm!==re.name)throw Error(`Resize requires --confirm ${re.name}.`);let Pe=U?.publicIp??re.public_net.ipv4?.ip;if(!Pe)throw Error(`Server ${re.name} has no public IPv4 address for verification.`);let ye={host:Pe,user:U?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},Ie=await ls(z),Le=new Date().toISOString(),Re={schemaVersion:1,operationId:Ie?.targetType===se&&Ie.serverId===re.id?Ie.operationId:crypto.randomUUID(),stackName:z,serverId:re.id,serverName:re.name,sourceType:we.currentType.name,targetType:se,upgradeDisk:he,phase:"planning",status:"running",attempts:Ie?.targetType===se?Ie.attempts:0,startedAt:Ie?.targetType===se?Ie.startedAt:Le,updatedAt:Le,manifest:Ie?.targetType===se?Ie.manifest:void 0};await pt(Re);let De=Za(m.pollSeconds,900)*1000,Ee=Za(m.maxWaitMinutes,0)*60000,Ke=Date.now();for(;;){let Be=await ci(X,re.id,se,he);if(!Be.capacityAvailable&&!Be.alreadyComplete){if(Re={...Re,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await pt(Re),!m.wait){if(!m.json)e(`${se} has no capacity in ${Be.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Ee>0&&Date.now()-Ke>=Ee)throw Error(`Timed out waiting for ${se} capacity in ${Be.location}.`);if(!m.json)e(`Waiting ${Math.round(De/1000)} seconds for ${se} capacity...`);await Bun.sleep(De);continue}let _e=await ds(z);try{let et=await(async()=>{try{return Re={...Re,status:"running",attempts:Re.attempts+1,updatedAt:new Date().toISOString()},await pt(Re),await ns({client:X,serverId:re.id,targetType:se,upgradeDisk:he,resumeFromOff:Re.phase==="shutting-down"||Re.phase==="resizing"||Re.phase==="powering-on"||Re.phase==="verifying",manifest:Re.manifest,hooks:{preflight:async()=>{let Rt=await is(ye);return Re={...Re,manifest:Rt,updatedAt:new Date().toISOString()},await pt(Re),Rt},afterBoot:async(Rt,Et,wt,Pt)=>os(ye,Et,wt,Pt),onPhase:async(Rt,Et)=>{if(Re={...Re,phase:Rt,status:Rt==="waiting-capacity"?"waiting-capacity":Rt==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await pt(Re),!m.json)e(`${Rt}${Et?` ${JSON.stringify(Et)}`:""}`)}}})}finally{await _e()}})();if(Re={...Re,status:et.status==="completed"||et.status==="already-complete"?"completed":et.status==="recovered"?"recovered":"waiting-capacity",lastError:et.status==="recovered"?et.error:void 0,updatedAt:new Date().toISOString()},await pt(Re),m.json)console.log(JSON.stringify({schemaVersion:1,result:et},null,2));else if(et.status==="completed"||et.status==="already-complete")n(`${re.name} is on ${se} and passed full post-boot verification.`);else if(et.status==="recovered"&&et.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(De/1000)} seconds before retry.`),await Bun.sleep(De);continue}else if(et.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${et.error}`);return}catch(et){throw Re={...Re,status:"failed",lastError:et instanceof Error?et.message:String(et),updatedAt:new Date().toISOString()},await pt(Re),et}}}async function vp(D,t){let m=await je();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await pe(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to optimize ${D}: project state is pinned to ${z.serverName}.`);let U=lr(m),Y=new We({apiToken:dr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=to(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:X.name,plan:re},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[X.name,re.firewallPorts.join(","),re.monitoring?"on":"off",re.autoUpdates?"on":"off",`${re.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${X.name} to execute.`);return}if(t.confirm!==X.name)throw Error(`Optimization requires --confirm ${X.name}.`);let se={host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15},he=await en(se),we=he.routeProbes.filter((wt)=>!wt.ok),Pe=m.infrastructure?.compute,ye=Z(Pe)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,Ie=he.failedUnits.filter((wt)=>!ye.has(wt));if(Ie.length>0)throw Error(`Preflight found failed services: ${Ie.join(", ")}`);if(we.length>0)throw Error(`Preflight found unhealthy routes: ${we.map((wt)=>wt.domain).join(", ")}`);let Le=Z(Pe)?[]:Object.values(m.sites??{}).flatMap((wt)=>typeof wt?.port==="number"&&![80,443].includes(wt.port)?[wt.port]:[]),Re=Yr({allowSsh:Pe?.allowSsh!==!1,sitePorts:Le,allowedPorts:Pe?.firewall?.allowedPorts}),De=(z.firewallId?(await Y.listFirewalls()).find((wt)=>wt.id===z.firewallId):void 0)??(await Y.listFirewalls()).find((wt)=>wt.name===`${m.project.slug}-${A}-app-fw`);if(!De)throw Error(`Managed firewall for ${X.name} was not found.`);let Ee=await Y.setFirewallRules(De.id,Re);await Promise.all(Ee.map((wt)=>Y.waitForAction(wt.id))),await ss(m,se);let[Ke,Be]=await Promise.all([en(se),as(se)]),_e=cs(re,Be),et=pc(he,Ke),Rt=Ke.routeProbes.filter((wt)=>!wt.ok);if(et.stoppedServices.length>0)_e.push(`services stopped: ${et.stoppedServices.join(", ")}`);if(et.changedRouteFragments.length>0)_e.push(`route fragments changed: ${et.changedRouteFragments.join(", ")}`);if(et.missingRouteIds.length>0)_e.push(`routes disappeared: ${et.missingRouteIds.join(", ")}`);if(et.changedReleaseLinks.length>0)_e.push(`release links changed: ${et.changedReleaseLinks.join(", ")}`);if(et.missingData.length>0)_e.push(`databases or volumes disappeared: ${et.missingData.join(", ")}`);if(Rt.length>0)_e.push(`unhealthy routes: ${Rt.map((wt)=>wt.domain).join(", ")}`);if(_e.length>0)throw Error(`Host optimization verification failed: ${_e.join("; ")}`);let Et={serverId:X.id,serverName:X.name,services:Ke.runningServices.length,routes:Ke.routeIds.length,healthyDomains:Ke.routeProbes.length,releaseLinks:Ke.releaseLinks.length,databasesAndVolumes:Ke.dataCatalog.length,report:Be};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:Et},null,2));else n(`${X.name} passed full host, rpx route, service, release, and data verification.`)}async function bp(D,t,m){let A=await je(),_=m.env??"production",z=T(A,_);await bi(async(U)=>{let Y=Mi(U,D),X=U.store.list(U.controlPlane.project.id,!0),ne=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let De=lr(A);return new We({apiToken:dr(De.apiToken,A)})}catch{return null}})():null,re=Y.providerId?Number(Y.providerId):Number.NaN,se=await pe(z),he=se!=null&&se.serverId===re,we=new Fr,Pe=Y.trustState==="pinned",ye={takenNames:async()=>{let De=X.map((Ee)=>Ee.name);if(ne)De.push(...(await ne.listServers()).map((Ee)=>Ee.name));return De},inventoryName:()=>U.store.get(Y.id)?.name??Y.name,renameInventory:(De)=>{U.store.update(Y.id,{name:De})},...ne&&Number.isFinite(re)?{providerName:async()=>(await ne.getServer(re)).name,renameProvider:async(De)=>{await ne.renameServer(re,De)}}:{},...he?{stateName:async()=>(await pe(z))?.serverName,writeStateName:async(De)=>{let Ee=await pe(z);if(Ee)await ut(z,{...Ee,serverName:De})}}:{},...Pe?{remoteHostname:async()=>{let De=await we.exec(Y,"hostname");return De.code===0?De.stdout.trim():void 0},setRemoteHostname:async(De)=>{let Ee=await we.exec(Y,hd(De));if(Ee.code!==0)throw Error(Ee.stderr.trim()||`hostname exited ${Ee.code}`)}}:{}},Ie=await gd(Y.name,t,ye),Le=await Ws(Ie);if(!m.apply){let De=[ne?"":"provider record (no provider id or no API token)",he?"":"local state pin (none points at this server)",Pe?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:Ie.operation,target:Ie.target,rename:{from:Y.name,to:t},notCovered:De,steps:Le.map((Ee)=>({id:Ee.step.id,title:Ee.step.title,state:Ee.state,change:Ee.step.change,reason:Ee.reason}))},null,2));return}for(let Ee of Vs(Ie,Le))console.log(Ee);for(let Ee of De)console.log(` not covered: ${Ee}`);console.log(" Re-run with --apply to perform it.");return}let Re=await Gs(Ie,Le,{log:(De)=>e(De),audit:(De)=>U.controlPlane.store.appendEvent({projectId:U.controlPlane.project.id,resourceId:Y.resourceId,type:`${De.operation}.${De.step}.${De.state}`,level:De.state==="failed"?"error":"info",payload:{target:De.target,renameTo:t,...De.error?{error:De.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Re},null,2));if(!Re.success){let De=Re.steps.find((Ee)=>Ee.state==="failed");throw Error(`${Ie.operation} stopped at '${De?.title}': ${De?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function Qa(D){D.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await bi(async(A)=>{let _=t?[Mi(A,t)]:A.store.list(A.controlPlane.project.id),z=_.flatMap((U)=>Object.entries(U.capabilities).map(([Y,X])=>({server:U.name,provider:U.provider,action:Y,...X})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:z},null,2));else c(["Server","Provider","Action","Support","Explanation"],z.map((U)=>[U.server,U.provider,U.action,U.supported?"supported":"unsupported",U.reason??"—"]))})}catch(A){yn(A)}}),D.command("server:resize <name> <type>","Safely resize Hetzner compute with full host verification").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Execute the reviewed resize plan").option("--confirm <name>","Exact server name required for mutation").option("--upgrade-disk","Permanently expand the root disk to the target size",{default:!0}).option("--wait","Poll capacity without taking the server offline until placement is available").option("--poll-seconds <seconds>","Capacity retry interval",{default:"900"}).option("--max-wait-minutes <minutes>","Stop waiting after this many minutes; 0 waits indefinitely",{default:"0"}).option("--json","Print structured JSON").action(async(t,m,A)=>{try{await yp(t,m,A)}catch(_){yn(_)}}),D.command("server:optimize <name>","Reconcile and verify a production Hetzner host").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Apply the reviewed host optimization plan").option("--confirm <name>","Exact server name required for mutation").option("--json","Print structured JSON").action(async(t,m)=>{try{await vp(t,m)}catch(A){yn(A)}}),D.command("server:monitoring <name>","Read historical Hetzner CPU, RAM, swap, disk, and network metrics").option("--env <environment>","Deployment environment",{default:"production"}).option("--range <duration>","Historical window from 5m to 24h",{default:"3h"}).option("--step <seconds>","Hetzner provider sample interval",{default:"60"}).option("--json","Print structured JSON").action(async(t,m)=>{try{await gp(t,m)}catch(A){yn(A)}}),D.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await bi(async(m)=>{let A=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],A.map((_)=>[_.name,_.providerId??"—",`${_.provider} / ${_.region??"external"}`,`${_.status} / ${_.trustState}`,_.roles.join(","),`${_.capacity.cpu??0} / ${_.capacity.memoryBytes??0}`,_.heartbeatAt??"never"]))})}catch(m){yn(m)}}),D.command("server:create <name>","Enroll a provisioned or existing server").option("--provider <provider>","aws, hetzner, or ssh",{default:"ssh"}).option("--provider-id <id>","Stable provider identity").option("--endpoint <host>","SSH hostname or IP").option("--user <user>","Non-root SSH user",{default:"deploy"}).option("--credential-ref <ref>","Secret reference",{default:"secret://fleet/agent"}).option("--region <region>","Provider region").option("--roles <roles>","Comma-separated roles",{default:"application"}).option("--labels <labels>","Comma-separated key=value labels").action(async(t,m)=>{try{await bi(async(A)=>{let _=m.provider;if(!["aws","hetzner","ssh"].includes(_)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let z=A.service.enroll({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,provider:_,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((U)=>U.split("=")).filter((U)=>U[0]&&U[1]))});n(`Enrolled ${z.name} as ${z.id}; no remote mutation was performed.`)})}catch(A){yn(A)}}),D.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(t,m)=>{try{await bi(async(A)=>{let _=Mi(A,t);if(_=await A.service.test(_.id),_.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${_.pendingHostKey}; review it first.`);_=A.service.reviewHostKey(_.id,m.acceptHostKey)}let z=await A.service.validate(_.id);if(m.json)console.log(JSON.stringify(z.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(z.validation?.findings??[]).map((U)=>[U.severity,U.code,U.message,U.remediation??"—"]));if(!z.validation?.valid)process.exitCode=1})}catch(A){yn(A)}}),D.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await bi(async(A)=>{let _=A.service.bootstrap(Mi(A,t).id,!!m.apply);if(_.preview)c(["Step"],_.steps.map((z)=>[z]));else n(`Bootstrap queued: ${_.operation?.id}`)})}catch(A){yn(A)}}),D.command("server:rename <name> <new-name>","Rename a server in place, without recreating it").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Perform the reviewed rename plan").option("--json","Print structured JSON").action(async(t,m,A)=>{try{await bp(t,m,A)}catch(_){yn(_)}}),D.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await bi(async(A)=>n(A.service.drain(Mi(A,t).id,!!m.complete).status))}catch(A){yn(A)}}),D.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await bi(async(m)=>{m.service.uncordon(Mi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){yn(m)}}),D.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await bi(async(A)=>{A.service.archive(Mi(A,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(A){yn(A)}}),D.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await bi(async(m)=>{let A=Mi(m,t);if(A.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let _=Bun.spawn(["ssh","-p",String(A.sshPort),"-o","StrictHostKeyChecking=yes",`${A.sshUser}@${A.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),z=await _.exited;if(z)process.exitCode=z})}catch(m){yn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])D.command(t,m).action(async(...A)=>En(t.split(" ")[0],{target:String(A[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as vd,mkdirSync as wp,readFileSync as Sp,writeFileSync as Cp}from"node:fs";import{join as bd,resolve as $p}from"node:path";var Xa=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};async function kp(){try{return await je()}catch{return}}function Ap(D){if(D===void 0)return;let t=Number(D);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${D}'.`);return t}function wd(D,t,m){let A=D?.ssh?.hosts?.find((_)=>_.host===t);return new fr({hosts:t?[A??{host:t}]:D?.ssh?.hosts,user:m.user,port:Ap(m.port),privateKeyPath:m.key,hostKey:D?.ssh?.hostKey,sudo:D?.ssh?.sudo,profile:m.profile??D?.ssh?.profile,publicIp:D?.ssh?.publicIp,lan:D?.ssh?.lan})}var Sd=1073741824;function ec(D){D.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let A=await kp(),_=wd(A,t,m),z=t??_.targetHost(),U=await _.ensureHostKey(z),{facts:Y,findings:X}=await _.preflight(z);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:z,hostKeyFingerprint:U.fingerprint,facts:Y,findings:X},null,2));else{if(i(`Preflight ${z}`),U.pinnedNow)e(`Pinned host key ${U.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/Sd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/Sd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(Zr(X)),gr(X))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(gr(X))process.exitCode=1}catch(A){Xa(A)}}),D.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await je(),A=t.env??"production";if(t.dryRun){let U=mr(m),[Y]=U.hosts;console.log(pr({config:m,environment:A,profile:U.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:U.lan}));return}let _=wd(m,void 0,{});i(`Adopt ${_.targetHost()}`);let z=await _.provisionComputeInfrastructure({config:m,environment:A});n(`${z.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${A}`)}catch(m){Xa(m)}}),D.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in Zi))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let A=await je(),_=t.env??"production",z=mr(A,{hosts:A.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),U=t.user??(A.ssh?.hosts?.[0]?.user??"pi"),Y=Qr(t.key??"~/.ssh/id_ed25519.pub");if(!vd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let X=Sp(Y,"utf8").trim(),ne;if(t.wifiSsid){let Pe=t.wifiPassphraseEnv??"WIFI_PASSWORD",ye=process.env[Pe];if(!ye)throw Error(`--wifi-ssid needs the passphrase in $${Pe} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");ne={ssid:t.wifiSsid,passphrase:ye,country:t.wifiCountry}}let re=pr({config:A,environment:_,profile:z.profile,sudoUser:U!=="root"?U:void 0,lan:z.lan}),se=eo({hostname:t.hostname,user:U,publicKey:X,timezone:t.timezone,locale:t.locale,wifi:ne},re,{os:m}),he=$p(t.out);wp(he,{recursive:!0});let we=Object.keys(se.files).filter((Pe)=>vd(bd(he,Pe)));if(we.length>0&&!t.force)throw Error(`${we.join(", ")} already exist in ${he}; pass --force to overwrite.`);for(let[Pe,ye]of Object.entries(se.files))Cp(bd(he,Pe),ye,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(se.files).join(", ")} to ${he}`),console.log(se.instructions)}catch(m){Xa(m)}})}async function Rp(){let D=await je(),t=y(process.cwd(),D),m=new xn(t.store),A=new _n(m,new ke(t.store));return{controlPlane:t,store:m,service:A}}async function gs(D){let t=await Rp();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Ks=(D)=>Object.fromEntries(String(D??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Cd=(D)=>Object.fromEntries(Object.entries(Ks(D)).map(([t,m])=>[t,Number(m)]));function tc(D){D.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>gs((m)=>{let A=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],A.map((_)=>[_.name,_.purpose,_.backend,`${_.region??"any"} / ${_.architecture??"any"}`,_.status,JSON.stringify(_.capacity),String(_.concurrency)]))})),D.command("pool:create <name>","Create a capacity pool").option("--purpose <purpose>","application, build, worker, monitoring, or backup",{default:"application"}).option("--backend <backend>","server, ecs, or asg",{default:"server"}).option("--capacity <values>","cpu=4,memoryBytes=8589934592,diskBytes=...").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Pool key=value labels").option("--selector <labels>","Required server labels").option("--max <count>","Maximum workloads",{default:"10"}).option("--concurrency <count>","Build concurrency",{default:"1"}).action(async(t,m)=>gs((A)=>{let{purpose:_,backend:z}=m;if(!["application","build","worker","monitoring","backup"].includes(_)||!["server","ecs","asg"].includes(z))throw Error("Unsupported pool purpose or backend.");let U=A.store.createPool({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,purpose:_,backend:z,region:m.region,architecture:m.arch,labels:Ks(m.labels),requiredServerLabels:Ks(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Cd(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${U.name} (${U.id}).`)})),D.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>gs((A)=>{let _=A.store.listPools(A.controlPlane.project.id).find((U)=>U.id===t||U.name===t),z=new ke(A.controlPlane.store).list(A.controlPlane.project.id).find((U)=>U.id===m||U.name===m);if(!_||!z)throw Error("Pool or server was not found.");A.store.addMember(_.id,z.id),n(`Attached ${z.name} to ${_.name}.`)})),D.command("placement:explain","Explain eligible and rejected placement targets").option("--purpose <purpose>","Workload purpose",{default:"application"}).option("--resources <values>","Requested resources").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Required pool labels").option("--json","Print structured JSON").action(async(t)=>gs((m)=>{let A=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Cd(t.resources),region:t.region,architecture:t.arch,labels:Ks(t.labels)});if(t.json)console.log(JSON.stringify(A,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],A.map((_)=>[_.poolName,_.serverId??"provider-managed",_.eligible?"yes":"no",JSON.stringify(_.available),`${_.score.fit.toFixed(2)} / ${_.score.spread} / ${_.score.cost}`,_.reasons.join("; ")||"eligible"]))})),D.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(t)=>gs((m)=>{let A=m.store.listPools(m.controlPlane.project.id).find((z)=>z.id===t||z.name===t);if(!A)throw Error("Pool was not found.");let _=m.service.drainPool(A.id);n(`Draining ${A.name}: moved ${_.moved.length}, blocked ${_.blocked.length} stateful placement(s).`)}))}async function Ip(){let D=await je(),t=y(process.cwd(),D),m=new On(t.store),A=new $n(m);return{controlPlane:t,store:m,service:A}}async function po(D){let t=await Ip();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var hs=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error("Regional topology was not found.");return m},Pp=(D)=>D.split(",").map((t,m)=>{let[A,_="aws"]=t.split(":");return{region:String(A),provider:_,role:m===0?"primary":"secondary"}}),Dp=(D)=>{let t=new Set(["s3","dynamodb","secrets"]),m=D.split(",").map((_)=>_.trim()),A=m.find((_)=>!t.has(_));if(A)throw Error(`Unsupported replication kind: ${A}`);return m};function nc(D){D.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>po((m)=>{let A=m.store.list(m.controlPlane.project.id).map((_)=>({topology:_,targets:m.store.targets(_.id),channels:m.store.channels(_.id),route:m.store.route(_.id),executions:m.store.executions(_.id)}));if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],A.map((_)=>[_.topology.name,_.topology.hostname,_.topology.activeRegion,_.topology.status,_.topology.revision??"—",`${_.channels.filter((z)=>z.status==="in_sync").length}/${_.channels.length} in sync`]))})),D.command("region:create <name>","Create a persistent multi-region topology").option("--hostname <hostname>","Traffic hostname").option("--regions <regions>","Comma-separated region[:provider], primary first").option("--replicate <kinds>","s3,dynamodb,secrets",{default:"s3,dynamodb,secrets"}).option("--max-lag <seconds>","Maximum failover lag",{default:"30"}).option("--cdn","Enable CloudFront edge state").option("--waf","Enable WAF edge state").action(async(t,m)=>po((A)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let _=A.service.create({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,hostname:m.hostname,regions:Pp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Dp(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`Created ${_.name} (${_.id}); run region:rollout with an immutable manifest.`)})),D.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(t,m,A)=>po((_)=>c(["Step"],_.service.plan(hs(_,t).id,m,A.target).map((z)=>[z])))),D.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,A)=>po(async(_)=>{let z=A.manifest?await Bun.file(A.manifest).json():{},U=_.service.enqueue({topologyId:hs(_,t).id,kind:"rollout",revision:m,manifest:z});n(`Regional rollout queued: ${U.operation.id}`)})),D.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${_.operation.id}`)})),D.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"failback",targetRegion:m});n(`Failback queued: ${_.operation.id}`)})),D.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${_.operation.id}; replicated data remains retained.`)}))}var ys="0.16.42";async function Ep(){let D=await je(),t=y(process.cwd(),D),m=new Ln(t.store),A=new Mn(m),_=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((z)=>new Un(z,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:A,cleanup:_}}async function Ii(D){let t=await Ep();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function rc(D){D.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>Ii((m)=>{let A={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},_=[...A.manifests.map((z)=>["update",z.version,z.compatibility.compatible?"compatible":"blocked",z.compatibility.reasons.join("; ")||z.channel]),...A.campaigns.map((z)=>["upgrade",z.id,z.status,z.currentStage??z.fromVersion]),...A.cleanups.map((z)=>["cleanup",z.kind,z.status,`${z.candidates.length} items / ${z.estimatedBytes} bytes`]),...A.drills.map((z)=>["DR drill",z.scenario,z.status,z.isolatedTarget])];if(t.json)console.log(JSON.stringify(A,null,2));else c(["Area","Name / version","Status","Detail"],_)})),D.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>Ii(async(A)=>{let _=A.store.addTrustedKey({organizationId:A.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${_.name}: ${_.fingerprint}`)})),D.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,A)=>Ii(async(_)=>{let z=await Bun.file(t).json(),U=(await Bun.file(m).text()).trim(),Y=_.store.importManifest({organizationId:_.controlPlane.organization.id,keyId:A,document:z,signature:U,current:{schemaVersion:_.controlPlane.store.health().schemaVersion,currentVersion:ys,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.compatibility.reasons.join("; ")}`)})),D.command("maintenance:window <name> <schedule>","Create an approved maintenance window").option("--timezone <timezone>","IANA timezone",{default:"UTC"}).option("--minutes <minutes>","Duration",{default:"60"}).action(async(t,m,A)=>Ii((_)=>{let z=_.store.createWindow({projectId:_.controlPlane.project.id,name:t,schedule:m,timezone:A.timezone,durationMinutes:Number(A.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${z.name} (${z.id}).`)})),D.command("platform:upgrade <manifest> <backup>","Plan and queue a signed staged platform update").option("--strategy <strategy>","canary or rolling",{default:"canary"}).option("--batch <count>","Rolling batch size",{default:"1"}).action(async(t,m,A)=>Ii((_)=>{let z=new ke(_.controlPlane.store).list(_.controlPlane.project.id).filter((X)=>X.status==="ready").map((X)=>({serverId:X.id,target:X.name,previousVersion:X.bootstrapVersion??ys}));if(!z.length)z.push({target:"control-plane",previousVersion:ys});let U=_.store.createCampaign({projectId:_.controlPlane.project.id,manifestId:t,fromVersion:ys,strategy:A.strategy==="rolling"?"rolling":"canary",batchSize:Number(A.batch),healthGate:{kind:"platform"},backupId:m,targets:z}),Y=_.service.enqueueCampaign(U.id);n(`Staged upgrade queued: ${Y.operation.id}`)})),D.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(t,m)=>Ii(async(A)=>{let _=await A.service.previewCleanup({projectId:A.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},A.cleanup);c(["ID","Candidate","Bytes"],_.candidates.map((z)=>[z.id,z.label,String(z.bytes)])),e(`Apply with: cloud cleanup:apply ${_.id} --confirm "DELETE ${_.candidates.length} ${_.kind}"`)})),D.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(t,m)=>Ii((A)=>{let _=A.service.enqueueCleanup(t,String(m.confirm??""));n(`Cleanup queued: ${_.operation.id}`)})),D.command("dr:plan <scenario> <target>","Plan an isolated disaster-recovery drill").option("--rpo <minutes>","RPO objective",{default:"60"}).option("--rto <minutes>","RTO objective",{default:"30"}).option("--recovery-point <id>","Recovery point").option("--topology <id>","Regional topology").action(async(t,m,A)=>Ii((_)=>{let z=_.store.createDrill({projectId:_.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(A.rpo),expectedRtoMinutes:Number(A.rto),recoveryPointId:A.recoveryPoint,topologyId:A.topology});n(`Planned isolated drill ${z.id}.`)})),D.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>Ii((m)=>{let A=m.service.enqueueDrill(t);n(`DR drill queued: ${A.operation.id}`)}))}async function ic(){try{return(await je()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function oc(D){D.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await ic(),A=new I(m);try{let{Functions:_=[]}=await A.listFunctions({MaxItems:50});if(!_.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],_.map((z)=>[z.FunctionName??"-",z.Runtime??"-",z.MemorySize?`${z.MemorySize} MB`:"-",z.Timeout?`${z.Timeout}s`:"-",z.LastModified??"-"]))}catch(_){r(`Failed to list functions: ${_.message}`),process.exitCode=1}}),D.command("function:invoke <name>","Invoke a Lambda function").option("--payload <json>","Event payload as JSON",{default:"{}"}).option("--async","Fire-and-forget (Event invocation)").option("--region <region>","AWS region").action(async(t,m)=>{i(`Invoking ${t}`);let A=m?.region||await ic(),_=new I(A),z=new s("Invoking function...");z.start();try{let U=await _.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(U.FunctionError){if(z.fail(`Function returned an error (${U.FunctionError})`),U.Payload)e(U.Payload);process.exitCode=1;return}if(z.succeed(`Invoked (status ${U.StatusCode})`),U.Payload)e(`
|
|
318
|
+
`)}async function pp(){let D=await je(),t=y(process.cwd(),D),m=new ke(t.store),A=new Nn(m,[new it("aws"),new it("hetzner"),new it("ssh")]);return{controlPlane:t,store:m,service:A}}async function bi(D){let t=await pp();try{return await D(t)}finally{t.controlPlane.store.close()}}var Mi=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error(`Server ${t} was not found.`);return m},yn=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};function Za(D,t){let m=Number.parseInt(D??"",10);return Number.isFinite(m)&&m>=0?m:t}function fp(D="3h"){let t=D.match(/^(\d+)(m|h)$/);if(!t)throw Error("--range must use minutes or hours, for example 30m or 3h.");let m=Number(t[1])*(t[2]==="h"?3600000:60000);if(m<300000||m>86400000)throw Error("--range must be between 5 minutes and 24 hours.");return m}function ps(D,t="%"){return D==null?"unavailable":`${D.toFixed(1)}${t}`}async function gp(D,t){let m=await je();if(m.cloud?.provider!=="hetzner")throw Error("server:monitoring currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await pe(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to read ${D}: project state is pinned to ${z.serverName}.`);let U=lr(m),Y=new We({apiToken:dr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=new Date,se=new Date(re.getTime()-fp(t.range)),he=Math.min(3600,Math.max(60,Za(t.step,60))),we=await fd({client:Y,serverId:X.id,cores:Math.max(1,Number(X.server_type.cores)||1),from:se,to:re,step:he,remote:{host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15}});if(t.json){console.log(JSON.stringify({schemaVersion:1,server:X.name,result:we},null,2));return}c(["Server","Window","CPU average / peak","RAM average / peak","Minimum available","Swap peak"],[[X.name,`${we.from} to ${we.to}`,`${ps(we.summary.cpuAveragePercent)} / ${ps(we.summary.cpuPeakPercent)}`,`${ps(we.summary.memoryAveragePercent)} / ${ps(we.summary.memoryPeakPercent)}`,we.summary.memoryMinimumAvailableBytes==null?"unavailable":`${(we.summary.memoryMinimumAvailableBytes/1073741824).toFixed(2)} GB`,ps(we.summary.swapPeakPercent)]])}function yd(D){let t=D.targetType.prices?.find((m)=>m.location===D.location);return{serverId:D.serverId,serverName:D.serverName,location:D.location,from:D.currentType.name,to:D.targetType.name,capacityAvailable:D.capacityAvailable,alreadyComplete:D.alreadyComplete,upgradeDisk:D.upgradeDisk,target:{cores:D.targetType.cores,memoryGb:D.targetType.memory,diskGb:D.targetType.disk,architecture:D.targetType.architecture,cpuType:D.targetType.cpu_type},price:t?{hourlyNet:t.price_hourly.net,hourlyGross:t.price_hourly.gross,monthlyNet:t.price_monthly.net,monthlyGross:t.price_monthly.gross}:void 0}}function hp(D){let t=yd(D);c(["Server","Location","Resize","Capacity","CPU / RAM / disk","Monthly"],[[`${t.serverName} (${t.serverId})`,t.location,`${t.from} -> ${t.to}`,t.capacityAvailable?"available":"waiting",`${t.target.cores??0} / ${t.target.memoryGb??0} GB / ${t.target.diskGb??0} GB`,t.price?.monthlyGross??t.price?.monthlyNet??"not reported"]])}async function yp(D,t,m){let A=await je();if(A.cloud?.provider!=="hetzner")throw Error("server:resize currently requires the Hetzner provider.");let _=m.env??process.env.CLOUD_ENV??"production",z=T(A,_),U=await pe(z),Y=lr(A),X=new We({apiToken:dr(Y.apiToken,A)}),re=U&&(D===U.serverName||D===String(U.serverId)||D===U.stackName)?await X.getServer(U.serverId):(await X.listServers()).find((Be)=>Be.name===D||String(Be.id)===D);if(!re)throw Error(`Hetzner server ${D} was not found.`);if(U?.serverId&&U.serverId!==re.id)throw Error(`Refusing to resize ${D}: project state is pinned to server ${U.serverId}.`);let se=dt(t),he=m.upgradeDisk!==!1,we=await ci(X,re.id,se,he);if(m.json)console.log(JSON.stringify({schemaVersion:1,plan:yd(we)},null,2));else hp(we);if(!m.apply){if(!m.json)e(`Preview only. Re-run with --apply --confirm ${re.name} to execute.`);return}if(m.confirm!==re.name)throw Error(`Resize requires --confirm ${re.name}.`);let Pe=U?.publicIp??re.public_net.ipv4?.ip;if(!Pe)throw Error(`Server ${re.name} has no public IPv4 address for verification.`);let ye={host:Pe,user:U?.sshUser??Y.sshUser,identityFile:Y.sshPrivateKeyPath,connectTimeoutSec:15,sshTimeoutMs:600000,routeTimeoutMs:20000},Ie=await ls(z),Le=new Date().toISOString(),Re={schemaVersion:1,operationId:Ie?.targetType===se&&Ie.serverId===re.id?Ie.operationId:crypto.randomUUID(),stackName:z,serverId:re.id,serverName:re.name,sourceType:we.currentType.name,targetType:se,upgradeDisk:he,phase:"planning",status:"running",attempts:Ie?.targetType===se?Ie.attempts:0,startedAt:Ie?.targetType===se?Ie.startedAt:Le,updatedAt:Le,manifest:Ie?.targetType===se?Ie.manifest:void 0};await pt(Re);let De=Za(m.pollSeconds,900)*1000,Ee=Za(m.maxWaitMinutes,0)*60000,Ke=Date.now();for(;;){let Be=await ci(X,re.id,se,he);if(!Be.capacityAvailable&&!Be.alreadyComplete){if(Re={...Re,phase:"waiting-capacity",status:"waiting-capacity",updatedAt:new Date().toISOString()},await pt(Re),!m.wait){if(!m.json)e(`${se} has no capacity in ${Be.location}. The server remains running and unchanged. Use --wait to poll safely.`);return}if(Ee>0&&Date.now()-Ke>=Ee)throw Error(`Timed out waiting for ${se} capacity in ${Be.location}.`);if(!m.json)e(`Waiting ${Math.round(De/1000)} seconds for ${se} capacity...`);await Bun.sleep(De);continue}let _e=await ds(z);try{let et=await(async()=>{try{return Re={...Re,status:"running",attempts:Re.attempts+1,updatedAt:new Date().toISOString()},await pt(Re),await ns({client:X,serverId:re.id,targetType:se,upgradeDisk:he,resumeFromOff:Re.phase==="shutting-down"||Re.phase==="resizing"||Re.phase==="powering-on"||Re.phase==="verifying",manifest:Re.manifest,hooks:{preflight:async()=>{let Rt=await is(ye);return Re={...Re,manifest:Rt,updatedAt:new Date().toISOString()},await pt(Re),Rt},afterBoot:async(Rt,Et,wt,Pt)=>os(ye,Et,wt,Pt),onPhase:async(Rt,Et)=>{if(Re={...Re,phase:Rt,status:Rt==="waiting-capacity"?"waiting-capacity":Rt==="complete"?"completed":"running",updatedAt:new Date().toISOString()},await pt(Re),!m.json)e(`${Rt}${Et?` ${JSON.stringify(Et)}`:""}`)}}})}finally{await _e()}})();if(Re={...Re,status:et.status==="completed"||et.status==="already-complete"?"completed":et.status==="recovered"?"recovered":"waiting-capacity",lastError:et.status==="recovered"?et.error:void 0,updatedAt:new Date().toISOString()},await pt(Re),m.json)console.log(JSON.stringify({schemaVersion:1,result:et},null,2));else if(et.status==="completed"||et.status==="already-complete")n(`${re.name} is on ${se} and passed full post-boot verification.`);else if(et.status==="recovered"&&et.retryable&&m.wait){e(`Capacity race recovered safely. Waiting ${Math.round(De/1000)} seconds before retry.`),await Bun.sleep(De);continue}else if(et.status==="recovered")throw Error(`Resize did not complete and the original server was recovered: ${et.error}`);return}catch(et){throw Re={...Re,status:"failed",lastError:et instanceof Error?et.message:String(et),updatedAt:new Date().toISOString()},await pt(Re),et}}}async function vp(D,t){let m=await je();if(m.cloud?.provider!=="hetzner")throw Error("server:optimize currently requires the Hetzner provider.");let A=t.env??process.env.CLOUD_ENV??"production",_=T(m,A),z=await pe(_);if(!z?.serverId)throw Error(`No pinned Hetzner server was found for ${_}.`);if(![z.serverName,String(z.serverId),z.stackName].includes(D))throw Error(`Refusing to optimize ${D}: project state is pinned to ${z.serverName}.`);let U=lr(m),Y=new We({apiToken:dr(U.apiToken,m)}),X=await Y.getServer(z.serverId),ne=z.publicIp??X.public_net.ipv4?.ip;if(!ne)throw Error(`Server ${X.name} has no public IPv4 address.`);let re=to(m);if(t.json)console.log(JSON.stringify({schemaVersion:1,server:X.name,plan:re},null,2));else c(["Server","Firewall ports","Monitoring","Auto updates","Swap","SSH passwords"],[[X.name,re.firewallPorts.join(","),re.monitoring?"on":"off",re.autoUpdates?"on":"off",`${re.swapGb} GB`,"disabled"]]);if(!t.apply){if(!t.json)e(`Preview only. Re-run with --apply --confirm ${X.name} to execute.`);return}if(t.confirm!==X.name)throw Error(`Optimization requires --confirm ${X.name}.`);let se={host:ne,user:z.sshUser??U.sshUser,identityFile:U.sshPrivateKeyPath,connectTimeoutSec:15},he=await en(se),we=he.routeProbes.filter((wt)=>!wt.ok),Pe=m.infrastructure?.compute,ye=Z(Pe)?new Set(["nginx.service","bun-gateway.service","ts-cloud-nginx.service"]):new Set,Ie=he.failedUnits.filter((wt)=>!ye.has(wt));if(Ie.length>0)throw Error(`Preflight found failed services: ${Ie.join(", ")}`);if(we.length>0)throw Error(`Preflight found unhealthy routes: ${we.map((wt)=>wt.domain).join(", ")}`);let Le=Z(Pe)?[]:Object.values(m.sites??{}).flatMap((wt)=>typeof wt?.port==="number"&&![80,443].includes(wt.port)?[wt.port]:[]),Re=Yr({allowSsh:Pe?.allowSsh!==!1,sitePorts:Le,allowedPorts:Pe?.firewall?.allowedPorts}),De=(z.firewallId?(await Y.listFirewalls()).find((wt)=>wt.id===z.firewallId):void 0)??(await Y.listFirewalls()).find((wt)=>wt.name===`${m.project.slug}-${A}-app-fw`);if(!De)throw Error(`Managed firewall for ${X.name} was not found.`);let Ee=await Y.setFirewallRules(De.id,Re);await Promise.all(Ee.map((wt)=>Y.waitForAction(wt.id))),await ss(m,se);let[Ke,Be]=await Promise.all([en(se),as(se)]),_e=cs(re,Be),et=pc(he,Ke),Rt=Ke.routeProbes.filter((wt)=>!wt.ok);if(et.stoppedServices.length>0)_e.push(`services stopped: ${et.stoppedServices.join(", ")}`);if(et.changedRouteFragments.length>0)_e.push(`route fragments changed: ${et.changedRouteFragments.join(", ")}`);if(et.missingRouteIds.length>0)_e.push(`routes disappeared: ${et.missingRouteIds.join(", ")}`);if(et.changedReleaseLinks.length>0)_e.push(`release links changed: ${et.changedReleaseLinks.join(", ")}`);if(et.missingData.length>0)_e.push(`databases or volumes disappeared: ${et.missingData.join(", ")}`);if(Rt.length>0)_e.push(`unhealthy routes: ${Rt.map((wt)=>wt.domain).join(", ")}`);if(_e.length>0)throw Error(`Host optimization verification failed: ${_e.join("; ")}`);let Et={serverId:X.id,serverName:X.name,services:Ke.runningServices.length,routes:Ke.routeIds.length,healthyDomains:Ke.routeProbes.length,releaseLinks:Ke.releaseLinks.length,databasesAndVolumes:Ke.dataCatalog.length,report:Be};if(t.json)console.log(JSON.stringify({schemaVersion:1,result:Et},null,2));else n(`${X.name} passed full host, rpx route, service, release, and data verification.`)}async function bp(D,t,m){let A=await je(),_=m.env??"production",z=T(A,_);await bi(async(U)=>{let Y=Mi(U,D),X=U.store.list(U.controlPlane.project.id,!0),ne=Y.provider==="hetzner"&&Y.providerId?(()=>{try{let De=lr(A);return new We({apiToken:dr(De.apiToken,A)})}catch{return null}})():null,re=Y.providerId?Number(Y.providerId):Number.NaN,se=await pe(z),he=se!=null&&se.serverId===re,we=new Fr,Pe=Y.trustState==="pinned",ye={takenNames:async()=>{let De=X.map((Ee)=>Ee.name);if(ne)De.push(...(await ne.listServers()).map((Ee)=>Ee.name));return De},inventoryName:()=>U.store.get(Y.id)?.name??Y.name,renameInventory:(De)=>{U.store.update(Y.id,{name:De})},...ne&&Number.isFinite(re)?{providerName:async()=>(await ne.getServer(re)).name,renameProvider:async(De)=>{await ne.renameServer(re,De)}}:{},...he?{stateName:async()=>(await pe(z))?.serverName,writeStateName:async(De)=>{let Ee=await pe(z);if(Ee)await ut(z,{...Ee,serverName:De})}}:{},...Pe?{remoteHostname:async()=>{let De=await we.exec(Y,"hostname");return De.code===0?De.stdout.trim():void 0},setRemoteHostname:async(De)=>{let Ee=await we.exec(Y,hd(De));if(Ee.code!==0)throw Error(Ee.stderr.trim()||`hostname exited ${Ee.code}`)}}:{}},Ie=await gd(Y.name,t,ye),Le=await Ws(Ie);if(!m.apply){let De=[ne?"":"provider record (no provider id or no API token)",he?"":"local state pin (none points at this server)",Pe?"":"box hostname (host key is not pinned — run server:validate first)"].filter(Boolean);if(m.json){console.log(JSON.stringify({schemaVersion:1,operation:Ie.operation,target:Ie.target,rename:{from:Y.name,to:t},notCovered:De,steps:Le.map((Ee)=>({id:Ee.step.id,title:Ee.step.title,state:Ee.state,change:Ee.step.change,reason:Ee.reason}))},null,2));return}for(let Ee of Vs(Ie,Le))console.log(Ee);for(let Ee of De)console.log(` not covered: ${Ee}`);console.log(" Re-run with --apply to perform it.");return}let Re=await Gs(Ie,Le,{log:(De)=>e(De),audit:(De)=>U.controlPlane.store.appendEvent({projectId:U.controlPlane.project.id,resourceId:Y.resourceId,type:`${De.operation}.${De.step}.${De.state}`,level:De.state==="failed"?"error":"info",payload:{target:De.target,renameTo:t,...De.error?{error:De.error}:{}}})});if(m.json)console.log(JSON.stringify({schemaVersion:1,outcome:Re},null,2));if(!Re.success){let De=Re.steps.find((Ee)=>Ee.state==="failed");throw Error(`${Ie.operation} stopped at '${De?.title}': ${De?.error}. Earlier steps stayed applied; re-run the same command to continue from here.`)}if(!m.json)n(`Renamed ${Y.name} to ${t}.`)})}function Qa(D){D.command("capabilities [server]","Show provider and target operation support").option("--json","Print structured JSON").action(async(t,m)=>{try{await bi(async(A)=>{let _=t?[Mi(A,t)]:A.store.list(A.controlPlane.project.id),z=_.flatMap((U)=>Object.entries(U.capabilities).map(([Y,X])=>({server:U.name,provider:U.provider,action:Y,...X})));if(m.json)console.log(JSON.stringify({schemaVersion:1,targets:z},null,2));else c(["Server","Provider","Action","Support","Explanation"],z.map((U)=>[U.server,U.provider,U.action,U.supported?"supported":"unsupported",U.reason??"—"]))})}catch(A){yn(A)}}),D.command("server:resize <name> <type>","Safely resize Hetzner compute with full host verification").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Execute the reviewed resize plan").option("--confirm <name>","Exact server name required for mutation").option("--upgrade-disk","Permanently expand the root disk to the target size",{default:!0}).option("--wait","Poll capacity without taking the server offline until placement is available").option("--poll-seconds <seconds>","Capacity retry interval",{default:"900"}).option("--max-wait-minutes <minutes>","Stop waiting after this many minutes; 0 waits indefinitely",{default:"0"}).option("--json","Print structured JSON").action(async(t,m,A)=>{try{await yp(t,m,A)}catch(_){yn(_)}}),D.command("server:optimize <name>","Reconcile and verify a production Hetzner host").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Apply the reviewed host optimization plan").option("--confirm <name>","Exact server name required for mutation").option("--json","Print structured JSON").action(async(t,m)=>{try{await vp(t,m)}catch(A){yn(A)}}),D.command("server:monitoring <name>","Read historical Hetzner CPU, RAM, swap, disk, and network metrics").option("--env <environment>","Deployment environment",{default:"production"}).option("--range <duration>","Historical window from 5m to 24h",{default:"3h"}).option("--step <seconds>","Hetzner provider sample interval",{default:"60"}).option("--json","Print structured JSON").action(async(t,m)=>{try{await gp(t,m)}catch(A){yn(A)}}),D.command("server:list","List fleet servers").option("--json","Print structured JSON").action(async(t)=>{try{await bi(async(m)=>{let A=m.store.list(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Provider ID","Provider / region","Status / trust","Roles","CPU / memory","Heartbeat"],A.map((_)=>[_.name,_.providerId??"—",`${_.provider} / ${_.region??"external"}`,`${_.status} / ${_.trustState}`,_.roles.join(","),`${_.capacity.cpu??0} / ${_.capacity.memoryBytes??0}`,_.heartbeatAt??"never"]))})}catch(m){yn(m)}}),D.command("server:create <name>","Enroll a provisioned or existing server").option("--provider <provider>","aws, hetzner, or ssh",{default:"ssh"}).option("--provider-id <id>","Stable provider identity").option("--endpoint <host>","SSH hostname or IP").option("--user <user>","Non-root SSH user",{default:"deploy"}).option("--credential-ref <ref>","Secret reference",{default:"secret://fleet/agent"}).option("--region <region>","Provider region").option("--roles <roles>","Comma-separated roles",{default:"application"}).option("--labels <labels>","Comma-separated key=value labels").action(async(t,m)=>{try{await bi(async(A)=>{let _=m.provider;if(!["aws","hetzner","ssh"].includes(_)||!m.endpoint)throw Error("A supported --provider and --endpoint are required; provisioning and enrollment are separate operations.");let z=A.service.enroll({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,provider:_,providerId:m.providerId,endpoint:m.endpoint,sshUser:m.user??"deploy",credentialRef:m.credentialRef??"secret://fleet/agent",region:m.region,roles:String(m.roles??"application").split(","),labels:Object.fromEntries(String(m.labels??"").split(",").map((U)=>U.split("=")).filter((U)=>U[0]&&U[1]))});n(`Enrolled ${z.name} as ${z.id}; no remote mutation was performed.`)})}catch(A){yn(A)}}),D.command("server:validate <name>","Pin trust and validate a server").option("--accept-host-key <fingerprint>","Accept reviewed rotation").option("--json","Print JSON").action(async(t,m)=>{try{await bi(async(A)=>{let _=Mi(A,t);if(_=await A.service.test(_.id),_.trustState==="rotation_pending"){if(!m.acceptHostKey)throw Error(`Host key changed to ${_.pendingHostKey}; review it first.`);_=A.service.reviewHostKey(_.id,m.acceptHostKey)}let z=await A.service.validate(_.id);if(m.json)console.log(JSON.stringify(z.validation,null,2));else c(["Severity","Code","Finding","Remediation"],(z.validation?.findings??[]).map((U)=>[U.severity,U.code,U.message,U.remediation??"—"]));if(!z.validation?.valid)process.exitCode=1})}catch(A){yn(A)}}),D.command("server:bootstrap <name>","Preview or queue bootstrap").option("--apply","Apply reviewed plan").action(async(t,m)=>{try{await bi(async(A)=>{let _=A.service.bootstrap(Mi(A,t).id,!!m.apply);if(_.preview)c(["Step"],_.steps.map((z)=>[z]));else n(`Bootstrap queued: ${_.operation?.id}`)})}catch(A){yn(A)}}),D.command("server:rename <name> <new-name>","Rename a server in place, without recreating it").option("--env <environment>","Deployment environment",{default:"production"}).option("--apply","Perform the reviewed rename plan").option("--json","Print structured JSON").action(async(t,m,A)=>{try{await bp(t,m,A)}catch(_){yn(_)}}),D.command("server:drain <name>","Drain without terminating").option("--complete","Mark movement complete").action(async(t,m)=>{try{await bi(async(A)=>n(A.service.drain(Mi(A,t).id,!!m.complete).status))}catch(A){yn(A)}}),D.command("server:uncordon <name>","Return a server to scheduling").action(async(t)=>{try{await bi(async(m)=>{m.service.uncordon(Mi(m,t).id),n(`Uncordoned ${t}.`)})}catch(m){yn(m)}}),D.command("server:archive <name>","Archive inventory without termination").option("--confirm <name>","Exact name").action(async(t,m)=>{try{await bi(async(A)=>{A.service.archive(Mi(A,t).id,m.confirm??""),n(`Archived ${t}; provider infrastructure was not terminated.`)})}catch(A){yn(A)}}),D.command("server:ssh <name>","Open strict SSH using the enrolled endpoint").action(async(t)=>{try{await bi(async(m)=>{let A=Mi(m,t);if(A.trustState!=="pinned")throw Error("Validate and pin the server host key first.");let _=Bun.spawn(["ssh","-p",String(A.sshPort),"-o","StrictHostKeyChecking=yes",`${A.sshUser}@${A.endpoint}`],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}),z=await _.exited;if(z)process.exitCode=z})}catch(m){yn(m)}});for(let[t,m]of[["server:logs <name>","Use the runtime log service"],["server:deploy <name>","Use immutable release deployment"],["server:reboot <name>","Reboot provider compute"],["server:destroy <name>","Terminate provider compute"],["server:recipe <name> <recipe>","Apply a server recipe"],["server:firewall:add <name> <rule>","Add firewall rule"],["server:firewall:list <name>","List firewall rules"],["server:firewall:remove <name> <rule>","Remove firewall rule"],["server:ssl:install <domain>","Install TLS"],["server:ssl:renew <domain>","Renew TLS"],["server:snapshot <name>","Create provider snapshot"],["server:snapshot:restore <name> <snapshot-id>","Restore provider snapshot"],["server:update <name>","Update OS packages"],["server:secure <name>","Apply OS hardening"]])D.command(t,m).action(async(...A)=>En(t.split(" ")[0],{target:String(A[0]??""),nextAction:"Use the dashboard capability view or the corresponding runtime, release, firewall, backup, or maintenance service."}))}import{existsSync as vd,mkdirSync as wp,readFileSync as Sp,writeFileSync as Cp}from"node:fs";import{join as bd,resolve as $p}from"node:path";var Xa=(D)=>{r(D instanceof Error?D.message:String(D)),process.exitCode=1};async function kp(){try{return await je()}catch{return}}function Ap(D){if(D===void 0)return;let t=Number(D);if(!Number.isInteger(t)||t<1||t>65535)throw Error(`--port must be a port number, not '${D}'.`);return t}function wd(D,t,m){let A=D?.ssh?.hosts?.find((_)=>_.host===t);return new fr({hosts:t?[A??{host:t}]:D?.ssh?.hosts,user:m.user,port:Ap(m.port),privateKeyPath:m.key,hostKey:D?.ssh?.hostKey,sudo:D?.ssh?.sudo,profile:m.profile??D?.ssh?.profile,publicIp:D?.ssh?.publicIp,lan:D?.ssh?.lan})}var Sd=1073741824;function ec(D){D.command("ssh:preflight [host]","Check a bring-your-own Linux host before adopting it").option("--user <user>","SSH user (default: ssh.hosts[].user, then root)").option("--port <port>","SSH port (default: ssh.hosts[].port, then 22)").option("--key <path>","SSH private key (default: ssh.hosts[].privateKeyPath, then ~/.ssh/id_ed25519)").option("--profile <profile>","raspberry-pi or generic (default: ssh.profile, then generic)").option("--json","Print the facts and findings as JSON").action(async(t,m)=>{try{let A=await kp(),_=wd(A,t,m),z=t??_.targetHost(),U=await _.ensureHostKey(z),{facts:Y,findings:X}=await _.preflight(z);if(m.json)console.log(JSON.stringify({schemaVersion:1,host:z,hostKeyFingerprint:U.fingerprint,facts:Y,findings:X},null,2));else{if(i(`Preflight ${z}`),U.pinnedNow)e(`Pinned host key ${U.fingerprint}`);if(e(`${Y.os} on ${Y.arch}, ${Y.cpuCores} cores, ${(Y.memoryBytes/Sd).toFixed(1)} GiB memory, ${(Y.diskFreeBytes/Sd).toFixed(1)} GiB free`),Y.piModel)e(Y.piModel);if(Y.lanIp)e(`LAN address ${Y.lanIp}`);if(console.log(Zr(X)),gr(X))r("The host is not ready; fix the errors above and run the preflight again.");else n("The host is ready to adopt.")}if(gr(X))process.exitCode=1}catch(A){Xa(A)}}),D.command("ssh:bootstrap","Adopt the configured host: pin its key, run the preflight, then bootstrap it").option("--env <environment>","Deployment environment",{default:"production"}).option("--dry-run","Print the bootstrap script instead of running it").action(async(t)=>{try{let m=await je(),A=t.env??"production";if(t.dryRun){let U=mr(m),[Y]=U.hosts;console.log(pr({config:m,environment:A,profile:U.profile,sudoUser:Y.user!=="root"?Y.user:void 0,lan:U.lan}));return}let _=wd(m,void 0,{});i(`Adopt ${_.targetHost()}`);let z=await _.provisionComputeInfrastructure({config:m,environment:A});n(`${z.appPublicIp} is bootstrapped; deploy with: cloud deploy --env ${A}`)}catch(m){Xa(m)}}),D.command("ssh:first-boot","Write cloud-init first-boot files for a freshly flashed Raspberry Pi OS or Ubuntu image").option("--os <os>","raspberry-pi-os or ubuntu",{default:"raspberry-pi-os"}).option("--out <dir>","Directory to write user-data, network-config and meta-data into (never a mounted card; copy them yourself)").option("--hostname <name>","Hostname of the new host").option("--user <user>","Deploy user created on first boot (default: ssh.hosts[].user, then pi)").option("--key <path>","Public key authorized for the user",{default:"~/.ssh/id_ed25519.pub"}).option("--wifi-ssid <ssid>","Join this Wi-Fi network on first boot").option("--wifi-passphrase-env <name>","Environment variable holding the Wi-Fi passphrase",{default:"WIFI_PASSWORD"}).option("--wifi-country <cc>","Wi-Fi regulatory domain, e.g. DE").option("--timezone <tz>","IANA timezone, e.g. Europe/Berlin").option("--locale <locale>","System locale, e.g. en_US.UTF-8").option("--env <environment>","Deployment environment the embedded bootstrap is built for",{default:"production"}).option("--force","Overwrite files already in --out").action(async(t)=>{try{if(!t.out)throw Error("--out <dir> is required.");if(!t.hostname)throw Error("--hostname <name> is required.");let m=t.os??"raspberry-pi-os";if(!(m in Zi))throw Error(`--os must be raspberry-pi-os or ubuntu, not '${m}'.`);let A=await je(),_=t.env??"production",z=mr(A,{hosts:A.ssh?.hosts?.length?void 0:[{host:t.hostname}],profile:m==="raspberry-pi-os"?"raspberry-pi":void 0}),U=t.user??(A.ssh?.hosts?.[0]?.user??"pi"),Y=Qr(t.key??"~/.ssh/id_ed25519.pub");if(!vd(Y))throw Error(`Public key not found at ${Y}; pass --key <path to a .pub file>.`);let X=Sp(Y,"utf8").trim(),ne;if(t.wifiSsid){let Pe=t.wifiPassphraseEnv??"WIFI_PASSWORD",ye=process.env[Pe];if(!ye)throw Error(`--wifi-ssid needs the passphrase in $${Pe} (set it in the environment, not on the command line).`);if(!t.wifiCountry)throw Error("--wifi-country <cc> is required with --wifi-ssid.");ne={ssid:t.wifiSsid,passphrase:ye,country:t.wifiCountry}}let re=pr({config:A,environment:_,profile:z.profile,sudoUser:U!=="root"?U:void 0,lan:z.lan}),se=eo({hostname:t.hostname,user:U,publicKey:X,timezone:t.timezone,locale:t.locale,wifi:ne},re,{os:m}),he=$p(t.out);wp(he,{recursive:!0});let we=Object.keys(se.files).filter((Pe)=>vd(bd(he,Pe)));if(we.length>0&&!t.force)throw Error(`${we.join(", ")} already exist in ${he}; pass --force to overwrite.`);for(let[Pe,ye]of Object.entries(se.files))Cp(bd(he,Pe),ye,{mode:384});i(`First boot for ${t.hostname}`),n(`Wrote ${Object.keys(se.files).join(", ")} to ${he}`),console.log(se.instructions)}catch(m){Xa(m)}})}async function Rp(){let D=await je(),t=y(process.cwd(),D),m=new xn(t.store),A=new _n(m,new ke(t.store));return{controlPlane:t,store:m,service:A}}async function gs(D){let t=await Rp();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var Ks=(D)=>Object.fromEntries(String(D??"").split(",").map((t)=>t.split("=")).filter((t)=>t[0]&&t[1])),Cd=(D)=>Object.fromEntries(Object.entries(Ks(D)).map(([t,m])=>[t,Number(m)]));function tc(D){D.command("pool:list","List capacity pools and reservations").option("--json","Print structured JSON").action(async(t)=>gs((m)=>{let A=m.store.listPools(m.controlPlane.project.id);if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Purpose","Backend","Region / arch","Status","Capacity","Concurrency"],A.map((_)=>[_.name,_.purpose,_.backend,`${_.region??"any"} / ${_.architecture??"any"}`,_.status,JSON.stringify(_.capacity),String(_.concurrency)]))})),D.command("pool:create <name>","Create a capacity pool").option("--purpose <purpose>","application, build, worker, monitoring, or backup",{default:"application"}).option("--backend <backend>","server, ecs, or asg",{default:"server"}).option("--capacity <values>","cpu=4,memoryBytes=8589934592,diskBytes=...").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Pool key=value labels").option("--selector <labels>","Required server labels").option("--max <count>","Maximum workloads",{default:"10"}).option("--concurrency <count>","Build concurrency",{default:"1"}).action(async(t,m)=>gs((A)=>{let{purpose:_,backend:z}=m;if(!["application","build","worker","monitoring","backup"].includes(_)||!["server","ecs","asg"].includes(z))throw Error("Unsupported pool purpose or backend.");let U=A.store.createPool({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,purpose:_,backend:z,region:m.region,architecture:m.arch,labels:Ks(m.labels),requiredServerLabels:Ks(m.selector),toleratedTaints:[],capacity:{cpu:0,memoryBytes:0,diskBytes:0,gpu:0,...Cd(m.capacity)},maxWorkloads:Number(m.max),costWeight:1,concurrency:Number(m.concurrency),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"});n(`Created ${U.name} (${U.id}).`)})),D.command("pool:add-server <pool> <server>","Attach an enrolled server to a pool").action(async(t,m)=>gs((A)=>{let _=A.store.listPools(A.controlPlane.project.id).find((U)=>U.id===t||U.name===t),z=new ke(A.controlPlane.store).list(A.controlPlane.project.id).find((U)=>U.id===m||U.name===m);if(!_||!z)throw Error("Pool or server was not found.");A.store.addMember(_.id,z.id),n(`Attached ${z.name} to ${_.name}.`)})),D.command("placement:explain","Explain eligible and rejected placement targets").option("--purpose <purpose>","Workload purpose",{default:"application"}).option("--resources <values>","Requested resources").option("--region <region>","Required region").option("--arch <architecture>","Required architecture").option("--labels <labels>","Required pool labels").option("--json","Print structured JSON").action(async(t)=>gs((m)=>{let A=m.service.explain(m.controlPlane.project.id,{purpose:t.purpose,resources:Cd(t.resources),region:t.region,architecture:t.arch,labels:Ks(t.labels)});if(t.json)console.log(JSON.stringify(A,null,2));else c(["Pool","Server","Eligible","Available","Fit / spread / cost","Reasons"],A.map((_)=>[_.poolName,_.serverId??"provider-managed",_.eligible?"yes":"no",JSON.stringify(_.available),`${_.score.fit.toFixed(2)} / ${_.score.spread} / ${_.score.cost}`,_.reasons.join("; ")||"eligible"]))})),D.command("pool:drain <pool>","Move stateless placements and block stateful placements").action(async(t)=>gs((m)=>{let A=m.store.listPools(m.controlPlane.project.id).find((z)=>z.id===t||z.name===t);if(!A)throw Error("Pool was not found.");let _=m.service.drainPool(A.id);n(`Draining ${A.name}: moved ${_.moved.length}, blocked ${_.blocked.length} stateful placement(s).`)}))}async function Ip(){let D=await je(),t=y(process.cwd(),D),m=new On(t.store),A=new $n(m);return{controlPlane:t,store:m,service:A}}async function po(D){let t=await Ip();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}var hs=(D,t)=>{let m=D.store.list(D.controlPlane.project.id).find((A)=>A.id===t||A.name===t);if(!m)throw Error("Regional topology was not found.");return m},Pp=(D)=>D.split(",").map((t,m)=>{let[A,_="aws"]=t.split(":");return{region:String(A),provider:_,role:m===0?"primary":"secondary"}}),Dp=(D)=>{let t=new Set(["s3","dynamodb","secrets"]),m=D.split(",").map((_)=>_.trim()),A=m.find((_)=>!t.has(_));if(A)throw Error(`Unsupported replication kind: ${A}`);return m};function nc(D){D.command("region:list","List regional topology, traffic, and replication health").option("--json","Print structured JSON").action(async(t)=>po((m)=>{let A=m.store.list(m.controlPlane.project.id).map((_)=>({topology:_,targets:m.store.targets(_.id),channels:m.store.channels(_.id),route:m.store.route(_.id),executions:m.store.executions(_.id)}));if(t.json)console.log(JSON.stringify(A,null,2));else c(["Name","Hostname","Active","Status","Revision","Replication"],A.map((_)=>[_.topology.name,_.topology.hostname,_.topology.activeRegion,_.topology.status,_.topology.revision??"—",`${_.channels.filter((z)=>z.status==="in_sync").length}/${_.channels.length} in sync`]))})),D.command("region:create <name>","Create a persistent multi-region topology").option("--hostname <hostname>","Traffic hostname").option("--regions <regions>","Comma-separated region[:provider], primary first").option("--replicate <kinds>","s3,dynamodb,secrets",{default:"s3,dynamodb,secrets"}).option("--max-lag <seconds>","Maximum failover lag",{default:"30"}).option("--cdn","Enable CloudFront edge state").option("--waf","Enable WAF edge state").action(async(t,m)=>po((A)=>{if(!m.hostname||!m.regions)throw Error("--hostname and --regions are required.");let _=A.service.create({organizationId:A.controlPlane.organization.id,projectId:A.controlPlane.project.id,name:t,hostname:m.hostname,regions:Pp(m.regions),trafficPolicy:"active_passive",dataPolicy:{replicate:Dp(String(m.replicate)),maxLagSeconds:Number(m.maxLag),retainOnDestroy:!0},dnsProvider:"route53",cdnEnabled:!!m.cdn,wafEnabled:!!m.waf});n(`Created ${_.name} (${_.id}); run region:rollout with an immutable manifest.`)})),D.command("region:plan <name> <operation>","Preview exact regional execution steps").option("--target <region>","Failover or failback region").action(async(t,m,A)=>po((_)=>c(["Step"],_.service.plan(hs(_,t).id,m,A.target).map((z)=>[z])))),D.command("region:rollout <name> <revision>","Queue secondary-first regional stack rollout").option("--manifest <file>","Regional stack manifest JSON").action(async(t,m,A)=>po(async(_)=>{let z=A.manifest?await Bun.file(A.manifest).json():{},U=_.service.enqueue({topologyId:hs(_,t).id,kind:"rollout",revision:m,manifest:z});n(`Regional rollout queued: ${U.operation.id}`)})),D.command("region:failover <name> <region>","Queue health and RPO-gated failover").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"failover",targetRegion:m});n(`Failover queued: ${_.operation.id}`)})),D.command("region:failback <name> <region>","Queue health and RPO-gated failback").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"failback",targetRegion:m});n(`Failback queued: ${_.operation.id}`)})),D.command("region:destroy <name>","Drain traffic and delete regional stacks while retaining data").option("--confirm <name>","Exact topology name").action(async(t,m)=>po((A)=>{let _=A.service.enqueue({topologyId:hs(A,t).id,kind:"destroy",confirmation:m.confirm});n(`Regional teardown queued: ${_.operation.id}; replicated data remains retained.`)}))}var ys="0.16.44";async function Ep(){let D=await je(),t=y(process.cwd(),D),m=new Ln(t.store),A=new Mn(m),_=["releases","artifacts","operations","logs","previews","snapshots","orphaned_resources"].map((z)=>new Un(z,t.store,t.project.id,t.organization.id));return{controlPlane:t,store:m,service:A,cleanup:_}}async function Ii(D){let t=await Ep();try{await D(t)}catch(m){r(m instanceof Error?m.message:String(m)),process.exitCode=1}finally{t.controlPlane.store.close()}}function rc(D){D.command("maintenance:list","List updates, campaigns, cleanup plans, and DR drills").option("--json","Print structured JSON").action(async(t)=>Ii((m)=>{let A={manifests:m.store.manifests(m.controlPlane.organization.id),windows:m.store.windows(m.controlPlane.project.id),campaigns:m.store.campaigns(m.controlPlane.project.id),cleanups:m.store.cleanups(m.controlPlane.project.id),drills:m.store.drills(m.controlPlane.project.id)},_=[...A.manifests.map((z)=>["update",z.version,z.compatibility.compatible?"compatible":"blocked",z.compatibility.reasons.join("; ")||z.channel]),...A.campaigns.map((z)=>["upgrade",z.id,z.status,z.currentStage??z.fromVersion]),...A.cleanups.map((z)=>["cleanup",z.kind,z.status,`${z.candidates.length} items / ${z.estimatedBytes} bytes`]),...A.drills.map((z)=>["DR drill",z.scenario,z.status,z.isolatedTarget])];if(t.json)console.log(JSON.stringify(A,null,2));else c(["Area","Name / version","Status","Detail"],_)})),D.command("maintenance:key:add <name> <pem>","Trust an Ed25519 update signing key").action(async(t,m)=>Ii(async(A)=>{let _=A.store.addTrustedKey({organizationId:A.controlPlane.organization.id,name:t,publicKeyPem:await Bun.file(m).text()});n(`Trusted ${_.name}: ${_.fingerprint}`)})),D.command("maintenance:manifest <document> <signature> <key>","Verify and import a signed update manifest").action(async(t,m,A)=>Ii(async(_)=>{let z=await Bun.file(t).json(),U=(await Bun.file(m).text()).trim(),Y=_.store.importManifest({organizationId:_.controlPlane.organization.id,keyId:A,document:z,signature:U,current:{schemaVersion:_.controlPlane.store.health().schemaVersion,currentVersion:ys,platform:process.platform,architecture:process.arch}});n(`Verified ${Y.version}; ${Y.compatibility.compatible?"compatible":"blocked: "+Y.compatibility.reasons.join("; ")}`)})),D.command("maintenance:window <name> <schedule>","Create an approved maintenance window").option("--timezone <timezone>","IANA timezone",{default:"UTC"}).option("--minutes <minutes>","Duration",{default:"60"}).action(async(t,m,A)=>Ii((_)=>{let z=_.store.createWindow({projectId:_.controlPlane.project.id,name:t,schedule:m,timezone:A.timezone,durationMinutes:Number(A.minutes),allowedOperations:["platform.upgrade"],requireApproval:!0});n(`Created ${z.name} (${z.id}).`)})),D.command("platform:upgrade <manifest> <backup>","Plan and queue a signed staged platform update").option("--strategy <strategy>","canary or rolling",{default:"canary"}).option("--batch <count>","Rolling batch size",{default:"1"}).action(async(t,m,A)=>Ii((_)=>{let z=new ke(_.controlPlane.store).list(_.controlPlane.project.id).filter((X)=>X.status==="ready").map((X)=>({serverId:X.id,target:X.name,previousVersion:X.bootstrapVersion??ys}));if(!z.length)z.push({target:"control-plane",previousVersion:ys});let U=_.store.createCampaign({projectId:_.controlPlane.project.id,manifestId:t,fromVersion:ys,strategy:A.strategy==="rolling"?"rolling":"canary",batchSize:Number(A.batch),healthGate:{kind:"platform"},backupId:m,targets:z}),Y=_.service.enqueueCampaign(U.id);n(`Staged upgrade queued: ${Y.operation.id}`)})),D.command("cleanup:preview <kind>","Discover a bounded cleanup candidate set without deleting").option("--older-than <days>","Minimum age",{default:"30"}).action(async(t,m)=>Ii(async(A)=>{let _=await A.service.previewCleanup({projectId:A.controlPlane.project.id,kind:t,criteria:{olderThanDays:Number(m.olderThan)}},A.cleanup);c(["ID","Candidate","Bytes"],_.candidates.map((z)=>[z.id,z.label,String(z.bytes)])),e(`Apply with: cloud cleanup:apply ${_.id} --confirm "DELETE ${_.candidates.length} ${_.kind}"`)})),D.command("cleanup:apply <plan>","Apply an unchanged cleanup preview").option("--confirm <text>","Exact preview confirmation").action(async(t,m)=>Ii((A)=>{let _=A.service.enqueueCleanup(t,String(m.confirm??""));n(`Cleanup queued: ${_.operation.id}`)})),D.command("dr:plan <scenario> <target>","Plan an isolated disaster-recovery drill").option("--rpo <minutes>","RPO objective",{default:"60"}).option("--rto <minutes>","RTO objective",{default:"30"}).option("--recovery-point <id>","Recovery point").option("--topology <id>","Regional topology").action(async(t,m,A)=>Ii((_)=>{let z=_.store.createDrill({projectId:_.controlPlane.project.id,scenario:t,isolatedTarget:m,expectedRpoMinutes:Number(A.rpo),expectedRtoMinutes:Number(A.rto),recoveryPointId:A.recoveryPoint,topologyId:A.topology});n(`Planned isolated drill ${z.id}.`)})),D.command("dr:run <drill>","Queue an isolated disaster-recovery drill").action(async(t)=>Ii((m)=>{let A=m.service.enqueueDrill(t);n(`DR drill queued: ${A.operation.id}`)}))}async function ic(){try{return(await je()).project.region||process.env.AWS_REGION||"us-east-1"}catch{return process.env.AWS_REGION||"us-east-1"}}function oc(D){D.command("function:list","List all Lambda functions").option("--region <region>","AWS region").action(async(t)=>{i("Lambda Functions");let m=t?.region||await ic(),A=new I(m);try{let{Functions:_=[]}=await A.listFunctions({MaxItems:50});if(!_.length){e("No functions found");return}c(["Name","Runtime","Memory","Timeout","Last Modified"],_.map((z)=>[z.FunctionName??"-",z.Runtime??"-",z.MemorySize?`${z.MemorySize} MB`:"-",z.Timeout?`${z.Timeout}s`:"-",z.LastModified??"-"]))}catch(_){r(`Failed to list functions: ${_.message}`),process.exitCode=1}}),D.command("function:invoke <name>","Invoke a Lambda function").option("--payload <json>","Event payload as JSON",{default:"{}"}).option("--async","Fire-and-forget (Event invocation)").option("--region <region>","AWS region").action(async(t,m)=>{i(`Invoking ${t}`);let A=m?.region||await ic(),_=new I(A),z=new s("Invoking function...");z.start();try{let U=await _.invoke({FunctionName:t,InvocationType:m?.async?"Event":"RequestResponse",Payload:m?.payload||"{}",LogType:m?.async?"None":"Tail"});if(U.FunctionError){if(z.fail(`Function returned an error (${U.FunctionError})`),U.Payload)e(U.Payload);process.exitCode=1;return}if(z.succeed(`Invoked (status ${U.StatusCode})`),U.Payload)e(`
|
|
319
319
|
Response:`),e(U.Payload);if(U.LogResult)e(`
|
|
320
320
|
Logs:`),e(Buffer.from(U.LogResult,"base64").toString("utf-8"))}catch(U){z.fail(`Invocation failed: ${U.message}`),process.exitCode=1}}),D.command("function:logs <name>","View recent function logs").option("--tail","Continuously stream new log events").option("--filter <pattern>","CloudWatch filter pattern").option("--since <minutes>","Look back this many minutes",{default:"15"}).option("--region <region>","AWS region").action(async(t,m)=>{i(`Logs for ${t}`);let A=m?.region||await ic(),_=new oe(A),z=t.startsWith("/aws/lambda/")?t:`/aws/lambda/${t}`,U=Number(m?.since??15),Y=(X)=>{for(let ne of X){let re=ne.timestamp?new Date(ne.timestamp).toISOString():"";e(`${re} ${(ne.message??"").trimEnd()}`)}};try{let X=Date.now()-U*60000,{events:ne=[]}=await _.filterLogEvents({logGroupName:z,startTime:X,filterPattern:m?.filter,limit:200});if(Y(ne),ne.length)X=(ne[ne.length-1].timestamp??X)+1;if(m?.tail){e(`
|
|
321
321
|
(streaming — Ctrl+C to stop)`);for(;;){await new Promise((se)=>setTimeout(se,3000));let{events:re=[]}=await _.filterLogEvents({logGroupName:z,startTime:X,filterPattern:m?.filter,limit:200});if(re.length)Y(re),X=(re[re.length-1].timestamp??X)+1}}}catch(X){r(`Failed to read logs: ${X.message}`),process.exitCode=1}})}async function $d(D){let t=Bun.spawn(["docker",...D],{stdin:"inherit",stdout:"inherit",stderr:"pipe"}),[m,A]=await Promise.all([t.exited,new Response(t.stderr).text()]);return{ok:m===0,exitCode:m,command:["docker",...D].join(" "),stderr:A.trim()}}function sc(D){D.command("container:build","Build a Docker image").option("--tag <tag>","Image tag",{default:"latest"}).option("--file <dockerfile>","Dockerfile",{default:"Dockerfile"}).option("--dry-run","Print the exact command").option("--json","Print result JSON").action(async(t)=>{let m=["build","--file",t.file??"Dockerfile","--tag",t.tag??"latest","."];if(t.dryRun){console.log(`docker ${m.join(" ")}`);return}let A=await $d(m);if(t.json)console.log(JSON.stringify(A));if(!A.ok)r(A.stderr||`docker exited ${A.exitCode}`),process.exitCode=A.exitCode;else n(`Built ${t.tag??"latest"}.`)}),D.command("container:push","Push an already-tagged image").option("--image <image>","Full registry image reference").option("--dry-run","Print command").option("--json","Print JSON").action(async(t)=>{if(!t.image){r("--image with a full registry reference is required; credentials must come from docker credential helpers."),process.exitCode=2;return}if(t.dryRun){console.log(`docker push ${t.image}`);return}let m=await $d(["push",t.image]);if(t.json)console.log(JSON.stringify(m));if(!m.ok)r(m.stderr),process.exitCode=m.exitCode;else n(`Pushed ${t.image}.`)}),D.command("container:deploy","Deploy a container image").action(async()=>En("container:deploy",{message:"Direct ECS mutation is not registered as a shared release driver.",nextAction:"Import the image as an application and use the immutable release deployment workflow."}))}function mc(D){D.command("domain:list","List all domains").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t)=>{i("Domains");try{let m=li(t?.provider),A=pn(t?.provider)?.provider||"unknown",_=new s(`Fetching domains from ${A}...`);_.start();let z=await m.listDomains();if(_.succeed(`Found ${z.length} domain(s)`),z.length===0){e("No domains found in this provider");return}let U=z.map((Y)=>[Y,"Active","-",A.charAt(0).toUpperCase()+A.slice(1)]);c(["Domain","Status","SSL","Provider"],U)}catch(m){r(`Failed to list domains: ${m instanceof Error?m.message:String(m)}`)}}),D.command("domain:add <domain>","Add a new domain").option("--provider <provider>","DNS provider: porkbun, godaddy, cloudflare, or route53").action(async(t,m)=>{i(`Adding Domain: ${t}`);try{let A=li(m?.provider),_=pn(m?.provider)?.provider||"unknown",z=new s(`Checking if ${_} can manage ${t}...`);if(z.start(),await A.canManageDomain(t))z.succeed(`Domain ${t} is already available in ${_}`),e(`
|
|
@@ -393,7 +393,7 @@ Resources: ${wt}
|
|
|
393
393
|
|
|
394
394
|
View in console:
|
|
395
395
|
https://console.aws.amazon.com/cloudformation/home?region=${he}#/stacks/stackinfo?stackId=${encodeURIComponent(se)}`,"green"),Object.keys(Vt).length>0){e(`
|
|
396
|
-
Stack Outputs:`);for(let[St,Ft]of Object.entries(Vt))e(` - ${St}: ${Ft}`)}if(nt.length>0){let{grantFailoverReplicaAccess:St}=await import("./chunk-5nc1g18b.js");d("Granting the distribution read access to its failover replicas..."),await St(nt,Vt,(Ft)=>e(` ${Ft}`))}if(U.infrastructure?.storage)for(let[St,Ft]of Object.entries(U.infrastructure.storage)){if(!Ft.website||!Ft.root)continue;let un=Vt[`${St}BucketName`]||Vt.FrontendBucketName,mn=Vt[`${St}CloudFrontDistributionId`];if(!un){a(`Could not find bucket name for storage '${St}' — skipping file upload`);continue}if(!vn(Ft.root)){a(`Source directory not found: ${Ft.root} — skipping file upload for '${St}'`);continue}d(`Uploading files from ${Ft.root} to s3://${un}...`);let{uploadStaticFiles:Sr,invalidateCache:Li}=await import("./chunk-
|
|
396
|
+
Stack Outputs:`);for(let[St,Ft]of Object.entries(Vt))e(` - ${St}: ${Ft}`)}if(nt.length>0){let{grantFailoverReplicaAccess:St}=await import("./chunk-5nc1g18b.js");d("Granting the distribution read access to its failover replicas..."),await St(nt,Vt,(Ft)=>e(` ${Ft}`))}if(U.infrastructure?.storage)for(let[St,Ft]of Object.entries(U.infrastructure.storage)){if(!Ft.website||!Ft.root)continue;let un=Vt[`${St}BucketName`]||Vt.FrontendBucketName,mn=Vt[`${St}CloudFrontDistributionId`];if(!un){a(`Could not find bucket name for storage '${St}' — skipping file upload`);continue}if(!vn(Ft.root)){a(`Source directory not found: ${Ft.root} — skipping file upload for '${St}'`);continue}d(`Uploading files from ${Ft.root} to s3://${un}...`);let{uploadStaticFiles:Sr,invalidateCache:Li}=await import("./chunk-yxpzm8ce.js"),fn=await Sr({sourceDir:Ft.root,bucket:un,region:he,onProgress:(Ht,wn,Cn)=>{if(Ht%10===0||Ht===wn)e(` ${Ht}/${wn}: ${Cn}`)}});if(fn.errors.length>0)a(`Upload completed with errors: ${fn.errors.join(", ")}`);else{let Ht=fn.skipped>0?`Uploaded ${fn.uploaded} files (${fn.skipped} unchanged)`:`Uploaded ${fn.uploaded} files`;n(Ht)}if(mn&&fn.uploaded>0){d("Invalidating CloudFront cache...");let{invalidationId:Ht}=await Li(mn);n(`Cache invalidation created: ${Ht}`)}}if(nt.length>0){let{seedFailoverReplicas:St}=await import("./chunk-5nc1g18b.js");d("Syncing failover replicas..."),await St(nt,(Ft)=>e(` ${Ft}`))}if(U.infrastructure?.compute)await ol(U,A,he,t?.site);if(U.infrastructure?.compute&&U.sites){let St=Object.values(U.sites).map((Ft)=>Ft.domain).filter((Ft)=>!!Ft);if(St.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ia(St)}}catch(z){if(r(`Deployment failed: ${z.message}`),process.exitCode=1,z.stack)e(`
|
|
397
397
|
Stack trace:`),console.error(z.stack)}finally{if(_)await _()}}),D.command("deploy:server","Deploy EC2 infrastructure").option("--env <environment>","Environment (production, staging, development)").option("--site <name>","Deploy specific site only (routes are still regenerated in full)").action(async(t)=>{i("Deploying Server Infrastructure");try{let m=await je(),A=t?.env||"production",_=m.project.region||"us-east-1",z=$r(m);if(z){r(z),process.exitCode=1;return}if(!ko(m)){r("No `infrastructure.compute` configured — nothing to deploy as a server."),e("Add an EC2 compute block to cloud.config, or use `cloud deploy:serverless` for Lambda apps."),process.exitCode=1;return}if(e(`Region: ${_}`),e(`Environment: ${A}`),!await ol(m,A,_,t?.site)){process.exitCode=1;return}if(m.sites){let Y=Object.values(m.sites).map((X)=>X.domain).filter((X)=>!!X);if(Y.length>0)d("Syncing CloudFront dynamic HTTP methods for app domains..."),await ia(Y)}n(`
|
|
398
398
|
Server deployment complete!`)}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:serverless","Deploy a serverless application (http/queue/cli Lambda functions)").option("--env <environment>","Environment (production, staging, development)").option("--skip-build","Skip local build hooks").option("--skip-hooks","Skip remote deploy hooks (e.g. migrations)").option("--redeploy","Re-activate the last build without rebuilding").action(async(t)=>{try{let m=await je(),A=t?.env||"production",_=$r(m);if(_){r(_),process.exitCode=1;return}let{deployServerlessApp:z,redeployServerlessApp:U}=await import("./chunk-bj7ashn6.js");if(t?.redeploy){await U(m,A);return}await z(m,A,{skipBuild:t?.skipBuild,skipDeployHooks:t?.skipHooks})}catch(m){r(`Deployment failed: ${m.message}`),process.exitCode=1}}),D.command("serverless:rollback","Roll back a serverless app to the previous build").option("--env <environment>","Environment (production, staging, development)").action(async(t)=>{try{let m=await je(),A=t?.env||"production",{rollbackServerlessApp:_}=await import("./chunk-bj7ashn6.js");await _(m,A)}catch(m){r(`Rollback failed: ${m.message}`),process.exitCode=1}}),D.command("deploy:rollback [site]","Roll a compute site back to a previous release").option("--env <environment>","Environment (production, staging, development)").option("--to <release>","Release id to roll back to (default: the previous release)").option("--dry-run","Say which release it would roll back to, and change nothing").option("--all","Every configured site, instead of one").option("--only-if-live <release>","Only roll back a site whose live release is this commit (what a failed deploy switched)").action(async(t,m)=>{i("Rolling Back Release");try{let A=await je(),_=m?.env||"production",z=m?.all?Object.keys(A.sites||{}):[t||Object.keys(A.sites||{})[0]].filter(Boolean);if(z.length===0){r("No site configured to roll back."),process.exitCode=1;return}let{rollbackComputeSite:U}=await import("./chunk-7fh7b8r1.js"),Y=O({config:A});for(let X of z){let ne=await U({driver:Y,slug:A.project.slug,environment:_,logger:f},{siteName:X,to:m?.to,dryRun:m?.dryRun,onlyIfLive:m?.onlyIfLive});for(let re of ne.perInstance||[])e(` ${X} ${re.instanceId}: ${re.output?.trim()||re.status}`);if(!ne.success)r(`Rollback of ${X} failed: ${ne.error||"unknown error"}`),process.exitCode=1}}catch(A){r(`Rollback failed: ${A.message}`),process.exitCode=1}}),D.command("deploy:history [site]","Show a compute site's deployment history").option("--env <environment>","Environment (production, staging, development)").option("--limit <n>","Number of entries to show",{default:"20"}).action(async(t,m)=>{i("Deployment History");try{let A=await je(),_=m?.env||"production",z=t||Object.keys(A.sites||{})[0];if(!z){r("No site configured."),process.exitCode=1;return}let{getComputeDeployHistory:U}=await import("./chunk-7fh7b8r1.js"),Y=await U({driver:O({config:A}),slug:A.project.slug,environment:_,logger:f},{siteName:z,limit:Number.parseInt(m?.limit||"20",10)||20});if(!Y.success){r(`Could not read history: ${Y.error||"unknown error"}`),process.exitCode=1;return}for(let X of Y.perInstance||[])e(`
|
|
399
399
|
${X.instanceId}:`),e(X.output?.trimEnd()||"(no output)")}catch(A){r(`History lookup failed: ${A.message}`),process.exitCode=1}}),D.command("deploy:recipe <name> <script>","Run a reusable server recipe (a local bash file) across servers").option("--env <environment>","Environment (production, staging, development)").option("--user <user>","User to run the recipe as",{default:"root"}).action(async(t,m,A)=>{i(`Running Recipe: ${t}`);try{if(!vn(m)){r(`Recipe script not found: ${m}`),process.exitCode=1;return}let _=await je(),z=A?.env||"production",U=al(m,"utf8").split(`
|
|
@@ -629,7 +629,7 @@ Full Event Record:`);let ne=JSON.parse(X.CloudTrailEvent);console.log(JSON.strin
|
|
|
629
629
|
Create this trail?`,!0)){e("Operation cancelled");return}let z=new s("Creating trail...");z.start();let U=await A.createTrail({Name:t,S3BucketName:m.bucket,S3KeyPrefix:m.prefix,IsMultiRegionTrail:m.multiRegion,EnableLogFileValidation:m.validation,IncludeGlobalServiceEvents:m.globalEvents??!0});z.text="Starting logging...",await A.startLogging(t),z.succeed("Trail created and logging started"),n(`
|
|
630
630
|
Trail ARN: ${U.TrailARN}`),e(`S3 Bucket: ${U.S3BucketName}`)}catch(A){r(`Failed to create trail: ${A.message}`),process.exit(1)}}),D.command("audit:start <trailName>","Start CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(t,m)=>{i("Start CloudTrail Logging");try{let A=await oo(m.region),_=new s("Starting logging...");_.start(),await A.startLogging(t),_.succeed("Logging started")}catch(A){r(`Failed to start logging: ${A.message}`),process.exit(1)}}),D.command("audit:stop <trailName>","Stop CloudTrail logging").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(t,m)=>{i("Stop CloudTrail Logging");try{let A=await oo(m.region);if(a(`This will stop logging for trail: ${t}`),!await u(`
|
|
631
631
|
Stop logging?`,!1)){e("Operation cancelled");return}let z=new s("Stopping logging...");z.start(),await A.stopLogging(t),z.succeed("Logging stopped")}catch(A){r(`Failed to stop logging: ${A.message}`),process.exit(1)}}),D.command("audit:delete <trailName>","Delete a CloudTrail trail").option("--region <region>","AWS region",{default:"us-east-1"}).action(async(t,m)=>{i("Delete CloudTrail Trail");try{let A=await oo(m.region);if(a(`This will permanently delete trail: ${t}`),!await u(`
|
|
632
|
-
Delete this trail?`,!1)){e("Operation cancelled");return}let z=new s("Deleting trail...");z.start(),await A.deleteTrail(t),z.succeed("Trail deleted")}catch(A){r(`Failed to delete trail: ${A.message}`),process.exit(1)}})}function El(D){D.command("status","Show overall infrastructure health dashboard").option("--region <region>","AWS region").action(async(t)=>{i("Infrastructure Status Dashboard");try{let m=await je(),A=t.region||m.project.region||"us-east-1";e(`Region: ${A}`),e(`Project: ${m.project.name||"Unknown"}`),e("");let _=[],z=new s("Checking EC2 instances...");z.start();try{let{EC2Client:ye}=await import("./chunk-7nsjehvx.js"),Le=await new ye(A).describeInstances({Filters:[{Name:"instance-state-name",Values:["running","pending","stopping","stopped"]}]}),Re=0,De=0,Ee=0;for(let Ke of Le.Reservations||[])for(let Be of Ke.Instances||[])if(Ee++,Be.State?.Name==="running")Re++;else if(Be.State?.Name==="stopped")De++;z.succeed("EC2 instances checked"),_.push({name:"EC2 Instances",status:Re>0?"OK":Ee>0?"WARN":"INFO",details:`${Re} running, ${De} stopped, ${Ee} total`})}catch(ye){z.fail("EC2 check failed"),_.push({name:"EC2 Instances",status:"ERROR",details:ye.message})}let U=new s("Checking RDS instances...");U.start();try{let{RDSClient:ye}=await import("./chunk-mh3rgn0e.js"),Re=(await new ye(A).describeDBInstances()).DBInstances||[],De=Re.filter((Ee)=>Ee.DBInstanceStatus==="available").length;U.succeed("RDS instances checked"),_.push({name:"RDS Databases",status:Re.length>0&&De===Re.length?"OK":Re.length>0?"WARN":"INFO",details:`${De} available, ${Re.length} total`})}catch(ye){U.fail("RDS check failed"),_.push({name:"RDS Databases",status:"ERROR",details:ye.message})}let Y=new s("Checking Lambda functions...");Y.start();try{let{LambdaClient:ye}=await import("./chunk-5khcwxhn.js"),Re=(await new ye(A).listFunctions()).Functions||[];Y.succeed("Lambda functions checked"),_.push({name:"Lambda Functions",status:"OK",details:`${Re.length} function(s)`})}catch(ye){Y.fail("Lambda check failed"),_.push({name:"Lambda Functions",status:"ERROR",details:ye.message})}let X=new s("Checking S3 buckets...");X.start();try{let{S3Client:ye}=await import("./chunk-k9ate69x.js"),Re=(await new ye(A).listBuckets()).Buckets||[];X.succeed("S3 buckets checked"),_.push({name:"S3 Buckets",status:"OK",details:`${Re.length} bucket(s)`})}catch(ye){X.fail("S3 check failed"),_.push({name:"S3 Buckets",status:"ERROR",details:ye.message})}let ne=new s("Checking CloudFront distributions...");ne.start();try{let{CloudFrontClient:ye}=await import("./chunk-s64d5nw2.js"),Le=await new ye().listDistributions(),Re=Le.filter((De)=>De.Status==="Deployed").length;ne.succeed("CloudFront checked"),_.push({name:"CloudFront",status:Le.length>0&&Re===Le.length?"OK":Le.length>0?"WARN":"INFO",details:`${Re} deployed, ${Le.length} total`})}catch(ye){ne.fail("CloudFront check failed"),_.push({name:"CloudFront",status:"ERROR",details:ye.message})}let re=new s("Checking SQS queues...");re.start();try{let{SQSClient:ye}=await import("./chunk-jv9qp13h.js"),Re=(await new ye(A).listQueues()).QueueUrls||[];re.succeed("SQS queues checked"),_.push({name:"SQS Queues",status:"OK",details:`${Re.length} queue(s)`})}catch(ye){re.fail("SQS check failed"),_.push({name:"SQS Queues",status:"ERROR",details:ye.message})}let se=new s("Checking CloudFormation stacks...");se.start();try{let{CloudFormationClient:ye}=await import("./chunk-qgqgdkg0.js"),Re=(await new ye(A).listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE","CREATE_IN_PROGRESS","UPDATE_IN_PROGRESS","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_COMPLETE"])).StackSummaries||[],De=Re.filter((Be)=>Be.StackStatus==="CREATE_COMPLETE"||Be.StackStatus==="UPDATE_COMPLETE").length,Ee=Re.filter((Be)=>Be.StackStatus?.includes("IN_PROGRESS")).length,Ke=Re.filter((Be)=>Be.StackStatus?.includes("ROLLBACK")).length;se.succeed("CloudFormation checked"),_.push({name:"CloudFormation",status:Ke>0?"WARN":Ee>0?"INFO":"OK",details:`${De} healthy, ${Ee} in progress, ${Ke} rolled back`})}catch(ye){se.fail("CloudFormation check failed"),_.push({name:"CloudFormation",status:"ERROR",details:ye.message})}let he=new s("Checking SSL certificates...");he.start();try{let{ACMClient:ye}=await import("./chunk-
|
|
632
|
+
Delete this trail?`,!1)){e("Operation cancelled");return}let z=new s("Deleting trail...");z.start(),await A.deleteTrail(t),z.succeed("Trail deleted")}catch(A){r(`Failed to delete trail: ${A.message}`),process.exit(1)}})}function El(D){D.command("status","Show overall infrastructure health dashboard").option("--region <region>","AWS region").action(async(t)=>{i("Infrastructure Status Dashboard");try{let m=await je(),A=t.region||m.project.region||"us-east-1";e(`Region: ${A}`),e(`Project: ${m.project.name||"Unknown"}`),e("");let _=[],z=new s("Checking EC2 instances...");z.start();try{let{EC2Client:ye}=await import("./chunk-7nsjehvx.js"),Le=await new ye(A).describeInstances({Filters:[{Name:"instance-state-name",Values:["running","pending","stopping","stopped"]}]}),Re=0,De=0,Ee=0;for(let Ke of Le.Reservations||[])for(let Be of Ke.Instances||[])if(Ee++,Be.State?.Name==="running")Re++;else if(Be.State?.Name==="stopped")De++;z.succeed("EC2 instances checked"),_.push({name:"EC2 Instances",status:Re>0?"OK":Ee>0?"WARN":"INFO",details:`${Re} running, ${De} stopped, ${Ee} total`})}catch(ye){z.fail("EC2 check failed"),_.push({name:"EC2 Instances",status:"ERROR",details:ye.message})}let U=new s("Checking RDS instances...");U.start();try{let{RDSClient:ye}=await import("./chunk-mh3rgn0e.js"),Re=(await new ye(A).describeDBInstances()).DBInstances||[],De=Re.filter((Ee)=>Ee.DBInstanceStatus==="available").length;U.succeed("RDS instances checked"),_.push({name:"RDS Databases",status:Re.length>0&&De===Re.length?"OK":Re.length>0?"WARN":"INFO",details:`${De} available, ${Re.length} total`})}catch(ye){U.fail("RDS check failed"),_.push({name:"RDS Databases",status:"ERROR",details:ye.message})}let Y=new s("Checking Lambda functions...");Y.start();try{let{LambdaClient:ye}=await import("./chunk-5khcwxhn.js"),Re=(await new ye(A).listFunctions()).Functions||[];Y.succeed("Lambda functions checked"),_.push({name:"Lambda Functions",status:"OK",details:`${Re.length} function(s)`})}catch(ye){Y.fail("Lambda check failed"),_.push({name:"Lambda Functions",status:"ERROR",details:ye.message})}let X=new s("Checking S3 buckets...");X.start();try{let{S3Client:ye}=await import("./chunk-k9ate69x.js"),Re=(await new ye(A).listBuckets()).Buckets||[];X.succeed("S3 buckets checked"),_.push({name:"S3 Buckets",status:"OK",details:`${Re.length} bucket(s)`})}catch(ye){X.fail("S3 check failed"),_.push({name:"S3 Buckets",status:"ERROR",details:ye.message})}let ne=new s("Checking CloudFront distributions...");ne.start();try{let{CloudFrontClient:ye}=await import("./chunk-s64d5nw2.js"),Le=await new ye().listDistributions(),Re=Le.filter((De)=>De.Status==="Deployed").length;ne.succeed("CloudFront checked"),_.push({name:"CloudFront",status:Le.length>0&&Re===Le.length?"OK":Le.length>0?"WARN":"INFO",details:`${Re} deployed, ${Le.length} total`})}catch(ye){ne.fail("CloudFront check failed"),_.push({name:"CloudFront",status:"ERROR",details:ye.message})}let re=new s("Checking SQS queues...");re.start();try{let{SQSClient:ye}=await import("./chunk-jv9qp13h.js"),Re=(await new ye(A).listQueues()).QueueUrls||[];re.succeed("SQS queues checked"),_.push({name:"SQS Queues",status:"OK",details:`${Re.length} queue(s)`})}catch(ye){re.fail("SQS check failed"),_.push({name:"SQS Queues",status:"ERROR",details:ye.message})}let se=new s("Checking CloudFormation stacks...");se.start();try{let{CloudFormationClient:ye}=await import("./chunk-qgqgdkg0.js"),Re=(await new ye(A).listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE","CREATE_IN_PROGRESS","UPDATE_IN_PROGRESS","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_COMPLETE"])).StackSummaries||[],De=Re.filter((Be)=>Be.StackStatus==="CREATE_COMPLETE"||Be.StackStatus==="UPDATE_COMPLETE").length,Ee=Re.filter((Be)=>Be.StackStatus?.includes("IN_PROGRESS")).length,Ke=Re.filter((Be)=>Be.StackStatus?.includes("ROLLBACK")).length;se.succeed("CloudFormation checked"),_.push({name:"CloudFormation",status:Ke>0?"WARN":Ee>0?"INFO":"OK",details:`${De} healthy, ${Ee} in progress, ${Ke} rolled back`})}catch(ye){se.fail("CloudFormation check failed"),_.push({name:"CloudFormation",status:"ERROR",details:ye.message})}let he=new s("Checking SSL certificates...");he.start();try{let{ACMClient:ye}=await import("./chunk-g3a9a8bx.js"),Ie=new ye("us-east-1"),Re=(await Ie.listCertificates()).CertificateSummaryList||[],De=await Promise.all(Re.map((_e)=>Ie.describeCertificate({CertificateArn:_e.CertificateArn}))),Ee=De.filter((_e)=>_e.Status==="ISSUED").length,Ke=De.filter((_e)=>_e.Status==="PENDING_VALIDATION").length,Be=De.filter((_e)=>{if(_e.NotAfter)return(new Date(_e.NotAfter).getTime()-Date.now())/86400000<30;return!1}).length;he.succeed("SSL certificates checked"),_.push({name:"SSL Certificates",status:Be>0?"WARN":Ke>0?"INFO":"OK",details:`${Ee} issued, ${Ke} pending${Be>0?`, ${Be} expiring soon`:""}`})}catch(ye){he.fail("ACM check failed"),_.push({name:"SSL Certificates",status:"ERROR",details:ye.message})}e(`
|
|
633
633
|
`+"=".repeat(60)),e("HEALTH SUMMARY"),e("=".repeat(60)+`
|
|
634
634
|
`);for(let ye of _){let Ie="";if(ye.status==="OK")Ie=`${C.green}[OK]${C.reset}`;else if(ye.status==="WARN")Ie=`${C.yellow}[WARN]${C.reset}`;else if(ye.status==="ERROR")Ie=`${C.red}[ERROR]${C.reset}`;else Ie=`${C.blue}[INFO]${C.reset}`;console.log(`${Ie} ${ye.name.padEnd(20)} ${ye.details}`)}let we=_.some((ye)=>ye.status==="ERROR"),Pe=_.some((ye)=>ye.status==="WARN");if(e(""),we)r("Some services have errors. Check the details above.");else if(Pe)a("Some services need attention. Check the warnings above.");else n("All services are healthy!")}catch(m){r(`Failed to get status: ${m.message}`),process.exit(1)}}),D.command("status:costs","Show current month cost summary").option("--region <region>","AWS region").action(async(t)=>{i("Cost Summary");try{e("Fetching cost data from AWS Cost Explorer..."),e("");let m=new Date,A=new Date(m.getFullYear(),m.getMonth(),1),_=new Date(m.getFullYear(),m.getMonth()+1,0);e(`Period: ${A.toISOString().split("T")[0]} to ${_.toISOString().split("T")[0]}`),e(""),e("Note: Cost data requires AWS Cost Explorer API access."),e("Run `cloud cost` for detailed cost analysis.")}catch(m){r(`Failed to get cost summary: ${m.message}`),process.exit(1)}}),D.command("status:alarms","Show CloudWatch alarm status").option("--region <region>","AWS region").action(async(t)=>{i("CloudWatch Alarms");try{let m=await je(),A=t.region||m.project.region||"us-east-1",{AWSClient:_}=await import("./chunk-bb08ms5q.js");class z{client;region;constructor(we){this.region=we,this.client=new _}async describeAlarms(){return this.client.request({service:"monitoring",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=DescribeAlarms&Version=2010-08-01"})}}let U=new z(A),Y=new s("Fetching alarms...");Y.start();let ne=(await U.describeAlarms()).MetricAlarms||[];if(Y.succeed(`Found ${ne.length} alarm(s)`),ne.length===0){e("No CloudWatch alarms configured");return}let re=ne.filter((we)=>we.StateValue==="ALARM"),se=ne.filter((we)=>we.StateValue==="OK"),he=ne.filter((we)=>we.StateValue==="INSUFFICIENT_DATA");if(e(""),e(`Alarming: ${re.length}`),e(`OK: ${se.length}`),e(`Insufficient Data: ${he.length}`),re.length>0){e(`
|
|
635
635
|
Alarms in ALARM state:`);for(let we of re)r(` - ${we.AlarmName}: ${we.AlarmDescription||"No description"}`)}}catch(m){r(`Failed to get alarms: ${m.message}`),process.exit(1)}})}async function Ur(D){let{AWSClient:t}=await import("./chunk-bb08ms5q.js");class m{client;region;constructor(A){this.region=A,this.client=new t}async jsonRpcRequest(A,_){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${A}`},body:JSON.stringify(_)})}async listBackupVaults(){return this.jsonRpcRequest("ListBackupVaults",{})}async listBackupPlans(){return this.jsonRpcRequest("ListBackupPlans",{})}async listRecoveryPointsByBackupVault(A,_){return this.jsonRpcRequest("ListRecoveryPointsByBackupVault",{BackupVaultName:A,..._})}async describeBackupVault(A){return this.jsonRpcRequest("DescribeBackupVault",{BackupVaultName:A})}async getBackupPlan(A){return this.jsonRpcRequest("GetBackupPlan",{BackupPlanId:A})}async createBackupVault(A,_){return this.jsonRpcRequest("CreateBackupVault",{BackupVaultName:A,..._})}async deleteBackupVault(A){return this.jsonRpcRequest("DeleteBackupVault",{BackupVaultName:A})}async createBackupPlan(A){return this.jsonRpcRequest("CreateBackupPlan",{BackupPlan:A})}async deleteBackupPlan(A){return this.jsonRpcRequest("DeleteBackupPlan",{BackupPlanId:A})}async startBackupJob(A){return this.jsonRpcRequest("StartBackupJob",A)}async startRestoreJob(A){return this.jsonRpcRequest("StartRestoreJob",A)}async describeBackupJob(A){return this.jsonRpcRequest("DescribeBackupJob",{BackupJobId:A})}async describeRestoreJob(A){return this.jsonRpcRequest("DescribeRestoreJob",{RestoreJobId:A})}async listBackupJobs(A){return this.jsonRpcRequest("ListBackupJobs",A||{})}async listRestoreJobs(A){return this.jsonRpcRequest("ListRestoreJobs",A||{})}async createBackupSelection(A,_){return this.jsonRpcRequest("CreateBackupSelection",{BackupPlanId:A,BackupSelection:_})}async listBackupSelections(A){return this.jsonRpcRequest("ListBackupSelections",{BackupPlanId:A})}}return new m(D)}function Tl(D){D.command("backup:vaults","List backup vaults").option("--region <region>","AWS region").action(async(t)=>{i("Backup Vaults");try{let m=await je(),A=t.region||m.project.region||"us-east-1",_=await Ur(A),z=new s("Fetching vaults...");z.start();let Y=(await _.listBackupVaults()).BackupVaultList||[];if(z.succeed(`Found ${Y.length} vault(s)`),Y.length===0){e("No backup vaults found"),e("Use `cloud backup:create-vault` to create a new vault");return}c(["Vault Name","Recovery Points","Created","Encrypted"],Y.map((X)=>[X.BackupVaultName||"N/A",(X.NumberOfRecoveryPoints||0).toString(),X.CreationDate?new Date(X.CreationDate).toLocaleDateString():"N/A",X.EncryptionKeyArn?"Yes":"Default"]))}catch(m){r(`Failed to list vaults: ${m.message}`),process.exit(1)}}),D.command("backup:list","List backup plans").option("--region <region>","AWS region").action(async(t)=>{i("Backup Plans");try{let m=await je(),A=t.region||m.project.region||"us-east-1",_=await Ur(A),z=new s("Fetching backup plans...");z.start();let Y=(await _.listBackupPlans()).BackupPlansList||[];if(z.succeed(`Found ${Y.length} backup plan(s)`),Y.length===0){e("No backup plans found"),e("Use `cloud backup:create` to create a backup plan");return}c(["Plan Name","Plan ID","Version","Created"],Y.map((X)=>[X.BackupPlanName||"N/A",X.BackupPlanId||"N/A",X.VersionId?.substring(0,8)||"N/A",X.CreationDate?new Date(X.CreationDate).toLocaleDateString():"N/A"]))}catch(m){r(`Failed to list backup plans: ${m.message}`),process.exit(1)}}),D.command("backup:recovery-points <vaultName>","List recovery points in a vault").option("--region <region>","AWS region").option("--limit <number>","Maximum results",{default:"50"}).action(async(t,m)=>{i(`Recovery Points: ${t}`);try{let A=await je(),_=m.region||A.project.region||"us-east-1",z=await Ur(_),U=new s("Fetching recovery points...");U.start();let X=(await z.listRecoveryPointsByBackupVault(t,{MaxResults:Number.parseInt(m.limit)})).RecoveryPoints||[];if(U.succeed(`Found ${X.length} recovery point(s)`),X.length===0){e("No recovery points found");return}c(["Resource","Status","Created","Size","Lifecycle"],X.map((ne)=>[ne.ResourceArn?.split(":").pop()||"N/A",ne.Status||"N/A",ne.CreationDate?new Date(ne.CreationDate).toLocaleString():"N/A",ne.BackupSizeInBytes?Du(ne.BackupSizeInBytes):"N/A",ne.Lifecycle?.DeleteAfterDays?`${ne.Lifecycle.DeleteAfterDays} days`:"Indefinite"]))}catch(A){r(`Failed to list recovery points: ${A.message}`),process.exit(1)}}),D.command("backup:create-vault <vaultName>","Create a backup vault").option("--region <region>","AWS region",{default:"us-east-1"}).option("--kms-key <arn>","KMS key ARN for encryption").action(async(t,m)=>{i("Create Backup Vault");try{let A=await Ur(m.region);if(e(`Vault Name: ${t}`),e(`Region: ${m.region}`),e(`Encryption: ${m.kmsKey?"Custom KMS":"AWS Managed"}`),!await u(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-tf8qxy9k.js";import"./chunk-4yym8xm4.js";import"./chunk-pnj95hwr.js";import"./chunk-vjfwnj9z.js";import{cr}from"./chunk-erf79tm2.js";import"./chunk-dkf2kcsc.js";import"./chunk-nmqjmx30.js";import"./chunk-kzpzkdpd.js";import"./chunk-8z4wgqkh.js";import"./chunk-t80pxn04.js";import"./chunk-7593hjcq.js";import"./chunk-3v2pd05g.js";import"./chunk-pf9dbm3b.js";import"./chunk-gn03w47w.js";import"./chunk-
|
|
1
|
+
import"./chunk-tf8qxy9k.js";import"./chunk-4yym8xm4.js";import"./chunk-pnj95hwr.js";import"./chunk-vjfwnj9z.js";import{cr}from"./chunk-erf79tm2.js";import"./chunk-dkf2kcsc.js";import"./chunk-nmqjmx30.js";import"./chunk-kzpzkdpd.js";import"./chunk-8z4wgqkh.js";import"./chunk-t80pxn04.js";import"./chunk-7593hjcq.js";import"./chunk-3v2pd05g.js";import"./chunk-pf9dbm3b.js";import"./chunk-gn03w47w.js";import"./chunk-gngsb689.js";import"./chunk-35x7z78g.js";import"./chunk-kdsgbvep.js";import"./chunk-9eqpnanr.js";import"./chunk-7p2va3nj.js";import"./chunk-cqc4e8md.js";import"./chunk-xxe9ga9r.js";import"./chunk-5amvqed8.js";import"./chunk-qj6tr7bw.js";import"./chunk-jaexpxs8.js";import"./chunk-nj9x0tb8.js";import"./chunk-fkzp9sg5.js";import"./chunk-f64jvh96.js";import n from"node:process";function r(o){let e=n.argv.indexOf(o);return e===-1?void 0:n.argv[e+1]}function t(o){return n.argv.includes(o)}async function i(){let o=await cr({host:r("--host")??"127.0.0.1",port:Number(r("--port")??7676),environment:r("--env"),box:t("--box"),verbose:t("--verbose")});console.log("ts-cloud Local Dashboard"),console.log(`Serving ${o.url}`),await new Promise((e)=>{let s=()=>{o.server.stop(!0),e()};n.once("SIGINT",s),n.once("SIGTERM",s)})}i();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{u}from"./chunk-
|
|
1
|
+
import{u}from"./chunk-hm6pwhne.js";var pt="/etc/rpx/sites.d",eA={start:3000,end:3999};function g(t){return t.slug?.trim()||"app"}function Kc(t){let r=t.lastIndexOf(":");if(r<0||r===t.length-1)return;let e=t.slice(r+1).trim();if(!/^\d+$/.test(e))return;let n=Number(e);return n>=1&&n<=65535?n:void 0}function bi(t,r={}){let e=r.ignoreSlug?.trim(),n=new Map;for(let o of t){let c=g(o);if(e&&c===e)continue;for(let a of o.proxies??[]){let f=typeof a.from==="string"?[a.from]:a.from??[];for(let i of f){let d=Kc(i);if(d!==void 0&&!n.has(d))n.set(d,c)}}}return n}function Ci(t=pt){return[`for __tsc_fragment in ${t}/*.json; do`,' [ -f "$__tsc_fragment" ] || continue',` base64 < "$__tsc_fragment" | tr -d '\\n'`," printf '\\n'","done"].join(`
|
|
2
2
|
`)}function Ei(t){let r=[];for(let e of t.split(`
|
|
3
3
|
`)){let n=e.trim();if(!n)continue;try{let o=JSON.parse(Buffer.from(n,"base64").toString("utf8"));if(o&&typeof o==="object"&&!Array.isArray(o))r.push(o)}catch{continue}}return r}function yp(t,r,e=eA){let n=[],o=[],c=new Set(r.keys());for(let[a,f]of Object.entries(t.sites??{})){if(!f||u(f)!=="server-app")continue;let i=typeof f.port==="number"?f.port:void 0,d=Math.max(i??e.start,e.start),p;for(let s=d;s<=e.end;s++)if(!c.has(s)){p=s;break}if(p===void 0){let s=i!==void 0?r.get(i):void 0;o.push(`No free port for site '${a}' in ${e.start}-${e.end}${i!==void 0?` (wanted ${i}${s?`, held by '${s}'`:""})`:""}. Widen the range or free a port on the box.`);continue}c.add(p),n.push({site:a,port:p,declared:i,moved:i!==void 0&&p!==i})}return{allocations:n,errors:o}}
|
|
4
4
|
export{pt,eA,Kc,bi,Ci,Ei,yp};
|